Merge branch 'mainstream'
[sliver-openvswitch.git] / lib / lockfile.c
index c37f332..50a4e0c 100644 (file)
@@ -1,4 +1,4 @@
- /* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ /* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
 #include "coverage.h"
 #include "hash.h"
 #include "hmap.h"
+#include "ovs-thread.h"
 #include "timeval.h"
 #include "util.h"
 #include "vlog.h"
@@ -54,6 +55,9 @@ struct lockfile {
  * once. */
 static struct hmap lock_table = HMAP_INITIALIZER(&lock_table);
 
+/* Protects 'lock_table'. */
+static pthread_mutex_t lock_table_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static void lockfile_unhash(struct lockfile *);
 static int lockfile_try_lock(const char *name, pid_t *pidp,
                              struct lockfile **lockfilep);
@@ -106,7 +110,9 @@ lockfile_lock(const char *file, struct lockfile **lockfilep)
 
     lock_name = lockfile_name(file);
 
+    xpthread_mutex_lock(&lock_table_mutex);
     error = lockfile_try_lock(lock_name, &pid, lockfilep);
+    xpthread_mutex_unlock(&lock_table_mutex);
 
     if (error) {
         COVERAGE_INC(lockfile_error);
@@ -118,7 +124,7 @@ lockfile_lock(const char *file, struct lockfile **lockfilep)
                       "pid %ld", lock_name, (long int) pid);
         } else {
             VLOG_WARN("%s: failed to lock file: %s",
-                      lock_name, strerror(error));
+                      lock_name, ovs_strerror(error));
         }
     }
 
@@ -132,8 +138,11 @@ void
 lockfile_unlock(struct lockfile *lockfile)
 {
     if (lockfile) {
-        COVERAGE_INC(lockfile_unlock);
+        xpthread_mutex_lock(&lock_table_mutex);
         lockfile_unhash(lockfile);
+        xpthread_mutex_unlock(&lock_table_mutex);
+
+        COVERAGE_INC(lockfile_unlock);
         free(lockfile->name);
         free(lockfile);
     }
@@ -225,7 +234,7 @@ lockfile_try_lock(const char *name, pid_t *pidp, struct lockfile **lockfilep)
         }
     } else if (errno != ENOENT) {
         VLOG_WARN("%s: failed to stat lock file: %s",
-                  name, strerror(errno));
+                  name, ovs_strerror(errno));
         return errno;
     }
 
@@ -233,13 +242,14 @@ lockfile_try_lock(const char *name, pid_t *pidp, struct lockfile **lockfilep)
     fd = open(name, O_RDWR | O_CREAT, 0600);
     if (fd < 0) {
         VLOG_WARN("%s: failed to open lock file: %s",
-                  name, strerror(errno));
+                  name, ovs_strerror(errno));
         return errno;
     }
 
     /* Get the inode and device number for the lock table. */
     if (fstat(fd, &s)) {
-        VLOG_ERR("%s: failed to fstat lock file: %s", name, strerror(errno));
+        VLOG_ERR("%s: failed to fstat lock file: %s",
+                 name, ovs_strerror(errno));
         close(fd);
         return errno;
     }