void Logger::logError(LogLevel level, char *fmt, ...) { if (level == LOGPASS) _pass++; if (level == LOGFAILURE) _fail++; if (level == LOGWARNING) _warning++; if (level <= _logLevel) { char buf[1024]; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); char *module = logLevelStr[level]; char *threadName = (char *)PR_GetThreadPrivate(_threadNameKey); PR_Lock(_logLock); if (threadName) fprintf(stdout, "%s: (%s) %s\n", module, threadName, buf); else fprintf(stdout, "%s: %s\n", module, buf); PR_Unlock(_logLock); }; };
// Asuming we have a valid thread state, release the Python lock. void PyXPCOM_InterpreterLock_Release() { ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex); NS_ABORT_IF_FALSE(pData, "Have no thread data for this thread!"); PyThreadState *thisThreadState = pData->ts; PyEval_ReleaseThread(thisThreadState); }
// static void Mark(PRUint32 aType, void * aItem, const char * aText, const char * aText2) { #ifdef MOZ_VISUAL_EVENT_TRACER if (!gInitialized) return; if (aType == eNone) return; if (!CheckEventFilters(aType, aItem, aText)) // Events use just aText return; RecordBatch * threadLogPrivate = static_cast<RecordBatch *>( PR_GetThreadPrivate(gThreadPrivateIndex)); if (!threadLogPrivate) { // Deletion is made by the flushing thread threadLogPrivate = new RecordBatch(); PR_SetThreadPrivate(gThreadPrivateIndex, threadLogPrivate); } Record * record = threadLogPrivate->mNextRecord; record->mType = aType; record->mTime = (mozilla::TimeStamp::Now() - gProfilerStart).ToMilliseconds(); record->mItem = aItem; record->mText = PL_strdup(aText); record->mText2 = aText2 ? PL_strdup(aText2) : nsnull; ++threadLogPrivate->mNextRecord; if (threadLogPrivate->mNextRecord == threadLogPrivate->mRecordsTail) { // This calls RecordBatch::FlushBatch(threadLogPrivate) PR_SetThreadPrivate(gThreadPrivateIndex, nsnull); } #endif }
static TimelineThreadData *GetThisThreadData() { NS_ABORT_IF_FALSE(gTLSIndex!=BAD_TLS_INDEX, "Our TLS not initialized"); TimelineThreadData *new_data = nsnull; TimelineThreadData *data = (TimelineThreadData *)PR_GetThreadPrivate(gTLSIndex); if (data == nsnull) { // First request for this thread - allocate it. new_data = new TimelineThreadData(); if (!new_data) goto done; // Fill it new_data->timers = PL_NewHashTable(100, PL_HashString, PL_CompareStrings, PL_CompareValues, NULL, NULL); if (new_data->timers==NULL) goto done; new_data->initTime = PR_Now(); NS_WARN_IF_FALSE(!gTimelineDisabled, "Why are we creating new state when disabled?"); new_data->disabled = PR_FALSE; data = new_data; new_data = nsnull; PR_SetThreadPrivate(gTLSIndex, data); } done: if (new_data) // eeek - error during creation! delete new_data; NS_WARN_IF_FALSE(data, "TimelineService could not get thread-local data"); return data; }
/* * Get current thread-local JSThread info, creating one if it doesn't exist. * Each thread has a unique JSThread pointer. * * Since we are dealing with thread-local data, no lock is needed. * * Return a pointer to the thread local info, NULL if the system runs out * of memory, or it failed to set thread private data (neither case is very * likely; both are probably due to out-of-memory). It is up to the caller * to report an error, if possible. */ JSThread * js_GetCurrentThread(JSRuntime *rt) { JSThread *thread; thread = (JSThread *)PR_GetThreadPrivate(threadTPIndex); if (!thread) { thread = (JSThread *) calloc(1, sizeof(JSThread)); if (!thread) return NULL; if (PR_FAILURE == PR_SetThreadPrivate(threadTPIndex, thread)) { free(thread); return NULL; } JS_INIT_CLIST(&thread->contextList); thread->id = js_CurrentThreadId(); /* js_SetContextThread initialize gcFreeLists as necessary. */ #ifdef DEBUG memset(thread->gcFreeLists, JS_FREE_PATTERN, sizeof(thread->gcFreeLists)); #endif } return thread; }
// static XPCPerThreadData* XPCPerThreadData::GetDataImpl(JSContext *cx) { XPCPerThreadData* data; if(!gLock) { gLock = PR_NewLock(); if(!gLock) return nsnull; } if(gTLSIndex == BAD_TLS_INDEX) { nsAutoLock lock(gLock); // check again now that we have the lock... if(gTLSIndex == BAD_TLS_INDEX) { if(PR_FAILURE == PR_NewThreadPrivateIndex(&gTLSIndex, xpc_ThreadDataDtorCB)) { NS_ERROR("PR_NewThreadPrivateIndex failed!"); gTLSIndex = BAD_TLS_INDEX; return nsnull; } } } data = (XPCPerThreadData*) PR_GetThreadPrivate(gTLSIndex); if(!data) { data = new XPCPerThreadData(); if(!data || !data->IsValid()) { NS_ERROR("new XPCPerThreadData() failed!"); if(data) delete data; return nsnull; } if(PR_FAILURE == PR_SetThreadPrivate(gTLSIndex, data)) { NS_ERROR("PR_SetThreadPrivate failed!"); delete data; return nsnull; } } if(cx && !sMainJSThread && NS_IsMainThread()) { sMainJSThread = cx->thread; sMainThreadData = data; sMainThreadData->mThread = PR_GetCurrentThread(); } return data; }
// Free the thread state for the current thread // (Presumably previously create with a call to // PyXPCOM_ThreadState_Ensure) void PyXPCOM_ThreadState_Free() { ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex); if (!pData) return; PyThreadState *thisThreadState = pData->ts; PyThreadState_Delete(thisThreadState); PR_SetThreadPrivate(tlsIndex, NULL); nsMemory::Free(pData); }
nsAutoLockBase::nsAutoLockBase(void* addr, nsAutoLockType type) { if (LockStackTPI == PRUintn(-1)) InitAutoLockStatics(); nsAutoLockBase* stackTop = (nsAutoLockBase*) PR_GetThreadPrivate(LockStackTPI); if (stackTop) { if (stackTop->mAddr == addr) { // Ignore reentry: it's legal for monitors, and NSPR will assert // if you reenter a PRLock. } else if (!addr) { // Ignore null addresses: the caller promises not to use the // lock at all, and NSPR will assert if you enter it. } else { const void* node = #ifdef NS_TRACE_MALLOC_XXX NS_GetStackTrace(1) #else nsnull #endif ; nsNamedVector* vec1; nsNamedVector* vec2; PRUint32 i2; if (!WellOrdered(stackTop->mAddr, addr, node, &i2, &vec1, &vec2)) { char buf[128]; PR_snprintf(buf, sizeof buf, "Potential deadlock between %s%s@%p and %s%s@%p", vec1->mName ? vec1->mName : "", LockTypeNames[stackTop->mType], stackTop->mAddr, vec2->mName ? vec2->mName : "", LockTypeNames[type], addr); #ifdef NS_TRACE_MALLOC_XXX fprintf(stderr, "\n*** %s\n\nCurrent stack:\n", buf); NS_DumpStackTrace(node, stderr); fputs("\nPrevious stack:\n", stderr); NS_DumpStackTrace(vec2->mInnerSites.ElementAt(i2), stderr); putc('\n', stderr); #endif NS_ERROR(buf); } } } mAddr = addr; mDown = stackTop; mType = type; if (mAddr) (void) PR_SetThreadPrivate(LockStackTPI, this); }
static void AssertActivityIsLegal() { if (gActivityTLS == BAD_TLS_INDEX || PR_GetThreadPrivate(gActivityTLS)) { if (PR_GetEnv("MOZ_FATAL_STATIC_XPCOM_CTORS_DTORS")) { NS_RUNTIMEABORT(kStaticCtorDtorWarning); } else { NS_WARNING(kStaticCtorDtorWarning); } } }
//------------------------------------------------------------------------- // // Return the nsIToolkit for the current thread. If a toolkit does not // yet exist, then one will be created... // //------------------------------------------------------------------------- NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult) { nsIToolkit* toolkit = nsnull; nsresult rv = NS_OK; PRStatus status; #ifdef DEBUG printf("TK-GetCTK\n"); #endif // Create the TLS index the first time through... if (0 == gToolkitTLSIndex) { status = PR_NewThreadPrivateIndex(&gToolkitTLSIndex, NULL); if (PR_FAILURE == status) { rv = NS_ERROR_FAILURE; } } if (NS_SUCCEEDED(rv)) { toolkit = (nsIToolkit*)PR_GetThreadPrivate(gToolkitTLSIndex); // // Create a new toolkit for this thread... // if (!toolkit) { toolkit = new nsToolkit(); if (!toolkit) { rv = NS_ERROR_OUT_OF_MEMORY; } else { NS_ADDREF(toolkit); toolkit->Init(PR_GetCurrentThread()); // // The reference stored in the TLS is weak. It is removed in the // nsToolkit destructor... // PR_SetThreadPrivate(gToolkitTLSIndex, (void*)toolkit); } } else { NS_ADDREF(toolkit); } *aResult = toolkit; } return rv; }
void nsAutoCMonitor::Enter() { #ifdef DEBUG nsAutoLockBase* stackTop = (nsAutoLockBase*) PR_GetThreadPrivate(LockStackTPI); NS_ASSERTION(stackTop == mDown, "non-LIFO nsAutoCMonitor::Enter"); mDown = stackTop; (void) PR_SetThreadPrivate(LockStackTPI, this); #endif PR_CEnterMonitor(mLockObject); mLockCount += 1; }
void nsAutoLockBase::Hide() { if (!mAddr) return; nsAutoLockBase* curr = (nsAutoLockBase*) PR_GetThreadPrivate(LockStackTPI); nsAutoLockBase* prev = nsnull; while (curr != this) { prev = curr; curr = prev->mDown; } if (!prev) PR_SetThreadPrivate(LockStackTPI, mDown); else prev->mDown = mDown; }
/* * mempool_destroy is a callback which is set to NSPR ThreadPrivateIndex */ static void mempool_destroy() { int i = 0; struct mempool *my_mempool; #ifdef SHARED_MEMPOOL for (i = 0; MEMPOOL_END != mempool[i].mempool_name; i++) { struct mempool_object *object = NULL; if (NULL == mempool[i].mempool_mutex) { /* mutex is NULL; this mempool is not enabled */ continue; } object = mempool[i].mempool_head; mempool[i].mempool_head = NULL; while (NULL != object) { struct mempool_object *next = object->mempool_next; if (NULL != mempool[i].mempool_cleanup_fn) { (mempool[i].mempool_cleanup_fn)((void *)object); } slapi_ch_free((void **)&object); object = next; } PR_DestroyLock(mempool[i].mempool_mutex); mempool[i].mempool_mutex = NULL; } #else my_mempool = (struct mempool *)PR_GetThreadPrivate(mempool_index); if (NULL == my_mempool || my_mempool[0].mempool_name != mempool_names[0]) { /* mempool is not initialized */ return; } for (i = 0; i < MAX_MEMPOOL; i++) { struct mempool_object *object = my_mempool[i].mempool_head; while (NULL != object) { struct mempool_object *next = object->mempool_next; if (NULL != my_mempool[i].mempool_cleanup_fn) { (my_mempool[i].mempool_cleanup_fn)((void *)object); } slapi_ch_free((void **)&object); object = next; } my_mempool[i].mempool_head = NULL; my_mempool[i].mempool_count = 0; } slapi_ch_free((void **)&my_mempool); PR_SetThreadPrivate (mempool_index, (void *)NULL); #endif }
nsAutoUnlockBase::nsAutoUnlockBase(void* addr) { if (addr) { nsAutoLockBase* curr = (nsAutoLockBase*) PR_GetThreadPrivate(LockStackTPI); while (curr && curr->mAddr != addr) curr = curr->mDown; mLock = curr; } else mLock = nsnull; if (mLock) mLock->Hide(); }
void nsAutoMonitor::Enter() { #ifdef DEBUG if (!mAddr) { NS_ERROR("It is not legal to enter a null monitor"); return; } nsAutoLockBase* stackTop = (nsAutoLockBase*) PR_GetThreadPrivate(LockStackTPI); NS_ASSERTION(stackTop == mDown, "non-LIFO nsAutoMonitor::Enter"); mDown = stackTop; (void) PR_SetThreadPrivate(LockStackTPI, this); #endif PR_EnterMonitor(mMonitor); mLockCount += 1; }
/* readonly attribute nsIExceptionManager currentExceptionManager; */ NS_IMETHODIMP nsExceptionService::GetCurrentExceptionManager(nsIExceptionManager * *aCurrentScriptManager) { CHECK_SERVICE_USE_OK(); nsExceptionManager *mgr = (nsExceptionManager *)PR_GetThreadPrivate(tlsIndex); if (mgr == nsnull) { // Stick the new exception object in with no reference count. mgr = new nsExceptionManager(this); if (mgr == nsnull) return NS_ERROR_OUT_OF_MEMORY; PR_SetThreadPrivate(tlsIndex, mgr); // The reference count is held in the thread-list AddThread(mgr); } *aCurrentScriptManager = mgr; NS_ADDREF(*aCurrentScriptManager); return NS_OK; }
/* * Function: prldap_get_thread_private() * Description: retrieve a piece of thread-private data. If not set, * NULL is returned. * Returns: 0 if successful and -1 if not. */ static void * prldap_get_thread_private( PRInt32 tpdindex ) { PRLDAP_TPDHeader *tsdhdr; tsdhdr = (PRLDAP_TPDHeader *)PR_GetThreadPrivate( prldap_tpdindex ); if ( tsdhdr == NULL ) { return( NULL ); /* no thread private data */ } if ( tpdindex >= tsdhdr->ptpdh_tpd_count || tsdhdr->ptpdh_dataitems == NULL ) { return( NULL ); /* fewer data items than requested index */ } return( tsdhdr->ptpdh_dataitems[ tpdindex ] ); }
/* * return memory to memory pool * (Callback cleanup function was intented to release nested memory in the * memory area. Initially, memory had its structure which could point * other memory area. But the current code (#else) expects no structure. * Thus, the cleanup callback is not needed) * The current code (#else) uses the memory pool stored in the * per-thread-private data. */ int mempool_return(int type, void *object, mempool_cleanup_callback cleanup) { PR_ASSERT(type >= 0 && type < MEMPOOL_END); if (!config_get_mempool_switch()) { return LDAP_SUCCESS; /* memory pool: off */ } #ifdef SHARED_MEMPOOL if (NULL == mempool[type].mempool_mutex) { /* mutex is NULL; this mempool is not enabled */ return LDAP_SUCCESS; } PR_Lock(mempool[type].mempool_mutex); ((struct mempool_object *)object)->mempool_next = mempool[type].mempool_head; mempool[type].mempool_head = (struct mempool_object *)object; mempool[type].mempool_cleanup_fn = cleanup; mempool[type].mempool_count++; PR_Unlock(mempool[type].mempool_mutex); return LDAP_SUCCESS; #else { struct mempool *my_mempool; int maxfreelist; my_mempool = (struct mempool *)PR_GetThreadPrivate(mempool_index); if (NULL == my_mempool || my_mempool[0].mempool_name != mempool_names[0]) { /* mempool is not initialized */ mempool_init(&my_mempool); } ((struct mempool_object *)object)->mempool_next = my_mempool[type].mempool_head; maxfreelist = config_get_mempool_maxfreelist(); if ((maxfreelist > 0) && (my_mempool[type].mempool_count > maxfreelist)) { return LDAP_UNWILLING_TO_PERFORM; } else { ((struct mempool_object *)object)->mempool_next = mempool[type].mempool_head; my_mempool[type].mempool_head = (struct mempool_object *)object; my_mempool[type].mempool_cleanup_fn = cleanup; my_mempool[type].mempool_count++; PR_SetThreadPrivate (mempool_index, (void *)my_mempool); return LDAP_SUCCESS; } } #endif }
static error_stack * error_get_my_stack ( void) { PRStatus st; error_stack *rv; PRUintn new_size; PRUint32 new_bytes; error_stack *new_stack; if( INVALID_TPD_INDEX == error_stack_index ) { st = PR_CallOnce(&error_call_once, error_once_function); if( PR_SUCCESS != st ) { return (error_stack *)NULL; } } rv = (error_stack *)PR_GetThreadPrivate(error_stack_index); if( (error_stack *)NULL == rv ) { /* Doesn't exist; create one */ new_size = 16; } else if( rv->header.count == rv->header.space && rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) { /* Too small, expand it */ new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT); } else { /* Okay, return it */ return rv; } new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack); /* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */ new_stack = PR_Calloc(1, new_bytes); if( (error_stack *)NULL != new_stack ) { if( (error_stack *)NULL != rv ) { (void)nsslibc_memcpy(new_stack,rv,rv->header.space); } new_stack->header.space = new_size; } /* Set the value, whether or not the allocation worked */ PR_SetThreadPrivate(error_stack_index, new_stack); return new_stack; }
nsThread * nsThreadManager::GetCurrentThread() { // read thread local storage void *data = PR_GetThreadPrivate(mCurThreadIndex); if (data) return static_cast<nsThread *>(data); if (!mInitialized) { return nsnull; } // OK, that's fine. We'll dynamically create one :-) nsRefPtr<nsThread> thread = new nsThread(); if (!thread || NS_FAILED(thread->InitCurrentThread())) return nsnull; return thread.get(); // reference held in TLS }
/* * Function: prldap_set_thread_private() * Description: store a piece of thread-private data. * Returns: 0 if successful and -1 if not. */ static int prldap_set_thread_private( PRInt32 tpdindex, void *priv ) { PRLDAP_TPDHeader *tsdhdr; if ( tpdindex > prldap_tpd_maxindex ) { return( -1 ); /* bad index */ } tsdhdr = (PRLDAP_TPDHeader *)PR_GetThreadPrivate( prldap_tpdindex ); if ( tsdhdr == NULL || tpdindex >= tsdhdr->ptpdh_tpd_count ) { tsdhdr = prldap_tsd_realloc( tsdhdr, tpdindex ); if ( tsdhdr == NULL ) { return( -1 ); /* realloc failed */ } } tsdhdr->ptpdh_dataitems[ tpdindex ] = priv; return( 0 ); }
// Ensure that we have a Python thread state available to use. // If this is called for the first time on a thread, it will allocate // the thread state. This does NOT change the state of the Python lock. // Returns TRUE if a new thread state was created, or FALSE if a // thread state already existed. PRBool PyXPCOM_ThreadState_Ensure() { ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex); if (pData==NULL) { /* First request on this thread */ /* Check we have an interpreter state */ if (PyXPCOM_InterpreterState==NULL) { Py_FatalError("Can not setup thread state, as have no interpreter state"); } pData = (ThreadData *)nsMemory::Alloc(sizeof(ThreadData)); if (!pData) Py_FatalError("Out of memory allocating thread state."); memset(pData, 0, sizeof(*pData)); if (NS_FAILED( PR_SetThreadPrivate( tlsIndex, pData ) ) ) { NS_ABORT_IF_FALSE(0, "Could not create thread data for this thread!"); Py_FatalError("Could not thread private thread data!"); } pData->ts = PyThreadState_New(PyXPCOM_InterpreterState); return PR_TRUE; // Did create a thread state state } return PR_FALSE; // Thread state was previously created }
/* * get memory from memory pool * The current code (#else) uses the memory pool stored in the * per-thread-private data. */ void * mempool_get(int type) { struct mempool_object *object = NULL; struct mempool *my_mempool; PR_ASSERT(type >= 0 && type < MEMPOOL_END); if (!config_get_mempool_switch()) { return NULL; /* memory pool: off */ } #ifdef SHARED_MEMPOOL if (NULL == mempool[type].mempool_mutex) { /* mutex is NULL; this mempool is not enabled */ return NULL; } PR_Lock(mempool[type].mempool_mutex); object = mempool[type].mempool_head; if (NULL != object) { mempool[type].mempool_head = object->mempool_next; mempool[type].mempool_count--; object->mempool_next = NULL; } PR_Unlock(mempool[type].mempool_mutex); #else my_mempool = (struct mempool *)PR_GetThreadPrivate(mempool_index); if (NULL == my_mempool || my_mempool[0].mempool_name != mempool_names[0]) { /* mempool is not initialized */ return NULL; } object = my_mempool[type].mempool_head; if (NULL != object) { my_mempool[type].mempool_head = object->mempool_next; my_mempool[type].mempool_count--; object->mempool_next = NULL; PR_SetThreadPrivate (mempool_index, (void *)my_mempool); } #endif return object; }
/* * Get current thread-local JSThread info, creating one if it doesn't exist. * Each thread has a unique JSThread pointer. * * Since we are dealing with thread-local data, no lock is needed. * * Return a pointer to the thread local info, NULL if the system runs out * of memory, or it failed to set thread private data (neither case is very * likely; both are probably due to out-of-memory). It is up to the caller * to report an error, if possible. */ JSThread * js_GetCurrentThread(JSRuntime *rt) { JSThread *thread; thread = (JSThread *)PR_GetThreadPrivate(rt->threadTPIndex); if (!thread) { /* New memory is set to 0 so that elements in gcFreeLists are NULL. */ thread = (JSThread *) calloc(1, sizeof(JSThread)); if (!thread) return NULL; if (PR_FAILURE == PR_SetThreadPrivate(rt->threadTPIndex, thread)) { free(thread); return NULL; } JS_INIT_CLIST(&thread->contextList); thread->id = js_CurrentThreadId(); } return thread; }
static inline SessionThreadData *find_thread_data(Session *sn) { NSAPISession *nsn = (NSAPISession *)sn; if (nsn && nsn->thread_data) return nsn->thread_data; HttpRequest *hrq = HttpRequest::CurrentRequest(); if (hrq) { DaemonSession &dsn = hrq->GetDaemonSession(); if (nsn) nsn->thread_data = &dsn.thread_data; return &dsn.thread_data; } // We're being called from a non-DaemonSession thread void *data = PR_GetThreadPrivate(_session_thread_key); if (!data) { data = PERM_CALLOC(sizeof(SessionThreadData)); PR_SetThreadPrivate(_session_thread_key, data); } return (SessionThreadData *)data; }
static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv) { void *pd; PRStatus rv; PRUintn keys; PRThread *thread; char *key_string[] = { "Key #0", "Key #1", "Key #2", "Key #3", "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; fout = PR_STDOUT; did = should = PR_FALSE; for (keys = 0; keys < 4; ++keys) { rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 0; keys < 8; ++keys) { pd = PR_GetThreadPrivate(key[keys]); MY_ASSERT(NULL == pd); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], key_string[keys]); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); for (keys = 4; keys < 8; ++keys) key[keys] = 4096; /* set to invalid value */ did = should = PR_FALSE; for (keys = 4; keys < 8; ++keys) { rv = PR_SetThreadPrivate(key[keys], key_string[keys]); MY_ASSERT(PR_FAILURE == rv); } PrintProgress(__LINE__); did = PR_FALSE; should = PR_TRUE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], key_string[keys]); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = PR_FALSE; should = PR_TRUE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 8; keys < 127; ++keys) { rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); MY_ASSERT(PR_SUCCESS == rv); rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = PR_FALSE; should = PR_TRUE; for (keys = 8; keys < 127; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 8; keys < 127; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } thread = PR_CreateThread( PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); (void)PR_JoinThread(thread); PrintProgress(__LINE__); #if defined(WIN16) printf( "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); #else (void)PR_fprintf( fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); #endif return 0; } /* Tpd */
static void PR_CALLBACK Thread(void *null) { void *pd; PRStatus rv; PRUintn keys; char *key_string[] = { "Key #0", "Key #1", "Key #2", "Key #3", "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; did = should = PR_FALSE; for (keys = 0; keys < 8; ++keys) { pd = PR_GetThreadPrivate(key[keys]); MY_ASSERT(NULL == pd); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], key_string[keys]); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 4; keys < 8; ++keys) { rv = PR_SetThreadPrivate(key[keys], key_string[keys]); MY_ASSERT(PR_FAILURE == rv); } PrintProgress(__LINE__); did = PR_FALSE; should = PR_TRUE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], key_string[keys]); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = PR_FALSE; should = PR_TRUE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 8; keys < 127; ++keys) { rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = PR_FALSE; should = PR_TRUE; for (keys = 8; keys < 127; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = should = PR_FALSE; for (keys = 8; keys < 127; ++keys) { rv = PR_SetThreadPrivate(key[keys], NULL); MY_ASSERT(PR_SUCCESS == rv); } /* put in keys and leave them there for thread exit */ did = should = PR_FALSE; for (keys = 0; keys < 4; ++keys) { rv = PR_SetThreadPrivate(key[keys], key_string[keys]); MY_ASSERT(PR_SUCCESS == rv); } PrintProgress(__LINE__); did = PR_FALSE; should = PR_TRUE; } /* Thread */
void PyXPCOM_ThreadState_Clear() { ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex); PyThreadState *thisThreadState = pData->ts; PyThreadState_Clear(thisThreadState); }
NSAPI_PUBLIC void *systhread_getdata(int key) { return PR_GetThreadPrivate(key); }
RCThreadPrivateData* RCThread::GetPrivateData(PRUintn index) { return (RCThreadPrivateData*)PR_GetThreadPrivate(index); }