void Thread::start() { Debug( 1, "Starting thread" ); if ( isThread() ) throw ThreadException( "Can't self start thread" ); mThreadMutex.lock(); if ( !mStarted ) { pthread_attr_t threadAttrs; pthread_attr_init( &threadAttrs ); pthread_attr_setscope( &threadAttrs, PTHREAD_SCOPE_SYSTEM ); mStarted = true; if ( pthread_create( &mThread, &threadAttrs, mThreadFunc, this ) < 0 ) throw ThreadException( stringtf( "Can't create thread: %s", strerror(errno) ) ); pthread_attr_destroy( &threadAttrs ); } else { Error( "Attempt to start already running thread %d", mPid ); } mThreadCondition.wait(); mThreadMutex.unlock(); Debug( 1, "Started thread %d", mPid ); }
void Thread::join() { Debug( 1, "Joining thread %d", mPid ); if ( isThread() ) throw ThreadException( "Can't self join thread" ); mThreadMutex.lock(); if ( mPid >= 0 ) { if ( mStarted ) { void *threadStatus = 0; if ( pthread_join( mThread, &threadStatus ) < 0 ) throw ThreadException( stringtf( "Can't join sender thread: %s", strerror(errno) ) ); mStarted = false; Debug( 1, "Thread %d exited, status %p", mPid, threadStatus ); } else { Warning( "Attempt to join already finished thread %d", mPid ); } } else { Warning( "Attempt to join non-started thread %d", mPid ); } mThreadMutex.unlock(); Debug( 1, "Joined thread %d", mPid ); }
virtual void start(Runnable *runnable, bool detached, bool runnableShouldBeFreed) throw(ThreadException) { this->runnable = runnable; this->detached = detached; this->runnableShouldBeFreed = runnableShouldBeFreed; if (detached) { pthread_attr_t attr; if (pthread_attr_init(&attr) != 0) { throw ThreadException("Cannot initialize pthread attribute."); } if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) { throw ThreadException("Cannot set pthread detach state."); } ref(); if (pthread_create(&thread, &attr, entry, this) != 0) { unref(); throw ThreadException("Cannot create a thread."); } pthread_attr_destroy(&attr); } else { ref(); if (pthread_create(&thread, NULL, entry, this) != 0) { unref(); throw ThreadException("Cannot create a thread."); } } }
/*! Ctor. \param detach detach thread if true \param stacksize default thread stacksize */ _threadbase(const bool detach, const size_t stacksize) throw(ThreadException) : _attr(), _tid(), _exitval() { if (pthread_attr_init(&_attr)) throw ThreadException("pthread_attr_init failure"); if (stacksize && pthread_attr_setstacksize(&_attr, stacksize)) throw ThreadException("pthread_attr_setstacksize failure"); if (detach && pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED)) throw ThreadException("pthread_attr_setdetachstate failure"); }
Thread::Thread(IRunnable& runnable, bool detach) : m_runnable(runnable) { if (pthread_attr_init(&m_attr) != 0) throw ThreadException("pthread_attr_init() error", __LINE__, __FILE__); if (detach && pthread_attr_setdetachstate(&m_attr, PTHREAD_CREATE_DETACHED) != 0) throw ThreadException("pthread_attr_setdetachstate error", __LINE__, __FILE__); m_started = false; }
void MutualExclusion::Unlock() { switch (pthread_mutex_unlock(&mutexTheMutex)) { case 0: return; case EPERM: throw ThreadException(ThreadException::errMutexNotOwned); default: throw ThreadException(ThreadException::errMutexUnknown); } }
void MutualExclusion::Lock() { switch (pthread_mutex_lock(&mutexTheMutex)) { case 0: return; case EDEADLK: throw ThreadException(ThreadException::errMutexWouldDeadlock); default: throw ThreadException(ThreadException::errMutexUnknown); } }
/** * Signal a event variable, waking up any waiting thread(s). */ void Event::notify() { int rc = 0; mutex.lock(); switch (type) { case DM1_EVENT_SINGLE: if (waitersCount == 0) { signaled = true; } else { rc = pthread_cond_signal(&cond); } break; case DM1_EVENT_BROADCAST: rc = pthread_cond_broadcast(&cond); break; } mutex.unlock(); if (rc != 0) { fprintf(stderr, "Event.notify: Failed to notify Event: errcode = %d\n", rc); throw ThreadException(__FILE__, __LINE__, DM1_ERR_EVENT_NOTIFY, rc); } }
// Sets a new prompt for the user and then gets an entire string from the input // queue for this thread's node. If no string present, waits until one is. char* GameThread::getStr(char* szBuffer, char* szPromptText, short nPromptCol, short nMaxLen) { // Display the new prompt gn->print(szPromptText, nPromptCol, 0, OP_COMMAND_PROMPT); gs->leaveCritical(); // While there's no input messages waiting, sleep. while ( gn->mqInput.isEmpty() ) { Sleep(50); } gs->enterCritical(); // Retreive the first waiting input message InputData idMessage = gn->mqInput.dequeue(); // If it's an IP_FORCE_EXIT message, shut down this thread. if ( idMessage.nType == IP_FORCE_EXIT ) throw ThreadException(); // If the message is too long, shorten it. if ( strlen(idMessage.szMessage) > nMaxLen && nMaxLen < 190 ) idMessage.szMessage[nMaxLen] = '\0'; // Copy the message to the buffer and return it. strcpy(szBuffer, idMessage.szMessage); return szBuffer; }
// Sets a new prompt for the user and then gets a single keypress (hotkey). // May wait for input, depending on value of bWait. char GameThread::getKey(char* szPromptText, short nPromptCol, bool bWait) { // Display the new prompt gn->print(szPromptText, nPromptCol, 0, OP_HOTKEY_PROMPT); if ( bWait ) gs->leaveCritical(); // While there's no input, if bWait is true, pause until input is present. // But if there's no input and bWait is false, return 0. while ( gn->mqInput.isEmpty() ) { if ( bWait ) Sleep(50); else return 0; } if ( bWait ) gs->enterCritical(); // Retreive the first waiting input message InputData idMessage = gn->mqInput.dequeue(); // If it's an IP_FORCE_EXIT message, shut down this thread. if ( idMessage.nType == IP_FORCE_EXIT ) throw ThreadException(); // Return the keystroke, which will be the first character of the input message. // Make it lowercase first. return tolower( idMessage.szMessage[0] ); }
Mutex::~Mutex() { if ( locked() ) Warning( "Destroying mutex when locked" ); if ( pthread_mutex_destroy( &mMutex ) < 0 ) throw ThreadException( stringtf( "Unable to destroy pthread mutex: %s", strerror(errno) ) ); }
void create(U callObj, T fctParam) { mCallObj = callObj; mFctParam = fctParam; if (pthread_create(&mThread, NULL, start_thread_trampoline<U, T>, this) != UnixThread::PTHREAD_SUCCESS) throw ThreadException("fail pthread_create()"); }
virtual unsigned run() throw(ThreadException) { Worker::run(); throw ThreadException("test exception throwing."); return 1; }
/** * This is the method that should be called to start the Thread */ void Thread::start() { ENTER("Thread.start"); if (debug) fprintf(stdout, "Thread.start: Starting thread %s\n", getName()); #if DM1_USE_PTHREAD int rc = pthread_create(&tid, 0, dm1_thread_main, this); if (rc != 0) { #else handle = (HANDLE) _beginthreadex(NULL, 0, dm1_thread_main, this, 0, (unsigned int *)&tid); //handle = (HANDLE) CreateThread(NULL, 0, dm1_thread_main, // this, CREATE_SUSPENDED, &tid); //if (handle == 0 || ResumeThread(handle) == (DWORD)-1) { if (handle == 0) { int rc = GetLastError(); #endif fprintf(stderr, "Thread.start: Error: Failed to start thread %s\n", getName()); throw ThreadException(__FILE__, __LINE__, DM1_ERR_THREAD_CREATE, rc); } EXIT("Thread.start"); } /** * The Thread constructor. */ Thread::Thread(Runnable *toRun, const char *name, bool isDaemon) : DLinkable() { ENTER("Thread.ctor"); status = DM1_THREAD_UNUSED; this->isDaemon = isDaemon; this->toRun = toRun; toRun->setThread(this); latchMode = 0; isSignaled = 0; this->name = strdup(name); status = DM1_THREAD_INITED; EXIT("Thread.ctor"); } /** * Terminates the thread. */ void Thread::exit() { ENTER("Thread.exit"); if (debug) fprintf(stdout, "Thread.exit: Exiting thread %s\n", getName()); #if !DM1_USE_PTHREAD cleanup(); _endthreadex(0); //ExitThread(0); #else pthread_exit(0); #endif EXIT("Thread.exit"); }
void ThreadBase::LaunchThread() { if (pthread_create(&pthreadThreadDetails, NULL, &(ThreadBase::ThreadMain), this)) { throw ThreadException(ThreadException::errThreadLaunch); } }
void Event::reset() { if (!ResetEvent(event)) { DWORD rc = GetLastError(); fprintf(stderr, "Event.reset: Failed to reset an Event: errcode = %d\n", rc); throw ThreadException(__FILE__, __LINE__, DM1_ERR_EVENT_RESET, rc); } }
void CommonThread::start() { if(!this->_create){ if(pthread_create(&this->thread_info.thread_id, NULL, start_thread, (void*)this) != 0) { stringstream error; error << "[create] create thread failed:" << strerror(errno) << endl; throw ThreadException(error.str()); } if (this->thread_info.detach == E_THREAD_DETACHED) { cout << "Detached Thread:" << this->thread_info.name << endl; if (pthread_detach(this->thread_info.thread_id)) { throw ThreadException("[detach] can't create detached thread"); } } this->_create = T_TRUE; this->thread_info.state = E_THREAD_RUNNING; } }
bool Condition::wait( double secs ) { // Locking done outside of this function struct timespec timeout = getTimeout( secs ); if ( pthread_cond_timedwait( &mCondition, mMutex.getMutex(), &timeout ) < 0 && errno != ETIMEDOUT ) throw ThreadException( stringtf( "Unable to timedwait pthread condition: %s", strerror(errno) ) ); return( errno != ETIMEDOUT ); }
void Event::wait() { if (WaitForSingleObject(event, INFINITE) == WAIT_FAILED) { DWORD rc = GetLastError(); fprintf(stderr, "Event.wait: Failed to wait on Event: errcode = %d\n", rc); throw ThreadException(__FILE__, __LINE__, DM1_ERR_EVENT_WAIT, rc); } }
void Thread::join(void) { if (pthread_join(this->_thread, 0)) { this->_status = Dead; throw ThreadException("fail to join thread."); } this->_status = Sleeping; }
bool Mutex::locked() { int state = pthread_mutex_trylock( &mMutex ); if ( state != 0 && state != EBUSY ) throw ThreadException( stringtf( "Unable to trylock pthread mutex: %s", strerror(errno) ) ); if ( state != EBUSY ) unlock(); return( state == EBUSY ); }
void Thread::start () { if (getState () != NOT_STARTED) throw ThreadException ("Thread was already started."); boost::thread* thread = new boost::thread (*this); // The thread is started immediately, we detach it (by deleting it). delete thread; }
bool MutualExclusion::TryLock() { switch (pthread_mutex_trylock(&mutexTheMutex)) { case 0: return true; case EBUSY: return false; default: throw ThreadException(ThreadException::errMutexUnknown); } }
Thread::ThreadImpl::ThreadImpl(Common::ICallback *callback) : ThreadHandle(0) { DWORD Id = 0; if (!(ThreadHandle = ::CreateThread(0, 0, &ThreadImpl::ThreadProc, callback, 0, &Id))) { throw ThreadException("Can't create thread"); } }
virtual void start(void) throw(ThreadException) { DWORD id; handle = CreateThread( NULL, // default security attributes 0, // use default stack size boot, // thread function name this, // argument to thread function 0, // use default creation flags &id); // returns the thread identifier if(handle == NULL) throw ThreadException(_ << "cannot create thread: " << GetLastError()); }
virtual unsigned run() throw(ThreadException) { try { // this->shutdown(SocketImpl::write); try { std::cout << "catch server socket from: " << this->info.getHostname() << ":" << this->info.getPort() << std::endl; } catch (std::exception& ) { std::cout << "catch server socket from: " << IP::getIpString(this->info.getIp()) << ":" << this->info.getPort() << std::endl; } char buffer[100]; size_t readCount; while((readCount = this->read(buffer, 1)) != 0) { if (buffer[0] == 'q') break; else if(buffer[0] == 'x') { this->parent->setFinalize(); std::cout << "end server request." << std::endl; break; } buffer[1] = 0; std::cout << buffer; std::cout.flush(); } } catch (std::exception& e) { std::cout << "raise exception: " << e.what() << std::endl; std::cout << "connection closed." << std::endl; this->shutdown(SocketImpl::read); this->close(); throw ThreadException(e.what()); } this->shutdown(SocketImpl::read); this->close(); return 0; }
virtual void start(void* (*fct)(void*), void* arg) { if ((_threadHandle = CreateThread( NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(_threadEntry), arg, 0, &_thread)) == NULL) throw ThreadException(GetLastError()); this->_status = IThread<T>::RUNNING; }
/* * Initialize a event. An event can be of two types: * DM1_EVENT_SINGLE - supports signalling and waking one waiting thread * DM1_EVENT_BROADCAST - supports signalling and waking up multiple threads. */ Event::Event(EventType type) { signaled = false; waitersCount = 0; this->type = type; int rc = pthread_cond_init(&cond, 0); if (rc != 0) { fprintf(stderr, "Event.ctor: Error creating Event object: errcode = %d\n", rc); throw ThreadException(__FILE__, __LINE__, DM1_ERR_EVENT_CREATE, rc); } if (debug) fprintf(stdout, "Event.ctor: Event created\n"); }
//call in father thread void CommonThread::stop() { this->thread_info.state = E_THREAD_STOPPING; /* Send signal to the thread to kick it out of any system call it was in */ pthread_kill(this->thread_info.thread_id, THREAD_SIGNAL); if (this->thread_info.detach == E_THREAD_JOINABLE){ if(pthread_join(this->thread_info.thread_id, NULL)){ stringstream error; error << "[join] pthread_join error:" << strerror(errno) << endl; throw ThreadException(error.str()); } } this->thread_info.state = E_THREAD_STOPPED; cout << "Stop Thread:" << this->name() << endl; }
void CommonThread::install_signal() { /* Set up sigmask to receive configured signal in the main thread. * All created threads also get this signal mask, so all threads * get the signal. But we can use pthread_signal to direct it at one. */ struct sigaction sa; sa.sa_handler = thread_signal_handler; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); cout << "install signal" << endl; if (sigaction(THREAD_SIGNAL, &sa, NULL) == -1) { throw ThreadException("[signal] can't install thread signal"); } }