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;
}
Beispiel #2
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
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
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;
    }
Beispiel #6
0
/**
 * 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);
}
Beispiel #7
0
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);
}
Beispiel #9
0
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);
    }
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
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);
}
Beispiel #14
0
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;
}
Beispiel #17
0
/* 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;
        }
    }
}
Beispiel #18
0
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");
        }
    }
}
Beispiel #19
0
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;
}
Beispiel #20
0
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;
}
Beispiel #21
0
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);
}
Beispiel #22
0
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;
}
Beispiel #23
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;
}
Beispiel #24
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;
}
Beispiel #25
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);
}
Beispiel #27
0
/* 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;
}
Beispiel #28
0
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;
}
Beispiel #29
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;
}
Beispiel #30
-1
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;
}