📄 ntthread.c
字号:
int nativePri; BOOL rv; if (newPri < PR_PRIORITY_FIRST) { newPri = PR_PRIORITY_FIRST; } else if (newPri > PR_PRIORITY_LAST) { newPri = PR_PRIORITY_LAST; } switch (newPri) { case PR_PRIORITY_LOW: nativePri = THREAD_PRIORITY_BELOW_NORMAL; break; case PR_PRIORITY_NORMAL: nativePri = THREAD_PRIORITY_NORMAL; break; case PR_PRIORITY_HIGH: nativePri = THREAD_PRIORITY_ABOVE_NORMAL; break; case PR_PRIORITY_URGENT: nativePri = THREAD_PRIORITY_HIGHEST; } rv = SetThreadPriority(thread->handle, nativePri); PR_ASSERT(rv); if (!rv) { PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_SetThreadPriority: can't set thread priority\n")); } return;}void_PR_MD_CLEAN_THREAD(PRThread *thread){ BOOL rv; if (thread->md.acceptex_buf) { PR_DELETE(thread->md.acceptex_buf); } if (thread->md.xmit_bufs) { PR_DELETE(thread->md.xmit_bufs); } if (thread->md.blocked_sema) { rv = CloseHandle(thread->md.blocked_sema); PR_ASSERT(rv); thread->md.blocked_sema = 0; } if (_native_threads_only) { if (thread->md.thr_event) { rv = CloseHandle(thread->md.thr_event); PR_ASSERT(rv); thread->md.thr_event = 0; } } if (thread->md.handle) { rv = CloseHandle(thread->md.handle); PR_ASSERT(rv); thread->md.handle = 0; } /* Don't call DeleteFiber on current fiber or we'll kill the whole thread. * Don't call free(thread) until we've switched off the thread. * So put this fiber (or thread) on a list to be deleted by the idle * fiber next time we have a chance. */ if (!(thread->flags & (_PR_ATTACHED|_PR_GLOBAL_SCOPE))) { _MD_LOCK(&_nt_idleLock); _nt_idleCount++; PR_APPEND_LINK(&thread->links, &_nt_idleList); _MD_UNLOCK(&_nt_idleLock); }}void_PR_MD_EXIT_THREAD(PRThread *thread){ BOOL rv; if (thread->md.acceptex_buf) { PR_DELETE(thread->md.acceptex_buf); } if (thread->md.xmit_bufs) { PR_DELETE(thread->md.xmit_bufs); } if (thread->md.blocked_sema) { rv = CloseHandle(thread->md.blocked_sema); PR_ASSERT(rv); thread->md.blocked_sema = 0; } if (_native_threads_only) { if (thread->md.thr_event) { rv = CloseHandle(thread->md.thr_event); PR_ASSERT(rv); thread->md.thr_event = 0; } } if (thread->md.handle) { rv = CloseHandle(thread->md.handle); PR_ASSERT(rv); thread->md.handle = 0; } if (thread->flags & _PR_GLOBAL_SCOPE) { _MD_SET_CURRENT_THREAD(NULL); }}void_PR_MD_EXIT(PRIntn status){ _exit(status);}#ifdef HAVE_FIBERSvoid_pr_fiber_mainline(void *unused) { PRThread *fiber = _PR_MD_CURRENT_THREAD(); POST_SWITCH_WORK(); fiber->md.fiber_fn(fiber->md.fiber_arg);}PRThread *_PR_MD_CREATE_USER_THREAD( PRUint32 stacksize, void (*start)(void *), void *arg){ PRThread *thread; if ( (thread = PR_NEW(PRThread)) == NULL ) { return NULL; } memset(thread, 0, sizeof(PRThread)); thread->md.fiber_fn = start; thread->md.fiber_arg = arg; thread->md.fiber_stacksize = stacksize; return thread;}void_PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *thread){ thread->md.fiber_id = ConvertThreadToFiber(NULL); PR_ASSERT(thread->md.fiber_id); _MD_SET_CURRENT_THREAD(thread); _MD_SET_LAST_THREAD(thread); thread->no_sched = 1; return;}void_PR_MD_INIT_CONTEXT(PRThread *thread, char *top, void (*start) (void), PRBool *status){ thread->md.fiber_fn = (void (*)(void *))start; thread->md.fiber_id = CreateFiber(thread->md.fiber_stacksize, (LPFIBER_START_ROUTINE)_pr_fiber_mainline, NULL); if (thread->md.fiber_id != 0) *status = PR_TRUE; else { DWORD oserror = GetLastError(); PRErrorCode prerror; if (oserror == ERROR_NOT_ENOUGH_MEMORY) { prerror = PR_OUT_OF_MEMORY_ERROR; } else { prerror = PR_UNKNOWN_ERROR; } PR_SetError(prerror, oserror); *status = PR_FALSE; }}void_PR_MD_SWITCH_CONTEXT(PRThread *thread){ PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); thread->md.fiber_last_error = GetLastError(); _PR_Schedule();}void_PR_MD_RESTORE_CONTEXT(PRThread *thread){ PRThread *me = _PR_MD_CURRENT_THREAD(); PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); /* The user-level code for yielding will happily add ourselves to the runq * and then switch to ourselves; the NT fibers can't handle switching to * ourselves. */ if (thread != me) { SetLastError(thread->md.fiber_last_error); _MD_SET_CURRENT_THREAD(thread); _PR_MD_SET_LAST_THREAD(me); thread->no_sched = 1; SwitchToFiber(thread->md.fiber_id); POST_SWITCH_WORK(); }}#endif /* HAVE_FIBERS */PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ){ int rv; rv = SetThreadAffinityMask(thread->md.handle, mask); return rv?0:-1;}PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask){ PRInt32 rv, system_mask; rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask); return rv?0:-1;}void _PR_MD_SUSPEND_CPU(_PRCPU *cpu) { _PR_MD_SUSPEND_THREAD(cpu->thread);}void_PR_MD_RESUME_CPU(_PRCPU *cpu){ _PR_MD_RESUME_THREAD(cpu->thread);}void_PR_MD_SUSPEND_THREAD(PRThread *thread){ if (_PR_IS_NATIVE_THREAD(thread)) { /* ** There seems to be some doubt about whether or not SuspendThread ** is a synchronous function. The test afterwards is to help veriry ** that it is, which is what Microsoft says it is. */ PRUintn rv = SuspendThread(thread->md.handle); PR_ASSERT(0xffffffffUL != rv); }}void_PR_MD_RESUME_THREAD(PRThread *thread){ if (_PR_IS_NATIVE_THREAD(thread)) { ResumeThread(thread->md.handle); }}PRThread*_MD_CURRENT_THREAD(void){PRThread *thread; thread = _MD_GET_ATTACHED_THREAD(); if (NULL == thread) { thread = _PRI_AttachThread( PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); } PR_ASSERT(thread != NULL); return thread;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -