|  | @@ -2544,109 +2544,6 @@ get_uname(void)
 | 
	
		
			
				|  |  |   *   Process control
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#if defined(USE_PTHREADS)
 | 
	
		
			
				|  |  | -/** Wraps a void (*)(void*) function and its argument so we can
 | 
	
		
			
				|  |  | - * invoke them in a way pthreads would expect.
 | 
	
		
			
				|  |  | - */
 | 
	
		
			
				|  |  | -typedef struct tor_pthread_data_t {
 | 
	
		
			
				|  |  | -  void (*func)(void *);
 | 
	
		
			
				|  |  | -  void *data;
 | 
	
		
			
				|  |  | -} tor_pthread_data_t;
 | 
	
		
			
				|  |  | -/** Given a tor_pthread_data_t <b>_data</b>, call _data->func(d->data)
 | 
	
		
			
				|  |  | - * and free _data.  Used to make sure we can call functions the way pthread
 | 
	
		
			
				|  |  | - * expects. */
 | 
	
		
			
				|  |  | -static void *
 | 
	
		
			
				|  |  | -tor_pthread_helper_fn(void *_data)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  tor_pthread_data_t *data = _data;
 | 
	
		
			
				|  |  | -  void (*func)(void*);
 | 
	
		
			
				|  |  | -  void *arg;
 | 
	
		
			
				|  |  | -  /* mask signals to worker threads to avoid SIGPIPE, etc */
 | 
	
		
			
				|  |  | -  sigset_t sigs;
 | 
	
		
			
				|  |  | -  /* We're in a subthread; don't handle any signals here. */
 | 
	
		
			
				|  |  | -  sigfillset(&sigs);
 | 
	
		
			
				|  |  | -  pthread_sigmask(SIG_SETMASK, &sigs, NULL);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  func = data->func;
 | 
	
		
			
				|  |  | -  arg = data->data;
 | 
	
		
			
				|  |  | -  tor_free(_data);
 | 
	
		
			
				|  |  | -  func(arg);
 | 
	
		
			
				|  |  | -  return NULL;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/**
 | 
	
		
			
				|  |  | - * A pthread attribute to make threads start detached.
 | 
	
		
			
				|  |  | - */
 | 
	
		
			
				|  |  | -static pthread_attr_t attr_detached;
 | 
	
		
			
				|  |  | -/** True iff we've called tor_threads_init() */
 | 
	
		
			
				|  |  | -static int threads_initialized = 0;
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -/** Minimalist interface to run a void function in the background.  On
 | 
	
		
			
				|  |  | - * Unix calls fork, on win32 calls beginthread.  Returns -1 on failure.
 | 
	
		
			
				|  |  | - * func should not return, but rather should call spawn_exit.
 | 
	
		
			
				|  |  | - *
 | 
	
		
			
				|  |  | - * NOTE: if <b>data</b> is used, it should not be allocated on the stack,
 | 
	
		
			
				|  |  | - * since in a multithreaded environment, there is no way to be sure that
 | 
	
		
			
				|  |  | - * the caller's stack will still be around when the called function is
 | 
	
		
			
				|  |  | - * running.
 | 
	
		
			
				|  |  | - */
 | 
	
		
			
				|  |  | -int
 | 
	
		
			
				|  |  | -spawn_func(void (*func)(void *), void *data)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -#if defined(USE_WIN32_THREADS)
 | 
	
		
			
				|  |  | -  int rv;
 | 
	
		
			
				|  |  | -  rv = (int)_beginthread(func, 0, data);
 | 
	
		
			
				|  |  | -  if (rv == (int)-1)
 | 
	
		
			
				|  |  | -    return -1;
 | 
	
		
			
				|  |  | -  return 0;
 | 
	
		
			
				|  |  | -#elif defined(USE_PTHREADS)
 | 
	
		
			
				|  |  | -  pthread_t thread;
 | 
	
		
			
				|  |  | -  tor_pthread_data_t *d;
 | 
	
		
			
				|  |  | -  if (PREDICT_UNLIKELY(!threads_initialized))
 | 
	
		
			
				|  |  | -    tor_threads_init();
 | 
	
		
			
				|  |  | -  d = tor_malloc(sizeof(tor_pthread_data_t));
 | 
	
		
			
				|  |  | -  d->data = data;
 | 
	
		
			
				|  |  | -  d->func = func;
 | 
	
		
			
				|  |  | -  if (pthread_create(&thread,&attr_detached,tor_pthread_helper_fn,d))
 | 
	
		
			
				|  |  | -    return -1;
 | 
	
		
			
				|  |  | -  return 0;
 | 
	
		
			
				|  |  | -#else
 | 
	
		
			
				|  |  | -  pid_t pid;
 | 
	
		
			
				|  |  | -  pid = fork();
 | 
	
		
			
				|  |  | -  if (pid<0)
 | 
	
		
			
				|  |  | -    return -1;
 | 
	
		
			
				|  |  | -  if (pid==0) {
 | 
	
		
			
				|  |  | -    /* Child */
 | 
	
		
			
				|  |  | -    func(data);
 | 
	
		
			
				|  |  | -    tor_assert(0); /* Should never reach here. */
 | 
	
		
			
				|  |  | -    return 0; /* suppress "control-reaches-end-of-non-void" warning. */
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    /* Parent */
 | 
	
		
			
				|  |  | -    return 0;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -/** End the current thread/process.
 | 
	
		
			
				|  |  | - */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -spawn_exit(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -#if defined(USE_WIN32_THREADS)
 | 
	
		
			
				|  |  | -  _endthread();
 | 
	
		
			
				|  |  | -  //we should never get here. my compiler thinks that _endthread returns, this
 | 
	
		
			
				|  |  | -  //is an attempt to fool it.
 | 
	
		
			
				|  |  | -  tor_assert(0);
 | 
	
		
			
				|  |  | -  _exit(0);
 | 
	
		
			
				|  |  | -#elif defined(USE_PTHREADS)
 | 
	
		
			
				|  |  | -  pthread_exit(NULL);
 | 
	
		
			
				|  |  | -#else
 | 
	
		
			
				|  |  | -  /* http://www.erlenstar.demon.co.uk/unix/faq_2.html says we should
 | 
	
		
			
				|  |  | -   * call _exit, not exit, from child processes. */
 | 
	
		
			
				|  |  | -  _exit(0);
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  /** Implementation logic for compute_num_cpus(). */
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  |  compute_num_cpus_impl(void)
 | 
	
	
		
			
				|  | @@ -2935,280 +2832,6 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#if defined(USE_WIN32_THREADS)
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_init(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  InitializeCriticalSection(&m->mutex);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_uninit(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  DeleteCriticalSection(&m->mutex);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_acquire(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  tor_assert(m);
 | 
	
		
			
				|  |  | -  EnterCriticalSection(&m->mutex);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_release(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  LeaveCriticalSection(&m->mutex);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -unsigned long
 | 
	
		
			
				|  |  | -tor_get_thread_id(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  return (unsigned long)GetCurrentThreadId();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -#elif defined(USE_PTHREADS)
 | 
	
		
			
				|  |  | -/** A mutex attribute that we're going to use to tell pthreads that we want
 | 
	
		
			
				|  |  | - * "reentrant" mutexes (i.e., once we can re-lock if we're already holding
 | 
	
		
			
				|  |  | - * them.) */
 | 
	
		
			
				|  |  | -static pthread_mutexattr_t attr_reentrant;
 | 
	
		
			
				|  |  | -/** Initialize <b>mutex</b> so it can be locked.  Every mutex must be set
 | 
	
		
			
				|  |  | - * up with tor_mutex_init() or tor_mutex_new(); not both. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_init(tor_mutex_t *mutex)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  int err;
 | 
	
		
			
				|  |  | -  if (PREDICT_UNLIKELY(!threads_initialized))
 | 
	
		
			
				|  |  | -    tor_threads_init();
 | 
	
		
			
				|  |  | -  err = pthread_mutex_init(&mutex->mutex, &attr_reentrant);
 | 
	
		
			
				|  |  | -  if (PREDICT_UNLIKELY(err)) {
 | 
	
		
			
				|  |  | -    log_err(LD_GENERAL, "Error %d creating a mutex.", err);
 | 
	
		
			
				|  |  | -    tor_fragile_assert();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Wait until <b>m</b> is free, then acquire it. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_acquire(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  int err;
 | 
	
		
			
				|  |  | -  tor_assert(m);
 | 
	
		
			
				|  |  | -  err = pthread_mutex_lock(&m->mutex);
 | 
	
		
			
				|  |  | -  if (PREDICT_UNLIKELY(err)) {
 | 
	
		
			
				|  |  | -    log_err(LD_GENERAL, "Error %d locking a mutex.", err);
 | 
	
		
			
				|  |  | -    tor_fragile_assert();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Release the lock <b>m</b> so another thread can have it. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_release(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  int err;
 | 
	
		
			
				|  |  | -  tor_assert(m);
 | 
	
		
			
				|  |  | -  err = pthread_mutex_unlock(&m->mutex);
 | 
	
		
			
				|  |  | -  if (PREDICT_UNLIKELY(err)) {
 | 
	
		
			
				|  |  | -    log_err(LD_GENERAL, "Error %d unlocking a mutex.", err);
 | 
	
		
			
				|  |  | -    tor_fragile_assert();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Clean up the mutex <b>m</b> so that it no longer uses any system
 | 
	
		
			
				|  |  | - * resources.  Does not free <b>m</b>.  This function must only be called on
 | 
	
		
			
				|  |  | - * mutexes from tor_mutex_init(). */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_uninit(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  int err;
 | 
	
		
			
				|  |  | -  tor_assert(m);
 | 
	
		
			
				|  |  | -  err = pthread_mutex_destroy(&m->mutex);
 | 
	
		
			
				|  |  | -  if (PREDICT_UNLIKELY(err)) {
 | 
	
		
			
				|  |  | -    log_err(LD_GENERAL, "Error %d destroying a mutex.", err);
 | 
	
		
			
				|  |  | -    tor_fragile_assert();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Return an integer representing this thread. */
 | 
	
		
			
				|  |  | -unsigned long
 | 
	
		
			
				|  |  | -tor_get_thread_id(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  union {
 | 
	
		
			
				|  |  | -    pthread_t thr;
 | 
	
		
			
				|  |  | -    unsigned long id;
 | 
	
		
			
				|  |  | -  } r;
 | 
	
		
			
				|  |  | -  r.thr = pthread_self();
 | 
	
		
			
				|  |  | -  return r.id;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -/** Return a newly allocated, ready-for-use mutex. */
 | 
	
		
			
				|  |  | -tor_mutex_t *
 | 
	
		
			
				|  |  | -tor_mutex_new(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
 | 
	
		
			
				|  |  | -  tor_mutex_init(m);
 | 
	
		
			
				|  |  | -  return m;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Release all storage and system resources held by <b>m</b>. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_mutex_free(tor_mutex_t *m)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  if (!m)
 | 
	
		
			
				|  |  | -    return;
 | 
	
		
			
				|  |  | -  tor_mutex_uninit(m);
 | 
	
		
			
				|  |  | -  tor_free(m);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -/* Conditions. */
 | 
	
		
			
				|  |  | -#ifdef USE_PTHREADS
 | 
	
		
			
				|  |  | -#if 0
 | 
	
		
			
				|  |  | -/** Cross-platform condition implementation. */
 | 
	
		
			
				|  |  | -struct tor_cond_t {
 | 
	
		
			
				|  |  | -  pthread_cond_t cond;
 | 
	
		
			
				|  |  | -};
 | 
	
		
			
				|  |  | -/** Return a newly allocated condition, with nobody waiting on it. */
 | 
	
		
			
				|  |  | -tor_cond_t *
 | 
	
		
			
				|  |  | -tor_cond_new(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  tor_cond_t *cond = tor_malloc_zero(sizeof(tor_cond_t));
 | 
	
		
			
				|  |  | -  if (pthread_cond_init(&cond->cond, NULL)) {
 | 
	
		
			
				|  |  | -    tor_free(cond);
 | 
	
		
			
				|  |  | -    return NULL;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  return cond;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Release all resources held by <b>cond</b>. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_cond_free(tor_cond_t *cond)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  if (!cond)
 | 
	
		
			
				|  |  | -    return;
 | 
	
		
			
				|  |  | -  if (pthread_cond_destroy(&cond->cond)) {
 | 
	
		
			
				|  |  | -    log_warn(LD_GENERAL,"Error freeing condition: %s", strerror(errno));
 | 
	
		
			
				|  |  | -    return;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  tor_free(cond);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Wait until one of the tor_cond_signal functions is called on <b>cond</b>.
 | 
	
		
			
				|  |  | - * All waiters on the condition must wait holding the same <b>mutex</b>.
 | 
	
		
			
				|  |  | - * Returns 0 on success, negative on failure. */
 | 
	
		
			
				|  |  | -int
 | 
	
		
			
				|  |  | -tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  return pthread_cond_wait(&cond->cond, &mutex->mutex) ? -1 : 0;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Wake up one of the waiters on <b>cond</b>. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_cond_signal_one(tor_cond_t *cond)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  pthread_cond_signal(&cond->cond);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Wake up all of the waiters on <b>cond</b>. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_cond_signal_all(tor_cond_t *cond)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  pthread_cond_broadcast(&cond->cond);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -/** Set up common structures for use by threading. */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_threads_init(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  if (!threads_initialized) {
 | 
	
		
			
				|  |  | -    pthread_mutexattr_init(&attr_reentrant);
 | 
	
		
			
				|  |  | -    pthread_mutexattr_settype(&attr_reentrant, PTHREAD_MUTEX_RECURSIVE);
 | 
	
		
			
				|  |  | -    tor_assert(0==pthread_attr_init(&attr_detached));
 | 
	
		
			
				|  |  | -    tor_assert(0==pthread_attr_setdetachstate(&attr_detached, 1));
 | 
	
		
			
				|  |  | -    threads_initialized = 1;
 | 
	
		
			
				|  |  | -    set_main_thread();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -#elif defined(USE_WIN32_THREADS)
 | 
	
		
			
				|  |  | -#if 0
 | 
	
		
			
				|  |  | -static DWORD cond_event_tls_index;
 | 
	
		
			
				|  |  | -struct tor_cond_t {
 | 
	
		
			
				|  |  | -  CRITICAL_SECTION mutex;
 | 
	
		
			
				|  |  | -  smartlist_t *events;
 | 
	
		
			
				|  |  | -};
 | 
	
		
			
				|  |  | -tor_cond_t *
 | 
	
		
			
				|  |  | -tor_cond_new(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  tor_cond_t *cond = tor_malloc_zero(sizeof(tor_cond_t));
 | 
	
		
			
				|  |  | -  InitializeCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -  cond->events = smartlist_new();
 | 
	
		
			
				|  |  | -  return cond;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_cond_free(tor_cond_t *cond)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  if (!cond)
 | 
	
		
			
				|  |  | -    return;
 | 
	
		
			
				|  |  | -  DeleteCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -  /* XXXX notify? */
 | 
	
		
			
				|  |  | -  smartlist_free(cond->events);
 | 
	
		
			
				|  |  | -  tor_free(cond);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -int
 | 
	
		
			
				|  |  | -tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  HANDLE event;
 | 
	
		
			
				|  |  | -  int r;
 | 
	
		
			
				|  |  | -  tor_assert(cond);
 | 
	
		
			
				|  |  | -  tor_assert(mutex);
 | 
	
		
			
				|  |  | -  event = TlsGetValue(cond_event_tls_index);
 | 
	
		
			
				|  |  | -  if (!event) {
 | 
	
		
			
				|  |  | -    event = CreateEvent(0, FALSE, FALSE, NULL);
 | 
	
		
			
				|  |  | -    TlsSetValue(cond_event_tls_index, event);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  EnterCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  tor_assert(WaitForSingleObject(event, 0) == WAIT_TIMEOUT);
 | 
	
		
			
				|  |  | -  tor_assert(!smartlist_contains(cond->events, event));
 | 
	
		
			
				|  |  | -  smartlist_add(cond->events, event);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  LeaveCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  tor_mutex_release(mutex);
 | 
	
		
			
				|  |  | -  r = WaitForSingleObject(event, INFINITE);
 | 
	
		
			
				|  |  | -  tor_mutex_acquire(mutex);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  switch (r) {
 | 
	
		
			
				|  |  | -    case WAIT_OBJECT_0: /* we got the mutex normally. */
 | 
	
		
			
				|  |  | -      break;
 | 
	
		
			
				|  |  | -    case WAIT_ABANDONED: /* holding thread exited. */
 | 
	
		
			
				|  |  | -    case WAIT_TIMEOUT: /* Should never happen. */
 | 
	
		
			
				|  |  | -      tor_assert(0);
 | 
	
		
			
				|  |  | -      break;
 | 
	
		
			
				|  |  | -    case WAIT_FAILED:
 | 
	
		
			
				|  |  | -      log_warn(LD_GENERAL, "Failed to acquire mutex: %d",(int) GetLastError());
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  return 0;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_cond_signal_one(tor_cond_t *cond)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  HANDLE event;
 | 
	
		
			
				|  |  | -  tor_assert(cond);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  EnterCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if ((event = smartlist_pop_last(cond->events)))
 | 
	
		
			
				|  |  | -    SetEvent(event);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  LeaveCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_cond_signal_all(tor_cond_t *cond)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  tor_assert(cond);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  EnterCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -  SMARTLIST_FOREACH(cond->events, HANDLE, event, SetEvent(event));
 | 
	
		
			
				|  |  | -  smartlist_clear(cond->events);
 | 
	
		
			
				|  |  | -  LeaveCriticalSection(&cond->mutex);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -tor_threads_init(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -#if 0
 | 
	
		
			
				|  |  | -  cond_event_tls_index = TlsAlloc();
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -  set_main_thread();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  #if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
 | 
	
		
			
				|  |  |  /** Attempt to raise the current and max rlimit to infinity for our process.
 | 
	
		
			
				|  |  |   * This only needs to be done once and can probably only be done when we have
 | 
	
	
		
			
				|  | @@ -3292,23 +2915,6 @@ tor_mlockall(void)
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/** Identity of the "main" thread */
 | 
	
		
			
				|  |  | -static unsigned long main_thread_id = -1;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -/** Start considering the current thread to be the 'main thread'.  This has
 | 
	
		
			
				|  |  | - * no effect on anything besides in_main_thread(). */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | -set_main_thread(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  main_thread_id = tor_get_thread_id();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -/** Return true iff called from the main thread. */
 | 
	
		
			
				|  |  | -int
 | 
	
		
			
				|  |  | -in_main_thread(void)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  return main_thread_id == tor_get_thread_id();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * On Windows, WSAEWOULDBLOCK is not always correct: when you see it,
 | 
	
		
			
				|  |  |   * you need to ask the socket for its actual errno.  Also, you need to
 |