Eric Wong <normalperson / yhbt.net> wrote:
>    https://80x24.org/spew/20180421021502.31552-1-e / 80x24.org/
>    Note: the /* TODO: check func() */ in rb_thread_io_blocking_region
>    But that WIP patch is broken...
> 
>    I think we need to replace rb_thread_io_blocking_region to
>    permanently fix your problem.  My change to check "val != Qundef"
>    is insufficient and wrong.  But I don't know how reasonable close
>    notifications can be with APIs like IO.copy_stream and
>    IO.select which work on multiple IOs, even...

Btw, this problem is present since 1.9.3 at least, probably
earlier; and your original script fails on older versions as
well.  (but they seem OK with my proposed reordering to
worker.join before output.close)

So maybe it's not so urgent and we can take our time with API
design.

I am thinking of replacing all GVL release functions with
something which takes an opaque attr like pthread_create uses.
It's a bit verbose, but should be extensible:

```
--- a/io.c
+++ b/io.c
@@ -983,11 +983,19 @@ static ssize_t
 rb_write_internal(int fd, const void *buf, size_t count)
 {
     struct io_internal_write_struct iis;
+    ssize_t w;
+    rb_thread_run_t tr;
+    rb_thread_attr_t attr;
     iis.fd = fd;
     iis.buf = buf;
     iis.capa = count;
 
-    return (ssize_t)rb_thread_io_blocking_region(internal_write_func, &iis, fd);
+    rb_thread_attr_init(&attr, 1);
+    rb_thread_attr_set_fds(&attr, 1, &fd);
+    rb_thread_attr_set_ubf(&attr, RUBY_UBF_IO, NULL);
+    rb_thread_run_do(&tr, &attr, internal_write_func, &iis);
+    rb_thread_run_join(tr, &w);
+    return w;
 }
 
 static ssize_t

```

	rb_thread_attr_set_fds would allow setting multiple FDs
	for functions like sendfile/splice/copy_file_range/tee,
	something rb_thread_io_blocking_region can't do.
	(but probably not used for poll/select/ppoll)

  rb_thread_attr_set_ubf - to set unblocking function + arg
  as with current rb_thread_call_without_gvl2

  rb_thread_attr_set_intrfail - set fail-if-interrupted flag
  This will allow removing confusing difference between
  rb_thread_call_without_gvl and rb_thread_call_without_gvl2
  calls (which does which again?)

Future expansion:

  rb_thread_attr_set_bind - allow migrating to different native thread

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>