spiped 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }