Thread safety.
authorIain Patterson <me@iain.cx>
Sat, 26 Feb 2011 11:50:13 +0000 (11:50 +0000)
committerIain Patterson <me@iain.cx>
Sat, 26 Feb 2011 11:50:13 +0000 (11:50 +0000)
Multiple threads might call error_string() so a static buffer is
dangerous.  Use TLS for a safe buffer.

event.cpp
nssm.cpp

index bd43be3..726c9f1 100644 (file)
--- a/event.cpp
+++ b/event.cpp
@@ -1,11 +1,20 @@
 #include "nssm.h"\r
 \r
-static char error_message[65535];\r
+#define NSSM_ERROR_BUFSIZE 65535\r
+unsigned long tls_index;\r
 \r
 /* Convert error code to error string - must call LocalFree() on return value */\r
 char *error_string(unsigned long error) {\r
-  if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &error_message, sizeof(error_message), 0)) {\r
-    if (_snprintf(error_message, sizeof(error_message), "system error %lu", error) < 0) return 0;\r
+  /* Thread-safe buffer */\r
+  char *error_message = (char *) TlsGetValue(tls_index);\r
+  if (! error_message) {\r
+    error_message = (char *) LocalAlloc(LPTR, NSSM_ERROR_BUFSIZE);\r
+    if (! error_message) return "<out of memory for error message>";\r
+    TlsSetValue(tls_index, (void *) error_message);\r
+  }\r
+\r
+  if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) error_message, NSSM_ERROR_BUFSIZE, 0)) {\r
+    if (_snprintf(error_message, NSSM_ERROR_BUFSIZE, "system error %lu", error) < 0) return 0;\r
   }\r
   return error_message;\r
 }\r
index 3ba473f..2933dea 100644 (file)
--- a/nssm.cpp
+++ b/nssm.cpp
@@ -1,5 +1,7 @@
 #include "nssm.h"\r
 \r
+extern unsigned long tls_index;\r
+\r
 /* String function */\r
 int str_equiv(const char *a, const char *b) {\r
   int i;\r
@@ -39,6 +41,9 @@ int main(int argc, char **argv) {
   /* Undocumented: "run" is used to actually do service stuff */\r
   if (! str_equiv(argv[1], NSSM_RUN)) exit(usage(2));\r
 \r
+  /* Thread local storage for error message buffer */\r
+  tls_index = TlsAlloc();\r
+\r
   /* Register messages */\r
   create_messages();\r
 \r