spiped 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/ext/spiped/extconf.rb +3 -0
  3. data/ext/spiped/spiped-source/BUILDING +46 -0
  4. data/ext/spiped/spiped-source/CHANGELOG +44 -0
  5. data/ext/spiped/spiped-source/COPYRIGHT +33 -0
  6. data/ext/spiped/spiped-source/Makefile +47 -0
  7. data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
  8. data/ext/spiped/spiped-source/Makefile.inc +20 -0
  9. data/ext/spiped/spiped-source/Makefile.prog +23 -0
  10. data/ext/spiped/spiped-source/POSIX/README +10 -0
  11. data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
  12. data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
  13. data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
  14. data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
  15. data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
  16. data/ext/spiped/spiped-source/README +198 -0
  17. data/ext/spiped/spiped-source/STYLE +151 -0
  18. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
  19. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
  20. data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
  21. data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
  22. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
  23. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
  24. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
  25. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
  26. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
  27. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
  28. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
  29. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
  30. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
  31. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
  32. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
  33. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
  34. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
  35. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
  36. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
  37. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
  38. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
  39. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
  40. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
  41. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
  42. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
  43. data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
  44. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
  45. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
  46. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
  47. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
  48. data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
  49. data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
  50. data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
  51. data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
  52. data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
  53. data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
  54. data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
  55. data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
  56. data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
  57. data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
  58. data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
  59. data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
  60. data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
  61. data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
  62. data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
  63. data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
  64. data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
  65. data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
  66. data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
  67. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
  68. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
  69. data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
  70. data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
  71. data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
  72. data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
  73. data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
  74. data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
  75. data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
  76. data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
  77. data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
  78. data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
  79. data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
  80. data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
  81. data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
  82. data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
  83. data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
  84. data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
  85. data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
  86. data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
  87. data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
  88. data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
  89. data/ext/spiped/spiped-source/spipe/Makefile +90 -0
  90. data/ext/spiped/spiped-source/spipe/README +24 -0
  91. data/ext/spiped/spiped-source/spipe/main.c +178 -0
  92. data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
  93. data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
  94. data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
  95. data/ext/spiped/spiped-source/spiped/Makefile +98 -0
  96. data/ext/spiped/spiped-source/spiped/README +62 -0
  97. data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
  98. data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
  99. data/ext/spiped/spiped-source/spiped/main.c +267 -0
  100. data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
  101. data/lib/spiped.rb +3 -0
  102. 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
+ }