iodine 0.2.17 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +36 -3
- data/bin/config.ru +23 -2
- data/bin/http-hello +1 -1
- data/bin/ws-shootout +5 -0
- data/ext/iodine/defer.c +468 -0
- data/ext/iodine/defer.h +105 -0
- data/ext/iodine/evio.c +263 -0
- data/ext/iodine/evio.h +133 -0
- data/ext/iodine/extconf.rb +2 -1
- data/ext/iodine/facil.c +958 -0
- data/ext/iodine/facil.h +423 -0
- data/ext/iodine/http.c +90 -0
- data/ext/iodine/http.h +50 -12
- data/ext/iodine/http1.c +200 -267
- data/ext/iodine/http1.h +17 -26
- data/ext/iodine/http1_request.c +81 -0
- data/ext/iodine/http1_request.h +58 -0
- data/ext/iodine/http1_response.c +403 -0
- data/ext/iodine/http1_response.h +90 -0
- data/ext/iodine/http1_simple_parser.c +124 -108
- data/ext/iodine/http1_simple_parser.h +8 -3
- data/ext/iodine/http_request.c +104 -0
- data/ext/iodine/http_request.h +58 -102
- data/ext/iodine/http_response.c +212 -208
- data/ext/iodine/http_response.h +89 -252
- data/ext/iodine/iodine_core.c +57 -46
- data/ext/iodine/iodine_core.h +3 -1
- data/ext/iodine/iodine_http.c +105 -81
- data/ext/iodine/iodine_websocket.c +17 -13
- data/ext/iodine/iodine_websocket.h +1 -0
- data/ext/iodine/rb-call.c +9 -7
- data/ext/iodine/{rb-libasync.h → rb-defer.c} +57 -49
- data/ext/iodine/rb-rack-io.c +12 -6
- data/ext/iodine/rb-rack-io.h +1 -1
- data/ext/iodine/rb-registry.c +5 -2
- data/ext/iodine/sock.c +1159 -0
- data/ext/iodine/{libsock.h → sock.h} +138 -142
- data/ext/iodine/spnlock.inc +77 -0
- data/ext/iodine/websockets.c +101 -112
- data/ext/iodine/websockets.h +38 -19
- data/iodine.gemspec +3 -3
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +6 -6
- metadata +23 -19
- data/ext/iodine/http_response_http1.h +0 -382
- data/ext/iodine/libasync.c +0 -570
- data/ext/iodine/libasync.h +0 -122
- data/ext/iodine/libreact.c +0 -350
- data/ext/iodine/libreact.h +0 -244
- data/ext/iodine/libserver.c +0 -957
- data/ext/iodine/libserver.h +0 -481
- data/ext/iodine/libsock.c +0 -1025
- data/ext/iodine/spnlock.h +0 -243
data/ext/iodine/libserver.h
DELETED
@@ -1,481 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz Segev, 2016-2017
|
3
|
-
License: MIT
|
4
|
-
|
5
|
-
Feel free to copy, use and enjoy according to the license provided.
|
6
|
-
*/
|
7
|
-
#ifndef LIB_SERVER
|
8
|
-
#define LIB_SERVER "0.4.1"
|
9
|
-
#define LIB_SERVER_VERSION_MAJOR 0
|
10
|
-
#define LIB_SERVER_VERSION_MINOR 4
|
11
|
-
#define LIB_SERVER_VERSION_PATCH 1
|
12
|
-
|
13
|
-
#ifndef _GNU_SOURCE
|
14
|
-
#define _GNU_SOURCE
|
15
|
-
#endif
|
16
|
-
|
17
|
-
#include <stdint.h>
|
18
|
-
#include <stdio.h>
|
19
|
-
#include <stdlib.h>
|
20
|
-
#include <unistd.h>
|
21
|
-
|
22
|
-
/* lib server is based off and requires the following libraries: */
|
23
|
-
#include "libasync.h"
|
24
|
-
#include "libreact.h"
|
25
|
-
#include "libsock.h"
|
26
|
-
#include "spnlock.h"
|
27
|
-
|
28
|
-
/** Set `SERVER_DELAY_IO` to 1 in order to delay the IO reactor review
|
29
|
-
* until the queue for scheduled tasks and events is empty.
|
30
|
-
*/
|
31
|
-
#ifndef SERVER_DELAY_IO
|
32
|
-
#define SERVER_DELAY_IO 0
|
33
|
-
#endif
|
34
|
-
|
35
|
-
#ifndef SERVER_PRINT_STATE
|
36
|
-
/**
|
37
|
-
When SERVER_PRINT_STATE is set to 1, the server API will print out common
|
38
|
-
messages regarding the server state (start / finish / listen messages).
|
39
|
-
*/
|
40
|
-
#define SERVER_PRINT_STATE 1
|
41
|
-
#endif
|
42
|
-
|
43
|
-
#if LIB_ASYNC_VERSION_MINOR != 4 || LIB_REACT_VERSION_MINOR != 3 || \
|
44
|
-
LIB_SOCK_VERSION_MINOR != 2
|
45
|
-
#warning Lib-Server dependency versions are not in sync. Please review API versions.
|
46
|
-
#endif
|
47
|
-
|
48
|
-
#ifndef UNUSED_FUNC
|
49
|
-
#define UNUSED_FUNC __attribute__((unused))
|
50
|
-
#endif
|
51
|
-
/** \file
|
52
|
-
## LibServer - a dynamic protocol network services library
|
53
|
-
|
54
|
-
* Library (not a framework): meanning, closer to the metal, abstracting only
|
55
|
-
what is required for API simplicity, error protection and performance.
|
56
|
-
|
57
|
-
* Dynamic Protocol: meanning a service can change protocols mid-stream. Example
|
58
|
-
usecase: Websockets (HTTP Upgrade).
|
59
|
-
|
60
|
-
* Network services: meanning multiple listening network ports, each with it's
|
61
|
-
own logic.
|
62
|
-
|
63
|
-
`libserver` utilizes `libreact`, `libasync` and `libsock` to create a simple
|
64
|
-
API wrapper around these minimalistic libraries and managing the "glue" that
|
65
|
-
makes them work together.
|
66
|
-
|
67
|
-
It's simple and it's awesome :-)
|
68
|
-
|
69
|
-
Here's a simple example that emulates an HTTP hello world server. This example
|
70
|
-
will count the number of client and messages using the server and demonstrates
|
71
|
-
some recommended implementation techniques, such as protocol inheritance.
|
72
|
-
|
73
|
-
#include "libserver.h" // the reactor library
|
74
|
-
#include <stdatomic.h> // We'll use atomics to safely count client events
|
75
|
-
|
76
|
-
#define THREADS 4
|
77
|
-
#define PROCESSES 4
|
78
|
-
|
79
|
-
void on_close(protocol_s* protocol);
|
80
|
-
void on_shutdown(intptr_t sock, protocol_s* protocol);
|
81
|
-
void on_data(intptr_t sock, protocol_s* protocol);
|
82
|
-
protocol_s* demo_on_open(intptr_t fd, void* udata);
|
83
|
-
|
84
|
-
// Our demo protocol object uses "C" style inheritance,
|
85
|
-
// where pointers location are the same so that a simple cast
|
86
|
-
// from one object to the other, allows us to access more data.
|
87
|
-
struct DemoProtocol {
|
88
|
-
protocol_s protocol; // must be first for C style inheritance
|
89
|
-
size_t _Atomic opened;
|
90
|
-
size_t _Atomic closed;
|
91
|
-
size_t _Atomic shutdown;
|
92
|
-
size_t _Atomic messages;
|
93
|
-
} demo_protocol = {
|
94
|
-
.protocol.service = "Demo", // This allows us to ID the protocol type.
|
95
|
-
.protocol.on_data = on_data,
|
96
|
-
.protocol.on_shutdown = on_shutdown,
|
97
|
-
.protocol.on_close = on_close,
|
98
|
-
};
|
99
|
-
|
100
|
-
// type-casting helper
|
101
|
-
#define pr2demo(protocol) ((struct DemoProtocol*)(protocol))
|
102
|
-
|
103
|
-
// A simple Hello World HTTP response emulation
|
104
|
-
char hello_message[] =
|
105
|
-
"HTTP/1.1 200 OK\r\n"
|
106
|
-
"Content-Length: 12\r\n"
|
107
|
-
"Connection: keep-alive\r\n"
|
108
|
-
"Keep-Alive: 1;timeout=5\r\n"
|
109
|
-
"\r\n"
|
110
|
-
"Hello World!";
|
111
|
-
|
112
|
-
protocol_s* on_open(intptr_t fd, void* udata) {
|
113
|
-
// Count events
|
114
|
-
atomic_fetch_add(&demo_protocol.opened, 1);
|
115
|
-
// Set timeout
|
116
|
-
server_set_timeout(fd, 5);
|
117
|
-
// * return pointer to the protocol.
|
118
|
-
// * This is the same as `(protocol_s *)&demo_protocol`
|
119
|
-
return &demo_protocol.protocol;
|
120
|
-
}
|
121
|
-
|
122
|
-
void on_data(intptr_t sock, protocol_s* protocol) {
|
123
|
-
// read data
|
124
|
-
char data[1024];
|
125
|
-
if (sock_read(sock, data, 1024)) {
|
126
|
-
// Count event
|
127
|
-
atomic_fetch_add(&pr2demo(protocol)->messages, 1);
|
128
|
-
// send reply
|
129
|
-
sock_write(sock, hello_message, sizeof(hello_message) - 1);
|
130
|
-
}
|
131
|
-
}
|
132
|
-
|
133
|
-
void on_close(protocol_s* protocol) {
|
134
|
-
// Count event
|
135
|
-
atomic_fetch_add(&pr2demo(protocol)->closed, 1);
|
136
|
-
}
|
137
|
-
|
138
|
-
void on_shutdown(intptr_t sock, protocol_s* protocol) {
|
139
|
-
// Count event
|
140
|
-
atomic_fetch_add(&pr2demo(protocol)->shutdown, 1);
|
141
|
-
}
|
142
|
-
|
143
|
-
void on_idle(void) {
|
144
|
-
// idle event example
|
145
|
-
fprintf(stderr, "Server was idle, with %lu connections.\n",
|
146
|
-
server_count(NULL));
|
147
|
-
}
|
148
|
-
|
149
|
-
int main() {
|
150
|
-
// this isn't required normally,
|
151
|
-
// but some systems require atomics to be initialized.
|
152
|
-
atomic_store(&demo_protocol.opened, 0);
|
153
|
-
atomic_store(&demo_protocol.closed, 0);
|
154
|
-
atomic_store(&demo_protocol.shutdown, 0);
|
155
|
-
atomic_store(&demo_protocol.messages, 0);
|
156
|
-
// run the server
|
157
|
-
server_listen(.port = "3000", .on_open = on_open, .udata = NULL);
|
158
|
-
server_run(.threads = THREADS, .processes = PROCESSES,
|
159
|
-
.on_idle = on_idle);
|
160
|
-
// print results
|
161
|
-
fprintf(stderr,
|
162
|
-
"** Server returned\n"
|
163
|
-
"** %lu clients connected.\n"
|
164
|
-
"** %lu clients disconnected.\n"
|
165
|
-
"** %lu clients were connected when shutdown was called.\n"
|
166
|
-
"** %lu messages were sent\n",
|
167
|
-
atomic_load(&demo_protocol.opened),
|
168
|
-
atomic_load(&demo_protocol.closed),
|
169
|
-
atomic_load(&demo_protocol.shutdown),
|
170
|
-
atomic_load(&demo_protocol.messages));
|
171
|
-
}
|
172
|
-
|
173
|
-
|
174
|
-
*/
|
175
|
-
|
176
|
-
/**************************************************************************/ /**
|
177
|
-
* General info
|
178
|
-
*/
|
179
|
-
|
180
|
-
/* The following types are defined for the userspace of this library: */
|
181
|
-
|
182
|
-
// struct Server; /** used internally. no public data exposed */
|
183
|
-
struct ServerSettings; /** sets up the server's behavior */
|
184
|
-
struct ServerServiceSettings; /** sets up a listening socket's behavior */
|
185
|
-
typedef struct Protocol protocol_s; /** controls connection events */
|
186
|
-
|
187
|
-
/**************************************************************************/ /**
|
188
|
-
* The Protocol
|
189
|
-
|
190
|
-
The Protocol struct defines the callbacks used for the connection and sets the
|
191
|
-
behaviour for the connection's protocol.
|
192
|
-
|
193
|
-
All the callbacks recieve a unique connection ID (a semi UUID) that can be
|
194
|
-
converted to the original file descriptor if in need.
|
195
|
-
|
196
|
-
This allows the Server API to prevent old connection handles from sending data
|
197
|
-
to new connections after a file descriptor is "recycled" by the OS.
|
198
|
-
*/
|
199
|
-
struct Protocol {
|
200
|
-
/**
|
201
|
-
* A string to identify the protocol's service (i.e. "http").
|
202
|
-
*
|
203
|
-
* The string should be a global constant, only a pointer comparison will be
|
204
|
-
* made (not `strcmp`).
|
205
|
-
*/
|
206
|
-
const char *service;
|
207
|
-
/** called when a data is available, but will not run concurrently */
|
208
|
-
void (*on_data)(intptr_t fduuid, protocol_s *protocol);
|
209
|
-
/** called when the socket is ready to be written to. */
|
210
|
-
void (*on_ready)(intptr_t fduuid, protocol_s *protocol);
|
211
|
-
/** called when the server is shutting down,
|
212
|
-
* but before closing the connection. */
|
213
|
-
void (*on_shutdown)(intptr_t fduuid, protocol_s *protocol);
|
214
|
-
/** called when the connection was closed, but will not run concurrently */
|
215
|
-
void (*on_close)(protocol_s *protocol);
|
216
|
-
/** called when a connection's timeout was reached */
|
217
|
-
void (*ping)(intptr_t fduuid, protocol_s *protocol);
|
218
|
-
/** private metadata used for object protection */
|
219
|
-
spn_lock_i callback_lock;
|
220
|
-
};
|
221
|
-
|
222
|
-
/**************************************************************************/ /**
|
223
|
-
* The Service Settings
|
224
|
-
|
225
|
-
These settings will be used to setup listening sockets.
|
226
|
-
*/
|
227
|
-
struct ServerServiceSettings {
|
228
|
-
/** Called whenever a new connection is accepted. Should return a pointer to
|
229
|
-
* the connection's protocol. */
|
230
|
-
protocol_s *(*on_open)(intptr_t fduuid, void *udata);
|
231
|
-
/** The network service / port. Defaults to "3000". */
|
232
|
-
const char *port;
|
233
|
-
/** The socket binding address. Defaults to the recommended NULL. */
|
234
|
-
const char *address;
|
235
|
-
/** Opaque user data. */
|
236
|
-
void *udata;
|
237
|
-
/**
|
238
|
-
* Called when the server starts, allowing for further initialization, such as
|
239
|
-
* timed event scheduling.
|
240
|
-
*
|
241
|
-
* This will be called seperately for every process. */
|
242
|
-
void (*on_start)(void *udata);
|
243
|
-
/** called when the server is done, to clean up any leftovers. */
|
244
|
-
void (*on_finish)(void *udata);
|
245
|
-
};
|
246
|
-
|
247
|
-
/**************************************************************************/ /**
|
248
|
-
* The Server Settings
|
249
|
-
|
250
|
-
These settings will be used to setup server behaviour. missing settings will be
|
251
|
-
filled in with default values.
|
252
|
-
*/
|
253
|
-
struct ServerSettings {
|
254
|
-
/** called if the event loop in cycled with no pending events. */
|
255
|
-
void (*on_idle)(void);
|
256
|
-
/**
|
257
|
-
* Called when the server starts, allowing for further initialization, such as
|
258
|
-
* timed event scheduling.
|
259
|
-
*
|
260
|
-
* This will be called seperately for every process. */
|
261
|
-
void (*on_init)(void);
|
262
|
-
/** called when the server is done, to clean up any leftovers. */
|
263
|
-
void (*on_finish)(void);
|
264
|
-
/**
|
265
|
-
Sets the amount of threads to be created for the server's thread-pool.
|
266
|
-
Defaults to 1 - the reactor and all callbacks will work using a single working
|
267
|
-
thread, allowing for an evented single threaded design. Limited to 1024.
|
268
|
-
*/
|
269
|
-
unsigned threads : 10;
|
270
|
-
/** Sets the amount of processes to be used (processes will be forked).
|
271
|
-
Defaults to 1 working processes (no forking), limited to 127.*/
|
272
|
-
unsigned processes : 7;
|
273
|
-
};
|
274
|
-
|
275
|
-
/* *****************************************************************************
|
276
|
-
* The Server API
|
277
|
-
* (and helper functions)
|
278
|
-
*/
|
279
|
-
|
280
|
-
/* *****************************************************************************
|
281
|
-
* Server actions
|
282
|
-
*/
|
283
|
-
|
284
|
-
/**
|
285
|
-
Listens to a server with any of the available service settings:
|
286
|
-
|
287
|
-
* `.on_open` called whenever a new connection is accepted.
|
288
|
-
|
289
|
-
Should return a pointer to the connection's protocol.
|
290
|
-
|
291
|
-
* `.port` the network service / port. Defaults to "3000".
|
292
|
-
|
293
|
-
* `.address` the socket binding address. Defaults to the recommended NULL.
|
294
|
-
|
295
|
-
* `.udata`opaque user data.
|
296
|
-
|
297
|
-
* `.on_start` called when the server starts, allowing for further
|
298
|
-
initialization, such as timed event scheduling.
|
299
|
-
|
300
|
-
This will be called seperately for every process.
|
301
|
-
|
302
|
-
* `.on_finish` called when the server is done, to clean up any leftovers.
|
303
|
-
|
304
|
-
*/
|
305
|
-
int server_listen(struct ServerServiceSettings);
|
306
|
-
#define server_listen(...) \
|
307
|
-
server_listen((struct ServerServiceSettings){__VA_ARGS__})
|
308
|
-
/**
|
309
|
-
Runs a server with any of the following server settings:
|
310
|
-
|
311
|
-
* `.threads` the number of threads to initiate in the server's thread pool.
|
312
|
-
|
313
|
-
* `.processes` the number of processes to use (a value of more then 1 will
|
314
|
-
initiate a `fork`).
|
315
|
-
|
316
|
-
* `.on_init` an on initialization callback (for every process forked).
|
317
|
-
`void (*callback)(void);``
|
318
|
-
|
319
|
-
* `.on_finish` a post run callback (for every process forked).
|
320
|
-
`void (*callback)(void);``
|
321
|
-
|
322
|
-
* `.on_idle` an idle server callback (for every process forked).
|
323
|
-
`void (*callback)(void);``
|
324
|
-
|
325
|
-
This method blocks the current thread until the server is stopped when a
|
326
|
-
SIGINT/SIGTERM is received.
|
327
|
-
|
328
|
-
To shutdown the server use the `kill` function with a SIGINT.
|
329
|
-
|
330
|
-
This function only returns after the server had completed it's shutdown process.
|
331
|
-
|
332
|
-
*/
|
333
|
-
ssize_t server_run(struct ServerSettings);
|
334
|
-
#define server_run(...) server_run((struct ServerSettings){__VA_ARGS__})
|
335
|
-
/** Stops the server, shouldn't be called unless int's impossible to send an
|
336
|
-
* INTR signal. */
|
337
|
-
void server_stop(void);
|
338
|
-
/**
|
339
|
-
Returns the last time the server reviewed any pending IO events.
|
340
|
-
*/
|
341
|
-
time_t server_last_tick(void);
|
342
|
-
/****************************************************************************
|
343
|
-
* Socket actions
|
344
|
-
*/
|
345
|
-
|
346
|
-
/**
|
347
|
-
Gets the active protocol object for the requested file descriptor.
|
348
|
-
|
349
|
-
Returns NULL on error (i.e. connection closed), otherwise returns a `protocol_s`
|
350
|
-
pointer.
|
351
|
-
*/
|
352
|
-
protocol_s *server_get_protocol(intptr_t uuid);
|
353
|
-
/**
|
354
|
-
Sets a new active protocol object for the requested file descriptor.
|
355
|
-
|
356
|
-
This also schedules the old protocol's `on_close` callback to run, making sure
|
357
|
-
all resources are released.
|
358
|
-
|
359
|
-
Returns -1 on error (i.e. connection closed), otherwise returns 0.
|
360
|
-
*/
|
361
|
-
ssize_t server_switch_protocol(intptr_t fd, protocol_s *new_protocol);
|
362
|
-
/**
|
363
|
-
Sets a connection's timeout.
|
364
|
-
|
365
|
-
Returns -1 on error (i.e. connection closed), otherwise returns 0.
|
366
|
-
*/
|
367
|
-
void server_set_timeout(intptr_t uuid, uint8_t timeout);
|
368
|
-
/**
|
369
|
-
Returns a connection's timeout, as a `uint8_t` value.
|
370
|
-
|
371
|
-
A value of 0 might mean that no timeout was set OR that the connection inquired
|
372
|
-
about was invalid.
|
373
|
-
*/
|
374
|
-
uint8_t server_get_timeout(intptr_t uuid);
|
375
|
-
|
376
|
-
/** Attaches an existing connection (fd) to the server's reactor and protocol
|
377
|
-
management system, so that the server can be used also to manage connection
|
378
|
-
based resources asynchronously (i.e. database resources etc').
|
379
|
-
|
380
|
-
On failure the fduuid_u.data.fd value will be -1.
|
381
|
-
*/
|
382
|
-
intptr_t server_attach(int fd, protocol_s *protocol);
|
383
|
-
/** Hijack a socket (file descriptor) from the server, clearing up it's
|
384
|
-
resources and calling the protocol's `on_close` callback (making sure allocated
|
385
|
-
resources are freed).
|
386
|
-
|
387
|
-
The control of the socket is totally relinquished.
|
388
|
-
|
389
|
-
This method will block until all the data in the buffer is sent before
|
390
|
-
releasing control of the socket.
|
391
|
-
|
392
|
-
The returned value is the fd for the socket, or -1 on error.
|
393
|
-
*/
|
394
|
-
int server_hijack(intptr_t uuid);
|
395
|
-
/** Counts the number of connections for the specified protocol (NULL = all
|
396
|
-
protocols). */
|
397
|
-
long server_count(char *service);
|
398
|
-
|
399
|
-
/****************************************************************************
|
400
|
-
* Read and Write
|
401
|
-
*
|
402
|
-
* Simpley use `libsock` API for read/write.
|
403
|
-
*/
|
404
|
-
|
405
|
-
/****************************************************************************
|
406
|
-
* Tasks + Async
|
407
|
-
*/
|
408
|
-
|
409
|
-
/**
|
410
|
-
Performs a task for each connection except the origin connection, unsafely and
|
411
|
-
synchronously.
|
412
|
-
|
413
|
-
The task will be performed synchronously (blocking), without waiting for a lock.
|
414
|
-
|
415
|
-
The task will be performed unsafely. For example, the protocol object might be
|
416
|
-
invalid midway through (or at the beginning) the execution, as there is no
|
417
|
-
protection against memory deallocation.
|
418
|
-
|
419
|
-
This function should probably be avoided except when implementing publication or
|
420
|
-
broadcast algorithms.
|
421
|
-
*/
|
422
|
-
void server_each_unsafe(intptr_t origin_uuid,
|
423
|
-
void (*task)(intptr_t origin_uuid, intptr_t target_uuid,
|
424
|
-
protocol_s *target_protocol, void *arg),
|
425
|
-
void *arg);
|
426
|
-
|
427
|
-
/**
|
428
|
-
Schedules a specific task to run asyncronously for each connection (except the
|
429
|
-
origin connection).
|
430
|
-
|
431
|
-
The task is performed within each target connection's busy "lock", meanning no
|
432
|
-
two tasks (or `on_data` events) should be performed at the same time
|
433
|
-
(concurrency will be avoided within the context of each connection, except for
|
434
|
-
`on_shutdown`, `on_close` and `ping`).
|
435
|
-
|
436
|
-
The `on_finish` callback will be called once the task is finished and it will
|
437
|
-
receive the originating connection's UUID (could be 0). The originating
|
438
|
-
connection might have been closed by that time.
|
439
|
-
|
440
|
-
The `service` identifier is required. The comparison is pointer value comparison
|
441
|
-
and isn't related to the content of the service string.
|
442
|
-
|
443
|
-
It is recommended the `on_finish` callback is only used to perform any
|
444
|
-
resource cleanup necessary.
|
445
|
-
*/
|
446
|
-
void server_each(intptr_t origin_uuid, const char *service,
|
447
|
-
void (*task)(intptr_t uuid, protocol_s *protocol, void *arg),
|
448
|
-
void *arg, void (*on_finish)(intptr_t origin_uuid,
|
449
|
-
protocol_s *protocol, void *arg));
|
450
|
-
/** Schedules a specific task to run asyncronously for a specific connection.
|
451
|
-
|
452
|
-
returns -1 on failure, 0 on success (success being scheduling the task).
|
453
|
-
|
454
|
-
If a connection was terminated before performing their sceduled tasks, the
|
455
|
-
`fallback` task will be performed instead.
|
456
|
-
|
457
|
-
It is recommended to perform any resource cleanup within the fallback function
|
458
|
-
and call the fallback function from within the main task, but other designes
|
459
|
-
are valid as well.
|
460
|
-
*/
|
461
|
-
void server_task(intptr_t uuid,
|
462
|
-
void (*task)(intptr_t uuid, protocol_s *protocol, void *arg),
|
463
|
-
void *arg, void (*fallback)(intptr_t uuid, void *arg));
|
464
|
-
/** Creates a system timer (at the cost of 1 file descriptor) and pushes the
|
465
|
-
timer to the reactor. The task will repeat `repetitions` times. if
|
466
|
-
`repetitions` is set to 0, task will repeat forever. Returns -1 on error
|
467
|
-
or the new file descriptor on succeess.
|
468
|
-
*/
|
469
|
-
int server_run_every(size_t milliseconds, size_t repetitions,
|
470
|
-
void (*task)(void *), void *arg,
|
471
|
-
void (*on_finish)(void *));
|
472
|
-
|
473
|
-
/** Creates a system timer (at the cost of 1 file descriptor) and pushes the
|
474
|
-
timer to the reactor. The task will NOT repeat. Returns -1 on error or the
|
475
|
-
new file descriptor on succeess. */
|
476
|
-
UNUSED_FUNC static inline int server_run_after(size_t milliseconds,
|
477
|
-
void task(void *), void *arg) {
|
478
|
-
return server_run_every(milliseconds, 1, task, arg, NULL);
|
479
|
-
}
|
480
|
-
|
481
|
-
#endif
|