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.
- 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
|
+
}
|