Commit 97b15a1d authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Extract the locking and logging code

The locking code gets its own module, since it's more fundamental
than the higher-level locking code.

Extracting the logging code was the whole point here. :)
parent 2cf033f2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -175,6 +175,8 @@ uptime-*.json
/src/lib/libtor-err-testing.a
/src/lib/libtor-intmath.a
/src/lib/libtor-intmath-testing.a
/src/lib/libtor-lock.a
/src/lib/libtor-lock-testing.a
/src/lib/libtor-malloc.a
/src/lib/libtor-malloc-testing.a
/src/lib/libtor-string.a
+4 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ endif
# "Common" libraries used to link tor's utility code.
TOR_UTIL_LIBS = \
	src/common/libor.a \
        src/lib/libtor-log.a \
        src/lib/libtor-lock.a \
	src/lib/libtor-container.a \
        src/lib/libtor-string.a \
	src/lib/libtor-malloc.a \
@@ -52,6 +54,8 @@ TOR_UTIL_LIBS = \
# and tests)
TOR_UTIL_TESTING_LIBS = \
	src/common/libor-testing.a \
        src/lib/libtor-log-testing.a \
        src/lib/libtor-lock-testing.a \
	src/lib/libtor-container-testing.a \
        src/lib/libtor-string-testing.a \
	src/lib/libtor-malloc-testing.a \
+1 −79
Original line number Diff line number Diff line
@@ -91,83 +91,6 @@ spawn_exit(void)
  pthread_exit(NULL);
}

/** A mutex attribute that we're going to use to tell pthreads that we want
 * "recursive" mutexes (i.e., once we can re-lock if we're already holding
 * them.) */
static pthread_mutexattr_t attr_recursive;

/** 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)
{
  if (PREDICT_UNLIKELY(!threads_initialized))
    tor_threads_init(); // LCOV_EXCL_LINE
  const int err = pthread_mutex_init(&mutex->mutex, &attr_recursive);
  if (PREDICT_UNLIKELY(err)) {
    // LCOV_EXCL_START
    raw_assert_unreached_msg("Error creating a mutex.");
    // LCOV_EXCL_STOP
  }
}

/** As tor_mutex_init, but initialize a mutex suitable that may be
 * non-recursive, if the OS supports that. */
void
tor_mutex_init_nonrecursive(tor_mutex_t *mutex)
{
  int err;
  if (!threads_initialized)
    tor_threads_init(); // LCOV_EXCL_LINE
  err = pthread_mutex_init(&mutex->mutex, NULL);
  if (PREDICT_UNLIKELY(err)) {
    // LCOV_EXCL_START
    raw_assert_unreached_msg("Error creating a mutex.");
    // LCOV_EXCL_STOP
  }
}

/** Wait until <b>m</b> is free, then acquire it. */
void
tor_mutex_acquire(tor_mutex_t *m)
{
  int err;
  raw_assert(m);
  err = pthread_mutex_lock(&m->mutex);
  if (PREDICT_UNLIKELY(err)) {
    // LCOV_EXCL_START
    raw_assert_unreached_msg("Error locking a mutex.");
    // LCOV_EXCL_STOP
  }
}
/** Release the lock <b>m</b> so another thread can have it. */
void
tor_mutex_release(tor_mutex_t *m)
{
  int err;
  raw_assert(m);
  err = pthread_mutex_unlock(&m->mutex);
  if (PREDICT_UNLIKELY(err)) {
    // LCOV_EXCL_START
    raw_assert_unreached_msg("Error unlocking a mutex.");
    // LCOV_EXCL_STOP
  }
}
/** 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;
  raw_assert(m);
  err = pthread_mutex_destroy(&m->mutex);
  if (PREDICT_UNLIKELY(err)) {
    // LCOV_EXCL_START
    raw_assert_unreached_msg("Error destroying a mutex.");
    // LCOV_EXCL_STOP
  }
}
/** Return an integer representing this thread. */
unsigned long
tor_get_thread_id(void)
@@ -328,8 +251,7 @@ void
tor_threads_init(void)
{
  if (!threads_initialized) {
    pthread_mutexattr_init(&attr_recursive);
    pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE);
    tor_locking_init();
    const int ret1 = pthread_attr_init(&attr_detached);
    tor_assert(ret1 == 0);
#ifndef PTHREAD_CREATE_DETACHED
+0 −28
Original line number Diff line number Diff line
@@ -29,33 +29,6 @@
#include <unistd.h>
#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;
}
/** Return a newly allocated, ready-for-use mutex.  This one might be
 * non-recursive, if that's faster. */
tor_mutex_t *
tor_mutex_new_nonrecursive(void)
{
  tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
  tor_mutex_init_nonrecursive(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);
}

/** Allocate and return a new condition variable. */
tor_cond_t *
tor_cond_new(void)
@@ -404,4 +377,3 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
  return oldval;
}
#endif /* !defined(HAVE_STDATOMIC_H) */
+1 −41
Original line number Diff line number Diff line
@@ -9,54 +9,15 @@
#include "orconfig.h"
#include "lib/cc/torint.h"
#include "lib/testsupport/testsupport.h"

#if defined(HAVE_PTHREAD_H) && !defined(_WIN32)
#include <pthread.h>
#endif
#include "lib/lock/compat_mutex.h"

#ifdef HAVE_STDATOMIC_H
#include <stdatomic.h>
#endif

#if defined(_WIN32)
#define USE_WIN32_THREADS
#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
#define USE_PTHREADS
#else
#error "No threading system was found"
#endif /* defined(_WIN32) || ... */

int spawn_func(void (*func)(void *), void *data);
void spawn_exit(void) ATTR_NORETURN;

/* Because we use threads instead of processes on most platforms (Windows,
 * Linux, etc), we need locking for them.  On platforms with poor thread
 * support or broken gethostbyname_r, these functions are no-ops. */

/** A generic lock structure for multithreaded builds. */
typedef struct tor_mutex_t {
#if defined(USE_WIN32_THREADS)
  /** Windows-only: on windows, we implement locks with CRITICAL_SECTIONS. */
  CRITICAL_SECTION mutex;
#elif defined(USE_PTHREADS)
  /** Pthreads-only: with pthreads, we implement locks with
   * pthread_mutex_t. */
  pthread_mutex_t mutex;
#else
  /** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
  int _unused;
#endif /* defined(USE_WIN32_THREADS) || ... */
} tor_mutex_t;

tor_mutex_t *tor_mutex_new(void);
tor_mutex_t *tor_mutex_new_nonrecursive(void);
void tor_mutex_init(tor_mutex_t *m);
void tor_mutex_init_nonrecursive(tor_mutex_t *m);
void tor_mutex_acquire(tor_mutex_t *m);
void tor_mutex_release(tor_mutex_t *m);
void tor_mutex_free_(tor_mutex_t *m);
#define tor_mutex_free(m) FREE_AND_NULL(tor_mutex_t, tor_mutex_free_, (m))
void tor_mutex_uninit(tor_mutex_t *m);
unsigned long tor_get_thread_id(void);
void tor_threads_init(void);

@@ -220,4 +181,3 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
#endif /* defined(HAVE_STDATOMIC_H) */

#endif /* !defined(TOR_COMPAT_THREADS_H) */
Loading