iodine 0.2.9 → 0.2.10
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 +27 -0
- data/README.md +14 -4
- data/bin/raw-rbhttp +4 -6
- data/bin/raw-rbhttp-em +63 -0
- data/ext/iodine/bscrypt-common.h +2 -2
- data/ext/iodine/http1.c +2 -2
- data/ext/iodine/http1_simple_parser.c +2 -1
- data/ext/iodine/http_request.h +4 -4
- data/ext/iodine/http_response.c +4 -3
- data/ext/iodine/http_response_http1.h +10 -10
- data/ext/iodine/iodine_core.c +60 -6
- data/ext/iodine/iodine_http.c +5 -2
- data/ext/iodine/libasync.c +22 -11
- data/ext/iodine/libasync.h +6 -1
- data/ext/iodine/libreact.c +8 -5
- data/ext/iodine/libreact.h +1 -1
- data/ext/iodine/libserver.c +32 -14
- data/ext/iodine/libserver.h +12 -6
- data/ext/iodine/libsock.c +16 -9
- data/ext/iodine/libsock.h +7 -7
- data/ext/iodine/mempool.h +17 -14
- data/ext/iodine/misc.c +2 -2
- data/ext/iodine/random.c +17 -2
- data/ext/iodine/sha1.h +1 -1
- data/ext/iodine/sha2.h +3 -3
- data/ext/iodine/siphash.c +2 -2
- data/ext/iodine/spnlock.h +35 -35
- data/lib/iodine/protocol.rb +4 -0
- data/lib/iodine/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30444cc800decb8b3339bdbc34e499e8fa8d7d75
|
4
|
+
data.tar.gz: 6657c29ca28a5aa8ef3dd3f50e848020f256b674
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be709de0f327815d3c8366f388395f8dc26c4a1789a25d5c80e04445efd9508c746a95df6538d34fcee405c0f7458d6fa9575b256483124e72db042e5c8ad907
|
7
|
+
data.tar.gz: f7d0fb12ed10468ffc2a1b3297d2a214da07753570873dc79224a1ae8279034a1abe72f2a78801850606921ae851874b91854380a4b0003d914c199dfbe08589
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,33 @@ Please notice that this change log contains changes for upcoming releases as wel
|
|
6
6
|
|
7
7
|
## Changes:
|
8
8
|
|
9
|
+
***
|
10
|
+
|
11
|
+
Change log v.0.2.10 (next release)
|
12
|
+
|
13
|
+
**Update**: added documentation and an extra helper method to set a connection's timeout when using custom protocols (Iodine as an EventMachine alternative).
|
14
|
+
|
15
|
+
**C Layer Update** updated the [`facil.io`](http://facil.io) library used, to incorporate the following fixes / update:
|
16
|
+
|
17
|
+
* Better cross platform compilation by avoiding some name-space clashes. i.e, fixes a name clash with the `__used` directive / macro, where some OSs (i.e. CentOS) used a similar directive with different semantics.
|
18
|
+
|
19
|
+
* Reviewed and fixed some signed vs. unsigned integer comparisons.
|
20
|
+
|
21
|
+
* Smoother event scheduling by increasing the event-node's pool size.
|
22
|
+
|
23
|
+
* Smoother thread concurrency growth by managing thread `nanosleep` times as thread count dependent.
|
24
|
+
|
25
|
+
* Cleared out "unused variable" warnings.
|
26
|
+
|
27
|
+
* Streamlined the `accept` process to remove a double socket's data clean-up.
|
28
|
+
|
29
|
+
* `SERVER_DELAY_IO` is now implemented as an event instead of a stack frame.
|
30
|
+
|
31
|
+
* Fixed a possible Linux `sendfile` implementation issue where sometimes errors wouldn't be caught or `sendfile` would be called past a file's limit (edge case handling).
|
32
|
+
|
33
|
+
* `bscrypt` random generator (where `dev/random` is unavailable) should now provide more entropy.
|
34
|
+
|
35
|
+
|
9
36
|
***
|
10
37
|
|
11
38
|
Change log v.0.2.9
|
data/README.md
CHANGED
@@ -6,7 +6,9 @@
|
|
6
6
|
[![Inline docs](http://inch-ci.org/github/boazsegev/iodine.svg?branch=master)](http://www.rubydoc.info/github/boazsegev/iodine/master/frames)
|
7
7
|
[![GitHub](https://img.shields.io/badge/GitHub-Open%20Source-blue.svg)](https://github.com/boazsegev/iodine)
|
8
8
|
|
9
|
-
Iodine
|
9
|
+
Iodine is a fast concurrent web server for real-time Ruby applications, with native support for Websockets, static file service and HTTP/1.1.
|
10
|
+
|
11
|
+
Iodine also supports custom protocol authoring, making Object Oriented **Network Services** easy to write.
|
10
12
|
|
11
13
|
Iodine is an **evented** framework with a simple API that builds off the low level [C code library facil.io](https://github.com/boazsegev/facil.io) with support for **epoll** and **kqueue** - this means that:
|
12
14
|
|
@@ -63,7 +65,7 @@ This means that even a Gigabyte long response will use ~32Kb of memory, as long
|
|
63
65
|
|
64
66
|
Iodine supports static file serving that allows the server to serve static files directly, with no Ruby layer (all from C-land).
|
65
67
|
|
66
|
-
This means that Iodine won't lock Ruby's GVL when sending static files
|
68
|
+
This means that Iodine won't lock Ruby's GVL when sending static files. The files will be sent directly, allowing for true native concurrency. Since the Ruby layer is unaware of these requests, logging can be performed by turning iodine's logger on.
|
67
69
|
|
68
70
|
To setup native static file service, setup the public folder's address **before** starting the server.
|
69
71
|
|
@@ -83,9 +85,17 @@ app = Proc.new { out }
|
|
83
85
|
run app
|
84
86
|
```
|
85
87
|
|
88
|
+
To enable logging from the command line, use the `-v` (verbose) option:
|
89
|
+
|
90
|
+
```bash
|
91
|
+
bundler exec iodine -p $PORT -t 16 -w 4 -www /my/public/folder -v
|
92
|
+
```
|
93
|
+
|
86
94
|
#### X-Sendfile
|
87
95
|
|
88
|
-
|
96
|
+
Ruby can leverage static file support (if enabled) by using the `X-Sendfile` header in the Ruby application response.
|
97
|
+
|
98
|
+
This allows Ruby to send very large files using a very small memory footprint, as well as (when possible) leveraging the `sendfile` system call.
|
89
99
|
|
90
100
|
i.e. (example `config.ru` for Iodine):
|
91
101
|
|
@@ -95,7 +105,7 @@ app = proc do |env|
|
|
95
105
|
if request.path_info == '/source'.freeze
|
96
106
|
[200, { 'X-Sendfile' => File.expand_path(__FILE__) }, []]
|
97
107
|
elsif request.path_info == '/file'.freeze
|
98
|
-
[200, { 'X-Header' => 'This was a Rack::Sendfile response sent as text' }, File.open(__FILE__)]
|
108
|
+
[200, { 'X-Header' => 'This was a Rack::Sendfile response sent as text.' }, File.open(__FILE__)]
|
99
109
|
else
|
100
110
|
[200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
101
111
|
'Content-Length'.freeze => request.path_info.length.to_s },
|
data/bin/raw-rbhttp
CHANGED
@@ -15,21 +15,19 @@ require 'bundler/setup'
|
|
15
15
|
require 'iodine'
|
16
16
|
|
17
17
|
class HttpProtocol
|
18
|
-
@timeout =
|
18
|
+
@timeout = 10
|
19
19
|
# `on_message` is an optional alternative to the `on_data` callback.
|
20
20
|
# `on_message` has a 1Kb buffer that recycles itself for memory optimization.
|
21
21
|
def on_data
|
22
22
|
# writing will never block and will use a buffer written in C when needed.
|
23
|
-
|
24
|
-
while (data = read)
|
25
|
-
write "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nKeep-Alive: timeout=1\r\nContent-Length: 12\r\n\r\nHello World!"
|
26
|
-
end
|
23
|
+
write "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nKeep-Alive: timeout=1\r\nContent-Length: 12\r\n\r\nHello World!"
|
27
24
|
end
|
28
25
|
end
|
29
26
|
|
30
27
|
puts "thread #{Iodine.threads}"
|
31
28
|
# Listen
|
32
29
|
Iodine.listen '3000', HttpProtocol
|
33
|
-
Iodine.threads =
|
30
|
+
Iodine.threads = 8
|
31
|
+
Iodine.processes = 1
|
34
32
|
puts "now, thread #{Iodine.threads}"
|
35
33
|
Iodine.start
|
data/bin/raw-rbhttp-em
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# this will compile Iodine and run a raw sockets server that emulates HTTP (without parsing any incoming requests).
|
4
|
+
|
5
|
+
# # test using:
|
6
|
+
# ab -n 100000 -c 200 -k http://127.0.0.1:3000/
|
7
|
+
# wrk -c200 -d4 -t12 http://localhost:3000/
|
8
|
+
|
9
|
+
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
10
|
+
# puts `rake clean`
|
11
|
+
# puts `rake compile`
|
12
|
+
|
13
|
+
require 'benchmark'
|
14
|
+
# $LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
15
|
+
# require 'bundler/setup'
|
16
|
+
|
17
|
+
require 'eventmachine'
|
18
|
+
|
19
|
+
module HttpProtocol
|
20
|
+
def receive_data data
|
21
|
+
send_data "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nKeep-Alive: timeout=1\r\nContent-Length: 12\r\n\r\nHello World!"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Running EM emulating HTTP."
|
26
|
+
|
27
|
+
if EventMachine.kqueue?
|
28
|
+
EventMachine.kqueue = true
|
29
|
+
puts "using Kqueue."
|
30
|
+
end
|
31
|
+
if EventMachine.epoll?
|
32
|
+
EventMachine.epoll = true
|
33
|
+
puts "using epoll."
|
34
|
+
end
|
35
|
+
|
36
|
+
# Note that this will block current thread.
|
37
|
+
EventMachine.run {
|
38
|
+
EventMachine.start_server "127.0.0.1", 3030, HttpProtocol
|
39
|
+
}
|
40
|
+
|
41
|
+
#
|
42
|
+
# require 'iodine'
|
43
|
+
#
|
44
|
+
# class HttpProtocol
|
45
|
+
# @timeout = 5
|
46
|
+
# # `on_message` is an optional alternative to the `on_data` callback.
|
47
|
+
# # `on_message` has a 1Kb buffer that recycles itself for memory optimization.
|
48
|
+
# def on_data
|
49
|
+
# # writing will never block and will use a buffer written in C when needed.
|
50
|
+
# data = nil
|
51
|
+
# while (data = read)
|
52
|
+
# write "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nKeep-Alive: timeout=1\r\nContent-Length: 12\r\n\r\nHello World!"
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# puts "thread #{Iodine.threads}"
|
58
|
+
# # Listen
|
59
|
+
# Iodine.listen '3000', HttpProtocol
|
60
|
+
# Iodine.threads = 7
|
61
|
+
# Iodine.processes = 1
|
62
|
+
# puts "now, thread #{Iodine.threads}"
|
63
|
+
# Iodine.start
|
data/ext/iodine/bscrypt-common.h
CHANGED
@@ -57,8 +57,8 @@ and: https://software.intel.com/sites/landingpage/IntrinsicsGuide/
|
|
57
57
|
# endif
|
58
58
|
#endif
|
59
59
|
|
60
|
-
#ifndef
|
61
|
-
# define
|
60
|
+
#ifndef UNUSED_FUNC
|
61
|
+
# define UNUSED_FUNC __attribute__((unused))
|
62
62
|
#endif
|
63
63
|
// clang-format on
|
64
64
|
|
data/ext/iodine/http1.c
CHANGED
@@ -47,7 +47,7 @@ struct {
|
|
47
47
|
void *memory;
|
48
48
|
http1_protocol_s *pool;
|
49
49
|
spn_lock_i lock;
|
50
|
-
} http1_pool = {
|
50
|
+
} http1_pool = {.memory = NULL};
|
51
51
|
|
52
52
|
inline static http1_protocol_s *pool_pop() {
|
53
53
|
http1_protocol_s *prot;
|
@@ -184,7 +184,7 @@ is_busy:
|
|
184
184
|
p_len = 94 + http_ul2a(packet->buffer + 94, file_data.st_size);
|
185
185
|
memcpy(packet->buffer + p_len, "\r\n\r\n", 4);
|
186
186
|
p_len += 4;
|
187
|
-
if (BUFFER_PACKET_SIZE - p_len > file_data.st_size) {
|
187
|
+
if ((off_t)(BUFFER_PACKET_SIZE - p_len) > file_data.st_size) {
|
188
188
|
if (read(file, packet->buffer + p_len, file_data.st_size) < 0) {
|
189
189
|
close(file);
|
190
190
|
sock_free_packet(packet);
|
@@ -297,7 +297,8 @@ ssize_t http1_parse_request_headers(void *buffer, size_t len,
|
|
297
297
|
}
|
298
298
|
// check if the body is contained within the buffer
|
299
299
|
EAT_EOL();
|
300
|
-
if (request->content_length &&
|
300
|
+
if (request->content_length &&
|
301
|
+
(end - pos) >= (ssize_t)request->content_length) {
|
301
302
|
request->body_str = (void *)pos;
|
302
303
|
// fprintf(stderr,
|
303
304
|
// "assigning body to string. content-length %lu, buffer left: "
|
data/ext/iodine/http_request.h
CHANGED
@@ -18,8 +18,8 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
18
18
|
#include <strings.h>
|
19
19
|
#include <unistd.h>
|
20
20
|
|
21
|
-
#ifndef
|
22
|
-
#define
|
21
|
+
#ifndef UNUSED_FUNC
|
22
|
+
#define UNUSED_FUNC __attribute__((unused))
|
23
23
|
#endif
|
24
24
|
|
25
25
|
typedef struct {
|
@@ -97,7 +97,7 @@ typedef struct {
|
|
97
97
|
http_headers_s headers[];
|
98
98
|
} http_request_s;
|
99
99
|
|
100
|
-
|
100
|
+
UNUSED_FUNC static inline void http_request_clear(http_request_s *request) {
|
101
101
|
if (request->body_file > 0) /* assumes no tempfile with fd 0 */
|
102
102
|
close(request->body_file);
|
103
103
|
*request = (http_request_s){
|
@@ -109,7 +109,7 @@ __unused static inline void http_request_clear(http_request_s *request) {
|
|
109
109
|
|
110
110
|
/** searches for a header in the header array, both reaturnning it's value and
|
111
111
|
* setting it's position in the `request->metadata.header_pos` variable.*/
|
112
|
-
|
112
|
+
UNUSED_FUNC static inline const char *
|
113
113
|
http_request_find_header(http_request_s *request, const char *header,
|
114
114
|
size_t header_len) {
|
115
115
|
if (header == NULL || request == NULL)
|
data/ext/iodine/http_response.c
CHANGED
@@ -24,6 +24,7 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
24
24
|
#include <sys/stat.h>
|
25
25
|
#include <sys/types.h>
|
26
26
|
#include <time.h>
|
27
|
+
#include <unistd.h>
|
27
28
|
|
28
29
|
/* *****************************************************************************
|
29
30
|
Helpers
|
@@ -340,7 +341,7 @@ int http_response_sendfile2(http_response_s *response, http_request_s *request,
|
|
340
341
|
ext++;
|
341
342
|
}
|
342
343
|
// fprintf(stderr, "Start: %lu / %lld\n", start, file_data.st_size);
|
343
|
-
if (start >= file_data.st_size - 1)
|
344
|
+
if ((off_t)start >= file_data.st_size - 1)
|
344
345
|
goto invalid_range;
|
345
346
|
ext++;
|
346
347
|
while (is_num(*ext)) {
|
@@ -349,7 +350,7 @@ int http_response_sendfile2(http_response_s *response, http_request_s *request,
|
|
349
350
|
ext++;
|
350
351
|
}
|
351
352
|
// going to the EOF (big chunk or EOL requested) - send as file
|
352
|
-
if (finish >= file_data.st_size)
|
353
|
+
if ((off_t)finish >= file_data.st_size)
|
353
354
|
finish = file_data.st_size;
|
354
355
|
char *pos = buffer + 6;
|
355
356
|
memcpy(buffer, "bytes ", 6);
|
@@ -405,7 +406,7 @@ no_file:
|
|
405
406
|
}
|
406
407
|
|
407
408
|
#ifdef RUSAGE_SELF
|
408
|
-
const
|
409
|
+
static const size_t CLOCK_RESOLUTION = 1000; /* in miliseconds */
|
409
410
|
static size_t get_clock_mili(void) {
|
410
411
|
struct rusage rusage;
|
411
412
|
getrusage(RUSAGE_SELF, &rusage);
|
@@ -12,8 +12,8 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
12
12
|
#include "http_response.h"
|
13
13
|
// clang-format on
|
14
14
|
|
15
|
-
#ifndef
|
16
|
-
#define
|
15
|
+
#ifndef UNUSED_FUNC
|
16
|
+
#define UNUSED_FUNC __attribute__((unused))
|
17
17
|
#endif
|
18
18
|
|
19
19
|
/* *****************************************************************************
|
@@ -63,7 +63,7 @@ static inline int h1p_protected_copy(http_response_s *response,
|
|
63
63
|
|
64
64
|
/* this function assume the padding in `h1p_protected_copy` saved enough room
|
65
65
|
* for the data to be safely written.*/
|
66
|
-
|
66
|
+
UNUSED_FUNC static inline sock_packet_s *
|
67
67
|
h1p_finalize_headers(http_response_s *response) {
|
68
68
|
if (HEADERS_FINISHED(response))
|
69
69
|
return NULL;
|
@@ -157,7 +157,7 @@ static int h1p_send_headers(http_response_s *response, sock_packet_s *packet) {
|
|
157
157
|
Implementation
|
158
158
|
***************************************************************************** */
|
159
159
|
|
160
|
-
|
160
|
+
UNUSED_FUNC static inline int h1p_response_write_header(http_response_s *response,
|
161
161
|
http_headers_s header) {
|
162
162
|
if (HEADERS_FINISHED(response) || header.name == NULL)
|
163
163
|
return -1;
|
@@ -179,7 +179,7 @@ __unused static inline int h1p_response_write_header(http_response_s *response,
|
|
179
179
|
/**
|
180
180
|
Set / Delete a cookie using this helper function.
|
181
181
|
*/
|
182
|
-
|
182
|
+
UNUSED_FUNC static int h1p_response_set_cookie(http_response_s *response,
|
183
183
|
http_cookie_s cookie) {
|
184
184
|
if (HEADERS_FINISHED(response) || cookie.name == NULL ||
|
185
185
|
overflowing(response))
|
@@ -287,7 +287,7 @@ __unused static int h1p_response_set_cookie(http_response_s *response,
|
|
287
287
|
/**
|
288
288
|
Sends the headers (if unsent) and sends the body.
|
289
289
|
*/
|
290
|
-
|
290
|
+
UNUSED_FUNC static inline int h1p_response_write_body(http_response_s *response,
|
291
291
|
const char *body,
|
292
292
|
size_t length) {
|
293
293
|
if (!response->content_length)
|
@@ -298,7 +298,7 @@ __unused static inline int h1p_response_write_body(http_response_s *response,
|
|
298
298
|
((BUFFER_PACKET_SIZE - H1P_HEADER_START) - headers->length);
|
299
299
|
if (i_read > 1024) {
|
300
300
|
/* we can fit at least some of the data inside the response buffer. */
|
301
|
-
if (i_read > length) {
|
301
|
+
if ((size_t)i_read > length) {
|
302
302
|
i_read = length;
|
303
303
|
/* we can fit the data inside the response buffer. */
|
304
304
|
memcpy(response->metadata.headers_pos, body, i_read);
|
@@ -322,7 +322,7 @@ __unused static inline int h1p_response_write_body(http_response_s *response,
|
|
322
322
|
/**
|
323
323
|
Sends the headers (if unsent) and schedules the file to be sent.
|
324
324
|
*/
|
325
|
-
|
325
|
+
UNUSED_FUNC static inline int h1p_response_sendfile(http_response_s *response,
|
326
326
|
int source_fd, off_t offset,
|
327
327
|
size_t length) {
|
328
328
|
if (!response->content_length)
|
@@ -337,7 +337,7 @@ __unused static inline int h1p_response_sendfile(http_response_s *response,
|
|
337
337
|
source_fd, response->metadata.headers_pos,
|
338
338
|
((BUFFER_PACKET_SIZE - H1P_HEADER_START) - headers->length), offset);
|
339
339
|
if (i_read > 0) {
|
340
|
-
if (i_read >= length) {
|
340
|
+
if ((size_t)i_read >= length) {
|
341
341
|
headers->length += length;
|
342
342
|
close(source_fd);
|
343
343
|
return h1p_send_headers(response, headers);
|
@@ -358,7 +358,7 @@ __unused static inline int h1p_response_sendfile(http_response_s *response,
|
|
358
358
|
return sock_sendfile(response->metadata.fd, source_fd, offset, length);
|
359
359
|
}
|
360
360
|
|
361
|
-
|
361
|
+
UNUSED_FUNC static inline int h1p_response_finish(http_response_s *response) {
|
362
362
|
sock_packet_s *headers = h1p_finalize_headers(response);
|
363
363
|
if (headers) {
|
364
364
|
return h1p_send_headers(response, headers);
|
data/ext/iodine/iodine_core.c
CHANGED
@@ -96,7 +96,7 @@ static VALUE dyn_read(int argc, VALUE *argv, VALUE self) {
|
|
96
96
|
len = rb_str_capacity(buffer);
|
97
97
|
// make sure the string is modifiable
|
98
98
|
rb_str_modify(buffer);
|
99
|
-
// resize
|
99
|
+
// resize the string if needed.
|
100
100
|
if (len < 1024)
|
101
101
|
rb_str_resize(buffer, (len = 1024));
|
102
102
|
str = buffer;
|
@@ -139,6 +139,30 @@ static VALUE dyn_write_urgent(VALUE self, VALUE data) {
|
|
139
139
|
return self;
|
140
140
|
}
|
141
141
|
|
142
|
+
/**
|
143
|
+
Update's a connection's timeout.
|
144
|
+
|
145
|
+
Returns self.
|
146
|
+
*/
|
147
|
+
static VALUE dyn_set_timeout(VALUE self, VALUE timeout) {
|
148
|
+
intptr_t fd = iodine_get_fd(self);
|
149
|
+
unsigned int tout = FIX2UINT(timeout);
|
150
|
+
if (tout > 255)
|
151
|
+
tout = 255;
|
152
|
+
server_set_timeout(fd, tout);
|
153
|
+
return self;
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
Returns the connection's timeout.
|
158
|
+
*/
|
159
|
+
static VALUE dyn_get_timeout(VALUE self) {
|
160
|
+
intptr_t fd = iodine_get_fd(self);
|
161
|
+
uint8_t tout = server_get_timeout(fd);
|
162
|
+
unsigned int tout_int = tout;
|
163
|
+
return UINT2NUM(tout_int);
|
164
|
+
}
|
165
|
+
|
142
166
|
/**
|
143
167
|
Closes a connection.
|
144
168
|
|
@@ -157,10 +181,13 @@ The Core dynamic Iodine protocol task implementation
|
|
157
181
|
*/
|
158
182
|
|
159
183
|
static void dyn_perform_defer(intptr_t uuid, protocol_s *protocol, void *arg) {
|
184
|
+
(void)(uuid);
|
185
|
+
(void)(protocol);
|
160
186
|
RubyCaller.call((VALUE)arg, call_proc_id);
|
161
187
|
Registry.remove((VALUE)arg);
|
162
188
|
}
|
163
189
|
static void dyn_defer_fallback(intptr_t uuid, void *arg) {
|
190
|
+
(void)(uuid);
|
164
191
|
Registry.remove((VALUE)arg);
|
165
192
|
};
|
166
193
|
|
@@ -190,11 +217,14 @@ static VALUE dyn_defer(VALUE self) {
|
|
190
217
|
|
191
218
|
static void dyn_perform_each_task(intptr_t fd, protocol_s *protocol,
|
192
219
|
void *data) {
|
220
|
+
(void)(fd);
|
193
221
|
RubyCaller.call2((VALUE)data, call_proc_id, 1,
|
194
222
|
&(dyn_prot(protocol)->handler));
|
195
223
|
}
|
196
224
|
static void dyn_finish_each_task(intptr_t fd, protocol_s *protocol,
|
197
225
|
void *data) {
|
226
|
+
(void)(protocol);
|
227
|
+
(void)(fd);
|
198
228
|
Registry.remove((VALUE)data);
|
199
229
|
}
|
200
230
|
|
@@ -268,9 +298,16 @@ static VALUE not_implemented_ping(VALUE self) {
|
|
268
298
|
return Qnil;
|
269
299
|
}
|
270
300
|
/** implement this callback to handle the event. */
|
271
|
-
static VALUE not_implemented(VALUE self) {
|
301
|
+
static VALUE not_implemented(VALUE self) {
|
302
|
+
(void)(self);
|
303
|
+
return Qnil;
|
304
|
+
}
|
272
305
|
/** implement this callback to handle the event. */
|
273
|
-
static VALUE not_implemented2(VALUE self, VALUE data) {
|
306
|
+
static VALUE not_implemented2(VALUE self, VALUE data) {
|
307
|
+
(void)(self);
|
308
|
+
(void)(data);
|
309
|
+
return Qnil;
|
310
|
+
}
|
274
311
|
|
275
312
|
/**
|
276
313
|
A default on_data implementation will read up to 1Kb into a reusable buffer from
|
@@ -295,15 +332,18 @@ static VALUE default_on_data(VALUE self) {
|
|
295
332
|
|
296
333
|
/** called when a data is available, but will not run concurrently */
|
297
334
|
static void dyn_protocol_on_data(intptr_t fduuid, protocol_s *protocol) {
|
335
|
+
(void)(fduuid);
|
298
336
|
RubyCaller.call(dyn_prot(protocol)->handler, on_data_func_id);
|
299
337
|
}
|
300
338
|
/** called when the socket is ready to be written to. */
|
301
339
|
static void dyn_protocol_on_ready(intptr_t fduuid, protocol_s *protocol) {
|
340
|
+
(void)(fduuid);
|
302
341
|
RubyCaller.call(dyn_prot(protocol)->handler, on_ready_func_id);
|
303
342
|
}
|
304
343
|
/** called when the server is shutting down,
|
305
344
|
* but before closing the connection. */
|
306
345
|
static void dyn_protocol_on_shutdown(intptr_t fduuid, protocol_s *protocol) {
|
346
|
+
(void)(fduuid);
|
307
347
|
RubyCaller.call(dyn_prot(protocol)->handler, on_shutdown_func_id);
|
308
348
|
}
|
309
349
|
/** called when the connection was closed, but will not run concurrently */
|
@@ -314,9 +354,10 @@ static void dyn_protocol_on_close(protocol_s *protocol) {
|
|
314
354
|
}
|
315
355
|
/** called when a connection's timeout was reached */
|
316
356
|
static void dyn_protocol_ping(intptr_t fduuid, protocol_s *protocol) {
|
357
|
+
(void)(fduuid);
|
317
358
|
RubyCaller.call(dyn_prot(protocol)->handler, ping_func_id);
|
318
359
|
}
|
319
|
-
|
360
|
+
/** Update's a connection's handler and timeout. */
|
320
361
|
static inline protocol_s *dyn_set_protocol(intptr_t fduuid, VALUE handler,
|
321
362
|
uint8_t timeout) {
|
322
363
|
Registry.add(handler);
|
@@ -339,6 +380,7 @@ static inline protocol_s *dyn_set_protocol(intptr_t fduuid, VALUE handler,
|
|
339
380
|
RubyCaller.call(handler, on_open_func_id);
|
340
381
|
return (protocol_s *)protocol;
|
341
382
|
}
|
383
|
+
|
342
384
|
static protocol_s *on_open_dyn_protocol(intptr_t fduuid, void *udata) {
|
343
385
|
VALUE rb_tout = rb_ivar_get((VALUE)udata, timeout_var_id);
|
344
386
|
uint8_t timeout = (TYPE(rb_tout) == T_FIXNUM) ? FIX2UINT(rb_tout) : 0;
|
@@ -385,6 +427,8 @@ void Init_DynamicProtocol(void) {
|
|
385
427
|
rb_define_method(DynamicProtocol, "defer", dyn_defer, 0);
|
386
428
|
rb_define_method(DynamicProtocol, "each", dyn_each, 0);
|
387
429
|
rb_define_method(DynamicProtocol, "upgrade", dyn_upgrade, 1);
|
430
|
+
rb_define_method(DynamicProtocol, "timeout=", dyn_set_timeout, 1);
|
431
|
+
rb_define_method(DynamicProtocol, "timeout", dyn_get_timeout, 0);
|
388
432
|
}
|
389
433
|
|
390
434
|
/* *****************************************************************************
|
@@ -474,6 +518,7 @@ will be delayed until Iodine.start is called, unless Iodine's event loop is
|
|
474
518
|
active).
|
475
519
|
*/
|
476
520
|
static VALUE iodine_run_async(VALUE self) {
|
521
|
+
(void)(self);
|
477
522
|
// requires a block to be passed
|
478
523
|
rb_need_block();
|
479
524
|
VALUE block = rb_block_proc();
|
@@ -494,6 +539,7 @@ Time is counted only once Iodine started running (using {Iodine.start}).
|
|
494
539
|
Always returns a copy of the block object.
|
495
540
|
*/
|
496
541
|
static VALUE iodine_run_after(VALUE self, VALUE milliseconds) {
|
542
|
+
(void)(self);
|
497
543
|
if (TYPE(milliseconds) != T_FIXNUM) {
|
498
544
|
rb_raise(rb_eTypeError, "milliseconds must be a number");
|
499
545
|
return Qnil;
|
@@ -526,6 +572,7 @@ The event will repeat itself until the number of repetitions had been delpeted.
|
|
526
572
|
Always returns a copy of the block object.
|
527
573
|
*/
|
528
574
|
static VALUE iodine_run_every(int argc, VALUE *argv, VALUE self) {
|
575
|
+
(void)(self);
|
529
576
|
VALUE milliseconds, repetitions, block;
|
530
577
|
|
531
578
|
rb_scan_args(argc, argv, "11&", &milliseconds, &repetitions, &block);
|
@@ -549,12 +596,16 @@ static VALUE iodine_run_every(int argc, VALUE *argv, VALUE self) {
|
|
549
596
|
return block;
|
550
597
|
}
|
551
598
|
|
552
|
-
static VALUE iodine_count(VALUE self) {
|
599
|
+
static VALUE iodine_count(VALUE self) {
|
600
|
+
(void)(self);
|
601
|
+
return ULONG2NUM(server_count(NULL));
|
602
|
+
}
|
553
603
|
/* *****************************************************************************
|
554
604
|
Running the server
|
555
605
|
*/
|
556
606
|
|
557
607
|
static void *srv_start_no_gvl(void *_) {
|
608
|
+
(void)(_);
|
558
609
|
// collect requested settings
|
559
610
|
VALUE rb_th_i = rb_iv_get(Iodine, "@threads");
|
560
611
|
VALUE rb_pr_i = rb_iv_get(Iodine, "@processes");
|
@@ -591,7 +642,10 @@ static void *srv_start_no_gvl(void *_) {
|
|
591
642
|
return NULL;
|
592
643
|
}
|
593
644
|
|
594
|
-
static void unblck(void *_) {
|
645
|
+
static void unblck(void *_) {
|
646
|
+
(void)(_);
|
647
|
+
server_stop();
|
648
|
+
}
|
595
649
|
/**
|
596
650
|
Starts the Iodine event loop. This will hang the thread until an interrupt
|
597
651
|
(`^C`) signal is received.
|