Browse Source

Merge branch 'issue-202'

Alexei Pastuchov 6 years ago
parent
commit
a333f31cac
4 changed files with 62 additions and 17 deletions
  1. 30 10
      libtest/signal.cc
  2. 3 1
      libtest/signal.h
  3. 26 5
      util/signal.cc
  4. 3 1
      util/signal.hpp

+ 30 - 10
libtest/signal.cc

@@ -39,6 +39,7 @@
 
 #include <fcntl.h>
 #include <semaphore.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include <csignal>
@@ -94,7 +95,7 @@ void SignalThread::test()
 {
   fatal_assert(magic_memory == MAGIC_MEMORY);
 
-  if (bool(getenv("LIBTEST_IN_GDB")) == false)
+  if (!getenv("LIBTEST_IN_GDB"))
   {
     assert(sigismember(&set, SIGALRM));
     assert(sigismember(&set, SIGABRT));
@@ -117,6 +118,27 @@ bool SignalThread::unblock()
   return true;
 }
 
+std::string SignalThread::random_lock_name(std::string::size_type len = 10)
+{
+  static auto& chrs = "0123456789"
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+  thread_local static std::mt19937 rg{std::random_device{}()};
+  thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
+
+  // convenient to named semaphore definition
+  // http://man7.org/linux/man-pages/man7/sem_overview.7.html
+  std::string s{"/"};
+  s.reserve(len--);
+
+  while (len--)
+  {
+    s += chrs[pick(rg)];
+  }
+  return s;
+}
+
 SignalThread::~SignalThread()
 {
   if (is_shutdown() == false)
@@ -198,11 +220,12 @@ static void *sig_thread(void *arg)
 
 SignalThread::SignalThread() :
   magic_memory(MAGIC_MEMORY),
+  __shutdown{},
   thread(pthread_self())
 {
   pthread_mutex_init(&shutdown_mutex, NULL);
   sigemptyset(&set);
-  if (bool(getenv("LIBTEST_IN_GDB")) == false)
+  if (!getenv("LIBTEST_IN_GDB"))
   {
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIGABRT);
@@ -211,12 +234,7 @@ SignalThread::SignalThread() :
     sigaddset(&set, SIGVTALRM);
   }
   sigaddset(&set, SIGPIPE);
-
   sigaddset(&set, SIGUSR2);
-
-  strcpy(lock_name, "/XXXXXXXX");
-  mktemp(lock_name);
-
   sigemptyset(&original_set);
   pthread_sigmask(SIG_BLOCK, NULL, &original_set);
 }
@@ -225,13 +243,15 @@ SignalThread::SignalThread() :
 bool SignalThread::setup()
 {
   set_shutdown(SHUTDOWN_RUNNING);
-  lock = sem_open(lock_name, O_CREAT|O_EXCL);
+
+  const char * lock_name = random_lock_name().c_str();
+  lock = sem_open(lock_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
   if (lock == SEM_FAILED)
   {
-    Error << strerror(errno) << " when opening lock.";
+    Error << errno << ": " << strerror(errno)
+          << " when opening lock '" << lock_name << "'.";
   }
 
-
   if (sigismember(&original_set, SIGQUIT))
   {
     Error << strsignal(SIGQUIT) << " has been previously set.";

+ 3 - 1
libtest/signal.h

@@ -39,6 +39,7 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
+#include <random>
 
 enum shutdown_t {
   SHUTDOWN_RUNNING,
@@ -50,7 +51,6 @@ namespace libtest {
 
 class SignalThread {
   sigset_t set;
-  char lock_name[10];
   sem_t *lock;
   uint64_t magic_memory;
   volatile shutdown_t __shutdown;
@@ -58,6 +58,8 @@ class SignalThread {
   pthread_t thread;
   sigset_t original_set;
 
+  std::string random_lock_name(std::string::size_type);
+
 public:
 
   SignalThread();

+ 26 - 5
util/signal.cc

@@ -35,7 +35,9 @@
  */
 
 #include "gear_config.h"
+#include <fcntl.h>
 #include <semaphore.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include <cassert>
@@ -109,6 +111,26 @@ void SignalThread::sighup(signal_callback_fn* arg)
   _sighup= arg;
 }
 
+std::string SignalThread::random_lock_name(std::string::size_type len = 10)
+{
+  static auto& chrs = "0123456789"
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+  thread_local static std::mt19937 rg{std::random_device{}()};
+  thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
+
+  // convenient to named semaphore definition
+  // http://man7.org/linux/man-pages/man7/sem_overview.7.html
+  std::string s{"/"};
+  s.reserve(len--);
+
+  while (len--)
+  {
+    s += chrs[pick(rg)];
+  }
+  return s;
+}
 void SignalThread::sighup()
 {
   if (_sighup)
@@ -204,9 +226,6 @@ SignalThread::SignalThread(bool exit_on_signal_arg) :
   sigaddset(&set, SIGQUIT);
   sigaddset(&set, SIGTERM);
   sigaddset(&set, SIGUSR2);
-
-  strcpy(lock_name, "/XXXXXXXXX");
-  mktemp(lock_name);
 }
 
 
@@ -227,9 +246,11 @@ bool SignalThread::setup()
     return false;
   }
 
-  lock = sem_open(lock_name, 0, 0);
+  const char * lock_name = random_lock_name().c_str();
+  lock = sem_open(lock_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
   if (lock == SEM_FAILED) {
-    std::cerr << "WARNING: sem_open failed(" << strerror(errno) << ")" << std::endl;
+    std::cerr << "WARNING: sem_open failed(" << strerror(errno) << ")"
+              << " when opening lock '" << lock_name << "'." << std::endl;
   } else {
     sem_wait(lock);
   }

+ 3 - 1
util/signal.hpp

@@ -38,6 +38,7 @@
 
 #include <pthread.h>
 #include <semaphore.h>
+#include <random>
 
 #ifdef HAVE_SIGNAL_H
 #include <signal.h>
@@ -65,12 +66,13 @@ enum shutdown_t {
 class SignalThread {
   bool _exit_on_signal;
   sigset_t set;
-  char lock_name[11];
   sem_t *lock;
   uint64_t magic_memory;
   volatile shutdown_t __shutdown;
   pthread_mutex_t shutdown_mutex;
 
+  std::string random_lock_name(std::string::size_type);
+
 public:
 
   SignalThread(bool exit_on_signal_arg= false);