diff options
Diffstat (limited to 'internal/io.h')
| -rw-r--r-- | internal/io.h | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/internal/io.h b/internal/io.h index 1891248a19..2110f0b087 100644 --- a/internal/io.h +++ b/internal/io.h @@ -14,10 +14,21 @@ struct rb_io; #include "ruby/io.h" /* for rb_io_t */ +#include "ccan/list/list.h" +#include "serial.h" -#define IO_WITHOUT_GVL(func, arg) rb_thread_call_without_gvl(func, arg, RUBY_UBF_IO, 0) +#define IO_WITHOUT_GVL(func, arg) rb_nogvl(func, arg, RUBY_UBF_IO, 0, RB_NOGVL_OFFLOAD_SAFE) #define IO_WITHOUT_GVL_INT(func, arg) (int)(VALUE)IO_WITHOUT_GVL(func, arg) +// Represents an in-flight blocking operation: +struct rb_io_blocking_operation { + // The linked list data structure. + struct ccan_list_node list; + + // The execution context of the blocking operation. + struct rb_execution_context_struct *ec; +}; + /** Ruby's IO, metadata and buffers. */ struct rb_io { @@ -31,7 +42,7 @@ struct rb_io { int fd; /** mode flags: FMODE_XXXs */ - int mode; + enum rb_io_mode mode; /** child's pid (for pipes) */ rb_pid_t pid; @@ -111,6 +122,18 @@ struct rb_io { * The timeout associated with this IO when performing blocking operations. */ VALUE timeout; + + /** + * Threads that are performing a blocking operation without the GVL using + * this IO. On calling IO#close, these threads will be interrupted so that + * the operation can be cancelled. + */ + struct ccan_list_head blocking_operations; + struct rb_execution_context_struct *closing_ec; + VALUE wakeup_mutex; + + // The fork generation of the blocking operations list. + rb_serial_t fork_generation; }; /* io.c */ @@ -119,22 +142,23 @@ void rb_stdio_set_default_encoding(void); VALUE rb_io_flush_raw(VALUE, int); size_t rb_io_memsize(const rb_io_t *); int rb_stderr_tty_p(void); -void rb_io_fptr_finalize_internal(void *ptr); -#ifdef rb_io_fptr_finalize -# undef rb_io_fptr_finalize -#endif -#define rb_io_fptr_finalize rb_io_fptr_finalize_internal VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt); VALUE rb_io_prep_stdin(void); VALUE rb_io_prep_stdout(void); VALUE rb_io_prep_stderr(void); +int rb_io_notify_close(struct rb_io *fptr); +bool rb_io_fptr_finalize_closed(struct rb_io *fptr); + RUBY_SYMBOL_EXPORT_BEGIN /* io.c (export) */ void rb_maygvl_fd_fix_cloexec(int fd); int rb_gc_for_fd(int err); void rb_write_error_str(VALUE mesg); + +VALUE rb_io_blocking_region_wait(struct rb_io *io, rb_blocking_function_t *function, void *argument, enum rb_io_event events); +VALUE rb_io_blocking_region(struct rb_io *io, rb_blocking_function_t *function, void *argument); RUBY_SYMBOL_EXPORT_END #endif /* INTERNAL_IO_H */ |
