summaryrefslogtreecommitdiff
path: root/tsd.c
diff options
context:
space:
mode:
authorrpj <rpj>2000-07-25 16:14:23 +0000
committerrpj <rpj>2000-07-25 16:14:23 +0000
commite2fd6e2de322cc12d9153da548ab76379049c11c (patch)
tree0e055e3496bbe45a4003d3e140e09a763d116fda /tsd.c
parentb035ed05977fdef5ced4691028284b7f0ebaba19 (diff)
2000-07-25 Ross Johnson <rpj@special.ise.canberra.edu.au>
* sched.c (sched_get_priority_max): Handle different WinCE and Win32 priority values together. (sched_get_priority_min): Ditto. - Tristan Savatier <tristan@mpegtv.com> * create.c (pthread_create): Force new threads to wait until pthread_create has the new thread's handle; we also retain a local copy of the handle for internal use until pthread_create returns. * private.c (_pthread_threadStart): Initialise ei[]. (_pthread_threadStart): When beginthread is used to start the thread, force waiting until the creator thread had the thread handle. * cancel.c (_pthread_cancel_thread): Include context switch code for defined(_X86_) environments in addition to _M_IX86. * rwlock.c (pthread_rwlock_destroy): Assignment changed to avoid compiler warning. * private.c (_pthread_get_exception_services_code): Cast NULL return value to avoid compiler warning. * cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable to avoid compiler warnings. * misc.c (_pthread_new): Change "new" variable to "t" to avoid confusion with the C++ keyword of the same name. * condvar.c (cond_wait_cleanup): Initialise lastWaiter variable. (cond_timedwait): Remove unused local variables. to avoid compiler warnings. * dll.c (dllMain): Remove 2000-07-21 change - problem appears to be in pthread_create(). 2000-07-22 Ross Johnson <rpj@special.ise.canberra.edu.au> * tsd.c (pthread_key_create): If a destructor was given and the pthread_mutex_init failed, then would try to reference a NULL pointer (*key); eliminate this section of code by using a dynamically initialised mutex (PTHREAD_MUTEX_INITIALIZER). * tsd.c (pthread_setspecific): Return an error if unable to set the value; simplify cryptic conditional. * tsd.c (pthread_key_delete): Locking threadsLock relied on mutex_lock returning an error if the key has no destructor. ThreadsLock is only initialised if the key has a destructor. Making this mutex a static could reduce the number of mutexes used by an application since it is actually created only at first use and it's often destroyed soon after. 2000-07-22 Ross Johnson <rpj@special.ise.canberra.edu.au> * FAQ: Added Q5 and Q6. tests/ChangeLog: 2000-07-25 Ross Johnson <rpj@special.ise.canberra.edu.au> * runtest.bat: modified to work under W98. * runall.bat: Add new tests; modified to work under W98. It was ok under NT. * Makefile: Add new tests. * exception1.c: New; Test passing exceptions back to the application and retaining library internal exceptions. * join0.c: New; Test a single join.
Diffstat (limited to 'tsd.c')
-rw-r--r--tsd.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/tsd.c b/tsd.c
index 5183cd7..1381ce2 100644
--- a/tsd.c
+++ b/tsd.c
@@ -71,9 +71,6 @@ pthread_key_create (pthread_key_t * key, void (*destructor) (void *))
}
else if (((*key)->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES)
{
- /*
- * Create system key
- */
result = EAGAIN;
free (*key);
@@ -86,6 +83,13 @@ pthread_key_create (pthread_key_t * key, void (*destructor) (void *))
* Therefore, need a lock that allows multiple threads
* to gain exclusive access to the key->threads list
*/
+#if 1
+ /*
+ * The mutex will only be created when it is first locked.
+ */
+ (*key)->threadsLock = PTHREAD_MUTEX_INITIALIZER;
+ (*key)->destructor = destructor;
+#else
result = pthread_mutex_init (&((*key)->threadsLock), NULL);
if (result != 0)
@@ -95,7 +99,11 @@ pthread_key_create (pthread_key_t * key, void (*destructor) (void *))
free (*key);
*key = NULL;
}
- (*key)->destructor = destructor;
+ else
+ {
+ (*key)->destructor = destructor;
+ }
+#endif
}
return (result);
@@ -134,6 +142,7 @@ pthread_key_delete (pthread_key_t key)
if (key != NULL)
{
if (key->threads != NULL &&
+ key->destructor != NULL &&
pthread_mutex_lock (&(key->threadsLock)) == 0)
{
/*
@@ -194,25 +203,24 @@ pthread_setspecific (pthread_key_t key, const void *value)
/*
* ------------------------------------------------------
* DOCPUBLIC
- * This function initializes an unnamed semaphore. the
- * initial value of the semaphore is 'value'
+ * This function sets the value of the thread specific
+ * key in the calling thread.
*
* PARAMETERS
- * sem
- * pointer to an instance of sem_t
+ * key
+ * an instance of pthread_key_t
+ * value
+ * the value to set key to
*
*
* DESCRIPTION
- * This function initializes an unnamed semaphore. The
- * initial value of the semaphore is set to 'value'.
+ * This function sets the value of the thread specific
+ * key in the calling thread.
*
* RESULTS
- * 0 successfully created semaphore,
- * EINVAL 'sem' is not a valid semaphore,
- * ENOSPC a required resource has been exhausted,
- * ENOSYS semaphores are not supported,
- * EPERM the process lacks appropriate privilege
- * ENOENT the thread couldn't find it's own handle
+ * 0 successfully set value
+ * EAGAIN could not set value
+ * ENOENT SERIOUS!!
*
* ------------------------------------------------------
*/
@@ -229,9 +237,9 @@ pthread_setspecific (pthread_key_t key, const void *value)
*/
self = pthread_self ();
if (self == NULL)
- {
- return ENOENT;
- }
+ {
+ return ENOENT;
+ }
}
else
{
@@ -284,20 +292,21 @@ pthread_setspecific (pthread_key_t key, const void *value)
/*
* create an association if not found
*/
- result = (assoc == NULL)
- ? _pthread_tkAssocCreate (&assoc, self, key)
- : 0;
- }
- else
- {
- result = 0;
+ if (assoc == NULL)
+ {
+ result = _pthread_tkAssocCreate (&assoc, self, key);
+ }
}
if (result == 0)
{
- TlsSetValue (key->key, (LPVOID) value);
+ if ( ! TlsSetValue (key->key, (LPVOID) value))
+ {
+ result = EAGAIN;
+ }
}
}
+
return (result);
} /* pthread_setspecific */