uringmachine 0.4 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +2 -1
- data/CHANGELOG.md +16 -0
- data/README.md +44 -1
- data/TODO.md +12 -3
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_sqlite.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/http_server.rb +42 -43
- data/examples/pg.rb +85 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/stream.rb +85 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +81 -14
- data/ext/um/um.c +468 -414
- data/ext/um/um.h +149 -40
- data/ext/um/um_async_op.c +40 -0
- data/ext/um/um_async_op_class.c +136 -0
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +176 -44
- data/ext/um/um_const.c +174 -9
- data/ext/um/um_ext.c +8 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +89 -111
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_ssl.c +850 -0
- data/ext/um/um_ssl.h +22 -0
- data/ext/um/um_ssl_class.c +138 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +1 -1
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/ssl/context_builder.rb +96 -0
- data/lib/uringmachine/ssl.rb +394 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +27 -3
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +6 -0
- data/test/test_async_op.rb +119 -0
- data/test/test_ssl.rb +155 -0
- data/test/test_um.rb +464 -47
- data/uringmachine.gemspec +3 -2
- data/vendor/liburing/.gitignore +5 -0
- data/vendor/liburing/CHANGELOG +1 -0
- data/vendor/liburing/configure +32 -0
- data/vendor/liburing/examples/Makefile +1 -0
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/include/liburing/io_uring.h +48 -2
- data/vendor/liburing/src/include/liburing.h +28 -2
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +13 -2
- data/vendor/liburing/src/liburing.map +9 -0
- data/vendor/liburing/src/queue.c +25 -16
- data/vendor/liburing/src/register.c +73 -4
- data/vendor/liburing/src/setup.c +46 -18
- data/vendor/liburing/src/setup.h +6 -0
- data/vendor/liburing/test/Makefile +7 -0
- data/vendor/liburing/test/cmd-discard.c +427 -0
- data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- data/vendor/liburing/test/io_uring_passthrough.c +2 -0
- data/vendor/liburing/test/io_uring_register.c +13 -2
- data/vendor/liburing/test/napi-test.c +1 -1
- data/vendor/liburing/test/no-mmap-inval.c +1 -1
- data/vendor/liburing/test/read-mshot-empty.c +2 -0
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +6 -0
- data/vendor/liburing/test/recvsend_bundle.c +2 -2
- data/vendor/liburing/test/reg-fd-only.c +1 -1
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +458 -0
- data/vendor/liburing/test/resize-rings.c +643 -0
- data/vendor/liburing/test/rsrc_tags.c +1 -1
- data/vendor/liburing/test/sqpoll-sleep.c +39 -8
- data/vendor/liburing/test/sqwait.c +136 -0
- data/vendor/liburing/test/sync-cancel.c +8 -1
- data/vendor/liburing/test/timeout.c +13 -8
- metadata +52 -8
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
@@ -0,0 +1,136 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: test that the app can always get a new sqe after having
|
4
|
+
* called io_uring_sqring_wait().
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <unistd.h>
|
10
|
+
|
11
|
+
#include "liburing.h"
|
12
|
+
#include "helpers.h"
|
13
|
+
|
14
|
+
#define NR_IOS 10000
|
15
|
+
#define INFLIGHT 256
|
16
|
+
#define FILE_SIZE (256 * 1024 * 1024)
|
17
|
+
|
18
|
+
static int inflight;
|
19
|
+
|
20
|
+
static int reap(struct io_uring *ring)
|
21
|
+
{
|
22
|
+
struct io_uring_cqe *cqe;
|
23
|
+
int ret;
|
24
|
+
|
25
|
+
while (inflight >= INFLIGHT / 2) {
|
26
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
27
|
+
if (ret < 0) {
|
28
|
+
fprintf(stderr, "wait=%d\n", ret);
|
29
|
+
return 1;
|
30
|
+
}
|
31
|
+
if (cqe->res < 0) {
|
32
|
+
printf("cqe res %d\n", cqe->res);
|
33
|
+
return 1;
|
34
|
+
}
|
35
|
+
io_uring_cqe_seen(ring, cqe);
|
36
|
+
inflight--;
|
37
|
+
}
|
38
|
+
|
39
|
+
return 0;
|
40
|
+
}
|
41
|
+
|
42
|
+
int main(int argc, char *argv[])
|
43
|
+
{
|
44
|
+
struct io_uring_sqe *sqe;
|
45
|
+
struct io_uring ring;
|
46
|
+
int fd = -1, i, iov_off, ret, fret;
|
47
|
+
struct iovec iovs[INFLIGHT];
|
48
|
+
const char *fname;
|
49
|
+
char buf[256];
|
50
|
+
loff_t off;
|
51
|
+
|
52
|
+
if (argc > 1) {
|
53
|
+
fname = argv[1];
|
54
|
+
} else {
|
55
|
+
srand((unsigned)time(NULL));
|
56
|
+
snprintf(buf, sizeof(buf), ".sqwait-%u-%u", (unsigned)rand(),
|
57
|
+
(unsigned)getpid());
|
58
|
+
fname = buf;
|
59
|
+
t_create_file(fname, FILE_SIZE);
|
60
|
+
}
|
61
|
+
|
62
|
+
fret = T_EXIT_SKIP;
|
63
|
+
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SQPOLL);
|
64
|
+
if (ret < 0) {
|
65
|
+
if (errno == EINVAL || errno == EPERM)
|
66
|
+
goto err;
|
67
|
+
fprintf(stderr, "queue init %d\n", ret);
|
68
|
+
fret = T_EXIT_FAIL;
|
69
|
+
goto err;
|
70
|
+
}
|
71
|
+
|
72
|
+
fd = open(fname, O_RDONLY | O_DIRECT);
|
73
|
+
if (fd < 0) {
|
74
|
+
if (errno == EACCES || errno == EPERM || errno == EINVAL)
|
75
|
+
return T_EXIT_SKIP;
|
76
|
+
perror("open");
|
77
|
+
fret = T_EXIT_FAIL;
|
78
|
+
goto err;
|
79
|
+
}
|
80
|
+
|
81
|
+
for (i = 0; i < INFLIGHT; i++) {
|
82
|
+
if (posix_memalign(&iovs[i].iov_base, 4096, 4096))
|
83
|
+
goto err;
|
84
|
+
iovs[i].iov_len = 4096;
|
85
|
+
}
|
86
|
+
|
87
|
+
iov_off = off = 0;
|
88
|
+
for (i = 0; i < NR_IOS; i++) {
|
89
|
+
struct iovec *iov = &iovs[iov_off];
|
90
|
+
|
91
|
+
sqe = io_uring_get_sqe(&ring);
|
92
|
+
if (!sqe) {
|
93
|
+
ret = io_uring_sqring_wait(&ring);
|
94
|
+
if (ret < 0) {
|
95
|
+
if (ret == -EINVAL)
|
96
|
+
return T_EXIT_SKIP;
|
97
|
+
fprintf(stderr, "sqwait=%d\n", ret);
|
98
|
+
fret = T_EXIT_FAIL;
|
99
|
+
goto err;
|
100
|
+
}
|
101
|
+
sqe = io_uring_get_sqe(&ring);
|
102
|
+
if (!sqe) {
|
103
|
+
fprintf(stderr, "No sqe post wait\n");
|
104
|
+
fret = T_EXIT_FAIL;
|
105
|
+
goto err;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
io_uring_prep_read(sqe, fd, iov->iov_base, iov->iov_len, 0);
|
109
|
+
io_uring_submit(&ring);
|
110
|
+
inflight++;
|
111
|
+
|
112
|
+
iov_off++;
|
113
|
+
if (iov_off == INFLIGHT)
|
114
|
+
iov_off = 0;
|
115
|
+
off += 8192;
|
116
|
+
if (off > FILE_SIZE - 8192)
|
117
|
+
off = 0;
|
118
|
+
if (reap(&ring)) {
|
119
|
+
fret = T_EXIT_FAIL;
|
120
|
+
goto err;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
if (fd != -1)
|
125
|
+
close(fd);
|
126
|
+
if (fname != argv[1])
|
127
|
+
unlink(fname);
|
128
|
+
io_uring_queue_exit(&ring);
|
129
|
+
return T_EXIT_PASS;
|
130
|
+
err:
|
131
|
+
if (fd != -1)
|
132
|
+
close(fd);
|
133
|
+
if (fname != argv[1])
|
134
|
+
unlink(fname);
|
135
|
+
return fret;
|
136
|
+
}
|
@@ -13,7 +13,7 @@
|
|
13
13
|
#include "liburing.h"
|
14
14
|
#include "helpers.h"
|
15
15
|
|
16
|
-
static int no_sync_cancel;
|
16
|
+
static int no_sync_cancel, no_sync_cancel_op;
|
17
17
|
|
18
18
|
static int test_sync_cancel_timeout(struct io_uring *ring, int async, int by_op)
|
19
19
|
{
|
@@ -47,6 +47,11 @@ static int test_sync_cancel_timeout(struct io_uring *ring, int async, int by_op)
|
|
47
47
|
reg.opcode = IORING_OP_READ;
|
48
48
|
reg.timeout.tv_nsec = 1;
|
49
49
|
ret = io_uring_register_sync_cancel(ring, ®);
|
50
|
+
/* earlier kernels had sync cancel, but not per-op */
|
51
|
+
if (ret == -EINVAL) {
|
52
|
+
no_sync_cancel_op = 1;
|
53
|
+
return 0;
|
54
|
+
}
|
50
55
|
if (async) {
|
51
56
|
/* we expect -ETIME here, but can race and get 0 */
|
52
57
|
if (ret != -ETIME && ret != 0) {
|
@@ -244,6 +249,8 @@ int main(int argc, char *argv[])
|
|
244
249
|
fprintf(stderr, "test_sync_cancel_timeout 0 0\n");
|
245
250
|
return T_EXIT_FAIL;
|
246
251
|
}
|
252
|
+
if (no_sync_cancel_op)
|
253
|
+
return T_EXIT_PASS;
|
247
254
|
|
248
255
|
ret = test_sync_cancel_timeout(&ring, 0, 1);
|
249
256
|
if (ret) {
|
@@ -1228,14 +1228,19 @@ static int test_timeout_link_cancel(void)
|
|
1228
1228
|
exit(0);
|
1229
1229
|
}
|
1230
1230
|
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1231
|
+
do {
|
1232
|
+
if (waitpid(p, &wstatus, 0) == (pid_t)-1) {
|
1233
|
+
perror("waitpid()");
|
1234
|
+
return 1;
|
1235
|
+
}
|
1236
|
+
if (!WIFEXITED(wstatus))
|
1237
|
+
continue;
|
1238
|
+
if (WEXITSTATUS(wstatus)) {
|
1239
|
+
fprintf(stderr, "child failed %i\n", WEXITSTATUS(wstatus));
|
1240
|
+
return 1;
|
1241
|
+
}
|
1242
|
+
break;
|
1243
|
+
} while (1);
|
1239
1244
|
|
1240
1245
|
for (i = 0; i < 2; ++i) {
|
1241
1246
|
ret = io_uring_wait_cqe(&ring, &cqe);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uringmachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.2.
|
19
|
+
version: 1.2.8
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.2.
|
26
|
+
version: 1.2.8
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.
|
61
|
+
version: 2.14.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
68
|
+
version: 2.14.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: localhost
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.1
|
69
83
|
description:
|
70
84
|
email: sharon@noteflakes.com
|
71
85
|
executables: []
|
@@ -84,23 +98,45 @@ files:
|
|
84
98
|
- README.md
|
85
99
|
- Rakefile
|
86
100
|
- TODO.md
|
101
|
+
- examples/bm_snooze.rb
|
102
|
+
- examples/bm_sqlite.rb
|
103
|
+
- examples/bm_write.rb
|
104
|
+
- examples/dns_client.rb
|
87
105
|
- examples/echo_server.rb
|
88
106
|
- examples/http_server.rb
|
89
|
-
- examples/http_server_multishot.rb
|
90
|
-
- examples/http_server_simpler.rb
|
91
107
|
- examples/inout.rb
|
92
108
|
- examples/nc.rb
|
109
|
+
- examples/pg.rb
|
110
|
+
- examples/server_client.rb
|
111
|
+
- examples/snooze.rb
|
112
|
+
- examples/stream.rb
|
113
|
+
- examples/write_dev_null.rb
|
93
114
|
- ext/um/extconf.rb
|
94
115
|
- ext/um/um.c
|
95
116
|
- ext/um/um.h
|
117
|
+
- ext/um/um_async_op.c
|
118
|
+
- ext/um/um_async_op_class.c
|
119
|
+
- ext/um/um_buffer.c
|
96
120
|
- ext/um/um_class.c
|
97
121
|
- ext/um/um_const.c
|
98
122
|
- ext/um/um_ext.c
|
123
|
+
- ext/um/um_mutex_class.c
|
99
124
|
- ext/um/um_op.c
|
125
|
+
- ext/um/um_queue_class.c
|
126
|
+
- ext/um/um_ssl.c
|
127
|
+
- ext/um/um_ssl.h
|
128
|
+
- ext/um/um_ssl_class.c
|
129
|
+
- ext/um/um_sync.c
|
100
130
|
- ext/um/um_utils.c
|
101
131
|
- lib/uringmachine.rb
|
132
|
+
- lib/uringmachine/dns_resolver.rb
|
133
|
+
- lib/uringmachine/ssl.rb
|
134
|
+
- lib/uringmachine/ssl/context_builder.rb
|
102
135
|
- lib/uringmachine/version.rb
|
136
|
+
- supressions/ruby.supp
|
103
137
|
- test/helper.rb
|
138
|
+
- test/test_async_op.rb
|
139
|
+
- test/test_ssl.rb
|
104
140
|
- test/test_um.rb
|
105
141
|
- uringmachine.gemspec
|
106
142
|
- vendor/liburing/.github/actions/codespell/stopwords
|
@@ -149,6 +185,7 @@ files:
|
|
149
185
|
- vendor/liburing/examples/poll-bench.c
|
150
186
|
- vendor/liburing/examples/proxy.c
|
151
187
|
- vendor/liburing/examples/proxy.h
|
188
|
+
- vendor/liburing/examples/reg-wait.c
|
152
189
|
- vendor/liburing/examples/rsrc-update-bench.c
|
153
190
|
- vendor/liburing/examples/send-zerocopy.c
|
154
191
|
- vendor/liburing/examples/ucontext-cp.c
|
@@ -207,6 +244,7 @@ files:
|
|
207
244
|
- vendor/liburing/test/buf-ring.c
|
208
245
|
- vendor/liburing/test/ce593a6c480a.c
|
209
246
|
- vendor/liburing/test/close-opath.c
|
247
|
+
- vendor/liburing/test/cmd-discard.c
|
210
248
|
- vendor/liburing/test/config
|
211
249
|
- vendor/liburing/test/connect-rep.c
|
212
250
|
- vendor/liburing/test/connect.c
|
@@ -239,6 +277,8 @@ files:
|
|
239
277
|
- vendor/liburing/test/fd-install.c
|
240
278
|
- vendor/liburing/test/fd-pass.c
|
241
279
|
- vendor/liburing/test/fdinfo.c
|
280
|
+
- vendor/liburing/test/fifo-nonblock-read.c
|
281
|
+
- vendor/liburing/test/file-exit-unreg.c
|
242
282
|
- vendor/liburing/test/file-register.c
|
243
283
|
- vendor/liburing/test/file-update.c
|
244
284
|
- vendor/liburing/test/file-verify.c
|
@@ -314,6 +354,7 @@ files:
|
|
314
354
|
- vendor/liburing/test/probe.c
|
315
355
|
- vendor/liburing/test/read-before-exit.c
|
316
356
|
- vendor/liburing/test/read-mshot-empty.c
|
357
|
+
- vendor/liburing/test/read-mshot-stdin.c
|
317
358
|
- vendor/liburing/test/read-mshot.c
|
318
359
|
- vendor/liburing/test/read-write.c
|
319
360
|
- vendor/liburing/test/recv-msgall-stream.c
|
@@ -324,10 +365,12 @@ files:
|
|
324
365
|
- vendor/liburing/test/reg-fd-only.c
|
325
366
|
- vendor/liburing/test/reg-hint.c
|
326
367
|
- vendor/liburing/test/reg-reg-ring.c
|
368
|
+
- vendor/liburing/test/reg-wait.c
|
327
369
|
- vendor/liburing/test/regbuf-clone.c
|
328
370
|
- vendor/liburing/test/regbuf-merge.c
|
329
371
|
- vendor/liburing/test/register-restrictions.c
|
330
372
|
- vendor/liburing/test/rename.c
|
373
|
+
- vendor/liburing/test/resize-rings.c
|
331
374
|
- vendor/liburing/test/ring-leak.c
|
332
375
|
- vendor/liburing/test/ring-leak2.c
|
333
376
|
- vendor/liburing/test/ringbuf-read.c
|
@@ -364,6 +407,7 @@ files:
|
|
364
407
|
- vendor/liburing/test/sqpoll-exec.c
|
365
408
|
- vendor/liburing/test/sqpoll-exit-hang.c
|
366
409
|
- vendor/liburing/test/sqpoll-sleep.c
|
410
|
+
- vendor/liburing/test/sqwait.c
|
367
411
|
- vendor/liburing/test/statx.c
|
368
412
|
- vendor/liburing/test/stdout.c
|
369
413
|
- vendor/liburing/test/submit-and-wait.c
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require_relative '../lib/iou'
|
2
|
-
require 'socket'
|
3
|
-
require 'http/parser'
|
4
|
-
|
5
|
-
def log(msg)
|
6
|
-
# return
|
7
|
-
STDERR.puts msg
|
8
|
-
end
|
9
|
-
|
10
|
-
socket = TCPServer.open('127.0.0.1', 1234)
|
11
|
-
log 'Listening on port 1234... (multishot read)'
|
12
|
-
|
13
|
-
@ring = IOU::Ring.new
|
14
|
-
@bg_id = @ring.setup_buffer_ring(count: 1024, size: 4096)
|
15
|
-
|
16
|
-
@ring.prep_accept(fd: socket.fileno, multishot: true) do |c|
|
17
|
-
setup_connection(c[:result]) if c[:result] > 0
|
18
|
-
end
|
19
|
-
|
20
|
-
def setup_connection(fd)
|
21
|
-
log "Connection accepted fd #{fd}"
|
22
|
-
|
23
|
-
parser = Http::Parser.new
|
24
|
-
parser.on_message_complete = -> {
|
25
|
-
http_send_response(fd, "Hello, world!\n")
|
26
|
-
}
|
27
|
-
|
28
|
-
http_prep_read(fd, parser)
|
29
|
-
end
|
30
|
-
|
31
|
-
def http_prep_read(fd, parser)
|
32
|
-
id = @ring.prep_read(fd: fd, multishot: true, buffer_group: @bg_id) do |c|
|
33
|
-
if c[:result] > 0
|
34
|
-
parser << c[:buffer]
|
35
|
-
elsif c[:result] == 0
|
36
|
-
log "Connection closed by client on fd #{fd}"
|
37
|
-
else
|
38
|
-
if c[:result] != -Errno::ECANCELED::Errno
|
39
|
-
log "Got error #{c[:result]} on fd #{fd}, closing connection..."
|
40
|
-
end
|
41
|
-
@ring.prep_close(fd: fd) do |c|
|
42
|
-
log "Connection closed on fd #{fd}, result #{c[:result]}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
rescue HTTP::Parser::Error
|
46
|
-
puts "Error parsing, closing connection..."
|
47
|
-
@ring.prep_cancel(id)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def http_send_response(fd, body)
|
52
|
-
msg = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: keep-alive\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
|
53
|
-
@ring.prep_write(fd: fd, buffer: msg)
|
54
|
-
end
|
55
|
-
|
56
|
-
trap('SIGINT') { exit! }
|
57
|
-
@ring.process_completions_loop
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require_relative '../lib/iou'
|
2
|
-
require 'socket'
|
3
|
-
require 'http/parser'
|
4
|
-
|
5
|
-
socket = TCPServer.open('127.0.0.1', 1234)
|
6
|
-
puts 'Listening on port 1234... (multishot read)'
|
7
|
-
|
8
|
-
@ring = IOU::Ring.new
|
9
|
-
@buffer_group = @ring.setup_buffer_ring(count: 1024, size: 4096)
|
10
|
-
|
11
|
-
@ring.prep_accept(fd: socket.fileno, multishot: true) do |c|
|
12
|
-
http_handle_connection(c[:result]) if c[:result] > 0
|
13
|
-
end
|
14
|
-
|
15
|
-
def http_handle_connection(fd)
|
16
|
-
parser = Http::Parser.new
|
17
|
-
parser.on_message_complete = -> { http_send_response(fd, "Hello, world!\n") }
|
18
|
-
|
19
|
-
@ring.prep_read(fd: fd, multishot: true, buffer_group: @buffer_group) do |c|
|
20
|
-
if c[:result] > 0
|
21
|
-
parser << c[:buffer]
|
22
|
-
else
|
23
|
-
puts "Connection closed on fd #{fd}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def http_send_response(fd, body)
|
29
|
-
msg = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: keep-alive\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
|
30
|
-
@ring.prep_write(fd: fd, buffer: msg)
|
31
|
-
end
|
32
|
-
|
33
|
-
trap('SIGINT') { exit! }
|
34
|
-
@ring.process_completions_loop
|