* thread_pthread.c (native_cond_signal): retry to call pthread_cond_signal

and pthread_cond_broadcast if they return EAGAIN in
  native_cond_signal and native_cond_broadcast, respectively.
  It is for the pthread implementation of Mac OS X 10.7 (Lion).
  fixes #5155.  [ruby-dev:44342].
* thread_pthread.c (native_cond_broadcast): ditto.
* thread_pthread.c (struct cached_thread_entry): stop using
  pthread_cond_t and its functions directly.
* thread_pthread.c (register_cached_thread_and_wait): ditto.
* thread_pthread.c (use_cached_thread): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32846 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
mrkn 2011-08-04 15:06:20 +00:00
Родитель 3fb4569534
Коммит 6a7081bb18
2 изменённых файлов: 40 добавлений и 7 удалений

Просмотреть файл

@ -1,3 +1,20 @@
Thu Aug 4 23:48:00 2011 Kenta Murata <mrkn@mrkn.jp>
* thread_pthread.c (native_cond_signal): retry to call pthread_cond_signal
and pthread_cond_broadcast if they return EAGAIN in
native_cond_signal and native_cond_broadcast, respectively.
It is for the pthread implementation of Mac OS X 10.7 (Lion).
fixes #5155. [ruby-dev:44342].
* thread_pthread.c (native_cond_broadcast): ditto.
* thread_pthread.c (struct cached_thread_entry): stop using
pthread_cond_t and its functions directly.
* thread_pthread.c (register_cached_thread_and_wait): ditto.
* thread_pthread.c (use_cached_thread): ditto.
Thu Aug 4 20:29:41 2011 Naohisa Goto <ngotogenome@gmail.com>
* configure.in: when Solaris cc, use $(CC) to link shared libs.

Просмотреть файл

@ -267,10 +267,23 @@ native_cond_destroy(rb_thread_cond_t *cond)
}
}
/*
* In OS X 10.7 (Lion), pthread_cond_signal and pthread_cond_broadcast return
* EAGAIN after retrying 8196 times. You can see them in the following page:
*
* http://www.opensource.apple.com/source/Libc/Libc-763.11/pthreads/pthread_cond.c
*
* The following native_cond_signal and native_cond_broadcast functions
* need to retrying until pthread functions don't return EAGAIN.
*/
static void
native_cond_signal(rb_thread_cond_t *cond)
{
int r = pthread_cond_signal(&cond->cond);
int r;
do {
r = pthread_cond_signal(&cond->cond);
} while (r == EAGAIN);
if (r != 0) {
rb_bug_errno("pthread_cond_signal", r);
}
@ -279,7 +292,10 @@ native_cond_signal(rb_thread_cond_t *cond)
static void
native_cond_broadcast(rb_thread_cond_t *cond)
{
int r = pthread_cond_broadcast(&cond->cond);
int r;
do {
r = pthread_cond_broadcast(&cond->cond);
} while (r == EAGAIN);
if (r != 0) {
rb_bug_errno("native_cond_broadcast", r);
}
@ -658,7 +674,7 @@ thread_start_func_1(void *th_ptr)
struct cached_thread_entry {
volatile rb_thread_t **th_area;
pthread_cond_t *cond;
rb_thread_cond_t *cond;
struct cached_thread_entry *next;
};
@ -670,7 +686,7 @@ struct cached_thread_entry *cached_thread_root;
static rb_thread_t *
register_cached_thread_and_wait(void)
{
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
rb_thread_cond_t cond = { PTHREAD_COND_INITIALIZER, };
volatile rb_thread_t *th_area = 0;
struct cached_thread_entry *entry =
(struct cached_thread_entry *)malloc(sizeof(struct cached_thread_entry));
@ -688,7 +704,7 @@ register_cached_thread_and_wait(void)
entry->next = cached_thread_root;
cached_thread_root = entry;
pthread_cond_timedwait(&cond, &thread_cache_lock, &ts);
native_cond_timedwait(&cond, &thread_cache_lock, &ts);
{
struct cached_thread_entry *e = cached_thread_root;
@ -710,7 +726,7 @@ register_cached_thread_and_wait(void)
}
free(entry); /* ok */
pthread_cond_destroy(&cond);
native_cond_destroy(&cond);
}
pthread_mutex_unlock(&thread_cache_lock);
@ -736,7 +752,7 @@ use_cached_thread(rb_thread_t *th)
}
}
if (result) {
pthread_cond_signal(entry->cond);
native_cond_signal(entry->cond);
}
pthread_mutex_unlock(&thread_cache_lock);
}