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/defer.h
ADDED
@@ -0,0 +1,105 @@
|
|
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 H_DEFER_H
|
8
|
+
/**
|
9
|
+
A library for deferring execution of code.
|
10
|
+
|
11
|
+
Deferred execution can be multi-threaded, although threads aren't managed by the
|
12
|
+
library.
|
13
|
+
|
14
|
+
All deferred execution is shared among the same process and inherited by any
|
15
|
+
forked process.
|
16
|
+
*/
|
17
|
+
#define H_DEFER_H
|
18
|
+
#define LIB_DEFER_VERSION_MAJOR 0
|
19
|
+
#define LIB_DEFER_VERSION_MINOR 1
|
20
|
+
#define LIB_DEFER_VERSION_PATCH 0
|
21
|
+
|
22
|
+
#ifdef __cplusplus
|
23
|
+
extern "C" {
|
24
|
+
#endif
|
25
|
+
/* *****************************************************************************
|
26
|
+
Core API
|
27
|
+
***************************************************************************** */
|
28
|
+
|
29
|
+
/** Defer an execution of a function for later. Returns -1 on error.*/
|
30
|
+
int defer(void (*func)(void *, void *), void *arg1, void *arg2);
|
31
|
+
|
32
|
+
/** Performs all deferred functions until the queue had been depleted. */
|
33
|
+
void defer_perform(void);
|
34
|
+
|
35
|
+
/** returns true if there are deferred functions waiting for execution. */
|
36
|
+
int defer_has_queue(void);
|
37
|
+
|
38
|
+
/* *****************************************************************************
|
39
|
+
Thread Pool support
|
40
|
+
***************************************************************************** */
|
41
|
+
|
42
|
+
/** an opaque thread pool type */
|
43
|
+
typedef struct defer_pool *pool_pt;
|
44
|
+
|
45
|
+
/** Starts a thread pool that will run deferred tasks in the background. */
|
46
|
+
pool_pt defer_pool_start(unsigned int thread_count);
|
47
|
+
/** Signals a running thread pool to stop. Returns immediately. */
|
48
|
+
void defer_pool_stop(pool_pt pool);
|
49
|
+
/** Waits for a running thread pool, joining threads and finishing all tasks. */
|
50
|
+
void defer_pool_wait(pool_pt pool);
|
51
|
+
/** Returns TRUE (1) if the pool is hadn't been signaled to finish up. */
|
52
|
+
int defer_pool_is_active(pool_pt pool);
|
53
|
+
|
54
|
+
/**
|
55
|
+
OVERRIDE THIS to replace the default pthread implementation.
|
56
|
+
|
57
|
+
Accepts a pointer to a function and a single argument that should be executed
|
58
|
+
within a new thread.
|
59
|
+
|
60
|
+
The function should allocate memory for the thread object and return a pointer
|
61
|
+
to the allocated memory that identifies the thread.
|
62
|
+
|
63
|
+
On error NULL should be returned.
|
64
|
+
*/
|
65
|
+
void *defer_new_thread(void *(*thread_func)(void *), pool_pt pool);
|
66
|
+
|
67
|
+
/**
|
68
|
+
OVERRIDE THIS to replace the default pthread implementation.
|
69
|
+
|
70
|
+
Accepts a pointer returned from `defer_new_thread` (should also free any
|
71
|
+
allocated memory) and joins the associated thread.
|
72
|
+
|
73
|
+
Return value is ignored.
|
74
|
+
*/
|
75
|
+
int defer_join_thread(void *p_thr);
|
76
|
+
|
77
|
+
/* *****************************************************************************
|
78
|
+
Child Process support (`fork`)
|
79
|
+
***************************************************************************** */
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Forks the process, starts up a thread pool and waits for all tasks to run.
|
83
|
+
* All existing tasks will run in all processes (multiple times).
|
84
|
+
*
|
85
|
+
* It's possible to synchronize workload across processes by using a pipe (or
|
86
|
+
* pipes) and a self-scheduling event that reads instructions from the pipe.
|
87
|
+
*
|
88
|
+
* This function will use SIGINT or SIGTERM to signal all the children processes
|
89
|
+
* to finish up and exit. It will also setup a child process reaper (which will
|
90
|
+
* remain active for the application's lifetime).
|
91
|
+
*
|
92
|
+
* Returns 0 on success, -1 on error and a positive number if this is a child
|
93
|
+
* process that was forked.
|
94
|
+
*/
|
95
|
+
int defer_perform_in_fork(unsigned int process_count,
|
96
|
+
unsigned int thread_count);
|
97
|
+
/** Returns TRUE (1) if the forked thread pool hadn't been signaled to finish
|
98
|
+
* up. */
|
99
|
+
int defer_fork_is_active(void);
|
100
|
+
|
101
|
+
#ifdef __cplusplus
|
102
|
+
} /* closing brace for extern "C" */
|
103
|
+
#endif
|
104
|
+
|
105
|
+
#endif
|
data/ext/iodine/evio.c
ADDED
@@ -0,0 +1,263 @@
|
|
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 _GNU_SOURCE
|
8
|
+
#define _GNU_SOURCE
|
9
|
+
#endif
|
10
|
+
|
11
|
+
#include "evio.h"
|
12
|
+
|
13
|
+
#if !defined(__unix__) && !defined(__linux__) && !defined(__APPLE__) && \
|
14
|
+
!defined(__CYGWIN__)
|
15
|
+
#error This library currently supports only Unix based systems (i.e. Linux and BSD)
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#if !defined(__linux__) && !defined(__CYGWIN__)
|
19
|
+
#include <sys/event.h>
|
20
|
+
#else
|
21
|
+
#include <sys/epoll.h>
|
22
|
+
#include <sys/timerfd.h>
|
23
|
+
#endif
|
24
|
+
#include <assert.h>
|
25
|
+
#include <errno.h>
|
26
|
+
#include <fcntl.h>
|
27
|
+
#include <netdb.h>
|
28
|
+
#include <stdint.h>
|
29
|
+
#include <stdio.h>
|
30
|
+
#include <stdlib.h>
|
31
|
+
#include <string.h>
|
32
|
+
#include <sys/socket.h>
|
33
|
+
#include <sys/time.h>
|
34
|
+
#include <sys/types.h>
|
35
|
+
#include <time.h>
|
36
|
+
#include <unistd.h>
|
37
|
+
|
38
|
+
/*
|
39
|
+
#define EVIO_MAX_EVENTS 64
|
40
|
+
#define EVIO_TICK 256
|
41
|
+
*/
|
42
|
+
|
43
|
+
#if (EVIO_MAX_EVENTS & 1) || EVIO_MAX_EVENTS < 3
|
44
|
+
#error EVIO_MAX_EVENTS must be an even number higher than 4
|
45
|
+
#endif
|
46
|
+
|
47
|
+
/* *****************************************************************************
|
48
|
+
Callbacks - weak versions to be overridden.
|
49
|
+
***************************************************************************** */
|
50
|
+
#pragma weak evio_on_data
|
51
|
+
void __attribute__((weak)) evio_on_data(void *arg) { (void)arg; }
|
52
|
+
#pragma weak evio_on_ready
|
53
|
+
void __attribute__((weak)) evio_on_ready(void *arg) { (void)arg; }
|
54
|
+
#pragma weak evio_on_error
|
55
|
+
void __attribute__((weak)) evio_on_error(void *arg) { (void)arg; }
|
56
|
+
#pragma weak evio_on_close
|
57
|
+
void __attribute__((weak)) evio_on_close(void *arg) { (void)arg; }
|
58
|
+
|
59
|
+
/* *****************************************************************************
|
60
|
+
Global data and system independant code
|
61
|
+
***************************************************************************** */
|
62
|
+
|
63
|
+
static int evio_fd = -1;
|
64
|
+
|
65
|
+
/** Closes the `epoll` / `kqueue` object, releasing it's resources. */
|
66
|
+
void evio_close() {
|
67
|
+
if (evio_fd != -1)
|
68
|
+
close(evio_fd);
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
returns true if the evio is available for adding or removing file descriptors.
|
73
|
+
*/
|
74
|
+
int evio_isactive(void) { return evio_fd >= 0; }
|
75
|
+
|
76
|
+
/* *****************************************************************************
|
77
|
+
Linux `epoll` implementation
|
78
|
+
***************************************************************************** */
|
79
|
+
#if defined(__linux__) || defined(__CYGWIN__)
|
80
|
+
/**
|
81
|
+
Creates the `epoll` or `kqueue` object.
|
82
|
+
*/
|
83
|
+
intptr_t evio_create() { return evio_fd = epoll_create1(EPOLL_CLOEXEC); }
|
84
|
+
|
85
|
+
/**
|
86
|
+
Removes a file descriptor from the polling object.
|
87
|
+
*/
|
88
|
+
int evio_remove(int fd) {
|
89
|
+
struct epoll_event chevent = {0};
|
90
|
+
return epoll_ctl(evio_fd, EPOLL_CTL_DEL, fd, &chevent);
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
Adds a file descriptor to the polling object.
|
95
|
+
*/
|
96
|
+
int evio_add(int fd, void *callback_arg) {
|
97
|
+
struct epoll_event chevent = {0};
|
98
|
+
chevent.data.ptr = (void *)callback_arg;
|
99
|
+
chevent.events =
|
100
|
+
EPOLLOUT | EPOLLIN | EPOLLET | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
|
101
|
+
return epoll_ctl(evio_fd, EPOLL_CTL_ADD, fd, &chevent);
|
102
|
+
}
|
103
|
+
|
104
|
+
/**
|
105
|
+
Creates a timer file descriptor, system dependent.
|
106
|
+
*/
|
107
|
+
intptr_t evio_open_timer(void) {
|
108
|
+
return timerfd_create(CLOCK_MONOTONIC, O_NONBLOCK);
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
Adds a timer file descriptor, so that callbacks will be called for it's events.
|
113
|
+
*/
|
114
|
+
intptr_t evio_add_timer(int fd, void *callback_arg,
|
115
|
+
unsigned long milliseconds) {
|
116
|
+
struct epoll_event chevent;
|
117
|
+
chevent.data.ptr = (void *)callback_arg;
|
118
|
+
chevent.events =
|
119
|
+
EPOLLOUT | EPOLLIN | EPOLLET | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
|
120
|
+
struct itimerspec new_t_data;
|
121
|
+
new_t_data.it_value.tv_sec = new_t_data.it_interval.tv_sec =
|
122
|
+
milliseconds / 1000;
|
123
|
+
new_t_data.it_value.tv_nsec = new_t_data.it_interval.tv_nsec =
|
124
|
+
(milliseconds % 1000) * 1000000;
|
125
|
+
timerfd_settime(fd, 0, &new_t_data, NULL);
|
126
|
+
return epoll_ctl(evio_fd, EPOLL_CTL_ADD, fd, &chevent);
|
127
|
+
}
|
128
|
+
|
129
|
+
/** Rearms the timer. Required only by `epoll`.*/
|
130
|
+
void evio_reset_timer(int timer_fd) {
|
131
|
+
char data[8]; // void * is 8 byte long
|
132
|
+
if (read(timer_fd, &data, 8) < 0)
|
133
|
+
data[0] = 0;
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
Reviews any pending events (up to EVIO_MAX_EVENTS) and calls any callbacks.
|
138
|
+
*/
|
139
|
+
int evio_review(const int timeout_millisec) {
|
140
|
+
if (evio_fd < 0)
|
141
|
+
return -1;
|
142
|
+
struct epoll_event events[EVIO_MAX_EVENTS];
|
143
|
+
/* wait for events and handle them */
|
144
|
+
int active_count =
|
145
|
+
epoll_wait(evio_fd, events, EVIO_MAX_EVENTS, timeout_millisec);
|
146
|
+
|
147
|
+
if (active_count > 0) {
|
148
|
+
for (int i = 0; i < active_count; i++) {
|
149
|
+
if (events[i].events & (~(EPOLLIN | EPOLLOUT))) {
|
150
|
+
// errors are hendled as disconnections (on_close)
|
151
|
+
evio_on_error(events[i].data.ptr);
|
152
|
+
} else {
|
153
|
+
// no error, then it's an active event(s)
|
154
|
+
if (events[i].events & EPOLLOUT) {
|
155
|
+
evio_on_ready(events[i].data.ptr);
|
156
|
+
}
|
157
|
+
if (events[i].events & EPOLLIN)
|
158
|
+
evio_on_data(events[i].data.ptr);
|
159
|
+
}
|
160
|
+
} // end for loop
|
161
|
+
} else if (active_count < 0) {
|
162
|
+
return -1;
|
163
|
+
}
|
164
|
+
return active_count;
|
165
|
+
}
|
166
|
+
|
167
|
+
#else
|
168
|
+
/* *****************************************************************************
|
169
|
+
BSD `kqueue` implementation
|
170
|
+
***************************************************************************** */
|
171
|
+
|
172
|
+
/**
|
173
|
+
Creates the `epoll` or `kqueue` object.
|
174
|
+
*/
|
175
|
+
intptr_t evio_create() { return evio_fd = kqueue(); }
|
176
|
+
|
177
|
+
/**
|
178
|
+
Removes a file descriptor from the polling object.
|
179
|
+
*/
|
180
|
+
int evio_remove(int fd) {
|
181
|
+
struct kevent chevent[3];
|
182
|
+
EV_SET(chevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
|
183
|
+
EV_SET(chevent + 1, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
|
184
|
+
EV_SET(chevent + 2, fd, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
|
185
|
+
return kevent(evio_fd, chevent, 3, NULL, 0, NULL);
|
186
|
+
}
|
187
|
+
|
188
|
+
/**
|
189
|
+
Adds a file descriptor to the polling object.
|
190
|
+
*/
|
191
|
+
int evio_add(int fd, void *callback_arg) {
|
192
|
+
struct kevent chevent[2];
|
193
|
+
EV_SET(chevent, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0,
|
194
|
+
callback_arg);
|
195
|
+
EV_SET(chevent + 1, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0,
|
196
|
+
callback_arg);
|
197
|
+
return kevent(evio_fd, chevent, 2, NULL, 0, NULL);
|
198
|
+
}
|
199
|
+
|
200
|
+
/**
|
201
|
+
Creates a timer file descriptor, system dependent.
|
202
|
+
*/
|
203
|
+
intptr_t evio_open_timer() {
|
204
|
+
#ifdef P_tmpdir
|
205
|
+
char template[] = P_tmpdir "evio_facil_timer_XXXXXX";
|
206
|
+
#else
|
207
|
+
char template[] = "/tmp/evio_facil_timer_XXXXXX";
|
208
|
+
#endif
|
209
|
+
return mkstemp(template);
|
210
|
+
}
|
211
|
+
|
212
|
+
/**
|
213
|
+
Adds a timer file descriptor, so that callbacks will be called for it's events.
|
214
|
+
*/
|
215
|
+
intptr_t evio_add_timer(int fd, void *callback_arg,
|
216
|
+
unsigned long milliseconds) {
|
217
|
+
struct kevent chevent;
|
218
|
+
EV_SET(&chevent, fd, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, milliseconds,
|
219
|
+
callback_arg);
|
220
|
+
return kevent(evio_fd, &chevent, 1, NULL, 0, NULL);
|
221
|
+
}
|
222
|
+
|
223
|
+
/** Rearms the timer. Required only by `epoll`.*/
|
224
|
+
void evio_reset_timer(int timer_fd) { (void)timer_fd; }
|
225
|
+
|
226
|
+
/**
|
227
|
+
Reviews any pending events (up to EVIO_MAX_EVENTS) and calls any callbacks.
|
228
|
+
*/
|
229
|
+
int evio_review(const int timeout_millisec) {
|
230
|
+
if (evio_fd < 0)
|
231
|
+
return -1;
|
232
|
+
struct kevent events[EVIO_MAX_EVENTS];
|
233
|
+
|
234
|
+
const struct timespec timeout = {.tv_sec = (timeout_millisec / 1024),
|
235
|
+
.tv_nsec =
|
236
|
+
((timeout_millisec % 1024) * 1000000)};
|
237
|
+
/* wait for events and handle them */
|
238
|
+
int active_count =
|
239
|
+
kevent(evio_fd, NULL, 0, events, EVIO_MAX_EVENTS, &timeout);
|
240
|
+
|
241
|
+
if (active_count > 0) {
|
242
|
+
for (int i = 0; i < active_count; i++) {
|
243
|
+
if (events[i].flags & (EV_EOF | EV_ERROR)) {
|
244
|
+
// errors are hendled as disconnections (on_close)
|
245
|
+
evio_on_error(events[i].udata);
|
246
|
+
} else {
|
247
|
+
// no error, then it's an active event(s)
|
248
|
+
if (events[i].filter == EVFILT_WRITE) {
|
249
|
+
evio_on_ready(events[i].udata);
|
250
|
+
}
|
251
|
+
if (events[i].filter == EVFILT_READ || events[i].filter == EVFILT_TIMER)
|
252
|
+
evio_on_data(events[i].udata);
|
253
|
+
}
|
254
|
+
} // end for loop
|
255
|
+
} else if (active_count < 0) {
|
256
|
+
if (errno == EINTR)
|
257
|
+
return 0;
|
258
|
+
return -1;
|
259
|
+
}
|
260
|
+
return active_count;
|
261
|
+
}
|
262
|
+
|
263
|
+
#endif /* system dependent code */
|
data/ext/iodine/evio.h
ADDED
@@ -0,0 +1,133 @@
|
|
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 H_FACIL_EVIO_H
|
8
|
+
#include <stdint.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
|
11
|
+
/**
|
12
|
+
This is an `epoll` / `kqueue` edge triggered wrapper, allowing for portability
|
13
|
+
between BSD and Linux polling machanisms as well as routing events to hard-coded
|
14
|
+
callbacks (weak function symbols) instead of the polling return values.
|
15
|
+
|
16
|
+
The callbacks supported by thils library:
|
17
|
+
|
18
|
+
* `evio_on_data(intptr_t)` called when data is available or on timer.
|
19
|
+
* `evio_on_ready(intptr_t)` called when writing is possible.
|
20
|
+
* `evio_on_error(intptr_t)` called when an error occured.
|
21
|
+
* `evio_on_close(intptr_t)` called when the connection was remotely closed.
|
22
|
+
|
23
|
+
*/
|
24
|
+
#define H_FACIL_EVIO_H
|
25
|
+
#define LIB_EVIO_VERSION_MAJOR 0
|
26
|
+
#define LIB_EVIO_VERSION_MINOR 1
|
27
|
+
#define LIB_EVIO_VERSION_PATCH 0
|
28
|
+
|
29
|
+
#ifdef __cplusplus
|
30
|
+
extern "C" {
|
31
|
+
#endif
|
32
|
+
|
33
|
+
#ifndef EVIO_MAX_EVENTS
|
34
|
+
#define EVIO_MAX_EVENTS 64
|
35
|
+
#endif
|
36
|
+
#ifndef EVIO_TICK
|
37
|
+
#define EVIO_TICK 256 /** in milliseconsd */
|
38
|
+
#endif
|
39
|
+
|
40
|
+
/**
|
41
|
+
Creates the `epoll` or `kqueue` object.
|
42
|
+
|
43
|
+
It's impossible to add or remove file descriptors from the polling system before
|
44
|
+
calling this method.
|
45
|
+
|
46
|
+
Returns -1 on error, otherwise returns a unique value representing the `epoll`
|
47
|
+
or `kqueue` object. The returned value can be safely ignored.
|
48
|
+
|
49
|
+
NOTE: Once an `epoll` / `kqueue` object was opened, `fork` should be avoided,
|
50
|
+
since ALL the events will be shared among the forked proccesses (while not ALL
|
51
|
+
the file descriptors are expected to be shared).
|
52
|
+
*/
|
53
|
+
intptr_t evio_create(void);
|
54
|
+
|
55
|
+
/**
|
56
|
+
Reviews any pending events (up to EVIO_MAX_EVENTS) and calls any callbacks.
|
57
|
+
|
58
|
+
Waits up to `timeout_millisec` for events to occur.
|
59
|
+
|
60
|
+
Returns -1 on error, otherwise returns the number of events handled.
|
61
|
+
*/
|
62
|
+
int evio_review(const int timeout_millisec);
|
63
|
+
|
64
|
+
/**
|
65
|
+
Closes the `epoll` / `kqueue` object, releasing it's resources.
|
66
|
+
*/
|
67
|
+
void evio_close(void);
|
68
|
+
|
69
|
+
/**
|
70
|
+
returns true if the evio is available for adding or removing file descriptors.
|
71
|
+
*/
|
72
|
+
int evio_isactive(void);
|
73
|
+
|
74
|
+
/* *****************************************************************************
|
75
|
+
Adding and removing normal file descriptors.
|
76
|
+
*/
|
77
|
+
|
78
|
+
/**
|
79
|
+
Adds a file descriptor to the polling object.
|
80
|
+
|
81
|
+
Returns -1 on error, otherwise return value is system dependent and can be
|
82
|
+
safely ignored.
|
83
|
+
*/
|
84
|
+
int evio_add(int fd, void *callback_arg);
|
85
|
+
|
86
|
+
/**
|
87
|
+
Removes a file descriptor from the polling object.
|
88
|
+
|
89
|
+
Returns -1 on error, otherwise return value is system dependent. If the file
|
90
|
+
descriptor did exist in the polling object, it isn't an error.
|
91
|
+
*/
|
92
|
+
int evio_remove(int fd);
|
93
|
+
|
94
|
+
/* *****************************************************************************
|
95
|
+
Timers.
|
96
|
+
*/
|
97
|
+
|
98
|
+
/**
|
99
|
+
Creates a timer file descriptor, system dependent.
|
100
|
+
|
101
|
+
Returns -1 on error, or a valid fd on success.
|
102
|
+
|
103
|
+
NOTE: Systems have a limit on the number of timers that can be opened.
|
104
|
+
*/
|
105
|
+
intptr_t evio_open_timer(void);
|
106
|
+
|
107
|
+
/**
|
108
|
+
Adds a timer file descriptor, so that callbacks will be called for it's events.
|
109
|
+
|
110
|
+
Returns -1 on error, otherwise return value is system dependent.
|
111
|
+
*/
|
112
|
+
intptr_t evio_add_timer(int fd, void *callback_arg, unsigned long milliseconds);
|
113
|
+
|
114
|
+
/**
|
115
|
+
Re-arms the timer.
|
116
|
+
|
117
|
+
Required only by `epoll`. `kqueue` timers will continue cycling regardless.
|
118
|
+
*/
|
119
|
+
void evio_reset_timer(int timer_fd);
|
120
|
+
|
121
|
+
/* *****************************************************************************
|
122
|
+
Callbacks - override these.
|
123
|
+
*/
|
124
|
+
void evio_on_data(void *);
|
125
|
+
void evio_on_ready(void *);
|
126
|
+
void evio_on_error(void *);
|
127
|
+
void evio_on_close(void *);
|
128
|
+
|
129
|
+
#ifdef __cplusplus
|
130
|
+
} /* extern "C" */
|
131
|
+
#endif
|
132
|
+
|
133
|
+
#endif /* H_FACIL_EVIO_H */
|