iodine 0.6.5 → 0.7.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.

Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +4 -4
  4. data/SPEC-Websocket-Draft.md +3 -6
  5. data/bin/mustache.rb +128 -0
  6. data/examples/test_template.mustache +16 -0
  7. data/ext/iodine/fio.c +9397 -0
  8. data/ext/iodine/fio.h +4723 -0
  9. data/ext/iodine/fio_ary.h +353 -54
  10. data/ext/iodine/fio_cli.c +351 -361
  11. data/ext/iodine/fio_cli.h +84 -105
  12. data/ext/iodine/fio_hashmap.h +70 -16
  13. data/ext/iodine/fio_json_parser.h +35 -24
  14. data/ext/iodine/fio_siphash.c +104 -4
  15. data/ext/iodine/fio_siphash.h +18 -2
  16. data/ext/iodine/fio_str.h +1218 -0
  17. data/ext/iodine/fio_tmpfile.h +1 -1
  18. data/ext/iodine/fiobj.h +13 -8
  19. data/ext/iodine/fiobj4sock.h +6 -8
  20. data/ext/iodine/fiobj_ary.c +107 -17
  21. data/ext/iodine/fiobj_ary.h +36 -4
  22. data/ext/iodine/fiobj_data.c +146 -127
  23. data/ext/iodine/fiobj_data.h +25 -23
  24. data/ext/iodine/fiobj_hash.c +7 -7
  25. data/ext/iodine/fiobj_hash.h +6 -5
  26. data/ext/iodine/fiobj_json.c +20 -17
  27. data/ext/iodine/fiobj_json.h +5 -5
  28. data/ext/iodine/fiobj_mem.h +71 -0
  29. data/ext/iodine/fiobj_mustache.c +310 -0
  30. data/ext/iodine/fiobj_mustache.h +40 -0
  31. data/ext/iodine/fiobj_numbers.c +199 -94
  32. data/ext/iodine/fiobj_numbers.h +7 -7
  33. data/ext/iodine/fiobj_str.c +142 -333
  34. data/ext/iodine/fiobj_str.h +65 -55
  35. data/ext/iodine/fiobject.c +49 -11
  36. data/ext/iodine/fiobject.h +40 -39
  37. data/ext/iodine/http.c +382 -190
  38. data/ext/iodine/http.h +124 -80
  39. data/ext/iodine/http1.c +99 -127
  40. data/ext/iodine/http1.h +5 -5
  41. data/ext/iodine/http1_parser.c +3 -2
  42. data/ext/iodine/http1_parser.h +2 -2
  43. data/ext/iodine/http_internal.c +14 -12
  44. data/ext/iodine/http_internal.h +25 -19
  45. data/ext/iodine/iodine.c +37 -18
  46. data/ext/iodine/iodine.h +4 -0
  47. data/ext/iodine/iodine_caller.c +9 -2
  48. data/ext/iodine/iodine_caller.h +2 -0
  49. data/ext/iodine/iodine_connection.c +82 -117
  50. data/ext/iodine/iodine_defer.c +57 -50
  51. data/ext/iodine/iodine_defer.h +0 -1
  52. data/ext/iodine/iodine_fiobj2rb.h +4 -2
  53. data/ext/iodine/iodine_helpers.c +4 -4
  54. data/ext/iodine/iodine_http.c +25 -32
  55. data/ext/iodine/iodine_json.c +2 -1
  56. data/ext/iodine/iodine_mustache.c +423 -0
  57. data/ext/iodine/iodine_mustache.h +6 -0
  58. data/ext/iodine/iodine_pubsub.c +48 -153
  59. data/ext/iodine/iodine_pubsub.h +5 -4
  60. data/ext/iodine/iodine_rack_io.c +7 -5
  61. data/ext/iodine/iodine_store.c +16 -13
  62. data/ext/iodine/iodine_tcp.c +26 -34
  63. data/ext/iodine/mustache_parser.h +1085 -0
  64. data/ext/iodine/redis_engine.c +740 -646
  65. data/ext/iodine/redis_engine.h +13 -15
  66. data/ext/iodine/resp_parser.h +11 -5
  67. data/ext/iodine/websocket_parser.h +13 -13
  68. data/ext/iodine/websockets.c +240 -393
  69. data/ext/iodine/websockets.h +52 -113
  70. data/lib/iodine.rb +1 -1
  71. data/lib/iodine/mustache.rb +140 -0
  72. data/lib/iodine/version.rb +1 -1
  73. metadata +15 -28
  74. data/ext/iodine/defer.c +0 -566
  75. data/ext/iodine/defer.h +0 -148
  76. data/ext/iodine/evio.c +0 -26
  77. data/ext/iodine/evio.h +0 -161
  78. data/ext/iodine/evio_callbacks.c +0 -26
  79. data/ext/iodine/evio_epoll.c +0 -251
  80. data/ext/iodine/evio_kqueue.c +0 -194
  81. data/ext/iodine/facil.c +0 -2325
  82. data/ext/iodine/facil.h +0 -616
  83. data/ext/iodine/fio_base64.c +0 -277
  84. data/ext/iodine/fio_base64.h +0 -71
  85. data/ext/iodine/fio_llist.h +0 -257
  86. data/ext/iodine/fio_mem.c +0 -675
  87. data/ext/iodine/fio_mem.h +0 -143
  88. data/ext/iodine/fio_random.c +0 -248
  89. data/ext/iodine/fio_random.h +0 -45
  90. data/ext/iodine/fio_sha1.c +0 -362
  91. data/ext/iodine/fio_sha1.h +0 -107
  92. data/ext/iodine/fio_sha2.c +0 -842
  93. data/ext/iodine/fio_sha2.h +0 -169
  94. data/ext/iodine/pubsub.c +0 -867
  95. data/ext/iodine/pubsub.h +0 -221
  96. data/ext/iodine/sock.c +0 -1366
  97. data/ext/iodine/sock.h +0 -566
  98. data/ext/iodine/spnlock.inc +0 -111
