summaryrefslogtreecommitdiff
path: root/thread_pthread.c
diff options
context:
space:
mode:
authormrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-04 15:06:20 +0000
committermrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-04 15:06:20 +0000
commit6a7081bb18d84d39a0d7d46f0197158eb600dced (patch)
tree173f3d4bf5060a5bd54e38a293c3c8fce763bd8e /thread_pthread.c
parent3fb456953417cd85514968587c819b428b75b6b5 (diff)
* 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
Diffstat (limited to 'thread_pthread.c')
-rw-r--r--thread_pthread.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/thread_pthread.c b/thread_pthread.c
index 8ef34dd15f..32109e8ab9 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -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);
}