spiped 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/spiped/extconf.rb +3 -0
- data/ext/spiped/spiped-source/BUILDING +46 -0
- data/ext/spiped/spiped-source/CHANGELOG +44 -0
- data/ext/spiped/spiped-source/COPYRIGHT +33 -0
- data/ext/spiped/spiped-source/Makefile +47 -0
- data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
- data/ext/spiped/spiped-source/Makefile.inc +20 -0
- data/ext/spiped/spiped-source/Makefile.prog +23 -0
- data/ext/spiped/spiped-source/POSIX/README +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
- data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
- data/ext/spiped/spiped-source/README +198 -0
- data/ext/spiped/spiped-source/STYLE +151 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
- data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
- data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
- data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
- data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
- data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
- data/ext/spiped/spiped-source/spipe/Makefile +90 -0
- data/ext/spiped/spiped-source/spipe/README +24 -0
- data/ext/spiped/spiped-source/spipe/main.c +178 -0
- data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
- data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
- data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
- data/ext/spiped/spiped-source/spiped/Makefile +98 -0
- data/ext/spiped/spiped-source/spiped/README +62 -0
- data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
- data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
- data/ext/spiped/spiped-source/spiped/main.c +267 -0
- data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
- data/lib/spiped.rb +3 -0
- metadata +143 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
#ifndef _PTRHEAP_H_
|
2
|
+
#define _PTRHEAP_H_
|
3
|
+
|
4
|
+
#include <stddef.h>
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Pointer-heap data structure. Arbitrary pointers can be inserted and are
|
8
|
+
* compared using a provided callback; the usual heapy getmin / increasemin /
|
9
|
+
* deletemin algorithms are supported. To use two additional functions,
|
10
|
+
* ptrheap_delete and ptrheap_increase, a setreccookie callback needs to be
|
11
|
+
* provided. Both functions require a record cookie to identify the element
|
12
|
+
* to increase or delete; each time a record's record cookie changes, the
|
13
|
+
* setreccookie callback will be called. Functions return NULL or (int)(-1)
|
14
|
+
* on error and set errno; other return types indicate that failure is not
|
15
|
+
* possible. On error, the heap will be unmodified.
|
16
|
+
*/
|
17
|
+
|
18
|
+
/* Opaque pointer-heap type. */
|
19
|
+
struct ptrheap;
|
20
|
+
|
21
|
+
/**
|
22
|
+
* ptrheap_init(compar, setreccookie, cookie):
|
23
|
+
* Create and return an empty heap. The function ${compar}(${cookie}, x, y)
|
24
|
+
* should return less than, equal to, or greater than 0 depending on whether
|
25
|
+
* x is less than, equal to, or greater than y; and if ${setreccookie} is
|
26
|
+
* non-zero it will be called as ${setreccookie}(${cookie}, ${ptr}, ${rc}) to
|
27
|
+
* indicate that the value ${rc} is the current record cookie for the pointer
|
28
|
+
* ${ptr}. The function ${setreccookie} may not make any ptrheap_* calls.
|
29
|
+
*/
|
30
|
+
struct ptrheap * ptrheap_init(int (*)(void *, const void *, const void *),
|
31
|
+
void (*)(void *, void *, size_t), void *);
|
32
|
+
|
33
|
+
/**
|
34
|
+
* ptrheap_create(compar, setreccookie, cookie, N, ptrs):
|
35
|
+
* Create and return a heap, as in ptrheap_init, but with the ${N} pointers
|
36
|
+
* in ${ptrs} as heap elements. This is faster than creating an empty heap
|
37
|
+
* and adding the elements individually.
|
38
|
+
*/
|
39
|
+
struct ptrheap * ptrheap_create(int (*)(void *, const void *, const void *),
|
40
|
+
void (*)(void *, void *, size_t), void *, size_t, void **);
|
41
|
+
|
42
|
+
/**
|
43
|
+
* ptrheap_add(H, ptr):
|
44
|
+
* Add the pointer ${ptr} to the heap ${H}.
|
45
|
+
*/
|
46
|
+
int ptrheap_add(struct ptrheap *, void *);
|
47
|
+
|
48
|
+
/**
|
49
|
+
* ptrheap_getmin(H):
|
50
|
+
* Return the minimum pointer in the heap ${H}. If the heap is empty, NULL
|
51
|
+
* is returned.
|
52
|
+
*/
|
53
|
+
void * ptrheap_getmin(struct ptrheap *);
|
54
|
+
|
55
|
+
/**
|
56
|
+
* ptrheap_delete(H, rc):
|
57
|
+
* Delete from the heap ${H} the element ptr for which the function call
|
58
|
+
* setreccookie(cookie, ptr, ${rc}) was most recently made.
|
59
|
+
*/
|
60
|
+
void ptrheap_delete(struct ptrheap *, size_t);
|
61
|
+
|
62
|
+
/**
|
63
|
+
* ptrheap_deletemin(H):
|
64
|
+
* Delete the minimum element in the heap ${H}. The heap must not be empty.
|
65
|
+
*/
|
66
|
+
void ptrheap_deletemin(struct ptrheap *);
|
67
|
+
|
68
|
+
/**
|
69
|
+
* ptrheap_increase(H, rc):
|
70
|
+
* Adjust the heap ${H} to account for the fact that the element ptr for
|
71
|
+
* which the function call setreccookie(cookie, ptr, ${rc}) was most recently
|
72
|
+
* made has increased.
|
73
|
+
*/
|
74
|
+
void ptrheap_increase(struct ptrheap *, size_t);
|
75
|
+
|
76
|
+
/**
|
77
|
+
* ptrheap_increasemin(H):
|
78
|
+
* Adjust the heap ${H} to account for the fact that the (formerly) minimum
|
79
|
+
* element has increased.
|
80
|
+
*/
|
81
|
+
void ptrheap_increasemin(struct ptrheap *);
|
82
|
+
|
83
|
+
/**
|
84
|
+
* ptrheap_free(H):
|
85
|
+
* Free the pointer heap ${H}.
|
86
|
+
*/
|
87
|
+
void ptrheap_free(struct ptrheap *);
|
88
|
+
|
89
|
+
#endif /* !_PTRHEAP_H_ */
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#include <sys/time.h>
|
2
|
+
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
|
6
|
+
#include "ptrheap.h"
|
7
|
+
|
8
|
+
#include "timerqueue.h"
|
9
|
+
|
10
|
+
struct timerqueue {
|
11
|
+
struct ptrheap * H;
|
12
|
+
};
|
13
|
+
|
14
|
+
struct timerrec {
|
15
|
+
struct timeval tv;
|
16
|
+
size_t rc;
|
17
|
+
void * ptr;
|
18
|
+
};
|
19
|
+
|
20
|
+
/* Compare two timevals. */
|
21
|
+
static int
|
22
|
+
tvcmp(const struct timeval * x, const struct timeval * y)
|
23
|
+
{
|
24
|
+
|
25
|
+
/* Does one have more seconds? */
|
26
|
+
if (x->tv_sec > y->tv_sec)
|
27
|
+
return (1);
|
28
|
+
if (x->tv_sec < y->tv_sec)
|
29
|
+
return (-1);
|
30
|
+
|
31
|
+
/* Does one have more microseconds? */
|
32
|
+
if (x->tv_usec > y->tv_usec)
|
33
|
+
return (1);
|
34
|
+
if (x->tv_usec < y->tv_usec)
|
35
|
+
return (-1);
|
36
|
+
|
37
|
+
/* They must be equal. */
|
38
|
+
return (0);
|
39
|
+
}
|
40
|
+
|
41
|
+
/* Record-comparison callback from ptrheap. */
|
42
|
+
static int
|
43
|
+
compar(void * cookie, const void * x, const void * y)
|
44
|
+
{
|
45
|
+
const struct timerrec * _x = x;
|
46
|
+
const struct timerrec * _y = y;
|
47
|
+
|
48
|
+
(void)cookie; /* UNUSED */
|
49
|
+
|
50
|
+
return (tvcmp(&_x->tv, &_y->tv));
|
51
|
+
}
|
52
|
+
|
53
|
+
/* Cookie-recording callback from ptrheap. */
|
54
|
+
static void
|
55
|
+
setreccookie(void * cookie, void * ptr, size_t rc)
|
56
|
+
{
|
57
|
+
struct timerrec * rec = ptr;
|
58
|
+
|
59
|
+
(void)cookie; /* UNUSED */
|
60
|
+
|
61
|
+
rec->rc = rc;
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* timerqueue_init(void):
|
66
|
+
* Create and return an empty timer priority queue.
|
67
|
+
*/
|
68
|
+
struct timerqueue *
|
69
|
+
timerqueue_init(void)
|
70
|
+
{
|
71
|
+
struct timerqueue * Q;
|
72
|
+
|
73
|
+
/* Allocate structure. */
|
74
|
+
if ((Q = malloc(sizeof(struct timerqueue))) == NULL)
|
75
|
+
goto err0;
|
76
|
+
|
77
|
+
/* Allocate heap. */
|
78
|
+
if ((Q->H = ptrheap_init(compar, setreccookie, Q)) == NULL)
|
79
|
+
goto err1;
|
80
|
+
|
81
|
+
/* Success! */
|
82
|
+
return (Q);
|
83
|
+
|
84
|
+
err1:
|
85
|
+
free(Q);
|
86
|
+
err0:
|
87
|
+
/* Failure! */
|
88
|
+
return (NULL);
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* timerqueue_add(Q, tv, ptr):
|
93
|
+
* Add the pair (${tv}, ${ptr}) to the priority queue ${Q}. Returns a cookie
|
94
|
+
* which can be passed to timerqueue_delete or timerqueue_increase.
|
95
|
+
*/
|
96
|
+
void *
|
97
|
+
timerqueue_add(struct timerqueue * Q, const struct timeval * tv, void * ptr)
|
98
|
+
{
|
99
|
+
struct timerrec * r;
|
100
|
+
|
101
|
+
/* Allocate (timeval, ptr) pair record. */
|
102
|
+
if ((r = malloc(sizeof(struct timerrec))) == NULL)
|
103
|
+
goto err0;
|
104
|
+
|
105
|
+
/* Fill in values. */
|
106
|
+
memcpy(&r->tv, tv, sizeof(struct timeval));
|
107
|
+
r->ptr = ptr;
|
108
|
+
|
109
|
+
/*
|
110
|
+
* Add the record to the heap. The value r->rc will be filled in
|
111
|
+
* by setreccookie which will be called by ptrheap_add.
|
112
|
+
*/
|
113
|
+
if (ptrheap_add(Q->H, r))
|
114
|
+
goto err1;
|
115
|
+
|
116
|
+
/* Success! */
|
117
|
+
return (r);
|
118
|
+
|
119
|
+
err1:
|
120
|
+
free(r);
|
121
|
+
err0:
|
122
|
+
/* Failure! */
|
123
|
+
return (NULL);
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* timerqueue_delete(Q, cookie):
|
128
|
+
* Delete the (timeval, ptr) pair associated with the cookie ${cookie} from
|
129
|
+
* the priority queue ${Q}.
|
130
|
+
*/
|
131
|
+
void
|
132
|
+
timerqueue_delete(struct timerqueue * Q, void * cookie)
|
133
|
+
{
|
134
|
+
struct timerrec * r = cookie;
|
135
|
+
|
136
|
+
/* Remove the record from the heap. */
|
137
|
+
ptrheap_delete(Q->H, r->rc);
|
138
|
+
|
139
|
+
/* Free the record. */
|
140
|
+
free(r);
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* timerqueue_increase(Q, cookie, tv):
|
145
|
+
* Increase the timer associated with the cookie ${cookie} in the priority
|
146
|
+
* queue ${Q} to ${tv}.
|
147
|
+
*/
|
148
|
+
void
|
149
|
+
timerqueue_increase(struct timerqueue * Q, void * cookie,
|
150
|
+
const struct timeval * tv)
|
151
|
+
{
|
152
|
+
struct timerrec * r = cookie;
|
153
|
+
|
154
|
+
/* Adjust timer value. */
|
155
|
+
memcpy(&r->tv, tv, sizeof(struct timeval));
|
156
|
+
|
157
|
+
/* Inform the heap that the record value has increased. */
|
158
|
+
ptrheap_increase(Q->H, r->rc);
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* timerqueue_getmin(Q):
|
163
|
+
* Return a pointer to the least timeval in ${Q}, or NULL if the priority
|
164
|
+
* queue is empty. The pointer will remain valid until the next call to a
|
165
|
+
* timerqueue_* function. This function cannot fail.
|
166
|
+
*/
|
167
|
+
const struct timeval *
|
168
|
+
timerqueue_getmin(struct timerqueue * Q)
|
169
|
+
{
|
170
|
+
struct timerrec * r;
|
171
|
+
|
172
|
+
/* Get the minimum element from the heap. */
|
173
|
+
r = ptrheap_getmin(Q->H);
|
174
|
+
|
175
|
+
/* If we have an element, return its timeval; otherwise, NULL. */
|
176
|
+
if (r != NULL)
|
177
|
+
return (&r->tv);
|
178
|
+
else
|
179
|
+
return (NULL);
|
180
|
+
}
|
181
|
+
|
182
|
+
/**
|
183
|
+
* timerqueue_getptr(Q, tv):
|
184
|
+
* If the least timeval in ${Q} is less than or equal to ${tv}, return the
|
185
|
+
* associated pointer and remove the pair from the priority queue. If not,
|
186
|
+
* return NULL.
|
187
|
+
*/
|
188
|
+
void *
|
189
|
+
timerqueue_getptr(struct timerqueue * Q, const struct timeval * tv)
|
190
|
+
{
|
191
|
+
struct timerrec * r;
|
192
|
+
void * ptr;
|
193
|
+
|
194
|
+
/*
|
195
|
+
* Get the minimum element from the heap. Return NULL if the heap
|
196
|
+
* has no minimum element (i.e., is empty).
|
197
|
+
*/
|
198
|
+
if ((r = ptrheap_getmin(Q->H)) == NULL)
|
199
|
+
return (NULL);
|
200
|
+
|
201
|
+
/* If the minimum timeval is greater than ${tv}, return NULL. */
|
202
|
+
if (tvcmp(&r->tv, tv) > 0)
|
203
|
+
return (NULL);
|
204
|
+
|
205
|
+
/* Remove this record from the heap. */
|
206
|
+
ptrheap_deletemin(Q->H);
|
207
|
+
|
208
|
+
/* Extract its pointer. */
|
209
|
+
ptr = r->ptr;
|
210
|
+
|
211
|
+
/* Free the record. */
|
212
|
+
free(r);
|
213
|
+
|
214
|
+
/*
|
215
|
+
* And finally return the pointer which was associated with the
|
216
|
+
* (formerly) minimum timeval in the heap.
|
217
|
+
*/
|
218
|
+
return (ptr);
|
219
|
+
}
|
220
|
+
|
221
|
+
/**
|
222
|
+
* timerqueue_free(Q):
|
223
|
+
* Free the timer priority queue ${Q}.
|
224
|
+
*/
|
225
|
+
void
|
226
|
+
timerqueue_free(struct timerqueue * Q)
|
227
|
+
{
|
228
|
+
struct timerrec * r;
|
229
|
+
|
230
|
+
/* Extract elements from the heap and free them one by one. */
|
231
|
+
while ((r = ptrheap_getmin(Q->H)) != NULL) {
|
232
|
+
free(r);
|
233
|
+
ptrheap_deletemin(Q->H);
|
234
|
+
}
|
235
|
+
|
236
|
+
/* Free the heap. */
|
237
|
+
ptrheap_free(Q->H);
|
238
|
+
|
239
|
+
/* Free the timer priority queue structure. */
|
240
|
+
free(Q);
|
241
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#ifndef _TIMERQUEUE_H_
|
2
|
+
#define _TIMERQUEUE_H_
|
3
|
+
|
4
|
+
#include <sys/time.h>
|
5
|
+
|
6
|
+
/* Timer priority queue. Contains (timeval, ptr) pairs. */
|
7
|
+
|
8
|
+
/* Opaque timer priority queue type. */
|
9
|
+
struct timerqueue;
|
10
|
+
|
11
|
+
/**
|
12
|
+
* timerqueue_init(void):
|
13
|
+
* Create and return an empty timer priority queue.
|
14
|
+
*/
|
15
|
+
struct timerqueue * timerqueue_init(void);
|
16
|
+
|
17
|
+
/**
|
18
|
+
* timerqueue_add(Q, tv, ptr):
|
19
|
+
* Add the pair (${tv}, ${ptr}) to the priority queue ${Q}. Returns a cookie
|
20
|
+
* which can be passed to timerqueue_delete or timerqueue_increase.
|
21
|
+
*/
|
22
|
+
void * timerqueue_add(struct timerqueue *, const struct timeval *, void *);
|
23
|
+
|
24
|
+
/**
|
25
|
+
* timerqueue_delete(Q, cookie):
|
26
|
+
* Delete the (timeval, ptr) pair associated with the cookie ${cookie} from
|
27
|
+
* the priority queue ${Q}.
|
28
|
+
*/
|
29
|
+
void timerqueue_delete(struct timerqueue *, void *);
|
30
|
+
|
31
|
+
/**
|
32
|
+
* timerqueue_increase(Q, cookie, tv):
|
33
|
+
* Increase the timer associated with the cookie ${cookie} in the priority
|
34
|
+
* queue ${Q} to ${tv}.
|
35
|
+
*/
|
36
|
+
void timerqueue_increase(struct timerqueue *, void *, const struct timeval *);
|
37
|
+
|
38
|
+
/**
|
39
|
+
* timerqueue_getmin(Q):
|
40
|
+
* Return a pointer to the least timeval in ${Q}, or NULL if the priority
|
41
|
+
* queue is empty. The pointer will remain valid until the next call to a
|
42
|
+
* timerqueue_* function. This function cannot fail.
|
43
|
+
*/
|
44
|
+
const struct timeval * timerqueue_getmin(struct timerqueue *);
|
45
|
+
|
46
|
+
/**
|
47
|
+
* timerqueue_getptr(Q, tv):
|
48
|
+
* If the least timeval in ${Q} is less than or equal to ${tv}, return the
|
49
|
+
* associated pointer and remove the pair from the priority queue. If not,
|
50
|
+
* return NULL. This function cannot fail.
|
51
|
+
*/
|
52
|
+
void * timerqueue_getptr(struct timerqueue *, const struct timeval *);
|
53
|
+
|
54
|
+
/**
|
55
|
+
* timerqueue_free(Q):
|
56
|
+
* Free the timer priority queue ${Q}.
|
57
|
+
*/
|
58
|
+
void timerqueue_free(struct timerqueue *);
|
59
|
+
|
60
|
+
#endif /* !_TIMERQUEUE_H_ */
|
@@ -0,0 +1,203 @@
|
|
1
|
+
#include <sys/time.h>
|
2
|
+
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
|
6
|
+
#include "mpool.h"
|
7
|
+
|
8
|
+
#include "events_internal.h"
|
9
|
+
#include "events.h"
|
10
|
+
|
11
|
+
/* Event structure. */
|
12
|
+
struct eventrec {
|
13
|
+
int (*func)(void *);
|
14
|
+
void * cookie;
|
15
|
+
};
|
16
|
+
|
17
|
+
MPOOL(eventrec, struct eventrec, 4096);
|
18
|
+
|
19
|
+
/* Zero timeval, for use with non-blocking event runs. */
|
20
|
+
static const struct timeval tv_zero = {0, 0};
|
21
|
+
|
22
|
+
/**
|
23
|
+
* events_mkrec(func, cookie):
|
24
|
+
* Package ${func}, ${cookie} into a struct eventrec.
|
25
|
+
*/
|
26
|
+
struct eventrec *
|
27
|
+
events_mkrec(int (*func)(void *), void * cookie)
|
28
|
+
{
|
29
|
+
struct eventrec * r;
|
30
|
+
|
31
|
+
/* Allocate structure. */
|
32
|
+
if ((r = mpool_eventrec_malloc()) == NULL)
|
33
|
+
goto err0;
|
34
|
+
|
35
|
+
/* Initialize. */
|
36
|
+
r->func = func;
|
37
|
+
r->cookie = cookie;
|
38
|
+
|
39
|
+
/* Success! */
|
40
|
+
return (r);
|
41
|
+
|
42
|
+
err0:
|
43
|
+
/* Failure! */
|
44
|
+
return (NULL);
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* events_freerec(r):
|
49
|
+
* Free the eventrec ${r}.
|
50
|
+
*/
|
51
|
+
void
|
52
|
+
events_freerec(struct eventrec * r)
|
53
|
+
{
|
54
|
+
|
55
|
+
mpool_eventrec_free(r);
|
56
|
+
}
|
57
|
+
|
58
|
+
/* Do an event. This makes events_run cleaner. */
|
59
|
+
static inline int
|
60
|
+
doevent(struct eventrec * r)
|
61
|
+
{
|
62
|
+
int rc;
|
63
|
+
|
64
|
+
/* Invoke the callback. */
|
65
|
+
rc = (r->func)(r->cookie);
|
66
|
+
|
67
|
+
/* Free the event record. */
|
68
|
+
mpool_eventrec_free(r);
|
69
|
+
|
70
|
+
/* Return the status code from the callback. */
|
71
|
+
return (rc);
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* events_run(void):
|
76
|
+
* Run events. Events registered via events_immediate_register will be run
|
77
|
+
* first, in order of increasing ${prio} values; then events associated with
|
78
|
+
* ready sockets registered via events_network_register; finally, events
|
79
|
+
* associated with expired timers registered via events_timer_register will
|
80
|
+
* be run. If any event function returns a non-zero result, no further
|
81
|
+
* events will be run and said non-zero result will be returned; on error,
|
82
|
+
* -1 will be returned.
|
83
|
+
*/
|
84
|
+
int
|
85
|
+
events_run(void)
|
86
|
+
{
|
87
|
+
struct eventrec * r;
|
88
|
+
struct timeval * tv;
|
89
|
+
struct timeval tv2;
|
90
|
+
int rc = 0;
|
91
|
+
|
92
|
+
/* If we have any immediate events, process them and return. */
|
93
|
+
if ((r = events_immediate_get()) != NULL) {
|
94
|
+
while (r != NULL) {
|
95
|
+
/* Process the event. */
|
96
|
+
if ((rc = doevent(r)) != 0)
|
97
|
+
goto done;
|
98
|
+
|
99
|
+
/* Get the next event. */
|
100
|
+
r = events_immediate_get();
|
101
|
+
}
|
102
|
+
|
103
|
+
/* We've processed at least one event; time to return. */
|
104
|
+
goto done;
|
105
|
+
}
|
106
|
+
|
107
|
+
/*
|
108
|
+
* Figure out the maximum duration to block, and wait up to that
|
109
|
+
* duration for network events to become available.
|
110
|
+
*/
|
111
|
+
if (events_timer_min(&tv))
|
112
|
+
goto err0;
|
113
|
+
if (events_network_select(tv))
|
114
|
+
goto err1;
|
115
|
+
free(tv);
|
116
|
+
|
117
|
+
/*
|
118
|
+
* Check for available immediate events, network events, and timer
|
119
|
+
* events, in that order of priority; exit only when no more events
|
120
|
+
* are available.
|
121
|
+
*/
|
122
|
+
do {
|
123
|
+
/* Run an immediate event, if one is available. */
|
124
|
+
if ((r = events_immediate_get()) != NULL) {
|
125
|
+
if ((rc = doevent(r)) != 0)
|
126
|
+
goto done;
|
127
|
+
continue;
|
128
|
+
}
|
129
|
+
|
130
|
+
/* Run a network event, if one is available. */
|
131
|
+
if ((r = events_network_get()) != NULL) {
|
132
|
+
if ((rc = doevent(r)) != 0)
|
133
|
+
goto done;
|
134
|
+
continue;
|
135
|
+
}
|
136
|
+
|
137
|
+
/* Check if any new network events are available. */
|
138
|
+
memcpy(&tv2, &tv_zero, sizeof(struct timeval));
|
139
|
+
if (events_network_select(&tv2))
|
140
|
+
goto err0;
|
141
|
+
if ((r = events_network_get()) != NULL) {
|
142
|
+
if ((rc = doevent(r)) != 0)
|
143
|
+
goto done;
|
144
|
+
continue;
|
145
|
+
}
|
146
|
+
|
147
|
+
/* Run a timer event, if one is available. */
|
148
|
+
if (events_timer_get(&r))
|
149
|
+
goto err0;
|
150
|
+
if (r != NULL) {
|
151
|
+
if ((rc = doevent(r)) != 0)
|
152
|
+
goto done;
|
153
|
+
continue;
|
154
|
+
}
|
155
|
+
|
156
|
+
/* No events available. */
|
157
|
+
break;
|
158
|
+
} while (1);
|
159
|
+
|
160
|
+
done:
|
161
|
+
/* Success! */
|
162
|
+
return (rc);
|
163
|
+
|
164
|
+
err1:
|
165
|
+
free(tv);
|
166
|
+
err0:
|
167
|
+
/* Failure! */
|
168
|
+
return (-1);
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* events_spin(done):
|
173
|
+
* Run events until ${done} is non-zero (and return 0), an error occurs (and
|
174
|
+
* return -1), or a callback returns a non-zero status (and return the status
|
175
|
+
* code from the callback).
|
176
|
+
*/
|
177
|
+
int
|
178
|
+
events_spin(int * done)
|
179
|
+
{
|
180
|
+
int rc = 0;
|
181
|
+
|
182
|
+
/* Loop until we're done or have a non-zero status. */
|
183
|
+
while ((done[0] == 0) && (rc == 0)) {
|
184
|
+
/* Run events. */
|
185
|
+
rc = events_run();
|
186
|
+
}
|
187
|
+
|
188
|
+
/* Return status code. */
|
189
|
+
return (rc);
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
* events_shutdown(void):
|
194
|
+
* Clean up and free memory. This call is not necessary on program exit and
|
195
|
+
* is only expected to be useful when checking for memory leaks.
|
196
|
+
*/
|
197
|
+
void
|
198
|
+
events_shutdown(void)
|
199
|
+
{
|
200
|
+
|
201
|
+
events_network_shutdown();
|
202
|
+
events_timer_shutdown();
|
203
|
+
}
|