polyphony 0.50.0 → 0.50.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2aac80a08ca16498c3ee0044b0ba6de039b179425051cbcee67af4c9b948c349
4
- data.tar.gz: bbe016d6b2ad3c5c89129089f9ebb8457a37159e03be2ff84f2572454880b0c2
3
+ metadata.gz: 126431d6f1b6c547d57dd99834c5a2371b4f2b3399df5556f55fdf7ff8465702
4
+ data.tar.gz: bf4e8d8cbde0a0d25930996f21ca723ffb68c065688ea2423f96b2a1e8946a80
5
5
  SHA512:
6
- metadata.gz: 2f91d0b40bceb4600e4bbd22f39cdbd6bfd4ac5b5fc038f77deb7d26a464ce3cad177884f9aadde60c78bc48df170ab6909c44d133283af3abf77a090ac58332
7
- data.tar.gz: 37dfa412a25f41dd704a203a865817bf273a23db0ccbe1bbec1a3f6017b9cd953301d67077e3b58601485f4dd96db94bef77da3d46cabd57fb563d3652173175
6
+ metadata.gz: 9b6cb2b64ac16e70941195aa17c019abdb026bac2d440550841f839bae96d248b87609979e6e9d7c57f9905845209714d90f74caa4488d8ba66afa96c35aa425
7
+ data.tar.gz: '093360cb9c3f5e81d7d23f1e707bf6399608475822b56d0171438748e65752adb2784b1ab36ce850a26840c615f73ce1fcc74ca842018361019269f7d3c31aa9'
@@ -1,3 +1,10 @@
1
+ ## 0.50.1
2
+
3
+ - Set `IOSQE_ASYNC` flag in io_uring backend
4
+ - Fix error handling in `Backend#waitpid`
5
+ - Reimplement libev backend's `#waitpid` by using pidfd_open (in similar manner
6
+ to the io_uring backend)
7
+
1
8
  ## 0.50.0
2
9
 
3
10
  - Use `Process::CLOCK_MONOTONIC` in Timer
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.50.0)
4
+ polyphony (0.50.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -3,6 +3,14 @@
3
3
  #include "ruby.h"
4
4
  #include "ruby/io.h"
5
5
 
6
+ #ifndef __NR_pidfd_open
7
+ #define __NR_pidfd_open 434 /* System call # on most architectures */
8
+ #endif
9
+
10
+ static int pidfd_open(pid_t pid, unsigned int flags) {
11
+ return syscall(__NR_pidfd_open, pid, flags);
12
+ }
13
+
6
14
  //////////////////////////////////////////////////////////////////////
7
15
  //////////////////////////////////////////////////////////////////////
8
16
  // the following is copied verbatim from the Ruby source code (io.c)
@@ -126,4 +134,16 @@ inline VALUE backend_timeout_exception(VALUE exception) {
126
134
  return rb_funcall(exception, ID_new, 0);
127
135
  else
128
136
  return rb_funcall(rb_eRuntimeError, ID_new, 1, exception);
129
- }
137
+ }
138
+
139
+ VALUE Backend_timeout_safe(VALUE arg) {
140
+ return rb_yield(arg);
141
+ }
142
+
143
+ VALUE Backend_timeout_rescue(VALUE arg, VALUE exception) {
144
+ return exception;
145
+ }
146
+
147
+ VALUE Backend_timeout_ensure_safe(VALUE arg) {
148
+ return rb_rescue2(Backend_timeout_safe, Qnil, Backend_timeout_rescue, Qnil, rb_eException, (VALUE)0);
149
+ }
@@ -19,14 +19,6 @@
19
19
  #include "ruby/thread.h"
20
20
  #include "backend_io_uring_context.h"
21
21
 
22
- #ifndef __NR_pidfd_open
23
- #define __NR_pidfd_open 434 /* System call # on most architectures */
24
- #endif
25
-
26
- static int pidfd_open(pid_t pid, unsigned int flags) {
27
- return syscall(__NR_pidfd_open, pid, flags);
28
- }
29
-
30
22
  VALUE SYM_io_uring;
