[Core/Utils] Make logging utility functions be thread-safe
authorWook Song <wook16.song@samsung.com>
Fri, 23 Aug 2019 10:18:40 +0000 (19:18 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Tue, 27 Aug 2019 02:10:17 +0000 (11:10 +0900)
This patch makes logging utility functions be thread-safe.

Signed-off-by: Wook Song <wook16.song@samsung.com>
src/core/ne-utils.c

index 022bbe0..fbcf129 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -245,6 +246,8 @@ hash_table_del (hash_table *ht, hash_node *node)
  ********************************************************************/
 #define logfilename "npu-engine.log"
 
+static pthread_mutex_t priv_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 /**
  * @brief Log Level String in 5 characters
  */
@@ -283,32 +286,45 @@ static FILE *fp = NULL;
  * @param[in] m Module designation
  */
 void logwrite(loglevel l, module m, const char *format, ...) {
-  va_list args;
-  time_t ltime;
+  time_t ltime = time (NULL);
   char* time_str;
+  va_list args;
 
-  ltime = time(NULL);
-
+  pthread_mutex_lock (&priv_mutex);
   if (fp == NULL) {
     char filename[FILENAME_MAX];
 
     snprintf(filename, FILENAME_MAX, "%s%s", conf->log_dir, logfilename);
     fp = fopen(filename, "a");
   }
+  pthread_mutex_unlock (&priv_mutex);
 
   assert(fp != NULL);
 
-  /* asctime() generates a new line; so remove it */
+  /**
+   * localtime() and asctime() are not MT-safe. There are alternatives,
+   * localtime_r() and asctime_r(), when __USE_POSIX is set. Without them, we
+   * need critical section here.
+   */
+  pthread_mutex_lock (&priv_mutex);
   time_str = asctime(localtime(&ltime));
-  time_str[strlen(time_str) - 1] = '\x00';
-  fprintf(fp, "[%s][%s][%s] ", loglevelstr[l], modulestr[m], time_str);
+  pthread_mutex_unlock (&priv_mutex);
 
+  time_str[strcspn(time_str, "\n")] = '\x00';
+  fprintf(fp, "[%s][%s][%s] ", loglevelstr[l], modulestr[m], time_str);
   va_start (args, format);
   vfprintf(fp, format, args);
   va_end (args);
 }
 
 void fini_logwrite (void) {
-  if (fp != NULL)
+  pthread_mutex_lock (&priv_mutex);
+  if (fp != NULL) {
     fclose(fp);
+    fp = NULL;
+  }
+  pthread_mutex_unlock (&priv_mutex);
+
+  /* Harmless statement */
+  pthread_mutex_init (&priv_mutex, NULL);
 }