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 ); }
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::exit(void) { if (isThread()) { setCancel(cancelDisabled); #ifdef WIN32 close(); ExitThread(0); #else pthread_exit(NULL); #endif // WIN32 } }
jthread inStream_readThreadRef(PacketInputStream *stream) { jobject object = inStream_readObjectRef(stream); if (object == NULL) { /* * Could be error or just the null reference. In either case, * stop now. */ return NULL; } if (!isThread(object)) { stream->error = JDWP_ERROR(INVALID_THREAD); return NULL; } return object; }
void Thread::terminate(void) { #ifdef WIN32 HANDLE hThread; if(!priv) return; hThread = priv->_hThread; if (!priv->_tid || isThread()) { if( priv->_cancellation) ::CloseHandle(priv->_cancellation); if(hThread) ::CloseHandle(hThread); delete priv; priv = NULL; return; } bool terminated = false; if(!priv->_active && hThread != NULL) { // NOTE: add a test in testthread for multiple // suspended Terminate ResumeThread(hThread); TerminateThread(hThread, 0); terminated = true; } else if(hThread != NULL) { switch(_cancel) { case cancelImmediate: TerminateThread(hThread, 0); terminated = true; break; default: SetEvent(priv->_cancellation); } } if(hThread != NULL) { WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); hThread = NULL; } // what if parent already exited? // if(_parent) // _parent->notify(this); if(priv->_cancellation != NULL) CloseHandle(priv->_cancellation); priv->_cancellation = NULL; priv->_tid = 0; if(getThread() == this) _self.setKey(DUMMY_INVALID_THREAD); if (terminated) final(); #else if(!priv) return; cctid_t jtid = priv->_jtid, tid = priv->_tid; if(jtid && (pthread_self() != jtid)) { pthread_join(jtid, NULL); priv->_jtid = 0; } else if((pthread_self() != tid) && tid) { // in suspend thread cannot be cancelled or signaled // ??? rigth // ccxx_resume(priv->_tid); // assure thread has ran before we try to cancel... if(_start) _start->post(); pthread_cancel(tid); if(!isDetached()) { pthread_join(tid,NULL); priv->_tid = 0; } } pthread_attr_destroy(&priv->_attr); #endif delete priv; priv = NULL; }