Commit fd992dee authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Don't attempt to log messages to a controller from a worker thread.

This patch adds a function to determine whether we're in the main
thread, and changes control_event_logmsg() to return immediately if
we're in a subthread.  This is necessary because otherwise we will
call connection_write_to_buf, which modifies non-locked data
structures.

Bugfix on 0.2.0.x; fix for at least one of the things currently
called "bug 977".
parent d66c3797
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@ Changes in version 0.2.1.16-?? - 2009-??-??
    - Don't warn users about low port and hibernation mix when they
      provide a *ListenAddress directive to fix that. Bugfix on
      0.2.1.15-rc.
    - Fix a race condition that could cause crashes or memory
      corruption when running as a server with a controller listening
      for log messages.

  o Minor bugfixes (on 0.2.1.x):
    - When switching back and forth between bridge mode, do not start
+19 −0
Original line number Diff line number Diff line
@@ -2076,6 +2076,7 @@ tor_threads_init(void)
    pthread_mutexattr_init(&attr_reentrant);
    pthread_mutexattr_settype(&attr_reentrant, PTHREAD_MUTEX_RECURSIVE);
    threads_initialized = 1;
    set_main_thread();
  }
}
#elif defined(USE_WIN32_THREADS)
@@ -2168,9 +2169,27 @@ tor_threads_init(void)
#if 0
  cond_event_tls_index = TlsAlloc();
#endif
  set_main_thread();
}
#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
+3 −0
Original line number Diff line number Diff line
@@ -522,6 +522,9 @@ void tor_threads_init(void);
#define tor_threads_init() STMT_NIL
#endif

void set_main_thread(void);
int in_main_thread(void);

#ifdef TOR_IS_MULTITHREADED
#if 0
typedef struct tor_cond_t tor_cond_t;
+2 −0
Original line number Diff line number Diff line
@@ -2480,6 +2480,8 @@ start_daemon(void)
    if (fork() != 0) {
      exit(0);
    }
    set_main_thread(); /* We are now the main thread. */

    return;
  }
}
+5 −0
Original line number Diff line number Diff line
@@ -3367,6 +3367,11 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
{
  int event;

  /* Don't even think of trying to add stuff to a buffer from a cpuworker
   * thread. */
  if (! in_main_thread())
    return;

  if (disable_log_messages)
    return;