This project is closed and read-only.
Backport #7134 » mutex_notrap.patch
| vm_core.h (working copy) | ||
|---|---|---|
|
void *altstack;
|
||
|
#endif
|
||
|
unsigned long running_time_us;
|
||
|
int trap_enabled;
|
||
|
} rb_thread_t;
|
||
|
/* iseq.c */
|
||
| ... | ... | |
|
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, 0x01)
|
||
|
#define RUBY_VM_SET_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, 0x02)
|
||
|
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, 0x04)
|
||
|
#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)
|
||
|
#define RUBY_VM_INTERRUPTED(th) ((th)->trap_enabled && ((th)->interrupt_flag & 0x02))
|
||
|
int rb_signal_buff_size(void);
|
||
|
void rb_signal_exec(rb_thread_t *th, int sig);
|
||
| ... | ... | |
|
void rb_thread_lock_unlock(rb_thread_lock_t *);
|
||
|
void rb_thread_lock_destroy(rb_thread_lock_t *);
|
||
|
#define THREAD_INTERRUPTED(th) ((th)->trap_enabled && (th)->interrupt_flag)
|
||
|
#define RUBY_VM_CHECK_INTS_BLOCKING(th) do { \
|
||
|
if (UNLIKELY((th)->interrupt_flag)) { \
|
||
|
if (UNLIKELY(THREAD_INTERRUPTED(th))) { \
|
||
|
rb_threadptr_execute_interrupts(th, 1); \
|
||
|
} \
|
||
|
} while (0)
|
||
|
#define RUBY_VM_CHECK_INTS(th) do { \
|
||
|
if (UNLIKELY((th)->interrupt_flag)) { \
|
||
|
if (UNLIKELY(THREAD_INTERRUPTED(th))) { \
|
||
|
rb_threadptr_execute_interrupts(th, 0); \
|
||
|
} \
|
||
|
} while (0)
|
||
| io.c (working copy) | ||
|---|---|---|
|
arg.ptr = ptr + offset;
|
||
|
arg.length = n;
|
||
|
if (fptr->write_lock) {
|
||
|
r = rb_mutex_synchronize(fptr->write_lock, io_binwrite_string, (VALUE)&arg);
|
||
|
r = rb_mutex_synchronize_notrap(fptr->write_lock, io_binwrite_string, (VALUE)&arg);
|
||
|
}
|
||
|
else {
|
||
|
long l = io_writable_length(fptr, n);
|
||
| thread.c (working copy) | ||
|---|---|---|
|
check_ints:
|
||
|
RUBY_VM_CHECK_INTS(th); /* check signal or so */
|
||
|
native_mutex_lock(&th->interrupt_lock);
|
||
|
if (th->interrupt_flag) {
|
||
|
if (THREAD_INTERRUPTED(th)) {
|
||
|
native_mutex_unlock(&th->interrupt_lock);
|
||
|
goto check_ints;
|
||
|
}
|
||
| ... | ... | |
|
native_mutex_initialize(&th->interrupt_lock);
|
||
|
th->trap_enabled = 1;
|
||
|
/* kick thread */
|
||
|
st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
|
||
|
err = native_thread_create(th);
|
||
| ... | ... | |
|
{
|
||
|
rb_thread_schedule_limits(0);
|
||
|
if (UNLIKELY(GET_THREAD()->interrupt_flag)) {
|
||
|
if (UNLIKELY(THREAD_INTERRUPTED(GET_THREAD()))) {
|
||
|
rb_threadptr_execute_interrupts_common(GET_THREAD(), 0);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
return rb_ensure(func, arg, rb_mutex_unlock, mutex);
|
||
|
}
|
||
|
typedef struct {
|
||
|
VALUE mutex;
|
||
|
int old_trap_enabled;
|
||
|
} sync_notrap_t;
|
||
|
/* :nodoc: */
|
||
|
VALUE
|
||
|
rb_mutex_unlock_notrap(VALUE value)
|
||
|
{
|
||
|
sync_notrap_t *arg = (sync_notrap_t*)value;
|
||
|
VALUE ret;
|
||
|
rb_thread_t *th = GET_THREAD();
|
||
|
ret = rb_mutex_unlock(arg->mutex);
|
||
|
th->trap_enabled = arg->old_trap_enabled;
|
||
|
return ret;
|
||
|
}
|
||
|
/*
|
||
|
* :nodoc:
|
||
|
* similar rb_mutex_synchronize(), but also prevent trap
|
||
|
*/
|
||
|
VALUE
|
||
|
rb_mutex_synchronize_notrap(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg)
|
||
|
{
|
||
|
rb_thread_t *th = GET_THREAD();
|
||
|
sync_notrap_t ensure_arg;
|
||
|
ensure_arg.mutex = mutex;
|
||
|
ensure_arg.old_trap_enabled = th->trap_enabled;
|
||
|
/* mask trap handler for prevent recursive mutex lock */
|
||
|
th->trap_enabled = 0;
|
||
|
rb_mutex_lock(mutex);
|
||
|
return rb_ensure(func, arg, rb_mutex_unlock_notrap, (VALUE)&ensure_arg);
|
||
|
}
|
||
|
/*
|
||
|
* Document-class: ThreadShield
|
||
|
*/
|
||
|
static void
|
||
| ... | ... | |
|
th->async_errinfo_queue = rb_ary_tmp_new(0);
|
||
|
th->async_errinfo_queue_checked = 0;
|
||
|
th->async_errinfo_mask_stack = rb_ary_tmp_new(0);
|
||
|
th->trap_enabled = 1;
|
||
|
}
|
||
|
}
|
||
| internal.h (working copy) | ||
|---|---|---|
|
VALUE rb_thread_shield_wait(VALUE self);
|
||
|
VALUE rb_thread_shield_release(VALUE self);
|
||
|
VALUE rb_thread_shield_destroy(VALUE self);
|
||
|
VALUE rb_mutex_synchronize_notrap(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg);
|
||
|
/* thread_pthread.c, thread_win32.c */
|
||
|
void Init_native_thread(void);
|
||
- « Previous
- 1
- 2
- Next »