static VALUE rb_mutex_lock(VALUE self, SEL sel) { rb_vm_thread_t *current = GetThreadPtr(rb_vm_current_thread()); rb_vm_mutex_t *m = GetMutexPtr(self); rb_vm_thread_status_t prev_status; if (m->thread == current) { rb_raise(rb_eThreadError, "deadlock; recursive locking"); } prev_status = current->status; if (current->status == THREAD_ALIVE) { current->status = THREAD_SLEEP; } current->wait_for_mutex_lock = true; pthread_assert(pthread_mutex_lock(&m->mutex)); current->wait_for_mutex_lock = false; current->status = prev_status; m->thread = current; if (current->mutexes == Qnil) { GC_WB(¤t->mutexes, rb_ary_new()); OBJ_UNTRUST(current->mutexes); } rb_ary_push(current->mutexes, self); return self; }
static VALUE inspect_enumerator(VALUE obj, VALUE dummy, int recur) { struct enumerator *e; const char *cname; VALUE eobj, str; int tainted, untrusted; TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, e); cname = rb_obj_classname(obj); if (!e || e->obj == Qundef) { return rb_sprintf("#<%s: uninitialized>", cname); } if (recur) { str = rb_sprintf("#<%s: ...>", cname); OBJ_TAINT(str); return str; } eobj = e->obj; tainted = OBJ_TAINTED(eobj); untrusted = OBJ_UNTRUSTED(eobj); /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */ str = rb_sprintf("#<%s: ", cname); rb_str_concat(str, rb_inspect(eobj)); rb_str_buf_cat2(str, ":"); rb_str_buf_cat2(str, rb_id2name(e->meth)); if (e->args) { long argc = RARRAY_LEN(e->args); VALUE *argv = RARRAY_PTR(e->args); rb_str_buf_cat2(str, "("); while (argc--) { VALUE arg = *argv++; rb_str_concat(str, rb_inspect(arg)); rb_str_buf_cat2(str, argc > 0 ? ", " : ")"); if (OBJ_TAINTED(arg)) tainted = TRUE; if (OBJ_UNTRUSTED(arg)) untrusted = TRUE; } } rb_str_buf_cat2(str, ">"); if (tainted) OBJ_TAINT(str); if (untrusted) OBJ_UNTRUST(str); return str; }
static void w_nbyte(const char *s, long n, struct dump_arg *arg) { VALUE buf = arg->str; rb_str_buf_cat(buf, s, n); if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) { if (arg->taint) OBJ_TAINT(buf); if (arg->untrust) OBJ_UNTRUST(buf); rb_io_write(arg->dest, buf); rb_str_resize(buf, 0); } }
static VALUE thgroup_s_alloc(VALUE self, SEL sel) { rb_thread_group_t *t = (rb_thread_group_t *)xmalloc( sizeof(rb_thread_group_t)); t->enclosed = false; GC_WB(&t->threads, rb_ary_new()); OBJ_UNTRUST(t->threads); VALUE mutex = mutex_s_alloc(rb_cMutex, 0); mutex_initialize(mutex, 0); GC_WB(&t->mutex, mutex); return Data_Wrap_Struct(self, NULL, NULL, t); }
VALUE rb_singleton_class(VALUE obj) { VALUE klass; ID attached; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } CONST_ID(attached, "__attached__"); if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_ivar_get(RBASIC(obj)->klass, attached) == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (BUILTIN_TYPE(obj) == T_CLASS) { if (rb_iv_get(RBASIC(klass)->klass, "__attached__") != klass) make_metametaclass(klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_UNTRUSTED(obj)) { OBJ_UNTRUST(klass); } else { FL_UNSET(klass, FL_UNTRUSTED); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); return klass; }
static VALUE rb_mutex_trylock(VALUE self, SEL sel) { rb_vm_mutex_t *m = GetMutexPtr(self); if (pthread_mutex_trylock(&m->mutex) == 0) { rb_vm_thread_t *current = GetThreadPtr(rb_vm_current_thread()); m->thread = current; if (current->mutexes == Qnil) { GC_WB(¤t->mutexes, rb_ary_new()); OBJ_UNTRUST(current->mutexes); } rb_ary_push(current->mutexes, self); return Qtrue; } return Qfalse; }
/*! * \internal * Returns the singleton class of \a obj. Creates it if necessary. * * \note DO NOT expose the returned singleton class to * outside of class.c. * Use \ref rb_singleton_class instead for * consistency of the metaclass hierarchy. */ static VALUE singleton_class_of(VALUE obj) { VALUE klass; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %p", (void *)obj); } if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_UNTRUSTED(obj)) { OBJ_UNTRUST(klass); } else { FL_UNSET(klass, FL_UNTRUSTED); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); return klass; }
static VALUE inspect_enumerator(VALUE obj, VALUE dummy, int recur) { struct enumerator *e; const char *cname; VALUE eobj, eargs, str, method; int tainted, untrusted; TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, e); cname = rb_obj_classname(obj); if (!e || e->obj == Qundef) { return rb_sprintf("#<%s: uninitialized>", cname); } if (recur) { str = rb_sprintf("#<%s: ...>", cname); OBJ_TAINT(str); return str; } eobj = rb_attr_get(obj, id_receiver); if (NIL_P(eobj)) { eobj = e->obj; } tainted = OBJ_TAINTED(eobj); untrusted = OBJ_UNTRUSTED(eobj); /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */ str = rb_sprintf("#<%s: ", cname); rb_str_concat(str, rb_inspect(eobj)); method = rb_attr_get(obj, id_method); if (NIL_P(method)) { rb_str_buf_cat2(str, ":"); rb_str_buf_cat2(str, rb_id2name(e->meth)); } else if (method != Qfalse) { Check_Type(method, T_SYMBOL); rb_str_buf_cat2(str, ":"); rb_str_buf_cat2(str, rb_id2name(SYM2ID(method))); } eargs = rb_attr_get(obj, id_arguments); if (NIL_P(eargs)) { eargs = e->args; } if (eargs != Qfalse) { long argc = RARRAY_LEN(eargs); VALUE *argv = RARRAY_PTR(eargs); if (argc > 0) { rb_str_buf_cat2(str, "("); while (argc--) { VALUE arg = *argv++; rb_str_concat(str, rb_inspect(arg)); rb_str_buf_cat2(str, argc > 0 ? ", " : ")"); if (OBJ_TAINTED(arg)) tainted = TRUE; if (OBJ_UNTRUSTED(arg)) untrusted = TRUE; } } } rb_str_buf_cat2(str, ">"); if (tainted) OBJ_TAINT(str); if (untrusted) OBJ_UNTRUST(str); return str; }