polyphony 0.50.0 → 0.50.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 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