@@ -1,566 +0,0 @@
1
- #ifndef H_LIBSOCK_H
2
- #define H_LIBSOCK_H
3
- /*
4
- Copyright: Boaz Segev, 2016-2017
5
- License: MIT
6
-
7
- Feel free to copy, use and enjoy according to the license provided.
8
- */
9
- #define LIB_SOCK_VERSION_MAJOR 0
10
- #define LIB_SOCK_VERSION_MINOR 4
11
- #define LIB_SOCK_VERSION_PATCH 0
12
-
13
- #ifndef LIB_SOCK_MAX_CAPACITY
14
- /** The maximum `fd` value `sock.h` should support. */
15
- #define LIB_SOCK_MAX_CAPACITY 131072
16
- #endif
17
- /** \file
18
- * The `sock.h` is a non-blocking socket helper library, using a user level
19
- * buffer, non-blocking sockets and some helper functions.
20
- *
21
- * This library is great when using it alongside `evio.h`.
22
- *
23
- * The library is designed to be thread safe, but not fork safe - mostly since
24
- * sockets, except listenning sockets, shouldn't be shared among processes.
25
- *
26
- * Socket connections accepted or created using this library will use the
27
- * TCP_NODELAY option by default.
28
- *
29
- * Non TCP/IP stream sockets and file descriptors (i.e., unix sockets) can be
30
- * safely used with this library. However, file descriptors that can't use the
31
- * `read` or `write` system calls MUST set correct Read / Write hooks or they
32
- * will fail.
33
- */
34
-
35
- #include <stdint.h>
36
- #include <stdio.h>
37
- #include <stdlib.h>
38
- #include <string.h>
39
- #include <sys/types.h>
40
- #include <unistd.h>
41
-
42
- #if defined(__FreeBSD__)
43
- #include <netinet/in.h>
44
- #include <sys/socket.h>
45
- #endif
46
-
47
- // clang-format off
48
- #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
49
- # if defined(__has_include)
50
- # if __has_include(<endian.h>)
51
- # include <endian.h>
52
- # elif __has_include(<sys/endian.h>)
53
- # include <sys/endian.h>
54
- # endif
55
- # endif
56
- # if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) && \
57
- __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
58
- # define __BIG_ENDIAN__
59
- # endif
60
- #endif
61
- // clang-format on
62
-
63
- #ifndef UNUSED_FUNC
64
- #define UNUSED_FUNC __attribute__((unused))
65
- #endif
66
-
67
- /* *****************************************************************************
68
- A simple, predictable UUID for file-descriptors, for collision prevention
69
- */
70
- #ifndef sock_uuid2fd
71
- #define sock_uuid2fd(uuid) ((int)((uintptr_t)uuid >> 8))
72
- #endif
73
-
74
- /* *****************************************************************************
75
- C++ extern
76
- */
77
- #if defined(__cplusplus)
78
- extern "C" {
79
- #endif
80
-
81
- /* *****************************************************************************
82
- Process wide and helper sock API.
83
- */
84
-
85
- /** MUST be called after forking a process. */
86
- void sock_on_fork(void);
87
-
88
- /**
89
- * Sets a socket to non blocking state.
90
- *
91
- * This function is called automatically for the new socket, when using
92
- * `sock_accept` or `sock_connect`.
93
- */
94
- int sock_set_non_block(int fd);
95
-
96
- /**
97
- Gets the maximum number of file descriptors this process can be allowed to
98
- access (== maximum fd value + 1).
99
-
100
- If the "soft" limit is lower then the "hard" limit, the process's limits will be
101
- extended to the allowed "hard" limit.
102
- */
103
- ssize_t sock_max_capacity(void);
104
-
105
- /* *****************************************************************************
106
- The main sock API.
107
- */
108
-
109
- /**
110
- * Opens a listening non-blocking socket. Return's the socket's UUID.
111
- *
112
- * If `port` is provided (`address` can be NULL), a TCP/IP socket will be
113
- * opened. Otherwise, `address` is required and a Unix Socket will be used
114
- * (remember Unix Sockets have name length restrictions).
115
- *
116
- * Returns -1 on error. Returns a valid socket (non-random) UUID.
117
- *
118
- * UUIDs with values less then -1 are valid values, depending on the system's
119
- * byte-ordering.
120
- *
121
- * Socket UUIDs are predictable and shouldn't be used outside the local system.
122
- * They protect against connection mixups on concurrent systems (i.e. when
123
- * saving client data for "broadcasting" or when an old client task is preparing
124
- * a response in the background while a disconnection and a new connection occur
125
- * on the same `fd`).
126
- */
127
- intptr_t sock_listen(const char *address, const char *port);
128
-
129
- /**
130
- * `sock_accept` accepts a new socket connection from the listening socket
131
- * `server_fd`, allowing the use of `sock_` functions with this new file
132
- * descriptor.
133
-
134
- * When using `evio`, remember to call `int evio_add(intptr_t uuid);` to
135
- * listen for events.
136
- *
137
- * Returns -1 on error. Returns a valid socket (non-random) UUID.
138
- *
139
- * Socket UUIDs are predictable and shouldn't be used outside the local system.
140
- * They protect against connection mixups on concurrent systems (i.e. when saving
141
- * client data for "broadcasting" or when an old client task is preparing a
142
- * response in the background while a disconnection and a new connection occur on
143
- * the same `fd`).
144
- */
145
- intptr_t sock_accept(intptr_t srv_uuid);
146
-
147
- /**
148
- * `sock_connect` is similar to `sock_accept` but should be used to initiate a
149
- * client connection to the address requested.
150
- *
151
- * If `port` is provided (`address` can be NULL), a TCP/IP socket will be
152
- * opened. Otherwise, `address` is required and a Unix Socket will be used
153
- * (remember Unix Sockets have name length restrictions).
154
- *
155
- * Returns -1 on error. Returns a valid socket (non-random) UUID.
156
- *
157
- * Socket UUIDs are predictable and shouldn't be used outside the local system.
158
- * They protect against connection mixups on concurrent systems (i.e. when
159
- * saving client data for "broadcasting" or when an old client task is preparing
160
- * a response in the background while a disconnection and a new connection occur
161
- * on the same `fd`).
162
- *
163
- * When using `evio`, remember to call `int evio_add(sock_fd2uuid(uuid),
164
- * (void*)uuid);` to listen for events.
165
- *
166
- * NOTICE:
167
- *
168
- * This function is non-blocking, meaning that the connection probably wasn't
169
- * established by the time the function returns (this prevents the function from
170
- * hanging while waiting for a network timeout).
171
- *
172
- * Use select, poll, `evio` or other solutions to review the connection state
173
- * before attempting to write to the socket.
174
- */
175
- intptr_t sock_connect(char *address, char *port);
176
-
177
- /**
178
- * `sock_open` takes an existing file descriptor `fd` and initializes it's status
179
- * as open and available for `sock_*` API calls, returning a valid UUID.
180
- *
181
- * This will reinitialize the data (user buffer etc') for the file descriptor
182
- * provided, calling the `sock_on_close` callback if the `fd` was previously
183
- * marked as used.
184
-
185
- * When using `evio`, remember to call `int evio_add(sock_fd2uuid(uuid),
186
- * (void*)uuid);` to listen for events.
187
- *
188
- * Returns -1 on error. Returns a valid socket (non-random) UUID.
189
- *
190
- * Socket UUIDs are predictable and shouldn't be used outside the local system.
191
- * They protect against connection mixups on concurrent systems (i.e. when saving
192
- * client data for "broadcasting" or when an old client task is preparing a
193
- * response in the background while a disconnection and a new connection occur on
194
- * the same `fd`).
195
- */
196
- intptr_t sock_open(int fd);
197
-
198
- /**
199
- * Returns 1 if the uuid refers to a valid and open, socket.
200
- *
201
- * Returns 0 if not.
202
- */
203
- int sock_isvalid(intptr_t uuid);
204
-
205
- /**
206
- Returns 1 if the uuid is invalid or the socket is flagged to be closed.
207
-
208
- Returns 0 if the socket is valid, open and isn't flagged to be closed.
209
- */
210
- int sock_isclosed(intptr_t uuid);
211
-
212
- /** The return type for the `sock_peer_addr` function. */
213
- typedef struct {
214
- uint32_t addrlen;
215
- struct sockaddr *addr;
216
- } sock_peer_addr_s;
217
- /**
218
- * Returns the information available about the socket's peer address.
219
- *
220
- * If no information is available, the struct will be initialized with zero
221
- * (`addr == NULL`).
222
- * The information is only available when the socket was accepted using
223
- * `sock_accept` or opened using `sock_connect`.
224
- */
225
- sock_peer_addr_s sock_peer_addr(intptr_t uuid);
226
-
227
- /**
228
- * `sock_fd2uuid` takes an existing file decriptor `fd` and returns it's active
229
- * `uuid`.
230
-
231
- * If the file descriptor is marked as closed (wasn't opened / registered with
232
- * `libsock`) the function returns -1;
233
- *
234
- * If the file descriptor was closed remotely (or not using `libsock`), a false
235
- * positive will be possible. This is not an issue, since the use of an invalid
236
- fd
237
- * will result in the registry being updated and the fd being closed.
238
- *
239
- * Returns -1 on error. Returns a valid socket (non-random) UUID.
240
- */
241
- intptr_t sock_fd2uuid(int fd);
242
-
243
- /**
244
- * OVERRIDABLE:
245
- *
246
- * "Touches" a socket connection.
247
- *
248
- * This is a place holder for an optional callback for systems that apply
249
- * timeout reviews.
250
- *
251
- * `sock` supplies a default implementation (that does nothing) is cases where a
252
- * callback wasn't defined.
253
- */
254
- void sock_touch(intptr_t uuid);
255
-
256
- /**
257
- * OVERRIDABLE:.
258
- *
259
- * This is a place holder for an optional callback for when the socket is closed
260
- * locally.
261
- *
262
- * Notice that calling `sock_close()` won't close the socket before all the data
263
- * in the buffer is sent. This function will be called only one the connection
264
- * is actually closed.
265
- *
266
- * `sock` supplies a default implementation (that does nothing) is cases where a
267
- * callback wasn't defined.
268
- */
269
- void sock_on_close(intptr_t uuid);
270
-
271
- /**
272
- * `sock_read` attempts to read up to count bytes from the socket into the
273
- * buffer starting at buf.
274
- *
275
- * `sock_read`'s return values are wildly different then the native return
276
- * values and they aim at making far simpler sense.
277
- *
278
- * `sock_read` returns the number of bytes read (0 is a valid return value which
279
- * simply means that no bytes were read from the buffer).
280
- *
281
- * On a connection error (NOT EAGAIN or EWOULDBLOCK), signal interrupt, or when
282
- * the connection was closed, `sock_read` returns -1.
283
- *
284
- * The value 0 is the valid value indicating no data was read.
285
- *
286
- * Data might be available in the kernel's buffer while it is not available to
287
- * be read using `sock_read` (i.e., when using a transport layer, such as TLS).
288
- */
289
- ssize_t sock_read(intptr_t uuid, void *buf, size_t count);
290
-
291
- typedef struct {
292
- /** The fsocket uuid for sending data. */
293
- intptr_t uuid;
294
- union {
295
- /** The in-memory data to be sent. */
296
- const void *buffer;
297
- /** The data to be sent, if this is a file. */
298
- const intptr_t data_fd;
299
- };
300
- union {
301
- /**
302
- * This deallocation callback will be called when the packet is finished
303
- * with the buffer if the `move` flags is set.
304
- *
305
- * If no deallocation callback is `free` will be used.
306
- *
307
- * Note: `sock` library functions MUST NEVER be called by a callback, or a
308
- * deadlock might occur.
309
- */
310
- void (*dealloc)(void *buffer);
311
- /**
312
- * This is an alternative deallocation callback accessor (same memory space
313
- * as `dealloc`) for conveniently setting the file `close` callback.
314
- *
315
- * Note: `sock` library functions MUST NEVER be called by a callback, or a
316
- * deadlock might occur.
317
- */
318
- void (*close)(intptr_t fd);
319
- };
320
- /** The length (size) of the buffer, or the amount of data to be sent from the
321
- * file descriptor.
322
- */
323
- uintptr_t length;
324
- /** Starting point offset from the buffer or file descriptor's beginning. */
325
- intptr_t offset;
326
- /** The packet will be sent as soon as possible. */
327
- unsigned urgent : 1;
328
- /**
329
- * The buffer contains the value of a file descriptor (`int`). i.e.:
330
- * `.data_fd = fd` or `.buffer = (void*)fd;`
331
- */
332
- unsigned is_fd : 1;
333
- /**
334
- * The buffer **points** to a file descriptor (`int`): `.buffer = (void*)&fd;`
335
- *
336
- * In the case the `dealloc` function will be called, allowing both closure
337
- * and deallocation of the `int` pointer.
338
- *
339
- * This feature can be used for file reference counting, such as implemented
340
- * by the `fio_file_cache` service.
341
- */
342
- unsigned is_pfd : 1;
343
- /** for internal use */
344
- unsigned rsv : 1;
345
- } sock_write_info_s;
346
-
347
- void SOCK_DEALLOC_NOOP(void *arg);
348
- #define SOCK_CLOSE_NOOP ((void (*)(intptr_t))SOCK_DEALLOC_NOOP)
349
-
350
- /**
351
- * `sock_write2_fn` is the actual function behind the macro `sock_write2`.
352
- */
353
- ssize_t sock_write2_fn(sock_write_info_s options);
354
-
355
- /**
356
- * `sock_write2` is similar to `sock_write`, except special properties can be
357
- * set.
358
- *
359
- * On error, -1 will be returned. Otherwise returns 0. All the bytes are
360
- * transferred to the socket's user level buffer.
361
- */
362
- #define sock_write2(...) sock_write2_fn((sock_write_info_s){__VA_ARGS__})
363
- /**
364
- * `sock_write` copies `legnth` data from the buffer and schedules the data to
365
- * be sent over the socket.
366
- *
367
- * The data isn't necessarily written to the socket and multiple calls to
368
- * `sock_flush` might be required before all the data is actually sent.
369
- *
370
- * On error, -1 will be returned. Otherwise returns 0. All the bytes are
371
- * transferred to the socket's user level buffer.
372
- *
373
- * Returns the same values as `sock_write2`.
374
- */
375
- // ssize_t sock_write(uintptr_t uuid, void *buffer, size_t legnth);
376
- UNUSED_FUNC static inline ssize_t
377
- sock_write(const intptr_t uuid, const void *buffer, const size_t length) {
378
- if (!length || !buffer)
379
- return 0;
380
- void *cpy = malloc(length);
381
- if (!cpy)
382
- return -1;
383
- memcpy(cpy, buffer, length);
384
- return sock_write2(.uuid = uuid, .buffer = cpy, .length = length);
385
- }
386
-
387
- /**
388
- * Sends data from a file as if it were a single atomic packet (sends up to
389
- * length bytes or until EOF is reached).
390
- *
391
- * Once the file was sent, the `source_fd` will be closed using `close`.
392
- *
393
- * The file will be buffered to the socket chunk by chunk, so that memory
394
- * consumption is capped. The system's `sendfile` might be used if conditions
395
- * permit.
396
- *
397
- * `offset` dictates the starting point for te data to be sent and length sets
398
- * the maximum amount of data to be sent.
399
- *
400
- * Returns -1 and closes the file on error. Returns 0 on success.
401
- */
402
- UNUSED_FUNC static inline ssize_t
403
- sock_sendfile(intptr_t uuid, intptr_t source_fd, off_t offset, size_t length) {
404
- return sock_write2(.uuid = uuid, .buffer = (void *)(source_fd),
405
- .length = length, .is_fd = 1, .offset = offset);
406
- }
407
-
408
- /**
409
- * `sock_close` marks the connection for disconnection once all the data was
410
- * sent. The actual disconnection will be managed by the `sock_flush` function.
411
- *
412
- * `sock_flash` will automatically be called.
413
- */
414
- void sock_close(intptr_t uuid);
415
-
416
- /**
417
- * `sock_force_close` closes the connection immediately, without adhering to any
418
- * protocol restrictions and without sending any remaining data in the
419
- * connection buffer.
420
- */
421
- void sock_force_close(intptr_t uuid);
422
-
423
- /**
424
- * `sock_hijack` is the reverse of the `sock_open` function, removing the
425
- * connection from the `sock` library and clearing it's data without closing it
426
- * (`sock_on_close` will NOT be called).
427
- *
428
- * Returns the original `fd` for the socket. On error returns -1.
429
- */
430
- int sock_hijack(intptr_t uuid);
431
-
432
- /* *****************************************************************************
433
- Direct user level buffer API.
434
- */
435
-
436
- /**
437
- * `sock_flush` writes the data in the internal buffer to the underlying file
438
- * descriptor and closes the underlying fd once it's marked for closure (and all
439
- * the data was sent).
440
- *
441
- * Return values: 1 will be returned if `sock_flush` should be called again. 0
442
- * will be returned if the socket was fully flushed. -1 will be returned on an
443
- * error or when the connection is closed.
444
- */
445
- ssize_t sock_flush(intptr_t uuid);
446
-
447
- /**
448
- * `sock_flush_strong` performs the same action as `sock_flush` but returns only
449
- * after all the data was sent. This is a "busy" wait, polling isn't performed.
450
- */
451
- void sock_flush_strong(intptr_t uuid);
452
-
453
- /**
454
- * Calls `sock_flush` for each file descriptor that's buffer isn't empty.
455
- */
456
- void sock_flush_all(void);
457
-
458
- /**
459
- * Returns the number of `sock_write` calls that are waiting in the socket's
460
- * queue and haven't been processed.
461
- *
462
- * This method will be deprecated in the 0.7.0 release. Use `sock_pending`
463
- * instead.
464
- */
465
- int __attribute__((deprecated("use sock_pending instead")))
466
- sock_has_pending(intptr_t uuid);
467
-
468
- /**
469
- * Returns the number of `sock_write` calls that are waiting in the socket's
470
- * queue and haven't been processed.
471
- */
472
- size_t sock_pending(intptr_t uuid);
473
-
474
- /**
475
- * This weak function can be overwritten when using the `defer` library.
476
- * However, the function MUST call {sock_flush} at some point.
477
- */
478
- void sock_flush_defer(void *arg, void *ignored);
479
-
480
- /* *****************************************************************************
481
- TLC - Transport Layer Callback.
482
- */
483
-
484
- /**
485
- * The following struct is used for setting a the read/write hooks that will
486
- * replace the default system calls to `recv` and `write`.
487
- *
488
- * Note: `sock` library functions MUST NEVER be called by any callback, or a
489
- * deadlock might occur.
490
- */
491
- typedef struct sock_rw_hook_s {
492
- /**
493
- * Implement reading from a file descriptor. Should behave like the file
494
- * system `read` call, including the setup or errno to EAGAIN / EWOULDBLOCK.
495
- *
496
- * Note: `sock` library functions MUST NEVER be called by any callback, or a
497
- * deadlock might occur.
498
- */
499
- ssize_t (*read)(intptr_t uuid, void *udata, void *buf, size_t count);
500
- /**
501
- * Implement writing to a file descriptor. Should behave like the file system
502
- * `write` call.
503
- *
504
- * Note: `sock` library functions MUST NEVER be called by any callback, or a
505
- * deadlock might occur.
506
- */
507
- ssize_t (*write)(intptr_t uuid, void *udata, const void *buf, size_t count);
508
- /**
509
- * When implemented, this function will be called to flush any data remaining
510
- * in the internal buffer.
511
- *
512
- * The function should return the number of bytes remaining in the internal
513
- * buffer (0 is a valid response) on -1 (on error).
514
- *
515
- * It is important thet the `flush` function write to the underlying fd until
516
- * the writing operation returns -1 with EWOULDBLOCK or all the data was
517
- * written.
518
- *
519
- * Note: `sock` library functions MUST NEVER be called by any callback, or a
520
- * deadlock might occur.
521
- */
522
- ssize_t (*flush)(intptr_t uuid, void *udata);
523
- /**
524
- * The `on_close` callback is called when the socket is closed, allowing for
525
- * dynamic sock_rw_hook_s memory management.
526
- *
527
- * The `on_close` callback should manage is own thread safety mechanism, if
528
- * required.
529
- *
530
- * Note: `sock` library functions MUST NEVER be called by any callback, or a
531
- * deadlock might occur.
532
- * */
533
- void (*on_close)(intptr_t uuid, struct sock_rw_hook_s *rw_hook, void *udata);
534
- } sock_rw_hook_s;
535
-
536
- /* *****************************************************************************
537
- RW hooks implementation
538
- */
539
-
540
- /** Sets a socket hook state (a pointer to the struct). */
541
- int sock_rw_hook_set(intptr_t uuid, sock_rw_hook_s *rw_hooks, void *udata);
542
-
543
- /** Gets a socket hook state (a pointer to the struct). */
544
- struct sock_rw_hook_s *sock_rw_hook_get(intptr_t uuid);
545
-
546
- /** Returns the socket's udata associated with the read/write hook. */
547
- void *sock_rw_udata(intptr_t uuid);
548
-
549
- /** The default Read/Write hooks used for system Read/Write (udata == NULL). */
550
- extern const sock_rw_hook_s SOCK_DEFAULT_HOOKS;
551
-
552
- /* *****************************************************************************
553
- test
554
- */
555
- #ifdef DEBUG
556
- void sock_libtest(void);
557
- #endif
558
-
559
- /* *****************************************************************************
560
- C++ extern
561
- */
562
- #if defined(__cplusplus)
563
- }
564
- #endif
565
-
566
- #endif /* H_LIBSOCK_H */