mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
move cleanup function to thread_start_func_2(). * thread.c, thread_pthread.ci, thread_win32.ci: add more destruct functions. (native_thread_destroy() and native_mutex_destroy()) * thread_pthread.ci, thread_pthread.h: make native_mutex_* functions (check error, etc), it's not macro any more. * thread_win32.ci (thread_start_func_1): store some values before running thread (to release these after running thread). * thread_win32.ci (native_thread_create): fix spaces. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11671 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
990ae267cd
commit
a9026242f2
6 changed files with 124 additions and 36 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
Fri Feb 9 05:08:17 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
|
||||||
|
move cleanup function to thread_start_func_2().
|
||||||
|
|
||||||
|
* thread.c, thread_pthread.ci, thread_win32.ci:
|
||||||
|
add more destruct functions.
|
||||||
|
(native_thread_destroy() and native_mutex_destroy())
|
||||||
|
|
||||||
|
* thread_pthread.ci, thread_pthread.h: make native_mutex_* functions
|
||||||
|
(check error, etc), it's not macro any more.
|
||||||
|
|
||||||
|
* thread_win32.ci (thread_start_func_1): store some values before
|
||||||
|
running thread (to release these after running thread).
|
||||||
|
|
||||||
|
* thread_win32.ci (native_thread_create): fix spaces.
|
||||||
|
|
||||||
Thu Feb 8 22:44:04 2007 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
Thu Feb 8 22:44:04 2007 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||||
|
|
||||||
* ext/win32ole/win32ole.c (ole_set_safe_array, ole_variant2val,
|
* ext/win32ole/win32ole.c (ole_set_safe_array, ole_variant2val,
|
||||||
|
|
6
thread.c
6
thread.c
|
@ -247,6 +247,8 @@ thread_cleanup_func(void *th_ptr)
|
||||||
rb_thread_t *th = th_ptr;
|
rb_thread_t *th = th_ptr;
|
||||||
th->status = THREAD_KILLED;
|
th->status = THREAD_KILLED;
|
||||||
th->machine_stack_start = th->machine_stack_end = 0;
|
th->machine_stack_start = th->machine_stack_end = 0;
|
||||||
|
native_mutex_destroy(&th->interrupt_lock);
|
||||||
|
native_thread_destroy(th);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -258,7 +260,6 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
|
||||||
rb_thread_t *join_th;
|
rb_thread_t *join_th;
|
||||||
th->machine_stack_start = stack_start;
|
th->machine_stack_start = stack_start;
|
||||||
th->thgroup = th->vm->thgroup_default;
|
th->thgroup = th->vm->thgroup_default;
|
||||||
|
|
||||||
thread_debug("thread start: %p\n", th);
|
thread_debug("thread start: %p\n", th);
|
||||||
|
|
||||||
native_mutex_lock(&th->vm->global_interpreter_lock);
|
native_mutex_lock(&th->vm->global_interpreter_lock);
|
||||||
|
@ -297,6 +298,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
|
||||||
}
|
}
|
||||||
st_delete_wrap(th->vm->living_threads, th->self);
|
st_delete_wrap(th->vm->living_threads, th->self);
|
||||||
}
|
}
|
||||||
|
thread_cleanup_func(th);
|
||||||
native_mutex_unlock(&th->vm->global_interpreter_lock);
|
native_mutex_unlock(&th->vm->global_interpreter_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -318,7 +320,6 @@ thread_create_core(VALUE klass, VALUE args, VALUE (*fn)(ANYARGS), void *arg)
|
||||||
th->first_func_arg = arg;
|
th->first_func_arg = arg;
|
||||||
|
|
||||||
native_mutex_initialize(&th->interrupt_lock);
|
native_mutex_initialize(&th->interrupt_lock);
|
||||||
|
|
||||||
/* kick thread */
|
/* kick thread */
|
||||||
st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
|
st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
|
||||||
native_thread_create(th);
|
native_thread_create(th);
|
||||||
|
@ -2082,6 +2083,7 @@ mutex_free(void *ptr)
|
||||||
if (mutex->th) {
|
if (mutex->th) {
|
||||||
native_mutex_unlock(&mutex->lock);
|
native_mutex_unlock(&mutex->lock);
|
||||||
}
|
}
|
||||||
|
native_mutex_destroy(&mutex->lock);
|
||||||
}
|
}
|
||||||
ruby_xfree(ptr);
|
ruby_xfree(ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,59 @@
|
||||||
|
|
||||||
#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
|
#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
|
||||||
|
|
||||||
#define native_mutex_initialize(lock) do { \
|
void
|
||||||
pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER; \
|
native_mutex_lock(pthread_mutex_t *lock)
|
||||||
((*lock) = _lock); \
|
{
|
||||||
} while (0)
|
int r;
|
||||||
|
r = pthread_mutex_trylock(lock);
|
||||||
|
if (r == EBUSY) {
|
||||||
|
r = pthread_mutex_lock(lock);
|
||||||
|
|
||||||
|
if (r != 0) {
|
||||||
|
rb_bug("pthread_mutex_lock: %d", r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
native_mutex_unlock(pthread_mutex_t *lock)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if ((r = pthread_mutex_unlock(lock)) != 0) {
|
||||||
|
rb_bug("native_mutex_unlock return non-zero: %d", r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
native_mutex_trylock(pthread_mutex_t *lock)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if ((r = pthread_mutex_trylock(lock)) != 0) {
|
||||||
|
if (r == EBUSY) {
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_bug("native_mutex_unlock return non-zero: %d", r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
native_mutex_initialize(pthread_mutex_t *lock)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_init(lock, 0) != 0) {
|
||||||
|
rb_bug("native_mutex_initialize return non-zero");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
native_mutex_destroy(pthread_mutex_t *lock)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_destroy(lock) != 0) {
|
||||||
|
rb_bug("native_mutex_destroy return non-zero");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define native_cleanup_push pthread_cleanup_push
|
#define native_cleanup_push pthread_cleanup_push
|
||||||
#define native_cleanup_pop pthread_cleanup_pop
|
#define native_cleanup_pop pthread_cleanup_pop
|
||||||
|
@ -40,9 +89,13 @@ Init_native_thread()
|
||||||
posix_signal(SIGVTALRM, null_func);
|
posix_signal(SIGVTALRM, null_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
NOINLINE(static int
|
NOINLINE(static int thread_start_func_2(rb_thread_t *th, VALUE *stack_start));
|
||||||
thread_start_func_2(rb_thread_t *th, VALUE *stack_start));
|
|
||||||
void static thread_cleanup_func(void *th_ptr);
|
static void
|
||||||
|
native_thread_destroy(rb_thread_t *th)
|
||||||
|
{
|
||||||
|
pthread_cond_destroy(&th->native_thread_data.sleep_cond);
|
||||||
|
}
|
||||||
|
|
||||||
#define USE_THREAD_CACHE 0
|
#define USE_THREAD_CACHE 0
|
||||||
|
|
||||||
|
@ -55,16 +108,9 @@ thread_start_func_1(void *th_ptr)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = th_ptr;
|
rb_thread_t *th = th_ptr;
|
||||||
VALUE stack_start;
|
VALUE stack_start;
|
||||||
/* ignore self and klass */
|
|
||||||
|
|
||||||
native_cleanup_push(thread_cleanup_func, th);
|
|
||||||
|
|
||||||
/* run */
|
/* run */
|
||||||
thread_start_func_2(th, &stack_start);
|
thread_start_func_2(th, &stack_start);
|
||||||
|
|
||||||
/* cleanup */
|
|
||||||
thread_cleanup_func(th);
|
|
||||||
native_cleanup_pop(0);
|
|
||||||
}
|
}
|
||||||
#if USE_THREAD_CACHE
|
#if USE_THREAD_CACHE
|
||||||
if (1) {
|
if (1) {
|
||||||
|
@ -171,6 +217,9 @@ use_cached_thread(rb_thread_t *th)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK_ERR(expr) \
|
||||||
|
{ int err; if ((err = (expr)) != 0) { printf("err: %d - " #expr, err); exit(1); }}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
native_thread_create(rb_thread_t *th)
|
native_thread_create(rb_thread_t *th)
|
||||||
{
|
{
|
||||||
|
@ -190,16 +239,20 @@ native_thread_create(rb_thread_t *th)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thread_debug("create: %p, stack size: %ld\n", th, stack_size);
|
thread_debug("create: %p, stack size: %ld\n", th, stack_size);
|
||||||
pthread_attr_init(&attr);
|
CHECK_ERR(pthread_attr_init(&attr));
|
||||||
|
|
||||||
#ifdef PTHREAD_STACK_MIN
|
#ifdef PTHREAD_STACK_MIN
|
||||||
pthread_attr_setstacksize(&attr, stack_size);
|
CHECK_ERR(pthread_attr_setstacksize(&attr, stack_size));
|
||||||
#endif
|
#endif
|
||||||
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
|
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
CHECK_ERR(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
|
||||||
|
CHECK_ERR(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
|
||||||
|
|
||||||
err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
|
err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
|
||||||
|
CHECK_ERR(pthread_attr_destroy(&attr));
|
||||||
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
st_delete_wrap(th->vm->living_threads, th->self);
|
||||||
th->status = THREAD_KILLED;
|
th->status = THREAD_KILLED;
|
||||||
rb_raise(rb_eThreadError, "can't create Thread (%d)", err);
|
rb_raise(rb_eThreadError, "can't create Thread (%d)", err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,12 @@
|
||||||
typedef pthread_t rb_thread_id_t;
|
typedef pthread_t rb_thread_id_t;
|
||||||
typedef pthread_mutex_t rb_thread_lock_t;
|
typedef pthread_mutex_t rb_thread_lock_t;
|
||||||
|
|
||||||
#define native_mutex_lock pthread_mutex_lock
|
void native_mutex_lock(pthread_mutex_t *lock);
|
||||||
#define native_mutex_unlock pthread_mutex_unlock
|
void native_mutex_unlock(pthread_mutex_t *lock);
|
||||||
#define native_mutex_trylock pthread_mutex_trylock
|
void native_mutex_destroy(pthread_mutex_t *lock);
|
||||||
|
int native_mutex_trylock(pthread_mutex_t *lock);
|
||||||
|
void native_mutex_initialize(pthread_mutex_t *lock);
|
||||||
|
void native_mutex_destroy(pthread_mutex_t *lock);
|
||||||
|
|
||||||
typedef struct native_thread_data_struct {
|
typedef struct native_thread_data_struct {
|
||||||
void *signal_thread_list;
|
void *signal_thread_list;
|
||||||
|
|
|
@ -201,29 +201,42 @@ native_mutex_initialize(rb_thread_lock_t *lock)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
native_mutex_destroy(rb_thread_lock_t *lock)
|
||||||
|
{
|
||||||
|
CloseHandle(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NOINLINE(static int
|
NOINLINE(static int
|
||||||
thread_start_func_2(rb_thread_t *th, VALUE *stack_start));
|
thread_start_func_2(rb_thread_t *th, VALUE *stack_start));
|
||||||
void static thread_cleanup_func(void *th_ptr);
|
|
||||||
|
static void
|
||||||
|
native_thread_destroy(rb_thread_t *th)
|
||||||
|
{
|
||||||
|
CloseHandle(th->native_thread_data.interrupt_event);
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int _stdcall
|
static unsigned int _stdcall
|
||||||
thread_start_func_1(void *th_ptr)
|
thread_start_func_1(void *th_ptr)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = th_ptr;
|
rb_thread_t *th = th_ptr;
|
||||||
VALUE stack_start;
|
VALUE stack_start;
|
||||||
|
HANDLE thread_id = th->thread_id;
|
||||||
|
HANDLE interrupt_event;
|
||||||
/* run */
|
/* run */
|
||||||
th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
|
interrupt_event = th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
|
||||||
|
|
||||||
thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
|
thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
|
||||||
th->thread_id, th->native_thread_data.interrupt_event);
|
th->thread_id, th->native_thread_data.interrupt_event);
|
||||||
thread_start_func_2(th, &stack_start);
|
thread_start_func_2(th, &stack_start);
|
||||||
thread_cleanup_func(th);
|
|
||||||
|
|
||||||
/* native_mutex_unlock(&GET_VM()->global_interpreter_lock); */
|
/* native_mutex_unlock(&GET_VM()->global_interpreter_lock); */
|
||||||
|
|
||||||
thread_debug("close handle - intr: %p, thid: %p\n",
|
thread_debug("close handle - intr: %p, thid: %p\n",
|
||||||
th->native_thread_data.interrupt_event, th->thread_id);
|
interrupt_event, thread_id);
|
||||||
CloseHandle(th->native_thread_data.interrupt_event);
|
CloseHandle(interrupt_event);
|
||||||
CloseHandle(th->thread_id);
|
CloseHandle(thread_id);
|
||||||
thread_debug("thread deleted (th: %p)\n", th);
|
thread_debug("thread deleted (th: %p)\n", th);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -246,11 +259,11 @@ w32_create_thread(DWORD stack_size, void *func, void *val)
|
||||||
static int
|
static int
|
||||||
native_thread_create(rb_thread_t *th)
|
native_thread_create(rb_thread_t *th)
|
||||||
{
|
{
|
||||||
size_t stack_size = 4 * 1024 - sizeof(int); /* 4KB */
|
size_t stack_size = 4 * 1024; /* 4KB */
|
||||||
|
th->thread_id = w32_create_thread(stack_size, thread_start_func_1, th);
|
||||||
|
|
||||||
if ((th->thread_id =
|
if ((th->thread_id) == 0) {
|
||||||
w32_create_thread(stack_size, thread_start_func_1, th))
|
st_delete_wrap(th->vm->living_threads, th->self);
|
||||||
== 0) {
|
|
||||||
rb_raise(rb_eThreadError, "can't create Thread (%d)", errno);
|
rb_raise(rb_eThreadError, "can't create Thread (%d)", errno);
|
||||||
}
|
}
|
||||||
if (THREAD_DEBUG) {
|
if (THREAD_DEBUG) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#define RUBY_VERSION "1.9.0"
|
#define RUBY_VERSION "1.9.0"
|
||||||
#define RUBY_RELEASE_DATE "2007-02-08"
|
#define RUBY_RELEASE_DATE "2007-02-09"
|
||||||
#define RUBY_VERSION_CODE 190
|
#define RUBY_VERSION_CODE 190
|
||||||
#define RUBY_RELEASE_CODE 20070208
|
#define RUBY_RELEASE_CODE 20070209
|
||||||
#define RUBY_PATCHLEVEL 0
|
#define RUBY_PATCHLEVEL 0
|
||||||
|
|
||||||
#define RUBY_VERSION_MAJOR 1
|
#define RUBY_VERSION_MAJOR 1
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
#define RUBY_VERSION_TEENY 0
|
#define RUBY_VERSION_TEENY 0
|
||||||
#define RUBY_RELEASE_YEAR 2007
|
#define RUBY_RELEASE_YEAR 2007
|
||||||
#define RUBY_RELEASE_MONTH 2
|
#define RUBY_RELEASE_MONTH 2
|
||||||
#define RUBY_RELEASE_DAY 8
|
#define RUBY_RELEASE_DAY 9
|
||||||
|
|
||||||
RUBY_EXTERN const char ruby_version[];
|
RUBY_EXTERN const char ruby_version[];
|
||||||
RUBY_EXTERN const char ruby_release_date[];
|
RUBY_EXTERN const char ruby_release_date[];
|
||||||
|
|
Loading…
Add table
Reference in a new issue