VLOG_DEFINE_THIS_MODULE(lockfile);
COVERAGE_DEFINE(lockfile_lock);
-COVERAGE_DEFINE(lockfile_timeout);
COVERAGE_DEFINE(lockfile_error);
COVERAGE_DEFINE(lockfile_unlock);
dev_t device;
ino_t inode;
int fd;
+ HANDLE lock_handle;
};
/* Lock table.
= &lock_table__;
static void lockfile_unhash(struct lockfile *);
-static int lockfile_try_lock(const char *name, pid_t *pidp,
- struct lockfile **lockfilep);
+#ifdef _WIN32
+static int lockfile_try_lock_windows(const char *name, pid_t *pidp,
+ struct lockfile **lockfilep);
+static void lockfile_unlock_windows(struct lockfile * lockfile);
+#else
+static int lockfile_try_lock_posix(const char *name, pid_t *pidp,
+ struct lockfile **lockfilep);
+#endif
/* Returns the name of the lockfile that would be created for locking a file
* named 'filename_'. The caller is responsible for freeing the returned name,
lock_name = lockfile_name(file);
ovs_mutex_lock(&lock_table_mutex);
- error = lockfile_try_lock(lock_name, &pid, lockfilep);
+#ifdef _WIN32
+ error = lockfile_try_lock_windows(lock_name, &pid, lockfilep);
+#else
+ error = lockfile_try_lock_posix(lock_name, &pid, lockfilep);
+#endif
ovs_mutex_unlock(&lock_table_mutex);
if (error) {
{
if (lockfile) {
ovs_mutex_lock(&lock_table_mutex);
+#ifdef _WIN32
+ lockfile_unlock_windows(lockfile);
+#else
lockfile_unhash(lockfile);
+#endif
ovs_mutex_unlock(&lock_table_mutex);
COVERAGE_INC(lockfile_unlock);
return lockfile;
}
+#ifdef _WIN32
+static void
+lockfile_unlock_windows(struct lockfile *lockfile)
+ OVS_REQUIRES(&lock_table_mutex)
+{
+ if (lockfile->fd >= 0) {
+ OVERLAPPED overl;
+ overl.hEvent = 0;
+ overl.Offset = 0;
+ overl.OffsetHigh = 0;
+ UnlockFileEx(lockfile->lock_handle, 0, 1, 0, &overl);
+
+ close(lockfile->fd);
+ lockfile->fd = -1;
+ }
+}
+
+static int
+lockfile_try_lock_windows(const char *name, pid_t *pidp,
+ struct lockfile **lockfilep)
+ OVS_REQUIRES(&lock_table_mutex)
+{
+ HANDLE lock_handle;
+ BOOL retval;
+ OVERLAPPED overl;
+ struct lockfile *lockfile;
+ int fd;
+
+ *pidp = 0;
+
+ fd = open(name, O_RDWR | O_CREAT, 0600);
+ if (fd < 0) {
+ VLOG_WARN("%s: failed to open lock file: %s",
+ name, ovs_strerror(errno));
+ return errno;
+ }
+
+ lock_handle = (HANDLE)_get_osfhandle(fd);
+ if (lock_handle < 0) {
+ VLOG_WARN("%s: failed to get the file handle: %s",
+ name, ovs_strerror(errno));
+ return errno;
+ }
+
+ /* Lock the file 'name' for the region that includes just the first
+ * byte. */
+ overl.hEvent = 0;
+ overl.Offset = 0;
+ overl.OffsetHigh = 0;
+ retval = LockFileEx(lock_handle, LOCKFILE_EXCLUSIVE_LOCK
+ | LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &overl);
+ if (!retval) {
+ VLOG_WARN("Failed to lock file : %s", ovs_lasterror_to_string());
+ return EEXIST;
+ }
+
+ lockfile = xmalloc(sizeof *lockfile);
+ lockfile->name = xstrdup(name);
+ lockfile->fd = fd;
+ lockfile->lock_handle = lock_handle;
+
+ *lockfilep = lockfile;
+ return 0;
+}
+#endif
+
+#ifndef _WIN32
static int
-lockfile_try_lock(const char *name, pid_t *pidp, struct lockfile **lockfilep)
+lockfile_try_lock_posix(const char *name, pid_t *pidp,
+ struct lockfile **lockfilep)
OVS_REQUIRES(&lock_table_mutex)
{
struct flock l;
}
return error;
}
-
+#endif