Index: mozilla/nsprpub/pr/src/threads/prtpd.c |
=================================================================== |
--- mozilla/nsprpub/pr/src/threads/prtpd.c (revision 191424) |
+++ mozilla/nsprpub/pr/src/threads/prtpd.c (working copy) |
@@ -1,248 +0,0 @@ |
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
- |
-/* |
-** Thread Private Data |
-** |
-** There is an aribitrary limit on the number of keys that will be allocated |
-** by the runtime. It's largish, so it is intended to be a sanity check, not |
-** an impediment. |
-** |
-** There is a counter, initialized to zero and incremented every time a |
-** client asks for a new key, that holds the high water mark for keys. All |
-** threads logically have the same high water mark and are permitted to |
-** ask for TPD up to that key value. |
-** |
-** The vector to hold the TPD are allocated when PR_SetThreadPrivate() is |
-** called. The size of the vector will be some value greater than or equal |
-** to the current high water mark. Each thread has its own TPD length and |
-** vector. |
-** |
-** Threads that get private data for keys they have not set (or perhaps |
-** don't even exist for that thread) get a NULL return. If the key is |
-** beyond the high water mark, an error will be returned. |
-*/ |
- |
-/* |
-** As of this time, BeOS has its own TPD implementation. Integrating |
-** this standard one is a TODO for anyone with a bit of spare time on |
-** their hand. For now, we just #ifdef out this whole file and use |
-** the routines in pr/src/btthreads/ |
-*/ |
- |
-#ifndef XP_BEOS |
- |
-#include "primpl.h" |
- |
-#include <string.h> |
- |
-#if defined(WIN95) |
-/* |
-** Some local variables report warnings on Win95 because the code paths |
-** using them are conditioned on HAVE_CUSTOME_USER_THREADS. |
-** The pragma suppresses the warning. |
-** |
-*/ |
-#pragma warning(disable : 4101) |
-#endif |
- |
-#define _PR_TPD_LIMIT 128 /* arbitary limit on the TPD slots */ |
-static PRInt32 _pr_tpd_length = 0; /* current length of destructor vector */ |
-static PRInt32 _pr_tpd_highwater = 0; /* next TPD key to be assigned */ |
-static PRThreadPrivateDTOR *_pr_tpd_destructors = NULL; |
- /* the destructors are associated with |
- the keys, therefore asserting that |
- the TPD key depicts the data's 'type' */ |
- |
-/* |
-** Initialize the thread private data manipulation |
-*/ |
-void _PR_InitTPD(void) |
-{ |
- _pr_tpd_destructors = (PRThreadPrivateDTOR*) |
- PR_CALLOC(_PR_TPD_LIMIT * sizeof(PRThreadPrivateDTOR*)); |
- PR_ASSERT(NULL != _pr_tpd_destructors); |
- _pr_tpd_length = _PR_TPD_LIMIT; |
-} |
- |
-/* |
-** Clean up the thread private data manipulation |
-*/ |
-void _PR_CleanupTPD(void) |
-{ |
-} /* _PR_CleanupTPD */ |
- |
-/* |
-** This routine returns a new index for per-thread-private data table. |
-** The index is visible to all threads within a process. This index can |
-** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines |
-** to save and retrieve data associated with the index for a thread. |
-** |
-** The index independently maintains specific values for each binding thread. |
-** A thread can only get access to its own thread-specific-data. |
-** |
-** Upon a new index return the value associated with the index for all threads |
-** is NULL, and upon thread creation the value associated with all indices for |
-** that thread is NULL. |
-** |
-** "dtor" is the destructor function to invoke when the private |
-** data is set or destroyed |
-** |
-** Returns PR_FAILURE if the total number of indices will exceed the maximun |
-** allowed. |
-*/ |
- |
-PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex( |
- PRUintn *newIndex, PRThreadPrivateDTOR dtor) |
-{ |
- PRStatus rv; |
- PRInt32 index; |
- |
- if (!_pr_initialized) _PR_ImplicitInitialization(); |
- |
- PR_ASSERT(NULL != newIndex); |
- PR_ASSERT(NULL != _pr_tpd_destructors); |
- |
- index = PR_ATOMIC_INCREMENT(&_pr_tpd_highwater) - 1; /* allocate index */ |
- if (_PR_TPD_LIMIT <= index) |
- { |
- PR_SetError(PR_TPD_RANGE_ERROR, 0); |
- rv = PR_FAILURE; /* that's just wrong */ |
- } |
- else |
- { |
- _pr_tpd_destructors[index] = dtor; /* record destructor @index */ |
- *newIndex = (PRUintn)index; /* copy into client's location */ |
- rv = PR_SUCCESS; /* that's okay */ |
- } |
- |
- return rv; |
-} |
- |
-/* |
-** Define some per-thread-private data. |
-** "index" is an index into the per-thread private data table |
-** "priv" is the per-thread-private data |
-** |
-** If the per-thread private data table has a previously registered |
-** destructor function and a non-NULL per-thread-private data value, |
-** the destructor function is invoked. |
-** |
-** This can return PR_FAILURE if index is invalid (ie., beyond the current |
-** high water mark) or memory is insufficient to allocate an exanded vector. |
-*/ |
- |
-PR_IMPLEMENT(PRStatus) PR_SetThreadPrivate(PRUintn index, void *priv) |
-{ |
- PRThread *self = PR_GetCurrentThread(); |
- |
- /* |
- ** The index being set might not have a sufficient vector in this |
- ** thread. But if the index has been allocated, it's okay to go |
- ** ahead and extend this one now. |
- */ |
- if ((index >= _PR_TPD_LIMIT) || (index >= _pr_tpd_highwater)) |
- { |
- PR_SetError(PR_TPD_RANGE_ERROR, 0); |
- return PR_FAILURE; |
- } |
- |
- PR_ASSERT(((NULL == self->privateData) && (0 == self->tpdLength)) |
- || ((NULL != self->privateData) && (0 != self->tpdLength))); |
- |
- if ((NULL == self->privateData) || (self->tpdLength <= index)) |
- { |
- void *extension = PR_CALLOC(_pr_tpd_length * sizeof(void*)); |
- if (NULL == extension) |
- { |
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); |
- return PR_FAILURE; |
- } |
- if (self->privateData) { |
- (void)memcpy( |
- extension, self->privateData, |
- self->tpdLength * sizeof(void*)); |
- PR_DELETE(self->privateData); |
- } |
- self->tpdLength = _pr_tpd_length; |
- self->privateData = (void**)extension; |
- } |
- /* |
- ** There wasn't much chance of having to call the destructor |
- ** unless the slot already existed. |
- */ |
- else if (self->privateData[index] && _pr_tpd_destructors[index]) |
- { |
- void *data = self->privateData[index]; |
- self->privateData[index] = NULL; |
- (*_pr_tpd_destructors[index])(data); |
- } |
- |
- PR_ASSERT(index < self->tpdLength); |
- self->privateData[index] = priv; |
- |
- return PR_SUCCESS; |
-} |
- |
-/* |
-** Recover the per-thread-private data for the current thread. "index" is |
-** the index into the per-thread private data table. |
-** |
-** The returned value may be NULL which is indistinguishable from an error |
-** condition. |
-** |
-*/ |
- |
-PR_IMPLEMENT(void*) PR_GetThreadPrivate(PRUintn index) |
-{ |
- PRThread *self = PR_GetCurrentThread(); |
- void *tpd = ((NULL == self->privateData) || (index >= self->tpdLength)) ? |
- NULL : self->privateData[index]; |
- |
- return tpd; |
-} |
- |
-/* |
-** Destroy the thread's private data, if any exists. This is called at |
-** thread termination time only. There should be no threading issues |
-** since this is being called by the thread itself. |
-*/ |
-void _PR_DestroyThreadPrivate(PRThread* self) |
-{ |
-#define _PR_TPD_DESTRUCTOR_ITERATIONS 4 |
- |
- if (NULL != self->privateData) /* we have some */ |
- { |
- PRBool clean; |
- PRUint32 index; |
- PRInt32 passes = _PR_TPD_DESTRUCTOR_ITERATIONS; |
- PR_ASSERT(0 != self->tpdLength); |
- do |
- { |
- clean = PR_TRUE; |
- for (index = 0; index < self->tpdLength; ++index) |
- { |
- void *priv = self->privateData[index]; /* extract */ |
- if (NULL != priv) /* we have data at this index */ |
- { |
- if (NULL != _pr_tpd_destructors[index]) |
- { |
- self->privateData[index] = NULL; /* precondition */ |
- (*_pr_tpd_destructors[index])(priv); /* destroy */ |
- clean = PR_FALSE; /* unknown side effects */ |
- } |
- } |
- } |
- } while ((--passes > 0) && !clean); /* limit # of passes */ |
- /* |
- ** We give up after a fixed number of passes. Any non-NULL |
- ** thread-private data value with a registered destructor |
- ** function is not destroyed. |
- */ |
- memset(self->privateData, 0, self->tpdLength * sizeof(void*)); |
- } |
-} /* _PR_DestroyThreadPrivate */ |
- |
-#endif /* !XP_BEOS */ |