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

📄 nt.cc

📁 编译工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
    //    // Now invoke the thread function with the given argument.    //    if (me->fn_void != NULL) {	(*me->fn_void)(me->thread_arg);	omni_thread::exit();    }    if (me->fn_ret != NULL) {	void* return_value = (*me->fn_ret)(me->thread_arg);	omni_thread::exit(return_value);    }    if (me->detached) {	me->run(me->thread_arg);	omni_thread::exit();    } else {	void* return_value = me->run_undetached(me->thread_arg);	omni_thread::exit(return_value);    }    // should never get here.#ifndef __BCPLUSPLUS__    return 0;#endif}//// Constructors for omni_thread - set up the thread object but don't// start it running.//// construct a detached thread running a given function.omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri){    common_constructor(arg, pri, 1);    fn_void = fn;    fn_ret = NULL;}// construct an undetached thread running a given function.omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri){    common_constructor(arg, pri, 0);    fn_void = NULL;    fn_ret = fn;}// construct a thread which will run either run() or run_undetached().omni_thread::omni_thread(void* arg, priority_t pri){    common_constructor(arg, pri, 1);    fn_void = NULL;    fn_ret = NULL;}// common part of all constructors.voidomni_thread::common_constructor(void* arg, priority_t pri, int det){    _state = STATE_NEW;    _priority = pri;    next_id_mutex->lock();    _id = next_id++;    next_id_mutex->unlock();    thread_arg = arg;    detached = det;	// may be altered in start_undetached()    cond_semaphore = CreateSemaphore(NULL, 0, SEMAPHORE_MAX, NULL);    if (cond_semaphore == NULL)	throw omni_thread_fatal(GetLastError());    cond_next = cond_prev = NULL;    cond_waiting = FALSE;    handle = NULL;    _dummy       = 0;    _values      = 0;    _value_alloc = 0;}//// Destructor for omni_thread.//omni_thread::~omni_thread(void){    DB(cerr << "destructor called for thread " << id() << endl);    if (_values) {        for (key_t i=0; i < _value_alloc; i++) {	    if (_values[i]) {	        delete _values[i];	    }        }	delete [] _values;    }    if (handle && !CloseHandle(handle))	throw omni_thread_fatal(GetLastError());    if (cond_semaphore && !CloseHandle(cond_semaphore))	throw omni_thread_fatal(GetLastError());}//// Start the thread//voidomni_thread::start(void){    omni_mutex_lock l(mutex);    if (_state != STATE_NEW)	throw omni_thread_invalid();#ifndef __BCPLUSPLUS__    // MSVC++ or compatiable    unsigned int t;    handle = (HANDLE)_beginthreadex(                        NULL,			stack_size,			omni_thread_wrapper,			(LPVOID)this,			CREATE_SUSPENDED, 			&t);    nt_id = t;    if (handle == NULL)      throw omni_thread_fatal(GetLastError());#else    // Borland C++    handle = (HANDLE)_beginthreadNT(omni_thread_wrapper,				    stack_size,				    (void*)this,				    NULL,				    CREATE_SUSPENDED,				    &nt_id);    if (handle == INVALID_HANDLE_VALUE)      throw omni_thread_fatal(errno);#endif    if (!SetThreadPriority(handle, nt_priority(_priority)))      throw omni_thread_fatal(GetLastError());    if (ResumeThread(handle) == 0xffffffff)	throw omni_thread_fatal(GetLastError());    _state = STATE_RUNNING;}//// Start a thread which will run the member function run_undetached().//voidomni_thread::start_undetached(void){    if ((fn_void != NULL) || (fn_ret != NULL))	throw omni_thread_invalid();    detached = 0;    start();}//// join - simply check error conditions & call WaitForSingleObject.//voidomni_thread::join(void** status){    mutex.lock();    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {	mutex.unlock();	throw omni_thread_invalid();    }    mutex.unlock();    if (this == self())	throw omni_thread_invalid();    if (detached)	throw omni_thread_invalid();    DB(cerr << "omni_thread::join: doing WaitForSingleObject\n");    if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0)	throw omni_thread_fatal(GetLastError());    DB(cerr << "omni_thread::join: WaitForSingleObject succeeded\n");    if (status)      *status = return_val;    delete this;}//// Change this thread's priority.//voidomni_thread::set_priority(priority_t pri){    omni_mutex_lock l(mutex);    if (_state != STATE_RUNNING)	throw omni_thread_invalid();    _priority = pri;    if (!SetThreadPriority(handle, nt_priority(pri)))	throw omni_thread_fatal(GetLastError());}//// create - construct a new thread object and start it running.  Returns thread// object if successful, null pointer if not.//// detached versionomni_thread*omni_thread::create(void (*fn)(void*), void* arg, priority_t pri){    omni_thread* t = new omni_thread(fn, arg, pri);    t->start();    return t;}// undetached versionomni_thread*omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri){    omni_thread* t = new omni_thread(fn, arg, pri);    t->start();    return t;}//// exit() _must_ lock the mutex even in the case of a detached thread.  This is// because a thread may run to completion before the thread that created it has// had a chance to get out of start().  By locking the mutex we ensure that the// creating thread must have reached the end of start() before we delete the// thread object.  Of course, once the call to start() returns, the user can// still incorrectly refer to the thread object, but that's their problem.//voidomni_thread::exit(void* return_value){    omni_thread* me = self();    if (me)      {	me->mutex.lock();	me->_state = STATE_TERMINATED;	me->mutex.unlock();	DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "	   << me->detached << " return value " << return_value << endl);	if (me->_values) {	  for (key_t i=0; i < me->_value_alloc; i++) {	    if (me->_values[i]) {	      delete me->_values[i];	    }	  }	  delete [] me->_values;	  me->_values = 0;	}	if (me->detached) {	  delete me;	} else {	  me->return_val = return_value;	}      }    else      {	DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);      }#ifndef __BCPLUSPLUS__    // MSVC++ or compatiable    //   _endthreadex() does not automatically closes the thread handle.    //   The omni_thread dtor closes the thread handle.    _endthreadex(0);#else    // Borland C++    //   _endthread() does not automatically closes the thread handle.    //   _endthreadex() is only available if __MFC_COMPAT__ is defined and    //   all it does is to call _endthread().    _endthread();#endif}omni_thread*omni_thread::self(void){    LPVOID me;    me = TlsGetValue(self_tls_index);    if (me == NULL) {      DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);    }    return (omni_thread*)me;}voidomni_thread::yield(void){    Sleep(0);}#define MAX_SLEEP_SECONDS (DWORD)4294966	// (2**32-2)/1000voidomni_thread::sleep(unsigned long secs, unsigned long nanosecs){    if (secs <= MAX_SLEEP_SECONDS) {	Sleep(secs * 1000 + nanosecs / 1000000);	return;    }    DWORD no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;    for (DWORD i = 0; i < no_of_max_sleeps; i++)	Sleep(MAX_SLEEP_SECONDS * 1000);    Sleep((secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);}voidomni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,		      unsigned long rel_sec, unsigned long rel_nsec){    get_time_now(abs_sec, abs_nsec);    *abs_nsec += rel_nsec;    *abs_sec += rel_sec + *abs_nsec / 1000000000;    *abs_nsec = *abs_nsec % 1000000000;}intomni_thread::nt_priority(priority_t pri){    switch (pri) {    case PRIORITY_LOW:	return THREAD_PRIORITY_LOWEST;    case PRIORITY_NORMAL:	return THREAD_PRIORITY_NORMAL;    case PRIORITY_HIGH:	return THREAD_PRIORITY_HIGHEST;    }    throw omni_thread_invalid();    return 0; /* keep msvc++ happy */}static voidget_time_now(unsigned long* abs_sec, unsigned long* abs_nsec){    static int days_in_preceding_months[12]	= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };    static int days_in_preceding_months_leap[12]	= { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };    SYSTEMTIME st;    GetSystemTime(&st);    *abs_nsec = st.wMilliseconds * 1000000;    // this formula should work until 1st March 2100    DWORD days = ((st.wYear - 1970) * 365 + (st.wYear - 1969) / 4		  + ((st.wYear % 4)		     ? days_in_preceding_months[st.wMonth - 1]		     : days_in_preceding_months_leap[st.wMonth - 1])		  + st.wDay - 1);    *abs_sec = st.wSecond + 60 * (st.wMinute + 60 * (st.wHour + 24 * days));}voidomni_thread::stacksize(unsigned long sz){  stack_size = sz;}unsigned longomni_thread::stacksize(){  return stack_size;}//// Dummy thread//class omni_thread_dummy : public omni_thread {public:  inline omni_thread_dummy() : omni_thread()  {    _dummy = 1;    _state = STATE_RUNNING;    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),			 GetCurrentProcess(), &handle,			 0, FALSE, DUPLICATE_SAME_ACCESS))      throw omni_thread_fatal(GetLastError());    nt_id = GetCurrentThreadId();    if (!TlsSetValue(self_tls_index, (LPVOID)this))      throw omni_thread_fatal(GetLastError());  }  inline ~omni_thread_dummy()  {    if (!TlsSetValue(self_tls_index, (LPVOID)0))      throw omni_thread_fatal(GetLastError());  }};omni_thread*omni_thread::create_dummy(){  if (omni_thread::self())    throw omni_thread_invalid();  return new omni_thread_dummy;}voidomni_thread::release_dummy(){  omni_thread* self = omni_thread::self();  if (!self || !self->_dummy)    throw omni_thread_invalid();  omni_thread_dummy* dummy = (omni_thread_dummy*)self;  delete dummy;}#if defined(__DMC__) && defined(_WINDLL)BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){  return TRUE;}#endif#define INSIDE_THREAD_IMPL_CC#include "threaddata.cc"#undef INSIDE_THREAD_IMPL_CC

⌨️ 快捷键说明

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