9 rb_nativethread_lock_t
lock;
17 #if defined(HAVE_WORKING_FORK) 18 static void rb_mutex_abandon_all(
rb_mutex_t *mutexes);
19 static void rb_mutex_abandon_keeping_mutexes(
rb_thread_t *
th);
49 #define GetMutexPtr(obj, tobj) \ 50 TypedData_Get_Struct((obj), rb_mutex_t, &mutex_data_type, (tobj)) 52 #define mutex_mark NULL 62 if (err)
rb_bug(
"%s", err);
64 native_mutex_destroy(&mutex->
lock);
65 native_cond_destroy(&mutex->
cond);
100 native_mutex_initialize(&mutex->
lock);
101 native_cond_initialize(&mutex->
cond, RB_CONDATTR_CLOCK_MONOTONIC);
163 native_mutex_lock(&mutex->
lock);
164 if (mutex->
th == 0) {
171 native_mutex_unlock(&mutex->
lock);
202 timeout_rel.
tv_nsec = timeout_ms * 1000 * 1000;
203 timeout = native_cond_timeout(&mutex->
cond, timeout_rel);
204 err = native_cond_timedwait(&mutex->
cond, &mutex->
lock, &timeout);
207 native_cond_wait(&mutex->
cond, &mutex->
lock);
220 native_mutex_lock(&mutex->
lock);
222 native_cond_broadcast(&mutex->
cond);
223 native_mutex_unlock(&mutex->
lock);
253 if (mutex->
th == th) {
257 while (mutex->
th != th) {
260 volatile int timeout_ms = 0;
267 native_mutex_lock(&mutex->
lock);
281 interrupted =
lock_func(th, mutex, (
int)timeout_ms);
282 native_mutex_unlock(&mutex->
lock);
285 if (patrol_thread == th)
286 patrol_thread =
NULL;
291 if (mutex->
th && interrupted == 2) {
335 native_mutex_lock(&mutex->
lock);
337 if (mutex->
th == 0) {
338 err =
"Attempt to unlock a mutex which is not locked";
340 else if (mutex->
th != th) {
341 err =
"Attempt to unlock a mutex which is locked by another thread";
346 native_cond_signal(&mutex->
cond);
349 native_mutex_unlock(&mutex->
lock);
353 while (*th_mutex != mutex) {
383 #if defined(HAVE_WORKING_FORK) 402 rb_mutex_abandon_all(mutex);
441 if (!
NIL_P(timeout)) {
446 if (
NIL_P(timeout)) {
529 #define QUEUE_CLOSED FL_USER5 531 #define GET_QUEUE_QUE(q) get_array((q), QUEUE_QUE) 532 #define GET_QUEUE_WAITERS(q) get_array((q), QUEUE_WAITERS) 533 #define GET_SZQUEUE_WAITERS(q) get_array((q), SZQUEUE_WAITERS) 534 #define GET_SZQUEUE_MAX(q) RSTRUCT_GET((q), SZQUEUE_MAX) 535 #define GET_SZQUEUE_ULONGMAX(q) NUM2ULONG(GET_SZQUEUE_MAX(q)) 809 int should_block = 1;
812 should_block = !
RTEST(argv[0]);
986 int should_block = 1;
989 should_block = !
RTEST(argv[1]);
1017 if (!should_block) {
1104 #define GET_CONDVAR_WAITERS(cv) get_array((cv), CONDVAR_WAITERS) 1261 "que",
"waiters",
NULL);
1286 "que",
"waiters",
"queue_waiters",
"size",
NULL);
1317 #define ALIAS_GLOBAL_CONST(name) \ 1318 alias_global_const(#name, rb_c##name) #define GetMutexPtr(obj, tobj)
static int vm_living_thread_num(rb_vm_t *vm)
VALUE rb_mutex_lock(VALUE self)
struct timeval rb_time_interval(VALUE num)
static size_t mutex_memsize(const void *ptr)
VALUE rb_mutex_sleep(VALUE self, VALUE timeout)
rb_nativethread_cond_t cond
static VALUE rb_condvar_signal(VALUE self)
static VALUE mutex_alloc(VALUE klass)
#define GET_SZQUEUE_ULONGMAX(q)
struct rb_mutex_struct * next_mutex
void rb_bug(const char *fmt,...)
#define RUBY_TYPED_FREE_IMMEDIATELY
static VALUE undumpable(VALUE obj)
VALUE rb_mutex_synchronize(VALUE mutex, VALUE(*func)(VALUE arg), VALUE arg)
static VALUE queue_delete_from_waiting(struct waiting_delete *p)
#define GET_SZQUEUE_MAX(q)
static int max(int a, int b)
static VALUE rb_queue_closed_p(VALUE self)
VALUE rb_mutex_trylock(VALUE self)
static VALUE queue_do_push(VALUE self, VALUE obj)
static void alias_global_const(const char *name, VALUE klass)
static VALUE szqueue_do_pop(VALUE self, int should_block)
static int lock_func(rb_thread_t *th, rb_mutex_t *mutex, int timeout_ms)
static VALUE rb_queue_num_waiting(VALUE self)
VALUE rb_ary_shift(VALUE ary)
VALUE rb_mutex_unlock(VALUE self)
static VALUE rb_queue_length(VALUE self)
struct rb_thread_struct volatile * th
static void wakeup_first_thread(VALUE list)
VALUE rb_struct_alloc_noinit(VALUE)
VALUE rb_ary_push(VALUE ary, VALUE item)
SSL_METHOD *(* func)(void)
static VALUE rb_queue_initialize(VALUE self)
VALUE rb_ary_tmp_new(long capa)
static unsigned long queue_num_waiting(VALUE self)
static VALUE rb_mutex_synchronize_m(VALUE self, VALUE args)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_ary_clear(VALUE ary)
static void wakeup_all_threads(VALUE list)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static VALUE rb_szqueue_clear(VALUE self)
rb_nativethread_lock_t lock
void rb_mutex_allow_trap(VALUE self, int val)
static const rb_thread_t * patrol_thread
void rb_undef_method(VALUE klass, const char *name)
static VALUE queue_do_pop(VALUE self, int should_block)
static void rb_thread_sleep_deadly_allow_spurious_wakeup(void)
#define RB_TYPE_P(obj, type)
#define RUBY_VM_CHECK_INTS_BLOCKING(th)
static VALUE rb_cSizedQueue
static VALUE rb_queue_pop(int argc, VALUE *argv, VALUE self)
int rb_block_given_p(void)
RUBY_EXTERN VALUE rb_cObject
static VALUE rb_szqueue_max_get(VALUE self)
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
static VALUE rb_szqueue_initialize(VALUE self, VALUE vmax)
static VALUE rb_queue_push(VALUE self, VALUE obj)
static VALUE get_array(VALUE obj, int idx)
VALUE rb_thread_current(void)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void rb_define_const(VALUE, const char *, VALUE)
static int szqueue_push_should_block(int argc, const VALUE *argv)
static VALUE rb_eClosedQueueError
#define GVL_UNLOCK_BEGIN()
VALUE rb_thread_wakeup_alive(VALUE)
static VALUE rb_condvar_broadcast(VALUE self)
#define GET_SZQUEUE_WAITERS(q)
static VALUE rb_mutex_sleep_forever(VALUE time)
#define GET_CONDVAR_WAITERS(cv)
static VALUE ary_buf_new(void)
static VALUE rb_mutex_wait_for(VALUE time)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
static VALUE rb_condvar_wait(int argc, VALUE *argv, VALUE self)
#define ALIAS_GLOBAL_CONST(name)
static VALUE do_sleep(VALUE args)
static const char * rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t volatile *th)
static void lock_interrupt(void *ptr)
struct rb_mutex_struct * keeping_mutexes
static int set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *arg, struct rb_unblock_callback *old, int fail_if_interrupted)
VALUE rb_ary_delete(VALUE ary, VALUE item)
VALUE rb_obj_is_mutex(VALUE obj)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
static VALUE rb_szqueue_push(int argc, VALUE *argv, VALUE self)
static VALUE rb_szqueue_pop(int argc, VALUE *argv, VALUE self)
static void rb_check_deadlock(rb_vm_t *vm)
VALUE rb_mutex_owned_p(VALUE self)
static VALUE rb_szqueue_close(VALUE self)
static VALUE rb_condvar_initialize(VALUE self)
#define FL_TEST_RAW(x, f)
static VALUE rb_szqueue_num_waiting(VALUE self)
RUBY_EXTERN VALUE rb_cThread
static VALUE queue_closed_result(VALUE self)
static int queue_pop_should_block(int argc, const VALUE *argv)
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
static void reset_unblock_function(rb_thread_t *th, const struct rb_unblock_callback *old)
static void mutex_locked(rb_thread_t *th, VALUE self)
register unsigned int len
static VALUE rb_queue_clear(VALUE self)
enum rb_thread_status status
static VALUE rb_szqueue_max_set(VALUE self, VALUE vmax)
#define RSTRUCT_SET(st, idx, v)
static unsigned long szqueue_num_waiting_producer(VALUE self)
#define RSTRUCT_GET(st, idx)
static void raise_closed_queue_error(VALUE self)
static VALUE delete_current_thread(VALUE ary)
#define RARRAY_AREF(a, i)
unsigned long interrupt_mask
static VALUE queue_sleep(VALUE arg)
static Bigint * diff(Bigint *a, Bigint *b)
static VALUE rb_cConditionVariable
struct rb_encoding_entry * list
static VALUE mutex_sleep(int argc, VALUE *argv, VALUE self)
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc,...)
static VALUE mutex_initialize(VALUE self)
#define TypedData_Make_Struct(klass, type, data_type, sval)
static unsigned long queue_length(VALUE self)
static VALUE rb_queue_close(VALUE self)
static VALUE queue_do_close(VALUE self, int is_szq)
static void sleep_timeval(rb_thread_t *th, struct timeval time, int spurious_check)
VALUE rb_mutex_locked_p(VALUE self)
#define RUBY_VM_INTERRUPTED(th)
struct rb_mutex_struct rb_mutex_t
static void mutex_free(void *ptr)
#define GET_QUEUE_WAITERS(q)
static VALUE rb_queue_empty_p(VALUE self)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_provide(const char *)
static const rb_data_type_t mutex_data_type
static int queue_closed_p(VALUE self)
static void Init_thread_sync(void)
VALUE rb_obj_class(VALUE)