int main() { barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); check(pthread_timedjoin_np(t, 0, &ts), ETIMEDOUT); barrier_wait(&barrier); clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 10000; check(pthread_timedjoin_np(t, 0, &ts), 0); var = 2; fprintf(stderr, "PASS\n"); return 0; }
bool udtThread::TimedJoin(u32 timeoutMs) { if(_threadhandle == NULL) { return false; } #if defined(UDT_WINDOWS) return WaitForSingleObject((HANDLE)_threadhandle, (DWORD)timeoutMs) == WAIT_OBJECT_0; #elif defined(_GNU_SOURCE) timespec ts; if(clock_gettime(CLOCK_REALTIME, &ts) == -1) { return false; } ts.tv_nsec += (long)timeoutMs * (long)1000000; return pthread_timedjoin_np(*(pthread_t*)_threadhandle, NULL, &ts) == 0; #else # error "pthread_timedjoin_np doesn't exist on your platform" #endif }
long thrJoin(LPDM_THREAD thr, int *exitcode, int timeout) { long dwRes = 0; #ifdef WIN32 int to = timeout > 0 ? timeout : INFINITE; dwRes = WaitForSingleObject(thr->hThread, to); if(dwRes != WAIT_TIMEOUT && exitcode) { DWORD dwExitCode = 0; GetExitCodeThread(thr->hThread, &dwExitCode); *exitcode = (int)dwExitCode; logInfo("Catched thread %d exited with code:%d", thr->dwThreadId, *exitcode); } else logInfo("Catched Thread %d exited.", thr->dwThreadId); #else struct timespec to; int ret; void *pExitPointer; if(timeout > 0) { to.tv_sec = timeout / 1000; to.tv_nsec = (timeout % 1000) * 1000000; dwRes = pthread_timedjoin_np(thr->hThread, &pExitPointer, &to); }else{ pthread_join(thr->hThread, &pExitPointer); } if(exitcode) *exitcode = (int)pExitPointer; logInfo("Catched Thread %d exited.", thr->hThread); #endif free(thr); return dwRes; }
int main(int argc, char * argv[]) { pthread_t id; struct timespec abstime, reltime = { 1, 0 }; void* result = (void*)-1; assert(pthread_create(&id, NULL, func, (void *)(size_t)999) == 0); /* * Let thread start before we attempt to join it. */ Sleep(100); (void) pthread_win32_getabstime_np(&abstime, &reltime); /* Test for pthread_timedjoin_np timeout */ assert(pthread_timedjoin_np(id, &result, &abstime) == ETIMEDOUT); assert((int)(size_t)result == -1); /* Test for pthread_tryjoin_np behaviour before thread has exited */ assert(pthread_tryjoin_np(id, &result) == EBUSY); assert((int)(size_t)result == -1); Sleep(500); /* Test for pthread_tryjoin_np behaviour after thread has exited */ assert(pthread_tryjoin_np(id, &result) == 0); assert((int)(size_t)result == 999); /* Success. */ return 0; }
/////////////////////////////////////////////////////////////////////// /// Function: TimedJoin /// /// Author: $author$ /// Date: 4/13/2012 /////////////////////////////////////////////////////////////////////// virtual XosError TimedJoin (void*& result, const struct timespec& untilTime) { XosError error = XOS_ERROR_FAILED; int err; if ((m_isCreated)) { if (!(err = pthread_timedjoin_np (m_thread, &result, &untilTime))) error = XOS_ERROR_NONE; else if (ETIMEDOUT == (err)) { XOS_DBT(("() timedout on pthread_timedjoin_np()")); error = XOS_ERROR_TIMEDOUT; } else { XOS_DBE(("() failed on pthread_timedjoin_np()")); } if (ETIMEDOUT != (err)) m_isForked = false; } return error; }
/** * close the log. * */ void slog_close(slog_t * log) { if(NULL == log) { return; } // log->running = 0; struct timespec to; to.tv_sec = log->rotate_period > 0 ? log->rotate_period : 60; to.tv_nsec= 0; pthread_timedjoin_np(log->tid, NULL, &to); // pthread_mutex_lock(&(log->lock)); if(NULL != log->fp) { slog_flush(log); fclose(log->fp); log->fp = NULL; } pthread_mutex_unlock(&(log->lock)); free(log); }
static int stream_wait(ObjectStream* os) { // sync if (os->flags & OSF_JOINED) return 0; // static const size_t TIMEOUT_SECS = 10; static const size_t TIMEOUT_SECS = 20; struct timespec timeout; if (clock_gettime(CLOCK_REALTIME, &timeout)) { LOG(LOG_ERR, "failed to get timer '%s'\n", strerror(errno)); return -1; // errno is set } timeout.tv_sec += TIMEOUT_SECS; int rc; void* thread_retval; while (1) { // check whether thread has returned. Could mean a curl error, an S3 // protocol error, or server flaking out. Successful return will // have saved retval in os->op_rc, so we don't have to return it. rc = pthread_timedjoin_np(os->op, &thread_retval, &timeout); LOG(LOG_INFO, "pthread_timedjoin_np returned %d (errno=%d)\n", rc, errno); LOG(LOG_INFO, "thread retval (via os->op_rc) %d\n", os->op_rc); if (! rc) { os->flags |= OSF_JOINED; return 0; // joined } else if (rc == ETIMEDOUT) { errno = rc; return -1; // timed-out } else if (rc == EINVAL) // EINVAL == another thread is also trying to join (?) timed-wait // will just return immediately again, and we'll turn into a // busy-wait. Add an explicit sleep here. [Alternatively, here's // another idea: If multiple threads are waiting on this thread, then // that implies the fuse handle was dup'ed. In that case, if we // return success, fuse might still wait until all threads have // flushed? I don't trust my knowledge of fuse enough to depend on // that.] sleep(1); else { errno = rc; return -1; // error } } }
SerialPort::~SerialPort() { mTreadFlag = false; struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_nsec += 200000000; pthread_timedjoin_np((pthread_t)mThread, 0, &ts); if(mTreadFlag==false) pthread_cancel((pthread_t)mThread); close(mCom); }
GameIntro::~GameIntro() { timespec ts; ts.tv_sec = 0; ts.tv_nsec = 50000000; if (!this->_loaded) { if (pthread_timedjoin_np(this->_thread, 0, &ts)) pthread_kill(this->_thread, SIGUSR1); } }
UINT CThreadLin::Wait(UINT uiMilliseconds) { int iResult; if (uiMilliseconds) { timespec kTime; kTime.tv_sec = uiMilliseconds / 1000; kTime.tv_nsec = (uiMilliseconds % 1000) * 1000000; iResult = pthread_timedjoin_np(m_Thread, (void **) &m_uiExitCode, &kTime); } else iResult = pthread_join(m_Thread, (void **) &m_uiExitCode); return iResult; }
static int thread_join (lua_State *L) { thread_t t=lstage_tothread(L,1); int timeout=lua_tointeger(L,2); if(timeout>0) { struct timespec to; clock_gettime(CLOCK_REALTIME, &to); to.tv_sec += timeout; pthread_timedjoin_np(*t->th,NULL,&to); } else { pthread_join(*t->th,NULL); } return 0; }
void Thread::join(double timeout_ms) { struct timespec abstime; clock_gettime(CLOCK_REALTIME, &abstime); long secs = timeout_ms / 1000; abstime.tv_sec += secs; abstime.tv_nsec += (timeout_ms - secs *1000) * 1000000; if(abstime.tv_nsec >= 1000000000) { abstime.tv_sec += 1; abstime.tv_nsec %= 1000000000; //TODO utiliser classe Clock } pthread_timedjoin_np(m_tid, NULL, &abstime); }
XN_C_API XnStatus xnOSWaitForThreadExit(XN_THREAD_HANDLE ThreadHandle, XnUInt32 nMilliseconds) { int rc = 0; // Make sure the actual thread handle isn't NULL XN_RET_IF_NULL(ThreadHandle, XN_STATUS_OS_INVALID_THREAD); if (nMilliseconds == XN_WAIT_INFINITE) { // join via the OS void* pReturnValue; rc = pthread_join(*ThreadHandle, &pReturnValue); } else { // calculate timeout absolute time. First we take current time struct timespec time; if (XN_STATUS_OK != xnOSGetMonoTime(&time)) { return (XN_STATUS_OS_EVENT_SET_FAILED); } // add timeout to this time time.tv_sec += (nMilliseconds / 1000); time.tv_nsec += ((nMilliseconds % 1000) * 1000000); // join via the OS void* pReturnValue; #ifndef XN_PLATFORM_HAS_NO_TIMED_OPS rc = pthread_timedjoin_np(*ThreadHandle, &pReturnValue, &time); #else rc = pthread_join(*ThreadHandle, &pReturnValue); #endif } // check for failures if (rc == ETIMEDOUT) { return (XN_STATUS_OS_THREAD_TIMEOUT); } else if (rc != 0) { return (XN_STATUS_OS_THREAD_TERMINATION_FAILED); } // All is good... return (XN_STATUS_OK); }
static void interface_stop(ifreader_t handle) { interface_handle_t *descriptor = handle->interface_data; if(descriptor->capture_packets == true) { struct timespec timeout = { 3, 0 }; descriptor->capture_packets = false; if(pthread_timedjoin_np(descriptor->thread, NULL, &timeout) != 0) { pthread_cancel(descriptor->thread); pthread_join(descriptor->thread, NULL); } } }
int OSAL_timedjoin_thread(OSAL_thread_t thread_id, unsigned int milliseconds, void **status) { #ifndef WIMAX_SYS_WINDOWS struct timespec ts; struct timeval tv; int ret; if ( thread_id == 0 ) return EINVAL; gettimeofday(&tv, NULL); TIMEVAL_TO_TIMESPEC(&tv, &ts); // Split the incoming millisecs into seconds and nano-seconds struct as required by the timedjoin method ts.tv_sec += (milliseconds / 1000); ts.tv_nsec += ((milliseconds % 1000) * 1000 * 1000); // 1 ms = 1000000 ns if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ++ts.tv_sec; } ret = pthread_timedjoin_np((pthread_t)thread_id, status, &ts); if ( ret != 0 ) { OSALTRACE(OSAL_ERROR, ("thread join failed. err: %d", errno)); switch (errno) { case ETIMEDOUT: ret = WAIT_TIMEOUT; break; case EINVAL: case ESRCH: ret = WAIT_FAILED; break; } } return ret; #else #endif }
bool FThread::wait(unsigned long timeout) { struct timespec t; time_t seconds = timeout / 1000; long nanoseconds = (timeout % 1000) * 1000; t.tv_sec = seconds; t.tv_nsec = nanoseconds; #if !defined(__APPLE__) && defined(__MACH__) if(pthread_timedjoin_np(pthread, NULL, &t) == ETIMEDOUT) { return true; } #endif return false; }
/* wait for all threads in the linked list to finish */ void wait_conn_list(struct conn_list *list) { struct conn_node *ptr = NULL; struct timespec ts; int s; if (!list) return; ptr = list->head; while (true) { if (!ptr) break; else { /* if this connection is active, we need to wait for long enough time */ if (ptr->connected) { s = pthread_join(ptr->thread, NULL); if (s != 0) { char msg[256] = {0}; snprintf(msg, 256, "Error: pthread_join() (to %s:%hu) in wait_conn_list()", list->ip, list->port); perror(msg); } } else { clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 5; s = pthread_timedjoin_np(ptr->thread, NULL, &ts); if (s != 0) { char msg[256] = {0}; snprintf(msg, 256, "Error: pthread_timedjoin_np() (to %s:%hu) in wait_conn_list()", list->ip, list->port); perror(msg); } } ptr = ptr->next; } } }
void Led::_stopBlinking() { if(!_blinking()){ return; } _pipe.send(Led::QUIT); //wait thread for 3sec timespec ts; if(clock_gettime(CLOCK_REALTIME, &ts) == -1) { log(LOG_ERR, "clock gettime failed"); } else{ ts.tv_sec += 3; int joined = pthread_timedjoin_np(_thread, NULL, &ts); if(joined != 0) { log(LOG_ERR, "unable to join the thread"); } } }
int thread_join( thread_t thread, unsigned int seconds) { int rc; #ifndef WIN32 struct timespec ts; if( clock_gettime(CLOCK_REALTIME, &ts) == -1 ) { rc = pthread_join( thread, NULL ); } else { ts.tv_sec += seconds; rc = pthread_timedjoin_np( thread, NULL, &ts); } #else rc = WaitForSingleObject( thread, ( seconds * 1000 ) ); #endif return rc; }
void cleanup(bool wait_for_termination) { assert(ctx); for (xpl_thread_id i = 0; i < ctx->thread_pool_size; ++i) { test_and_set_thread_state(i, ts_all, ts_terminate_request); } #ifndef XPL_PLATFORM_WINDOWS struct timespec join_delay; join_delay.tv_sec = 1; #endif for (xpl_thread_id i = 0; i < ctx->thread_pool_size; ++i) { #ifdef XPL_PLATFORM_WINDOWS WaitForSingleObject(ctx->thread_pool[i].thread, wait_for_termination ? INFINITE : 1000); CloseHandle(ctx->thread_pool[i].thread); #else if (wait_for_termination) { pthread_join(ctx->thread_pool[i].thread, NULL); } else { pthread_timedjoin_np(ctx->thread_pool[i].thread, NULL, &join_delay); } pthread_detach(ctx->thread_pool[i].thread); #endif xpl_mutex_destroy(&ctx->thread_pool[i].thread_mutex); } xpl_free(ctx->thread_pool); ctx->thread_pool = NULL; ctx->thread_pool_size = 0; if (ctx->local_data_key != INVALID_LOCAL_DATA_KEY) { #ifdef XPL_PLATFORM_WINDOWS TlsFree(ctx->local_data_key); #else pthread_key_delete(ctx->local_data_key); #endif } ctx->local_data_key = INVALID_LOCAL_DATA_KEY; }
int CPacBioUtility::InitLoadQuerySeqs(void) { tsLoadQuerySeqsThreadPars ThreadPars; // initiate loading the reads m_ThreadLoadQuerySeqsRslt = -1; ThreadPars.pRslt = &m_ThreadLoadQuerySeqsRslt; ThreadPars.pThis = this; ThreadPars.Rslt = 0; #ifdef _WIN32 m_hThreadLoadQuerySeqs = ThreadPars.threadHandle = (HANDLE)_beginthreadex(NULL,0x0fffff,LoadReadsFileThread,&ThreadPars,0,&m_ThreadLoadQuerySeqsID); #else int ThreadRslt = ThreadPars.threadRslt = pthread_create (&m_ThreadLoadQuerySeqsID , NULL , LoadReadsFileThread , &ThreadPars ); #endif // wait a few seconds, if major problems with loading reads then should show very quickly #ifdef _WIN32 if(WAIT_TIMEOUT != WaitForSingleObject(m_hThreadLoadQuerySeqs, 10000)) { CloseHandle(m_hThreadLoadQuerySeqs); m_hThreadLoadQuerySeqs = NULL; m_bAsyncLoading = false; return(m_ThreadLoadQuerySeqsRslt); } #else struct timespec ts; int JoinRlt; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 3; if((JoinRlt = pthread_timedjoin_np(m_ThreadLoadQuerySeqsID, NULL, &ts)) == 0) { m_ThreadLoadQuerySeqsID = 0; return(m_ThreadLoadQuerySeqsRslt); } #endif return(eBSFSuccess); }
int main(int argc, char * argv[]) { pthread_t id; struct timespec abstime; void* result = (void*)-1; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_create(&id, NULL, func, (void *)(size_t)999) == 0); /* * Let thread start before we attempt to join it. */ Sleep(100); PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; /* Test for pthread_timedjoin_np timeout */ abstime.tv_sec += 1; assert(pthread_timedjoin_np(id, &result, &abstime) == ETIMEDOUT); assert((int)(size_t)result == -1); /* Test for pthread_tryjoin_np behaviour before thread has exited */ assert(pthread_tryjoin_np(id, &result) == EBUSY); assert((int)(size_t)result == -1); Sleep(500); /* Test for pthread_tryjoin_np behaviour after thread has exited */ assert(pthread_tryjoin_np(id, &result) == 0); assert((int)(size_t)result == 999); /* Success. */ return 0; }
bool FThread::wait(unsigned long timeout) { #if defined(POSIX) && !defined(MAC) && !defined(FUN_IPHONE) struct timespec t; if (clock_gettime(CLOCK_REALTIME, &t) != 0) { /* Handle error */ t.tv_sec = time(NULL); t.tv_nsec = 0; } time_t seconds = timeout / 1000; long nanoseconds = (timeout % 1000) * 1000000; t.tv_sec += seconds; t.tv_nsec += nanoseconds; // there can not be more than 1000000000 nanoseconds (1 sec) overflow if ((unsigned long)t.tv_nsec >= 1000000000) { t.tv_nsec -= 1000000000; ++t.tv_sec; } #endif #ifdef ANDROID int res = pthread_join(pthread, NULL); if (res != 0) { while (nanosleep(&t, &t) == -1 && EINTR == errno); res = pthread_join(pthread, NULL); } #elif defined(MAC) || defined(FUN_IPHONE) int res = pthread_join( pthread, NULL); #elif defined(POSIX) int res = pthread_timedjoin_np(pthread, NULL, &t); #endif return res == 0; }
/******************************* web_to_memory return -1 on error return 0 on success ******************************/ int web_to_memory( char * url, network_page_t * page) { CURL * easyhandle; char * proxy; int err; pthread_t thread; void * thread_ret; struct timespec t; char curl_error_buffer[CURL_ERROR_SIZE]; easyhandle = curl_easy_init(); if(easyhandle == NULL) { printd(DEBUG_ERROR,"curl_easy_init failed: %s",curl_error_buffer); return -1; } proxy = getenv("http_proxy"); if(proxy) { printd(DEBUG_HTTP,"Set proxy to %s\n",proxy); curl_easy_setopt(easyhandle, CURLOPT_PROXY, proxy); } if(page->data) { free(page->data); page->data=NULL; page->size=0; } curl_easy_setopt(easyhandle, CURLOPT_URL, url); curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, data_to_mem); curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, (void *)page); curl_easy_setopt(easyhandle, CURLOPT_TIMEOUT, DEF_HTTP_TIMEOUT); curl_easy_setopt(easyhandle, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, curl_error_buffer); curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, "web-shooter/1.0"); curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1L); /* experimental */ //curl_easy_setopt(easyhandle, CURLOPT_AUTOREFERER, 1); //curl_easy_setopt(easyhandle, CURLOPT_TRANSFER_ENCODING, 1); pthread_create(&thread,NULL,async_perform,easyhandle); clock_gettime(CLOCK_REALTIME, &t); t.tv_sec += DEF_HTTP_TIMEOUT + 2; err = pthread_timedjoin_np(thread,&thread_ret,&t); if(err) { pthread_cancel(thread); printd(DEBUG_ERROR,"pthread_timedjoin_np failed: %s\n",strerror(err)); curl_easy_cleanup(easyhandle); return -1; } if(thread_ret != NULL) { printd(DEBUG_ERROR,"curl_easy_perform failed: %s\n",curl_error_buffer); curl_easy_cleanup(easyhandle); return -1; } curl_easy_cleanup(easyhandle); return 0; }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) { fprintf(stderr, "WaitForSingleObject failed: invalid hHandle.\n"); return WAIT_FAILED; } if (Type == HANDLE_TYPE_THREAD) { int status = 0; WINPR_THREAD* thread; void* thread_status = NULL; thread = (WINPR_THREAD*) Object; if (thread->started) { if (dwMilliseconds != INFINITE) { struct timespec timeout; /* pthread_timedjoin_np returns ETIMEDOUT in case the timeout is 0, * so set it to the smallest value to get a proper return value. */ if (dwMilliseconds == 0) dwMilliseconds ++; clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); if (ETIMEDOUT == status) return WAIT_TIMEOUT; } else status = pthread_join(thread->thread, &thread_status); if (status != 0) { fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n", status, strerror(status)); } if (thread_status) thread->dwExitCode = ((DWORD) (size_t) thread_status); } } else if (Type == HANDLE_TYPE_PROCESS) { WINPR_PROCESS* process; process = (WINPR_PROCESS*) Object; if (waitpid(process->pid, &(process->status), 0) != -1) { fprintf(stderr, "WaitForSingleObject: waitpid failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } process->dwExitCode = (DWORD) process->status; } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; if (dwMilliseconds != INFINITE) { int status; struct timespec timeout; clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_mutex_timedlock(&mutex->mutex, &timeout); if (ETIMEDOUT == status) return WAIT_TIMEOUT; } else { pthread_mutex_lock(&mutex->mutex); } } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: event select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: semaphore select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) { fprintf(stderr, "WaitForSingleObject: semaphore read failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer; timer = (WINPR_TIMER*) Object; #ifdef HAVE_EVENTFD_H if (timer->fd != -1) { int status; fd_set rfds; UINT64 expirations; struct timeval timeout; FD_ZERO(&rfds); FD_SET(timer->fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(timer->fd + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: timer select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; status = read(timer->fd, (void*) &expirations, sizeof(UINT64)); if (status != 8) { if (status == -1) { if (errno == ETIMEDOUT) return WAIT_TIMEOUT; fprintf(stderr, "WaitForSingleObject: timer read() failure [%d] %s\n", errno, strerror(errno)); } else { fprintf(stderr, "WaitForSingleObject: timer read() failure - incorrect number of bytes read"); } return WAIT_FAILED; } } else { fprintf(stderr, "WaitForSingleObject: invalid timer file descriptor\n"); return WAIT_FAILED; } #else fprintf(stderr, "WaitForSingleObject: file descriptors not supported\n"); return WAIT_FAILED; #endif } else if (Type == HANDLE_TYPE_NAMED_PIPE) { int fd; int status; fd_set rfds; struct timeval timeout; WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; if (fd == -1) { fprintf(stderr, "WaitForSingleObject: invalid pipe file descriptor\n"); return WAIT_FAILED; } FD_ZERO(&rfds); FD_SET(fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(fd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: named pipe select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) { return WAIT_TIMEOUT; } } else { fprintf(stderr, "WaitForSingleObject: unknown handle type %lu\n", Type); } return WAIT_OBJECT_0; }
void *probe_signal_handler(void *arg) { probe_t *probe = (probe_t *)arg; siginfo_t siinf; sigset_t siset; #if defined(HAVE_PTHREAD_SETNAME_NP) # if defined(__APPLE__) pthread_setname_np("signal_handler"); # else pthread_setname_np(pthread_self(), "signal_handler"); # endif #endif sigemptyset(&siset); sigaddset(&siset, SIGHUP); sigaddset(&siset, SIGUSR1); sigaddset(&siset, SIGUSR2); sigaddset(&siset, SIGINT); sigaddset(&siset, SIGTERM); sigaddset(&siset, SIGQUIT); sigaddset(&siset, SIGPIPE); #if defined(__linux__) if (prctl(PR_SET_PDEATHSIG, SIGTERM) != 0) dW("prctl(PR_SET_PDEATHSIG, SIGTERM) failed"); #endif dD("Signal handler ready"); switch (errno = pthread_barrier_wait(&OSCAP_GSYM(th_barrier))) { case 0: case PTHREAD_BARRIER_SERIAL_THREAD: break; default: dE("pthread_barrier_wait: %d, %s.", errno, strerror(errno)); return (NULL); } while (sigwaitinfo(&siset, &siinf) != -1) { dD("Received signal %d from %u (%s)", siinf.si_signo, (unsigned int)siinf.si_pid, getppid() == siinf.si_pid ? "parent" : "not my parent"); #if defined(PROBE_SIGNAL_PARENTONLY) /* Listen only to signals sent from the parent process */ if (getppid() != siinf.si_pid) continue; #endif switch(siinf.si_signo) { case SIGUSR1:/* probe abort */ probe->probe_exitcode = ECONNABORTED; /* FALLTHROUGH */ case SIGINT: case SIGTERM: case SIGQUIT: case SIGPIPE: { __thr_collection coll; coll.thr = NULL; coll.cnt = 0; pthread_cancel(probe->th_input); /* collect IDs and cancel threads */ rbt_walk_inorder2(probe->workers, __abort_cb, &coll, 0); /* * Wait till all threads are canceled (they may temporarily disable * cancelability), but at most 60 seconds per thread. */ for (; coll.cnt > 0; --coll.cnt) { probe_worker_t *thr = coll.thr[coll.cnt - 1]; #if defined(HAVE_PTHREAD_TIMEDJOIN_NP) && defined(HAVE_CLOCK_GETTIME) struct timespec j_tm; if (clock_gettime(CLOCK_REALTIME, &j_tm) == -1) { dE("clock_gettime(CLOCK_REALTIME): %d, %s.", errno, strerror(errno)); continue; } j_tm.tv_sec += 60; if ((errno = pthread_timedjoin_np(thr->tid, NULL, &j_tm)) != 0) { dE("[%llu] pthread_timedjoin_np: %d, %s.", (uint64_t)thr->sid, errno, strerror(errno)); /* * Memory will be leaked here by continuing to the next thread. However, we are in the * process of shutting down the whole probe. We're just nice and gave the probe_main() * thread a chance to finish it's critical section which shouldn't take that long... */ continue; } #else if ((errno = pthread_join(thr->tid, NULL)) != 0) { dE("pthread_join: %d, %s.", errno, strerror(errno)); continue; } #endif SEAP_msg_free(coll.thr[coll.cnt - 1]->msg); oscap_free(coll.thr[coll.cnt - 1]); } oscap_free(coll.thr); goto exitloop; } case SIGUSR2: case SIGHUP: /* ignore */ break; } } exitloop: return (NULL); }
/* the main program... */ int main(int argc, char *argv[]) { int i; sigset_t signalmask, oldmask; #ifdef HAVE_PTHREAD_TIMEDJOIN_NP struct timespec ts; #endif /* HAVE_PTHREAD_TIMEDJOIN_NP */ /* close all file descriptors (except stdin/out/err) */ i = sysconf(_SC_OPEN_MAX) - 1; /* if the system does not have OPEN_MAX just close the first 32 and hope we closed enough */ if (i < 0) i = 32; for (; i > 3; i--) close(i); /* parse the command line */ parse_cmdline(argc, argv); /* clean the environment */ #ifdef HAVE_CLEARENV if (clearenv() || putenv("HOME=/") || putenv("TMPDIR=/tmp") || putenv("LDAPNOINIT=1")) { log_log(LOG_ERR, "clearing environment failed"); exit(EXIT_FAILURE); } #else /* not HAVE_CLEARENV */ /* this is a bit ugly */ environ = sane_environment; #endif /* not HAVE_CLEARENV */ /* disable the nss_ldap module for this process */ disable_nss_ldap(); /* set LDAP log level */ if (myldap_set_debuglevel(nslcd_debugging) != LDAP_SUCCESS) exit(EXIT_FAILURE); /* read configuration file */ cfg_init(NSLCD_CONF_PATH); /* set default mode for pidfile and socket */ (void)umask((mode_t)0022); /* see if someone already locked the pidfile if --check option was given exit TRUE if daemon runs (pidfile locked), FALSE otherwise */ if (nslcd_checkonly) { if (is_locked(NSLCD_PIDFILE)) { log_log(LOG_DEBUG, "pidfile (%s) is locked", NSLCD_PIDFILE); exit(EXIT_SUCCESS); } else { log_log(LOG_DEBUG, "pidfile (%s) is not locked", NSLCD_PIDFILE); exit(EXIT_FAILURE); } } /* normal check for pidfile locked */ if (is_locked(NSLCD_PIDFILE)) { log_log(LOG_ERR, "daemon may already be active, cannot acquire lock (%s): %s", NSLCD_PIDFILE, strerror(errno)); exit(EXIT_FAILURE); } /* daemonize */ if ((!nslcd_debugging) && (!nslcd_nofork) && (daemon(0, 0) < 0)) { log_log(LOG_ERR, "unable to daemonize: %s", strerror(errno)); exit(EXIT_FAILURE); } /* intilialize logging */ if (!nslcd_debugging) log_startlogging(); log_log(LOG_INFO, "version %s starting", VERSION); /* start subprocess to do invalidating if reconnect_invalidate is set */ for (i = 0; i < LM_NONE; i++) if (nslcd_cfg->reconnect_invalidate[i]) break; if (i < LM_NONE) invalidator_start(); /* write pidfile */ create_pidfile(NSLCD_PIDFILE); /* install handler to close stuff off on exit and log notice */ if (atexit(exithandler)) { log_log(LOG_ERR, "atexit() failed: %s", strerror(errno)); exit(EXIT_FAILURE); } /* create socket */ nslcd_serversocket = create_socket(NSLCD_SOCKET); if ((nslcd_cfg->gid != NOGID) && (nslcd_cfg->uidname != NULL)) { #ifdef HAVE_INITGROUPS /* load supplementary groups */ if (initgroups(nslcd_cfg->uidname, nslcd_cfg->gid) < 0) log_log(LOG_WARNING, "cannot initgroups(\"%s\",%d) (ignored): %s", nslcd_cfg->uidname, (int)nslcd_cfg->gid, strerror(errno)); else log_log(LOG_DEBUG, "initgroups(\"%s\",%d) done", nslcd_cfg->uidname, (int)nslcd_cfg->gid); #else /* not HAVE_INITGROUPS */ #ifdef HAVE_SETGROUPS /* just drop all supplemental groups */ if (setgroups(0, NULL) < 0) log_log(LOG_WARNING, "cannot setgroups(0,NULL) (ignored): %s", strerror(errno)); else log_log(LOG_DEBUG, "setgroups(0,NULL) done"); #else /* not HAVE_SETGROUPS */ log_log(LOG_DEBUG, "neither initgroups() or setgroups() available"); #endif /* not HAVE_SETGROUPS */ #endif /* not HAVE_INITGROUPS */ } /* change to nslcd gid */ if (nslcd_cfg->gid != NOGID) { if (setgid(nslcd_cfg->gid) != 0) { log_log(LOG_ERR, "cannot setgid(%d): %s", (int)nslcd_cfg->gid, strerror(errno)); exit(EXIT_FAILURE); } log_log(LOG_DEBUG, "setgid(%d) done", (int)nslcd_cfg->gid); } /* change to nslcd uid */ if (nslcd_cfg->uid != NOUID) { if (setuid(nslcd_cfg->uid) != 0) { log_log(LOG_ERR, "cannot setuid(%d): %s", (int)nslcd_cfg->uid, strerror(errno)); exit(EXIT_FAILURE); } log_log(LOG_DEBUG, "setuid(%d) done", (int)nslcd_cfg->uid); } /* block all these signals so our worker threads won't handle them */ sigemptyset(&signalmask); sigaddset(&signalmask, SIGHUP); sigaddset(&signalmask, SIGINT); sigaddset(&signalmask, SIGQUIT); sigaddset(&signalmask, SIGABRT); sigaddset(&signalmask, SIGPIPE); sigaddset(&signalmask, SIGTERM); sigaddset(&signalmask, SIGUSR1); sigaddset(&signalmask, SIGUSR2); pthread_sigmask(SIG_BLOCK, &signalmask, &oldmask); /* start worker threads */ log_log(LOG_INFO, "accepting connections"); nslcd_threads = (pthread_t *)malloc(nslcd_cfg->threads * sizeof(pthread_t)); if (nslcd_threads == NULL) { log_log(LOG_CRIT, "main(): malloc() failed to allocate memory"); exit(EXIT_FAILURE); } for (i = 0; i < nslcd_cfg->threads; i++) { if (pthread_create(&nslcd_threads[i], NULL, worker, NULL)) { log_log(LOG_ERR, "unable to start worker thread %d: %s", i, strerror(errno)); exit(EXIT_FAILURE); } } pthread_sigmask(SIG_SETMASK, &oldmask, NULL); /* install signalhandlers for some signals */ install_sighandler(SIGHUP, sig_handler); install_sighandler(SIGINT, sig_handler); install_sighandler(SIGQUIT, sig_handler); install_sighandler(SIGABRT, sig_handler); install_sighandler(SIGPIPE, SIG_IGN); install_sighandler(SIGTERM, sig_handler); install_sighandler(SIGUSR1, sig_handler); install_sighandler(SIGUSR2, SIG_IGN); /* wait until we received a signal */ while ((nslcd_receivedsignal == 0) || (nslcd_receivedsignal == SIGUSR1)) { sleep(INT_MAX); /* sleep as long as we can or until we receive a signal */ if (nslcd_receivedsignal == SIGUSR1) { log_log(LOG_INFO, "caught signal %s (%d), refresh retries", signame(nslcd_receivedsignal), nslcd_receivedsignal); myldap_immediate_reconnect(); nslcd_receivedsignal = 0; } } /* print something about received signal */ log_log(LOG_INFO, "caught signal %s (%d), shutting down", signame(nslcd_receivedsignal), nslcd_receivedsignal); /* cancel all running threads */ for (i = 0; i < nslcd_cfg->threads; i++) if (pthread_cancel(nslcd_threads[i])) log_log(LOG_WARNING, "failed to stop thread %d (ignored): %s", i, strerror(errno)); /* close server socket to trigger failures in threads waiting on accept() */ close(nslcd_serversocket); nslcd_serversocket = -1; /* if we can, wait a few seconds for the threads to finish */ #ifdef HAVE_PTHREAD_TIMEDJOIN_NP ts.tv_sec = time(NULL) + 3; ts.tv_nsec = 0; #endif /* HAVE_PTHREAD_TIMEDJOIN_NP */ for (i = 0; i < nslcd_cfg->threads; i++) { #ifdef HAVE_PTHREAD_TIMEDJOIN_NP pthread_timedjoin_np(nslcd_threads[i], NULL, &ts); #endif /* HAVE_PTHREAD_TIMEDJOIN_NP */ if (pthread_kill(nslcd_threads[i], 0) == 0) log_log(LOG_ERR, "thread %d is still running, shutting down anyway", i); } /* we're done */ return EXIT_FAILURE; }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) return WAIT_FAILED; if (Type == HANDLE_TYPE_THREAD) { int status = 0; WINPR_THREAD* thread; void* thread_status = NULL; thread = (WINPR_THREAD*) Object; if (thread->started) { if (dwMilliseconds != INFINITE) { #if HAVE_PTHREAD_GNU_EXT struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); #else fprintf(stderr, "[ERROR] %s: Thread timeouts not implemented.\n", __func__); assert(0); #endif } else status = pthread_join(thread->thread, &thread_status); if (status != 0) fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n", status, strerror(status)); if (thread_status) thread->dwExitCode = ((DWORD) (size_t) thread_status); } } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; #if HAVE_PTHREAD_GNU_EXT if (dwMilliseconds != INFINITE) { struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); ts_add_ms(&timeout, dwMilliseconds); pthread_mutex_timedlock(&mutex->mutex, &timeout); } else #endif { pthread_mutex_lock(&mutex->mutex); } } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) return WAIT_FAILED; } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer; timer = (WINPR_TIMER*) Object; #ifdef HAVE_EVENTFD_H if (timer->fd != -1) { int status; fd_set rfds; UINT64 expirations; struct timeval timeout; FD_ZERO(&rfds); FD_SET(timer->fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(timer->fd + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; status = read(timer->fd, (void*) &expirations, sizeof(UINT64)); if (status != 8) return WAIT_TIMEOUT; } else { return WAIT_FAILED; } #else return WAIT_FAILED; #endif } else if (Type == HANDLE_TYPE_NAMED_PIPE) { int status; fd_set rfds; struct timeval timeout; WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; FD_ZERO(&rfds); FD_SET(pipe->clientfd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(pipe->clientfd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else { fprintf(stderr, "WaitForSingleObject: unknown handle type %lu\n", Type); } return WAIT_OBJECT_0; }
static int do_test (void) { pthread_t th; if (pthread_mutex_lock (&lock) != 0) { puts ("mutex_lock failed"); exit (1); } if (pthread_create (&th, NULL, tf, NULL) != 0) { puts ("mutex_create failed"); exit (1); } void *status; struct timespec ts; struct timeval tv; (void) gettimeofday (&tv, NULL); TIMEVAL_TO_TIMESPEC (&tv, &ts); ts.tv_nsec += 200000000; if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ++ts.tv_sec; } int val = pthread_timedjoin_np (th, &status, &ts); if (val == 0) { puts ("1st timedjoin succeeded"); exit (1); } else if (val != ETIMEDOUT) { puts ("1st timedjoin didn't return ETIMEDOUT"); exit (1); } if (pthread_mutex_unlock (&lock) != 0) { puts ("mutex_unlock failed"); exit (1); } while (1) { (void) gettimeofday (&tv, NULL); TIMEVAL_TO_TIMESPEC (&tv, &ts); ts.tv_nsec += 200000000; if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ++ts.tv_sec; } val = pthread_timedjoin_np (th, &status, &ts); if (val == 0) break; if (val != ETIMEDOUT) { printf ("timedjoin returned %s (%d), expected only 0 or ETIMEDOUT\n", strerror (val), val); exit (1); } } if (status != (void *) 42l) { printf ("return value %p, expected %p\n", status, (void *) 42l); exit (1); } return 0; }
nxbool nx_thread_wait(nx_thread *self, nxuint32 timeout_ms) { struct timespec timeout_spec; if(nx_thread_is_running(self) != nxtrue) return nxtrue; /* wait forever */ if(timeout_ms == 0) { if(!pthread_join(self->handle, 0)) return nxtrue; return nxfalse; } #ifndef NX_OS_MACX timeout_spec.tv_sec = timeout_ms / 1000; timeout_spec.tv_nsec = (timeout_ms % 1000) * 1000; if(!pthread_timedjoin_np(self->handle, 0, &timeout_spec)) return nxtrue; #endif return nxfalse; }