Browse Source

Thread safety.

Multiple threads might call error_string() so a static buffer is
dangerous.  Use TLS for a safe buffer.
Iain Patterson 11 years ago
parent
commit
70453ecb69
2 changed files with 17 additions and 3 deletions
  1. 12 3
      event.cpp
  2. 5 0
      nssm.cpp

+ 12 - 3
event.cpp

@@ -1,11 +1,20 @@
 #include "nssm.h"
 
-static char error_message[65535];
+#define NSSM_ERROR_BUFSIZE 65535
+unsigned long tls_index;
 
 /* Convert error code to error string - must call LocalFree() on return value */
 char *error_string(unsigned long error) {
-  if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &error_message, sizeof(error_message), 0)) {
-    if (_snprintf(error_message, sizeof(error_message), "system error %lu", error) < 0) return 0;
+  /* Thread-safe buffer */
+  char *error_message = (char *) TlsGetValue(tls_index);
+  if (! error_message) {
+    error_message = (char *) LocalAlloc(LPTR, NSSM_ERROR_BUFSIZE);
+    if (! error_message) return "<out of memory for error message>";
+    TlsSetValue(tls_index, (void *) error_message);
+  }
+
+  if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) error_message, NSSM_ERROR_BUFSIZE, 0)) {
+    if (_snprintf(error_message, NSSM_ERROR_BUFSIZE, "system error %lu", error) < 0) return 0;
   }
   return error_message;
 }

+ 5 - 0
nssm.cpp

@@ -1,5 +1,7 @@
 #include "nssm.h"
 
+extern unsigned long tls_index;
+
 /* String function */
 int str_equiv(const char *a, const char *b) {
   int i;
@@ -39,6 +41,9 @@ int main(int argc, char **argv) {
   /* Undocumented: "run" is used to actually do service stuff */
   if (! str_equiv(argv[1], NSSM_RUN)) exit(usage(2));
 
+  /* Thread local storage for error message buffer */
+  tls_index = TlsAlloc();
+
   /* Register messages */
   create_messages();