31
23
 
32
24
  typedef struct Backend_t {
@@ -260,7 +252,7 @@ int io_uring_backend_defer_submit_and_await(
260
252
  VALUE switchpoint_result = Qnil;
261
253
 
262
254
  io_uring_sqe_set_data(sqe, ctx);
263
- // io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
255
+ io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
264
256
  io_uring_backend_defer_submit(backend);
265
257
 
266
258
  switchpoint_result = backend_await(backend);
@@ -811,18 +803,6 @@ VALUE Backend_timer_loop(VALUE self, VALUE interval) {
811
803
  }
812
804
  }
813
805
 
814
- VALUE Backend_timeout_safe(VALUE arg) {
815
- return rb_yield(arg);
816
- }
817
-
818
- VALUE Backend_timeout_rescue(VALUE arg, VALUE exception) {
819
- return exception;
820
- }
821
-
822
- VALUE Backend_timeout_ensure_safe(VALUE arg) {
823
- return rb_rescue2(Backend_timeout_safe, Qnil, Backend_timeout_rescue, Qnil, rb_eException, (VALUE)0);
824
- }
825
-
826
806
  struct Backend_timeout_ctx {
827
807
  Backend_t *backend;
828
808
  op_context_t *ctx;
@@ -861,7 +841,6 @@ VALUE Backend_timeout(int argc, VALUE *argv, VALUE self) {
861
841
  ctx->resume_value = timeout;
862
842
  io_uring_prep_timeout(sqe, &ts, 0, 0);
863
843
  io_uring_sqe_set_data(sqe, ctx);
864
- io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
865
844
  io_uring_backend_defer_submit(backend);
866
845
 
867
846
  struct Backend_timeout_ctx timeout_ctx = {backend, ctx};
@@ -879,19 +858,28 @@ VALUE Backend_timeout(int argc, VALUE *argv, VALUE self) {
879
858
  }
880
859
 
881
860
  VALUE Backend_waitpid(VALUE self, VALUE pid) {
882
- Backend_t *backend;
883
861
  int pid_int = NUM2INT(pid);
884
862
  int fd = pidfd_open(pid_int, 0);
885
- GetBackend(self, backend);
886
-
887
- VALUE resume_value = io_uring_backend_wait_fd(backend, fd, 0);
888
- close(fd);
889
863
 
890
- RAISE_IF_EXCEPTION(resume_value);
891
- RB_GC_GUARD(resume_value);
864
+ if (fd >= 0) {
865
+ Backend_t *backend;
866
+ GetBackend(self, backend);
892
867
 
868
+ VALUE resume_value = io_uring_backend_wait_fd(backend, fd, 0);
869
+ close(fd);
870
+ RAISE_IF_EXCEPTION(resume_value);
871
+ RB_GC_GUARD(resume_value);
872
+ }
873
+
893
874
  int status;
894
875
  pid_t ret = waitpid(pid_int, &status, WNOHANG);
876
+ if (ret < 0) {
877
+ int e = errno;
878
+ if (e == ECHILD)
879
+ ret = pid_int;
880
+ else
881
+ rb_syserr_fail(e, strerror(e));
882
+ }
895
883
  return rb_ary_new_from_args(2, INT2NUM(ret), INT2NUM(WEXITSTATUS(status)));
896
884
  }
897
885
 
@@ -8,6 +8,8 @@
8
8
  #include <netinet/in.h>
9
9
  #include <arpa/inet.h>
10
10
  #include <stdnoreturn.h>
11
+ #include <sys/types.h>
12
+ #include <sys/wait.h>
11
13
 
12
14
  #include "polyphony.h"
13
15
  #include "../libev/ev.h"
@@ -685,26 +687,12 @@ noreturn VALUE Backend_timer_loop(VALUE self, VALUE interval) {
685
687
  RB_GC_GUARD(switchpoint_result);
686
688
 
687
689
  rb_yield(Qnil);
688
-
689
- while (1) {
690
+ do {
690
691
  next_time += interval_d;
691
- if (next_time > now) break;
692
- }
692
+ } while (next_time <= now);
693
693
  }
694
694
  }
695
695
 
696
- VALUE Backend_timeout_safe(VALUE arg) {
697
- return rb_yield(arg);
698
- }
699
-
700
- VALUE Backend_timeout_rescue(VALUE arg, VALUE exception) {
701
- return exception;
702
- }
703
-
704
- VALUE Backend_timeout_ensure_safe(VALUE arg) {
705
- return rb_rescue2(Backend_timeout_safe, Qnil, Backend_timeout_rescue, Qnil, rb_eException, (VALUE)0);
706
- }
707
-
708
696
  struct libev_timeout {
709
697
  struct ev_timer timer;
710
698
  VALUE fiber;
@@ -759,38 +747,29 @@ VALUE Backend_timeout(int argc,VALUE *argv, VALUE self) {
759
747
  return result;
760
748
  }
761
749
 
762
- struct libev_child {
763
- struct ev_child child;
764
- VALUE fiber;
765
- };
766
-
767
- void Backend_child_callback(EV_P_ ev_child *w, int revents)
768
- {
769
- struct libev_child *watcher = (struct libev_child *)w;
770
- int exit_status = WEXITSTATUS(w->rstatus);
771
- VALUE status;
772
-
773
- status = rb_ary_new_from_args(2, INT2NUM(w->rpid), INT2NUM(exit_status));
774
- Fiber_make_runnable(watcher->fiber, status);
775
- }
776
-
777
750
  VALUE Backend_waitpid(VALUE self, VALUE pid) {
778
- Backend_t *backend;
779
- struct libev_child watcher;
780
- VALUE switchpoint_result = Qnil;
781
- GetBackend(self, backend);
782
-
783
- watcher.fiber = rb_fiber_current();
784
- ev_child_init(&watcher.child, Backend_child_callback, NUM2INT(pid), 0);
785
- ev_child_start(backend->ev_loop, &watcher.child);
786
-
787
- switchpoint_result = backend_await(backend);
751
+ int pid_int = NUM2INT(pid);
752
+ int fd = pidfd_open(pid_int, 0);
753
+ if (fd >= 0) {
754
+ Backend_t *backend;
755
+ GetBackend(self, backend);
756
+
757
+ VALUE resume_value = libev_wait_fd(backend, fd, EV_READ, 0);
758
+ close(fd);
759
+ RAISE_IF_EXCEPTION(resume_value);
760
+ RB_GC_GUARD(resume_value);
761
+ }
788
762
 
789
- ev_child_stop(backend->ev_loop, &watcher.child);
790
- RAISE_IF_EXCEPTION(switchpoint_result);
791
- RB_GC_GUARD(watcher.fiber);
792
- RB_GC_GUARD(switchpoint_result);
793
- return switchpoint_result;
763
+ int status = 0;
764
+ pid_t ret = waitpid(pid_int, &status, WNOHANG);
765
+ if (ret < 0) {
766
+ int e = errno;
767
+ if (e == ECHILD)
768
+ ret = pid_int;
769
+ else
770
+ rb_syserr_fail(e, strerror(e));
771
+ }
772
+ return rb_ary_new_from_args(2, INT2NUM(ret), INT2NUM(WEXITSTATUS(status)));
794
773
  }
795
774
 
796
775
  void Backend_async_callback(EV_P_ ev_async *w, int revents) { }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.50.0'
4
+ VERSION = '0.50.1'
5
5
  end
@@ -110,7 +110,7 @@ class IOTest < MiniTest::Test
110
110
  assert_equal [], buf
111
111
 
112
112
  o << "ulous\n"
113
- 10.times { snooze }
113
+ 15.times { snooze }
114
114
  assert_equal ["fabulous\n"], buf
115
115
 
116
116
  o.close
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyphony
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.50.0
4
+ version: 0.50.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: 2021-01-28 00:00:00.000000000 Z
11
+ date: 2021-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler