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

📄 thread.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{#ifdef WIN32	Thread::sleep(1);   // note: on Win32, Sleep(0) is "optimized" to NOP.#else#ifdef	CCXX_SIG_THREAD_CANCEL	Thread* th = getThread();	sigset_t cancel, old;	sigemptyset(&cancel);	sigaddset(&cancel, CCXX_SIG_THREAD_CANCEL);	if(th && th->_cancel != cancelDisabled && 	   th->_cancel != cancelInitial)		pthread_sigmask(SIG_UNBLOCK, &cancel, &old);#else	pthread_testcancel();#endif#ifdef	HAVE_PTHREAD_YIELD	pthread_yield();#endif#ifdef	CCXX_SIG_THREAD_CANCEL	if(th && th->_cancel != cancelDisabled && th->_cancel != cancelInitial)		pthread_sigmask(SIG_SETMASK, &old, NULL);#endif#endif // WIN32}void Thread::setException(Thread::Throw mode){	Thread *thread = getThread();	thread->priv->_throw = mode;}Thread::Throw Thread::getException(void){	Thread *thread = getThread();	return thread->priv->_throw;}Cancellation::Cancellation(Thread::Cancel cancel){	Thread *thread = getThread();	if(!thread)		return;	prior = thread->getCancel();	thread->setCancel(cancel);}Cancellation::~Cancellation(){	Thread *thread = getThread();	if(!thread)		return;	thread->setCancel(prior);}bool Thread::testCancel(void){#ifdef WIN32	switch(_cancel)	{	case cancelInitial:	case cancelDisabled:		break;	default:		if(WaitForSingleObject(priv->_cancellation, 0) == WAIT_OBJECT_0)		{			if (_cancel == cancelManual)				THROW(InterruptException());			else				exit();		}	}	return false;#else // WIN32#ifdef  CCXX_SIG_THREAD_CANCEL        sigset_t cancel, old;         sigemptyset(&cancel);        sigaddset(&cancel, CCXX_SIG_THREAD_CANCEL);         if(_cancel != cancelDisabled &&           _cancel != cancelInitial)                pthread_sigmask(SIG_UNBLOCK, &cancel, &old);#else        pthread_testcancel();#endif #ifdef  CCXX_SIG_THREAD_CANCEL        if(_cancel != cancelDisabled)                pthread_sigmask(SIG_SETMASK, &old, NULL);#endif	return false;#endif // WIN32} #ifdef WIN32bool Thread::isCancelled(){	return waitThread(priv->_cancellation, 0) == WAIT_OBJECT_0;}DWORD Thread::waitThread(HANDLE hRef, timeout_t timeout){	Thread *th = getThread();	if(th)		return th->waitHandle(hRef, timeout);	else		return WaitForSingleObject(hRef, timeout);}void Thread::sleep(timeout_t timeout) {	Thread *th = getThread();	if(!th)	{		SleepEx(timeout, FALSE);		return;	}	switch(th->_cancel)	{	case cancelInitial:	case cancelDisabled:		SleepEx(timeout, FALSE);		break;	default:		if(WaitForSingleObject(th->priv->_cancellation, timeout) == WAIT_OBJECT_0)		{			if (th->_cancel == cancelManual)				THROW(InterruptException());			else				th->exit();		}	}}DWORD Thread::waitHandle(HANDLE obj, timeout_t timeout) {	HANDLE objects[2];	DWORD stat;	objects[0] = priv->_cancellation;	objects[1] = obj;	// FIXME: what should happen if someone enable cancellation on wait??	switch(_cancel)	{	case cancelInitial:	case cancelDisabled:		return WaitForSingleObject(obj, timeout);	default:		switch(stat = WaitForMultipleObjects(2, objects, false, timeout)) 	{		case WAIT_OBJECT_0:			if (_cancel == cancelManual)				THROW(InterruptException());			else				exit();		case WAIT_OBJECT_0 + 1:			return WAIT_OBJECT_0;		default:			return stat;		}	}}// Entry point linked for default disable thread call, not suitable// for threading library...BOOL WINAPI DllMain(        HANDLE  hDllHandle,        DWORD   dwReason,        LPVOID  lpreserved        ){	switch(dwReason)	{	case DLL_THREAD_DETACH:		DummyThread::CheckDelete();		break;	}        return TRUE ;}#endif // WIN32#ifndef WIN32Thread *Thread::get(void){	Thread *thread;		// fix strange no-init on Solaris        if(!Thread::_main)	{		new (&_mainthread) MainThread();		return &_mainthread;	}	thread = (Thread *)ThreadImpl::_self.getKey();	// class have been deleted, return NULL	if (thread == DUMMY_INVALID_THREAD)		return NULL;	if(!thread)	{		// this Thread will be deleted by ccxx_thread_destruct		thread = new DummyThread;		ThreadImpl::_self.setKey(thread);	}	return thread;}#else // WIN32Thread *Thread::get(void){	Thread *th = (Thread *)_self.getKey();	if (th == DUMMY_INVALID_THREAD) return NULL;	// for no common c++ thread construct a dummy thread	if (!th)		th = new DummyThread();	return th;}unsigned __stdcall Thread::Execute(Thread *th){	_self.setKey(th);	th->yield();	if(th->_start)	{		th->_start->wait();		th->_start = NULL;	}	try	{		th->priv->_tid = GetCurrentThreadId();		if(!th->_name[0])			snprintf(th->_name, sizeof(th->_name), "%d", GetCurrentThreadId());		th->initial();		if(th->getCancel() == cancelInitial) 			th->setCancel(cancelDefault);		th->run();	}	// ignore cancellation exception	catch(const InterruptException&)	{ ; }	th->close();	return 0;}#endif //WIN32#if !defined(WIN32)/* * PosixThread implementation */inline void ThreadImpl::PosixThreadSigHandler(int signo){	Thread	*t = getThread();	PosixThread *th = NULL;#ifdef	CCXX_EXCEPTIONS	if (t) th = dynamic_cast<PosixThread*>(t);#else        if (t) th = (PosixThread*)(t);#endif	if (!th) return;	switch(signo)	{	case SIGHUP:		if(th)			th->onHangup();		break;	case SIGABRT:		if(th)			th->onException();		break;	case SIGPIPE:		if(th)			th->onDisconnect();		break;	case SIGALRM:#ifndef	CCXX_SIG_THREAD_ALARM		if(PosixThread::_timer)		{			PosixThread::_timer->_alarm = 0;			PosixThread::_timer->onTimer();		}		else#endif 		    if(th)			th->onTimer();		break;#ifdef	SIGPOLL	case SIGPOLL:#else	case SIGIO:#endif		if(th)			th->onPolling();		break;	default:		if(th)			th->onSignal(signo);	}}static void ccxx_sig_handler(int signo){	ThreadImpl::PosixThreadSigHandler(signo);}PosixThread::PosixThread(int pri, size_t stack):	Thread(pri,stack){       SysTime::getTime(&_alarm);}void PosixThread::onTimer(void){}void PosixThread::onHangup(void){}void PosixThread::onException(void){}void PosixThread::onDisconnect(void){}void PosixThread::onPolling(void){}void PosixThread::onSignal(int sig){}void PosixThread::setTimer(timeout_t timer, bool periodic){	sigset_t sigs;#ifdef	HAVE_SETITIMER	struct itimerval itimer;		memset(&itimer, 0, sizeof(itimer));	itimer.it_value.tv_usec = (timer * 1000) % 1000000;	itimer.it_value.tv_sec = timer / 1000;	if (periodic) {		itimer.it_interval.tv_usec = itimer.it_value.tv_usec;		itimer.it_interval.tv_sec = itimer.it_value.tv_sec;	}#else	timer /= 1000;#endif#ifndef	CCXX_SIG_THREAD_ALARM		_arm.enterMutex();	_timer = this;#endif       SysTime::getTime(&_alarm);	sigemptyset(&sigs);	sigaddset(&sigs, SIGALRM);	pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);#ifdef	HAVE_SETITIMER	setitimer(ITIMER_REAL, &itimer, NULL);#else	alarm(timer);#endif}	timeout_t PosixThread::getTimer(void) const{#ifdef	HAVE_SETITIMER	struct itimerval itimer;#endif	if(!_alarm)		return 0;#ifdef	HAVE_SETITIMER	getitimer(ITIMER_REAL, &itimer);	return (timeout_t)(itimer.it_value.tv_sec * 1000 +		itimer.it_value.tv_usec / 1000);#else	time_t now = SysTime::getTime();	return (timeout_t)(((now - _alarm) * 1000) + 500);#endif}void PosixThread::endTimer(void){#ifdef	HAVE_SETITIMER	static const struct itimerval itimer = {{0, 0},{0,0}};#endif	sigset_t sigs;#ifndef	CCXX_SIG_THREAD_ALARM	if(_timer != this)		return;#endif#ifdef	HAVE_SETITIMER	setitimer(ITIMER_REAL, (struct itimerval *)&itimer, NULL);#else	alarm(0);#endif	sigemptyset(&sigs);	sigaddset(&sigs, SIGALRM);	pthread_sigmask(SIG_BLOCK, &sigs, NULL);#ifndef	CCXX_SIG_THREAD_ALARM	_arm.leaveMutex();	_timer = NULL;#endif}#if defined(HAVE_SIGWAIT) || defined(HAVE_SIGWAIT2)void	PosixThread::waitSignal(signo_t signo){	sigset_t	mask;	sigemptyset(&mask);	sigaddset(&mask, signo);#ifndef HAVE_SIGWAIT2	signo = sigwait(&mask);#else	sigwait(&mask, &signo);#endif}#endif // ifdef HAVE_SIGWAITvoid	PosixThread::setSignal(int signo, bool mode){	sigset_t sigs;	sigemptyset(&sigs);	sigaddset(&sigs, signo);	if(mode)		pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);	else		pthread_sigmask(SIG_BLOCK, &sigs, NULL);}	void	PosixThread::signalThread(Thread* th,signo_t signo){	pthread_kill(th->priv->_tid, signo);}pthread_attr_t * PosixThread::getPthreadAttrPtr(void){ 	return &priv->_attr;}pthread_t PosixThread::getPthreadId(void){	return priv->_tid;}void PosixThread::sigInstall(int signo){	struct sigaction act;		act.sa_handler = (signalexec_t)&ccxx_sig_handler;	sigemptyset(&act.sa_mask);#ifdef	SA_INTERRUPT	act.sa_flags = SA_INTERRUPT;#else	act.sa_flags = 0;#endif	sigaction(signo, &act, NULL);}#endif#ifdef	USE_POLLPoller::Poller(){	nufds = 0;	ufds = NULL;}Poller::~Poller(){	if(ufds)	{		delete[] ufds;		ufds = NULL;	}}pollfd *Poller::getList(int cnt){	if(nufds < cnt)	{		if(ufds)			delete[] ufds;		ufds = new pollfd[cnt];		nufds = cnt;	}	return ufds;}#endifMutex SysTime::timeLock;time_t SysTime::getTime(time_t *tloc) {    time_t ret;    lock();    time_t temp;#ifdef	WIN32    ::time(&temp);#else    std::time(&temp);#endif    memcpy(&ret, &temp, sizeof(time_t));    if (tloc != NULL)         memcpy(tloc, &ret, sizeof(time_t));    unlock();    return ret;   }int SysTime::getTimeOfDay(struct timeval *tp) {	struct timeval temp;    int ret(0);    lock();#ifdef	WIN32    // We could use _ftime(), but it is not available on WinCE.    // (WinCE also lacks time.h)    // Note also that the average error of _ftime is around 20 ms :)    time(&temp.tv_sec);    temp.tv_usec = (GetTickCount() % 1000) * 1000;	memcpy(tp, &temp, sizeof(struct timeval));#else    ret = ::gettimeofday(&temp, NULL);    if (ret == 0)         memcpy(tp, &temp, sizeof(struct timeval));#endif    unlock();    return ret;}struct tm *SysTime::getLocalTime(const time_t *clock, struct tm* result) {    lock();#ifdef	WIN32    struct tm *temp = ::localtime(clock);#else    struct tm *temp = std::localtime(clock);#endif    memcpy(result, temp, sizeof(struct tm));    unlock();	return result;}struct tm *SysTime::getGMTTime(const time_t *clock, struct tm* result) {    lock();#ifdef	WIN32    struct tm *temp = ::gmtime(clock);#else    struct tm *temp = std::gmtime(clock);#endif    memcpy(result, temp, sizeof(struct tm));    unlock();	return result;}// C stuff// this function must declared as extern "C" for some compiler#ifdef CCXX_NAMESPACES}#endif /** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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