summaryrefslogtreecommitdiff
path: root/internal/thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'internal/thread.h')
-rw-r--r--internal/thread.h53
1 files changed, 43 insertions, 10 deletions
diff --git a/internal/thread.h b/internal/thread.h
index 47273436e3..ea891b4372 100644
--- a/internal/thread.h
+++ b/internal/thread.h
@@ -13,6 +13,7 @@
#include "ccan/list/list.h" /* for list in rb_io_close_wait_list */
struct rb_thread_struct; /* in vm_core.h */
+struct rb_io;
#define RB_VM_SAVE_MACHINE_CONTEXT(th) \
do { \
@@ -46,27 +47,35 @@ VALUE rb_thread_shield_wait(VALUE self);
VALUE rb_thread_shield_release(VALUE self);
VALUE rb_thread_shield_destroy(VALUE self);
int rb_thread_to_be_killed(VALUE thread);
+void rb_thread_acquire_fork_lock(void);
+void rb_thread_release_fork_lock(void);
+void rb_thread_reset_fork_lock(void);
void rb_mutex_allow_trap(VALUE self, int val);
VALUE rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data);
VALUE rb_mutex_owned_p(VALUE self);
VALUE rb_exec_recursive_outer_mid(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h, ID mid);
void ruby_mn_threads_params(void);
-int rb_thread_wait_for_single_fd(int fd, int events, struct timeval * timeout);
+int rb_thread_io_wait(struct rb_thread_struct *th, struct rb_io *io, int events, struct timeval * timeout);
+int rb_thread_wait_for_single_fd(struct rb_thread_struct *th, int fd, int events, struct timeval * timeout);
-struct rb_io_close_wait_list {
- struct ccan_list_head pending_fd_users;
- VALUE closing_thread;
- VALUE wakeup_mutex;
-};
-int rb_notify_fd_close(int fd, struct rb_io_close_wait_list *busy);
-void rb_notify_fd_close_wait(struct rb_io_close_wait_list *busy);
+size_t rb_thread_io_close_interrupt(struct rb_io *);
+void rb_thread_io_close_wait(struct rb_io *);
+
+void rb_ec_check_ints(struct rb_execution_context_struct *ec);
+
+void rb_thread_free_native_thread(void *th_ptr);
RUBY_SYMBOL_EXPORT_BEGIN
+void *rb_thread_prevent_fork(void *(*func)(void *), void *data); /* for ext/socket/raddrinfo.c */
+
/* Temporary. This API will be removed (renamed). */
-VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
-VALUE rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events);
+VALUE rb_thread_io_blocking_region(struct rb_io *io, rb_blocking_function_t *func, void *data1);
+VALUE rb_thread_io_blocking_call(struct rb_io *io, rb_blocking_function_t *func, void *data1, int events);
+
+// Invoke the given function, with the specified argument, in a way that `IO#close` from another execution context can interrupt it.
+VALUE rb_thread_io_blocking_operation(VALUE self, VALUE(*function)(VALUE), VALUE argument);
/* thread.c (export) */
int ruby_thread_has_gvl_p(void); /* for ext/fiddle/closure.c */
@@ -76,4 +85,28 @@ RUBY_SYMBOL_EXPORT_END
int rb_threadptr_execute_interrupts(struct rb_thread_struct *th, int blocking_timing);
bool rb_thread_mn_schedulable(VALUE thread);
+bool rb_thread_resolve_unblock_function(rb_unblock_function_t **unblock_function, void **data2, struct rb_thread_struct *thread);
+
+// interrupt exec
+
+typedef VALUE (rb_interrupt_exec_func_t)(void *data);
+
+enum rb_interrupt_exec_flag {
+ rb_interrupt_exec_flag_none = 0x00,
+ rb_interrupt_exec_flag_value_data = 0x01,
+ rb_interrupt_exec_flag_new_thread = 0x02,
+};
+
+// interrupt the target_th and run func.
+struct rb_ractor_struct;
+
+void rb_threadptr_interrupt_exec(struct rb_thread_struct *target_th,
+ rb_interrupt_exec_func_t *func, void *data, enum rb_interrupt_exec_flag flags);
+
+// create a thread in the target_r and run func on the created thread.
+void rb_ractor_interrupt_exec(struct rb_ractor_struct *target_r,
+ rb_interrupt_exec_func_t *func, void *data, enum rb_interrupt_exec_flag flags);
+
+void rb_threadptr_interrupt_exec_task_mark(struct rb_thread_struct *th);
+
#endif /* INTERNAL_THREAD_H */