polyphony 0.43 → 0.43.5
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 +1 -1
- data/CHANGELOG.md +29 -0
- data/Gemfile.lock +2 -2
- data/README.md +0 -1
- data/docs/_sass/custom/custom.scss +10 -0
- data/docs/favicon.ico +0 -0
- data/docs/getting-started/overview.md +2 -2
- data/docs/index.md +6 -3
- data/docs/main-concepts/design-principles.md +23 -34
- data/docs/main-concepts/fiber-scheduling.md +1 -1
- data/docs/polyphony-logo.png +0 -0
- data/examples/adapters/concurrent-ruby.rb +9 -0
- data/examples/adapters/redis_blpop.rb +12 -0
- data/examples/core/xx-daemon.rb +14 -0
- data/examples/performance/mem-usage.rb +34 -28
- data/examples/performance/messaging.rb +29 -0
- data/examples/performance/multi_snooze.rb +11 -9
- data/ext/polyphony/libev_agent.c +181 -151
- data/ext/polyphony/libev_queue.c +129 -57
- data/ext/polyphony/polyphony.c +0 -6
- data/ext/polyphony/polyphony.h +12 -5
- data/ext/polyphony/polyphony_ext.c +0 -2
- data/ext/polyphony/ring_buffer.c +120 -0
- data/ext/polyphony/ring_buffer.h +28 -0
- data/ext/polyphony/thread.c +13 -13
- data/lib/polyphony.rb +26 -10
- data/lib/polyphony/adapters/redis.rb +3 -2
- data/lib/polyphony/core/global_api.rb +5 -3
- data/lib/polyphony/core/resource_pool.rb +19 -9
- data/lib/polyphony/core/thread_pool.rb +1 -1
- data/lib/polyphony/extensions/core.rb +40 -0
- data/lib/polyphony/extensions/fiber.rb +8 -13
- data/lib/polyphony/extensions/io.rb +17 -16
- data/lib/polyphony/extensions/socket.rb +12 -2
- data/lib/polyphony/version.rb +1 -1
- data/test/q.rb +24 -0
- data/test/test_agent.rb +13 -7
- data/test/test_fiber.rb +3 -3
- data/test/test_global_api.rb +50 -17
- data/test/test_io.rb +10 -2
- data/test/test_queue.rb +26 -1
- data/test/test_resource_pool.rb +12 -0
- data/test/test_throttler.rb +6 -5
- metadata +11 -3
- data/ext/polyphony/socket.c +0 -213
data/ext/polyphony/libev_agent.c
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
#include <netdb.h>
|
2
|
+
#include <sys/socket.h>
|
3
|
+
|
1
4
|
#include "polyphony.h"
|
2
5
|
#include "../libev/ev.h"
|
3
|
-
#include <sys/socket.h>
|
4
6
|
|
5
7
|
VALUE cLibevAgent = Qnil;
|
6
8
|
VALUE cTCPSocket;
|
@@ -128,7 +130,7 @@ VALUE LibevAgent_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue
|
|
128
130
|
GetLibevAgent(self, agent);
|
129
131
|
|
130
132
|
if (is_nowait) {
|
131
|
-
|
133
|
+
long runnable_count = LibevQueue_len(queue);
|
132
134
|
agent->run_no_wait_count++;
|
133
135
|
if (agent->run_no_wait_count < runnable_count || agent->run_no_wait_count < 10)
|
134
136
|
return self;
|
@@ -234,7 +236,7 @@ struct libev_io {
|
|
234
236
|
VALUE fiber;
|
235
237
|
};
|
236
238
|
|
237
|
-
|
239
|
+
void LibevAgent_io_callback(EV_P_ ev_io *w, int revents)
|
238
240
|
{
|
239
241
|
struct libev_io *watcher = (struct libev_io *)w;
|
240
242
|
Fiber_make_runnable(watcher->fiber, Qnil);
|
@@ -255,11 +257,32 @@ VALUE libev_agent_await(VALUE self) {
|
|
255
257
|
return libev_await(agent);
|
256
258
|
}
|
257
259
|
|
260
|
+
VALUE libev_io_wait(struct LibevAgent_t *agent, struct libev_io *watcher, rb_io_t *fptr, int flags) {
|
261
|
+
VALUE switchpoint_result;
|
262
|
+
|
263
|
+
if (watcher->fiber == Qnil) {
|
264
|
+
watcher->fiber = rb_fiber_current();
|
265
|
+
ev_io_init(&watcher->io, LibevAgent_io_callback, fptr->fd, flags);
|
266
|
+
}
|
267
|
+
ev_io_start(agent->ev_loop, &watcher->io);
|
268
|
+
switchpoint_result = libev_await(agent);
|
269
|
+
ev_io_stop(agent->ev_loop, &watcher->io);
|
270
|
+
|
271
|
+
RB_GC_GUARD(switchpoint_result);
|
272
|
+
return switchpoint_result;
|
273
|
+
}
|
274
|
+
|
275
|
+
VALUE libev_snooze() {
|
276
|
+
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
277
|
+
return Thread_switch_fiber(rb_thread_current());
|
278
|
+
}
|
279
|
+
|
258
280
|
VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
|
259
281
|
struct LibevAgent_t *agent;
|
260
282
|
struct libev_io watcher;
|
261
283
|
rb_io_t *fptr;
|
262
|
-
|
284
|
+
long dynamic_len = length == Qnil;
|
285
|
+
long len = dynamic_len ? 4096 : NUM2INT(length);
|
263
286
|
int shrinkable = io_setstrbuf(&str, len);
|
264
287
|
char *buf = RSTRING_PTR(str);
|
265
288
|
long total = 0;
|
@@ -276,44 +299,35 @@ VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eo
|
|
276
299
|
|
277
300
|
OBJ_TAINT(str);
|
278
301
|
|
279
|
-
while (
|
280
|
-
|
281
|
-
if (n
|
282
|
-
break;
|
283
|
-
if (n > 0) {
|
284
|
-
total = total + n;
|
285
|
-
buf += n;
|
286
|
-
len -= n;
|
287
|
-
if (!read_to_eof || (len == 0)) break;
|
288
|
-
}
|
289
|
-
else {
|
302
|
+
while (1) {
|
303
|
+
ssize_t n = read(fptr->fd, buf, len - total);
|
304
|
+
if (n < 0) {
|
290
305
|
int e = errno;
|
291
|
-
if (
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
}
|
296
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
297
|
-
switchpoint_result = libev_await(agent);
|
298
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
299
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
300
|
-
goto error;
|
301
|
-
}
|
302
|
-
}
|
303
|
-
else
|
304
|
-
rb_syserr_fail(e, strerror(e));
|
305
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
306
|
+
if (e != EWOULDBLOCK && e != EAGAIN) rb_syserr_fail(e, strerror(e));
|
307
|
+
|
308
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
309
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
306
310
|
}
|
307
|
-
|
311
|
+
else {
|
312
|
+
switchpoint_result = libev_snooze();
|
313
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
308
314
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
315
|
+
if (n == 0) break; // EOF
|
316
|
+
total = total + n;
|
317
|
+
if (!read_to_eof) break;
|
318
|
+
|
319
|
+
if (total == len) {
|
320
|
+
if (!dynamic_len) break;
|
321
|
+
|
322
|
+
rb_str_resize(str, total);
|
323
|
+
rb_str_modify_expand(str, len);
|
324
|
+
buf = RSTRING_PTR(str) + total;
|
325
|
+
shrinkable = 0;
|
326
|
+
len += len;
|
327
|
+
}
|
328
|
+
else buf += n;
|
314
329
|
}
|
315
330
|
}
|
316
|
-
|
317
331
|
if (total == 0) return Qnil;
|
318
332
|
|
319
333
|
io_set_read_length(str, total, shrinkable);
|
@@ -347,8 +361,8 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
|
|
347
361
|
struct libev_io watcher;
|
348
362
|
rb_io_t *fptr;
|
349
363
|
VALUE str;
|
350
|
-
|
351
|
-
|
364
|
+
long total;
|
365
|
+
long len = 8192;
|
352
366
|
int shrinkable;
|
353
367
|
char *buf;
|
354
368
|
VALUE switchpoint_result = Qnil;
|
@@ -366,10 +380,20 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
|
|
366
380
|
OBJ_TAINT(str);
|
367
381
|
|
368
382
|
while (1) {
|
369
|
-
|
370
|
-
if (n
|
371
|
-
|
372
|
-
|
383
|
+
ssize_t n = read(fptr->fd, buf, len);
|
384
|
+
if (n < 0) {
|
385
|
+
int e = errno;
|
386
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
387
|
+
|
388
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
389
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
390
|
+
}
|
391
|
+
else {
|
392
|
+
switchpoint_result = libev_snooze();
|
393
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
394
|
+
|
395
|
+
if (n == 0) break; // EOF
|
396
|
+
|
373
397
|
total = n;
|
374
398
|
YIELD_STR();
|
375
399
|
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
@@ -378,24 +402,6 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
|
|
378
402
|
goto error;
|
379
403
|
}
|
380
404
|
}
|
381
|
-
else {
|
382
|
-
int e = errno;
|
383
|
-
if ((e == EWOULDBLOCK || e == EAGAIN)) {
|
384
|
-
if (watcher.fiber == Qnil) {
|
385
|
-
watcher.fiber = rb_fiber_current();
|
386
|
-
ev_io_init(&watcher.io, LibevAgent_io_callback, fptr->fd, EV_READ);
|
387
|
-
}
|
388
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
389
|
-
switchpoint_result = libev_await(agent);
|
390
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
391
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
392
|
-
goto error;
|
393
|
-
}
|
394
|
-
}
|
395
|
-
else
|
396
|
-
rb_syserr_fail(e, strerror(e));
|
397
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
398
|
-
}
|
399
405
|
}
|
400
406
|
|
401
407
|
RB_GC_GUARD(str);
|
@@ -407,62 +413,60 @@ error:
|
|
407
413
|
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
408
414
|
}
|
409
415
|
|
410
|
-
VALUE LibevAgent_write(
|
416
|
+
VALUE LibevAgent_write(int argc, VALUE *argv, VALUE self) {
|
411
417
|
struct LibevAgent_t *agent;
|
412
418
|
struct libev_io watcher;
|
413
419
|
rb_io_t *fptr;
|
414
420
|
VALUE switchpoint_result = Qnil;
|
421
|
+
VALUE io;
|
422
|
+
VALUE underlying_io;
|
423
|
+
long total_written = 0;
|
424
|
+
int arg_idx = 1;
|
415
425
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
426
|
+
if (argc < 2)
|
427
|
+
rb_raise(rb_eRuntimeError, "(wrong number of arguments (expected 2 or more))");
|
428
|
+
|
429
|
+
io = argv[0];
|
430
|
+
underlying_io = rb_iv_get(io, "@io");
|
421
431
|
if (underlying_io != Qnil) io = underlying_io;
|
422
432
|
GetLibevAgent(self, agent);
|
423
433
|
io = rb_io_get_write_io(io);
|
424
434
|
GetOpenFile(io, fptr);
|
425
435
|
watcher.fiber = Qnil;
|
426
436
|
|
427
|
-
while (
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
437
|
+
while (arg_idx < argc) {
|
438
|
+
VALUE str = argv[arg_idx];
|
439
|
+
char *buf = StringValuePtr(str);
|
440
|
+
long len = RSTRING_LEN(str);
|
441
|
+
long left = len;
|
442
|
+
|
443
|
+
while (left > 0) {
|
444
|
+
ssize_t n = write(fptr->fd, buf, left);
|
445
|
+
if (n < 0) {
|
446
|
+
int e = errno;
|
447
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
448
|
+
|
449
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
|
450
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
441
451
|
}
|
442
452
|
else {
|
443
|
-
|
444
|
-
|
445
|
-
|
453
|
+
buf += n;
|
454
|
+
left -= n;
|
446
455
|
}
|
447
456
|
}
|
448
|
-
|
449
|
-
|
450
|
-
left -= result;
|
451
|
-
}
|
457
|
+
total_written += len;
|
458
|
+
arg_idx++;
|
452
459
|
}
|
453
460
|
|
454
461
|
if (watcher.fiber == Qnil) {
|
455
|
-
|
456
|
-
|
457
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
458
|
-
goto error;
|
459
|
-
}
|
462
|
+
switchpoint_result = libev_snooze();
|
463
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
460
464
|
}
|
461
465
|
|
462
466
|
RB_GC_GUARD(watcher.fiber);
|
463
467
|
RB_GC_GUARD(switchpoint_result);
|
464
468
|
|
465
|
-
return INT2NUM(
|
469
|
+
return INT2NUM(total_written);
|
466
470
|
error:
|
467
471
|
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
468
472
|
}
|
@@ -488,50 +492,39 @@ VALUE LibevAgent_accept(VALUE self, VALUE sock) {
|
|
488
492
|
fd = accept(fptr->fd, &addr, &len);
|
489
493
|
if (fd < 0) {
|
490
494
|
int e = errno;
|
491
|
-
if (e
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
}
|
496
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
497
|
-
switchpoint_result = libev_await(agent);
|
498
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
499
|
-
|
500
|
-
TEST_RESUME_EXCEPTION(switchpoint_result);
|
501
|
-
RB_GC_GUARD(watcher.fiber);
|
502
|
-
RB_GC_GUARD(switchpoint_result);
|
503
|
-
}
|
504
|
-
else
|
505
|
-
rb_syserr_fail(e, strerror(e));
|
506
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
495
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
496
|
+
|
497
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
498
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
507
499
|
}
|
508
500
|
else {
|
509
|
-
VALUE
|
501
|
+
VALUE socket;
|
510
502
|
rb_io_t *fp;
|
511
|
-
|
503
|
+
switchpoint_result = libev_snooze();
|
504
|
+
if (TEST_EXCEPTION(switchpoint_result)) {
|
505
|
+
close(fd); // close fd since we're raising an exception
|
506
|
+
goto error;
|
507
|
+
}
|
508
|
+
|
509
|
+
socket = rb_obj_alloc(cTCPSocket);
|
510
|
+
MakeOpenFile(socket, fp);
|
512
511
|
rb_update_max_fd(fd);
|
513
512
|
fp->fd = fd;
|
514
513
|
fp->mode = FMODE_READWRITE | FMODE_DUPLEX;
|
515
|
-
rb_io_ascii8bit_binmode(
|
514
|
+
rb_io_ascii8bit_binmode(socket);
|
516
515
|
rb_io_set_nonblock(fp);
|
517
516
|
rb_io_synchronized(fp);
|
518
517
|
|
519
518
|
// if (rsock_do_not_reverse_lookup) {
|
520
519
|
// fp->mode |= FMODE_NOREVLOOKUP;
|
521
520
|
// }
|
522
|
-
|
523
|
-
if (watcher.fiber == Qnil) {
|
524
|
-
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
525
|
-
switchpoint_result = Thread_switch_fiber(rb_thread_current());
|
526
|
-
if (TEST_EXCEPTION(switchpoint_result)) {
|
527
|
-
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
528
|
-
}
|
529
|
-
}
|
530
|
-
|
531
|
-
return connection;
|
521
|
+
return socket;
|
532
522
|
}
|
533
523
|
}
|
524
|
+
RB_GC_GUARD(switchpoint_result);
|
534
525
|
return Qnil;
|
526
|
+
error:
|
527
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
535
528
|
}
|
536
529
|
|
537
530
|
VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
|
@@ -542,7 +535,7 @@ VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
|
|
542
535
|
struct sockaddr addr;
|
543
536
|
socklen_t len = (socklen_t)sizeof addr;
|
544
537
|
VALUE switchpoint_result = Qnil;
|
545
|
-
VALUE
|
538
|
+
VALUE socket = Qnil;
|
546
539
|
VALUE underlying_sock = rb_iv_get(sock, "@io");
|
547
540
|
if (underlying_sock != Qnil) sock = underlying_sock;
|
548
541
|
|
@@ -555,46 +548,82 @@ VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
|
|
555
548
|
fd = accept(fptr->fd, &addr, &len);
|
556
549
|
if (fd < 0) {
|
557
550
|
int e = errno;
|
558
|
-
if (e
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
}
|
563
|
-
ev_io_start(agent->ev_loop, &watcher.io);
|
564
|
-
switchpoint_result = libev_await(agent);
|
565
|
-
ev_io_stop(agent->ev_loop, &watcher.io);
|
566
|
-
|
567
|
-
TEST_RESUME_EXCEPTION(switchpoint_result);
|
568
|
-
}
|
569
|
-
else
|
570
|
-
rb_syserr_fail(e, strerror(e));
|
571
|
-
// rb_syserr_fail_path(e, fptr->pathv);
|
551
|
+
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
552
|
+
|
553
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
|
554
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
572
555
|
}
|
573
556
|
else {
|
574
557
|
rb_io_t *fp;
|
575
|
-
|
576
|
-
|
558
|
+
switchpoint_result = libev_snooze();
|
559
|
+
if (TEST_EXCEPTION(switchpoint_result)) {
|
560
|
+
close(fd); // close fd since we're raising an exception
|
561
|
+
goto error;
|
562
|
+
}
|
563
|
+
|
564
|
+
socket = rb_obj_alloc(cTCPSocket);
|
565
|
+
MakeOpenFile(socket, fp);
|
577
566
|
rb_update_max_fd(fd);
|
578
567
|
fp->fd = fd;
|
579
568
|
fp->mode = FMODE_READWRITE | FMODE_DUPLEX;
|
580
|
-
rb_io_ascii8bit_binmode(
|
569
|
+
rb_io_ascii8bit_binmode(socket);
|
581
570
|
rb_io_set_nonblock(fp);
|
582
571
|
rb_io_synchronized(fp);
|
583
572
|
|
584
|
-
rb_yield(
|
585
|
-
|
586
|
-
|
587
|
-
Fiber_make_runnable(rb_fiber_current(), Qnil);
|
588
|
-
switchpoint_result = Thread_switch_fiber(rb_thread_current());
|
589
|
-
TEST_RESUME_EXCEPTION(switchpoint_result);
|
573
|
+
rb_yield(socket);
|
574
|
+
socket = Qnil;
|
590
575
|
}
|
591
576
|
}
|
592
577
|
|
593
|
-
RB_GC_GUARD(
|
578
|
+
RB_GC_GUARD(socket);
|
594
579
|
RB_GC_GUARD(watcher.fiber);
|
595
580
|
RB_GC_GUARD(switchpoint_result);
|
581
|
+
return Qnil;
|
582
|
+
error:
|
583
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
596
584
|
}
|
597
585
|
|
586
|
+
// VALUE LibevAgent_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
|
587
|
+
// struct LibevAgent_t *agent;
|
588
|
+
// struct libev_io watcher;
|
589
|
+
// rb_io_t *fptr;
|
590
|
+
// struct sockaddr_in addr;
|
591
|
+
// char *host_buf = StringValueCStr(host);
|
592
|
+
// VALUE switchpoint_result = Qnil;
|
593
|
+
// VALUE underlying_sock = rb_iv_get(sock, "@io");
|
594
|
+
// if (underlying_sock != Qnil) sock = underlying_sock;
|
595
|
+
|
596
|
+
// GetLibevAgent(self, agent);
|
597
|
+
// GetOpenFile(sock, fptr);
|
598
|
+
// rb_io_set_nonblock(fptr);
|
599
|
+
// watcher.fiber = Qnil;
|
600
|
+
|
601
|
+
// addr.sin_family = AF_INET;
|
602
|
+
// addr.sin_addr.s_addr = inet_addr(host_buf);
|
603
|
+
// addr.sin_port = htons(NUM2INT(port));
|
604
|
+
|
605
|
+
// while (1) {
|
606
|
+
// int result = connect(fptr->fd, &addr, sizeof(addr));
|
607
|
+
// if (result < 0) {
|
608
|
+
// int e = errno;
|
609
|
+
// if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
610
|
+
|
611
|
+
// switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
|
612
|
+
// if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
613
|
+
// }
|
614
|
+
// else {
|
615
|
+
// switchpoint_result = libev_snooze();
|
616
|
+
// if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
617
|
+
|
618
|
+
// return sock;
|
619
|
+
// }
|
620
|
+
// }
|
621
|
+
// RB_GC_GUARD(switchpoint_result);
|
622
|
+
// return Qnil;
|
623
|
+
// error:
|
624
|
+
// return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
625
|
+
// }
|
626
|
+
|
598
627
|
VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write) {
|
599
628
|
struct LibevAgent_t *agent;
|
600
629
|
struct libev_io watcher;
|
@@ -624,7 +653,7 @@ struct libev_timer {
|
|
624
653
|
VALUE fiber;
|
625
654
|
};
|
626
655
|
|
627
|
-
|
656
|
+
void LibevAgent_timer_callback(EV_P_ ev_timer *w, int revents)
|
628
657
|
{
|
629
658
|
struct libev_timer *watcher = (struct libev_timer *)w;
|
630
659
|
Fiber_make_runnable(watcher->fiber, Qnil);
|
@@ -654,7 +683,7 @@ struct libev_child {
|
|
654
683
|
VALUE fiber;
|
655
684
|
};
|
656
685
|
|
657
|
-
|
686
|
+
void LibevAgent_child_callback(EV_P_ ev_child *w, int revents)
|
658
687
|
{
|
659
688
|
struct libev_child *watcher = (struct libev_child *)w;
|
660
689
|
int exit_status = w->rstatus >> 8; // weird, why should we do this?
|
@@ -709,9 +738,10 @@ void Init_LibevAgent() {
|
|
709
738
|
|
710
739
|
rb_define_method(cLibevAgent, "read", LibevAgent_read, 4);
|
711
740
|
rb_define_method(cLibevAgent, "read_loop", LibevAgent_read_loop, 1);
|
712
|
-
rb_define_method(cLibevAgent, "write", LibevAgent_write,
|
741
|
+
rb_define_method(cLibevAgent, "write", LibevAgent_write, -1);
|
713
742
|
rb_define_method(cLibevAgent, "accept", LibevAgent_accept, 1);
|
714
743
|
rb_define_method(cLibevAgent, "accept_loop", LibevAgent_accept_loop, 1);
|
744
|
+
// rb_define_method(cLibevAgent, "connect", LibevAgent_accept, 3);
|
715
745
|
rb_define_method(cLibevAgent, "wait_io", LibevAgent_wait_io, 2);
|
716
746
|
rb_define_method(cLibevAgent, "sleep", LibevAgent_sleep, 1);
|
717
747
|
rb_define_method(cLibevAgent, "waitpid", LibevAgent_waitpid, 1);
|