[前][次][番号順一覧][スレッド一覧]

ruby-changes:52342

From: normal <ko1@a...>
Date: Mon, 27 Aug 2018 14:32:23 +0900 (JST)
Subject: [ruby-changes:52342] normal:r64550 (trunk): thread.c: check interrupts explicitly in select/ppoll blocking regions

normal	2018-08-27 14:32:18 +0900 (Mon, 27 Aug 2018)

  New Revision: 64550

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64550

  Log:
    thread.c: check interrupts explicitly in select/ppoll blocking regions
    
    The logic around blocking_region_begin is confusing to me,
    but the goal of this patch is to ensure rb_sigwait_fd_get
    and rb_sigwait_fd_put are matched.
    
    In other words, we don't want a thread to hold sigwait_fd
    forever if an exception is raised while calling select()
    or ppoll().

  Modified files:
    trunk/thread.c
Index: thread.c
===================================================================
--- thread.c	(revision 64549)
+++ thread.c	(revision 64550)
@@ -3854,7 +3854,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L3854
 do_select(VALUE p)
 {
     struct select_set *set = (struct select_set *)p;
-    int MAYBE_UNUSED(result);
+    int result = 0;
     int lerrno;
     rb_hrtime_t *to, rel, end;
 
@@ -3876,10 +3876,13 @@ do_select(VALUE p) https://github.com/ruby/ruby/blob/trunk/thread.c#L3876
             struct timeval tv;
 
             sto = sigwait_timeout(set->th, set->sigwait_fd, to, &drained);
-	    result = native_fd_select(set->max, set->rset, set->wset, set->eset,
-				      rb_hrtime2timeval(&tv, sto), set->th);
-	    if (result < 0) lerrno = errno;
-	}, set->sigwait_fd >= 0 ? ubf_sigwait : ubf_select, set->th, FALSE);
+            if (!RUBY_VM_INTERRUPTED(set->th->ec)) {
+                result = native_fd_select(set->max, set->rset, set->wset,
+                                          set->eset,
+                                          rb_hrtime2timeval(&tv, sto), set->th);
+                if (result < 0) lerrno = errno;
+            }
+	}, set->sigwait_fd >= 0 ? ubf_sigwait : ubf_select, set->th, TRUE);
 
         if (set->sigwait_fd >= 0) {
             if (result > 0 && rb_fd_isset(set->sigwait_fd, set->rset))
@@ -3949,6 +3952,7 @@ rb_thread_fd_select(int max, rb_fdset_t https://github.com/ruby/ruby/blob/trunk/thread.c#L3952
     struct select_set set;
 
     set.th = GET_THREAD();
+    RUBY_VM_CHECK_INTS_BLOCKING(set.th->ec);
     set.max = max;
     set.sigwait_fd = rb_sigwait_fd_get(set.th);
     set.rset = read;
@@ -4018,6 +4022,7 @@ rb_wait_for_single_fd(int fd, int events https://github.com/ruby/ruby/blob/trunk/thread.c#L4022
     nfds_t nfds;
     rb_unblock_function_t *ubf;
 
+    RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
     timeout_prepare(&to, &rel, &end, timeout);
     fds[0].fd = fd;
     fds[0].events = (short)events;
@@ -4042,9 +4047,11 @@ rb_wait_for_single_fd(int fd, int events https://github.com/ruby/ruby/blob/trunk/thread.c#L4047
             struct timespec ts;
 
             sto = sigwait_timeout(th, fds[1].fd, to, &drained);
-            result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, sto), NULL);
-            if (result < 0) lerrno = errno;
-        }, ubf, th, FALSE);
+            if (!RUBY_VM_INTERRUPTED(th->ec)) {
+                result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, sto), NULL);
+                if (result < 0) lerrno = errno;
+            }
+        }, ubf, th, TRUE);
 
         if (fds[1].fd >= 0) {
             if (result > 0 && fds[1].revents) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]