summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZheng Da <zhengda1936@gmail.com>2009-12-13 12:24:02 +0100
committerZheng Da <zhengda1936@gmail.com>2009-12-13 12:24:02 +0100
commitc02fb40c744dc0789a69432d4d0b59f65cceac34 (patch)
tree76ecddfc5f550b7d9513d0fe52f5d6e6a3e6364c
parentf78cc8600bb68fe1970e1bbfbd4ffc8fffb866e2 (diff)
Use a global lock to protect a thread's local data.
-rw-r--r--libddekit/thread.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/libddekit/thread.c b/libddekit/thread.c
index f9aa6e58..b6ef987a 100644
--- a/libddekit/thread.c
+++ b/libddekit/thread.c
@@ -36,18 +36,20 @@ struct ddekit_sem
int value;
};
+static struct mutex global_lock = MUTEX_INITIALIZER;
+
static void _thread_cleanup ()
{
const char *name;
struct _ddekit_private_data *data;
cthread_t t = cthread_self ();
- // TODO I need a lock to protect ldata and name.
-
/* I have to free the sleep condition variable
* before the thread exits. */
+ mutex_lock (&global_lock);
data = cthread_ldata (t);
cthread_set_ldata (t, NULL);
+ mutex_unlock (&global_lock);
mach_port_destroy (mach_task_self (),
data->wakeupmsg.msgh_remote_port);
condition_free (data->sleep_cond);
@@ -125,7 +127,9 @@ static void setup_thread (struct ddekit_thread *t, const char *name) {
if (err)
error (1, err, "_create_wakeupmsg");
+ mutex_lock (&global_lock);
cthread_set_ldata (&t->thread, private_data);
+ mutex_unlock (&global_lock);
}
ddekit_thread_t *ddekit_thread_setup_myself(const char *name) {
@@ -236,7 +240,11 @@ void ddekit_thread_nsleep(unsigned long nsecs) {
}
void ddekit_thread_sleep(ddekit_lock_t *lock) {
- struct _ddekit_private_data *data = cthread_ldata (cthread_self ());
+ struct _ddekit_private_data *data;
+
+ mutex_lock (&global_lock);
+ data= cthread_ldata (cthread_self ());
+ mutex_unlock (&global_lock);
// TODO condition_wait cannot guarantee that the thread is
// woke up by another thread, maybe by signals.
@@ -245,8 +253,14 @@ void ddekit_thread_sleep(ddekit_lock_t *lock) {
}
void ddekit_thread_wakeup(ddekit_thread_t *td) {
- struct _ddekit_private_data *data = cthread_ldata (&td->thread);
+ struct _ddekit_private_data *data;
+
+ mutex_lock (&global_lock);
+ data = cthread_ldata (&td->thread);
+ mutex_unlock (&global_lock);
+ if (data == NULL)
+ return;
condition_signal (data->sleep_cond);
}
@@ -348,7 +362,9 @@ static int _sem_timedwait_internal (ddekit_sem_t *restrict sem,
}
/* Add ourselves to the queue. */
+ mutex_lock (&global_lock);
self_private_data = cthread_ldata (cthread_self ());
+ mutex_unlock (&global_lock);
add_entry_head (&sem->head, (struct list *) self_private_data);
spin_unlock (&sem->lock);