⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btthread.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
					PRThreadStack *stack){	/* PR_GetCurrentThread() will attach a thread if necessary */	return PR_GetCurrentThread();}PR_IMPLEMENT(void)	PR_DetachThread(){	/* we don't support detaching */}PR_IMPLEMENT(PRStatus)    PR_JoinThread (PRThread* thred){    status_t eval, status;    PR_ASSERT(thred != NULL);	if ((thred->state & BT_THREAD_JOINABLE) == 0)    {	PR_SetError( PR_INVALID_ARGUMENT_ERROR, 0 );	return( PR_FAILURE );    }	/* synchronize access to the thread's joinSem */	PR_Lock(joinSemLock);		if (thred->md.is_joining)	{		/* another thread is already waiting to join the specified		   thread - we must fail */		PR_Unlock(joinSemLock);		return PR_FAILURE;	}	/* let others know we are waiting to join */	thred->md.is_joining = PR_TRUE;	if (thred->md.joinSem == B_ERROR)	{		/* the thread hasn't finished yet - it is our responsibility to		   allocate a joinSem and wait on it */		thred->md.joinSem = create_sem(0, "join sem");		/* we're done changing the joinSem now */		PR_Unlock(joinSemLock);		/* wait for the thread to finish */		while (acquire_sem(thred->md.joinSem) == B_INTERRUPTED);	}	else	{		/* the thread has already finished, and has allocated the		   joinSem itself - let it know it can finally die */		delete_sem(thred->md.joinSem);				PR_Unlock(joinSemLock);    }	/* make sure the thread is dead */    wait_for_thread(thred->md.tid, &eval);    return PR_SUCCESS;}PR_IMPLEMENT(PRThread*)    PR_GetCurrentThread (){    PRThread* thred;    if (!_pr_initialized) _PR_ImplicitInitialization();    thred = (PRThread *)tls_get( tls_prThreadSlot);	if (thred == NULL)	{		/* this thread doesn't have a PRThread structure (it must be		   a native thread not created by the NSPR) - assimilate it */		thred = _bt_AttachThread();	}    PR_ASSERT(NULL != thred);    return thred;}PR_IMPLEMENT(PRThreadScope)    PR_GetThreadScope (const PRThread* thred){    PR_ASSERT(thred != NULL);    return PR_GLOBAL_THREAD;}PR_IMPLEMENT(PRThreadType)    PR_GetThreadType (const PRThread* thred){    PR_ASSERT(thred != NULL);    return (thred->state & BT_THREAD_SYSTEM) ?        PR_SYSTEM_THREAD : PR_USER_THREAD;}PR_IMPLEMENT(PRThreadState)    PR_GetThreadState (const PRThread* thred){    PR_ASSERT(thred != NULL);    return (thred->state & BT_THREAD_JOINABLE)?    					PR_JOINABLE_THREAD: PR_UNJOINABLE_THREAD;}PR_IMPLEMENT(PRThreadPriority)    PR_GetThreadPriority (const PRThread* thred){    PR_ASSERT(thred != NULL);    return thred->priority;}  /* PR_GetThreadPriority */PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred,                                        PRThreadPriority newPri){    PRUint32 bePriority;    PR_ASSERT( thred != NULL );    thred->priority = newPri;    bePriority = _bt_MapNSPRToNativePriority( newPri );    set_thread_priority( thred->md.tid, bePriority );}PR_IMPLEMENT(PRStatus)    PR_NewThreadPrivateIndex (PRUintn* newIndex,                              PRThreadPrivateDTOR destructor){	int32    index;    if (!_pr_initialized) _PR_ImplicitInitialization();	/* reserve the next available tpd slot */	index = atomic_add( &tpd_slotsUsed, 1 );	if (index >= BT_TPD_LIMIT)	{		/* no slots left - decrement value, then fail */		atomic_add( &tpd_slotsUsed, -1 );		PR_SetError( PR_TPD_RANGE_ERROR, 0 );	    return( PR_FAILURE );	}	/* allocate a beos-native TLS slot for this index (the new slot	   automatically contains NULL) */	tpd_beosTLSSlots[index] = tls_allocate();	/* remember the destructor */	tpd_dtors[index] = destructor;    *newIndex = (PRUintn)index;    return( PR_SUCCESS );}PR_IMPLEMENT(PRStatus)    PR_SetThreadPrivate (PRUintn index, void* priv){	void *oldValue;    /*    ** Sanity checking    */    if(index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)    {		PR_SetError( PR_TPD_RANGE_ERROR, 0 );	return( PR_FAILURE );    }	/* if the old value isn't NULL, and the dtor for this slot isn't	   NULL, we must destroy the data */	oldValue = tls_get(tpd_beosTLSSlots[index]);	if (oldValue != NULL && tpd_dtors[index] != NULL)		(*tpd_dtors[index])(oldValue);	/* save new value */	tls_set(tpd_beosTLSSlots[index], priv);	    return( PR_SUCCESS );	}PR_IMPLEMENT(void*)    PR_GetThreadPrivate (PRUintn index){	/* make sure the index is valid */	if (index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)    {   		PR_SetError( PR_TPD_RANGE_ERROR, 0 );		return NULL;    }	/* return the value */	return tls_get( tpd_beosTLSSlots[index] );	}PR_IMPLEMENT(PRStatus)    PR_Interrupt (PRThread* thred){    PRIntn rv;    PR_ASSERT(thred != NULL);    /*    ** there seems to be a bug in beos R5 in which calling    ** resume_thread() on a blocked thread returns B_OK instead    ** of B_BAD_THREAD_STATE (beos bug #20000422-19095).  as such,    ** to interrupt a thread, we will simply suspend then resume it    ** (no longer call resume_thread(), check for B_BAD_THREAD_STATE,    ** the suspend/resume to wake up a blocked thread).  this wakes    ** up blocked threads properly, and doesn't hurt unblocked threads    ** (they simply get stopped then re-started immediately)    */    rv = suspend_thread( thred->md.tid );    if( rv != B_NO_ERROR )    {        /* this doesn't appear to be a valid thread_id */        PR_SetError( PR_UNKNOWN_ERROR, rv );        return PR_FAILURE;    }    rv = resume_thread( thred->md.tid );    if( rv != B_NO_ERROR )    {        PR_SetError( PR_UNKNOWN_ERROR, rv );        return PR_FAILURE;    }    return PR_SUCCESS;}PR_IMPLEMENT(void)    PR_ClearInterrupt (){}PR_IMPLEMENT(PRStatus)    PR_Yield (){    /* we just sleep for long enough to cause a reschedule (100       microseconds) */    snooze(100);}#define BT_MILLION 1000000ULPR_IMPLEMENT(PRStatus)    PR_Sleep (PRIntervalTime ticks){    bigtime_t tps;    status_t status;    if (!_pr_initialized) _PR_ImplicitInitialization();    tps = PR_IntervalToMicroseconds( ticks );    status = snooze(tps);    if (status == B_NO_ERROR) return PR_SUCCESS;    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, status);    return PR_FAILURE;}PR_IMPLEMENT(PRStatus)    PR_Cleanup (){    PRThread *me = PR_CurrentThread();    PR_ASSERT(me->state & BT_THREAD_PRIMORD);    if ((me->state & BT_THREAD_PRIMORD) == 0) {        return PR_FAILURE;    }    PR_Lock( bt_book.ml );	if (bt_book.threadCount != 0)    {		/* we'll have to wait for some threads to finish - create a		   sem to block on */		bt_book.cleanUpSem = create_sem(0, "cleanup sem");    }    PR_Unlock( bt_book.ml );	/* note that, if all the user threads were already dead, we	   wouldn't have created a sem above, so this acquire_sem()	   will fail immediately */	while (acquire_sem(bt_book.cleanUpSem) == B_INTERRUPTED);    return PR_SUCCESS;}PR_IMPLEMENT(void)    PR_ProcessExit (PRIntn status){    exit(status);}PRThread *_bt_AttachThread(){	PRThread *thread;	thread_info tInfo;	/* make sure this thread doesn't already have a PRThread structure */	PR_ASSERT(tls_get(tls_prThreadSlot) == NULL);	/* allocate a PRThread structure for this thread */	thread = PR_NEWZAP(PRThread);	if (thread == NULL)	{		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);		return NULL;	}	/* get the native thread's current state */	get_thread_info(find_thread(NULL), &tInfo);	/* initialize new PRThread */	thread->md.tid = tInfo.thread;	thread->md.joinSem = B_ERROR;	thread->priority = _bt_MapNativeToNSPRPriority(tInfo.priority);	/* attached threads are always non-joinable user threads */	thread->state = 0;	/* increment user thread count */	PR_Lock(bt_book.ml);	bt_book.threadCount++;	PR_Unlock(bt_book.ml);	/* store this thread's PRThread */	tls_set(tls_prThreadSlot, thread);		/* the thread must call _bt_CleanupThread() before it dies, in order	   to clean up its PRThread, synchronize with the primordial thread,	   etc. */	on_exit_thread(_bt_CleanupThread, NULL);		return thread;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -