summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2015-12-14 23:02:09 +0000
committerChris Wilson <chris+github@qwirx.com>2015-12-14 23:02:09 +0000
commit48c7dd5e90885b42371c5d0153b8f457925fb5cd (patch)
treea10c1701156d85ddd143036046ed0ab63564afb7 /lib
parent3e43e6766d48ad9b5cf9798e9106fb820581c681 (diff)
Really fix file locking on Windows
Diffstat (limited to 'lib')
-rw-r--r--lib/common/NamedLock.cpp44
-rw-r--r--lib/common/NamedLock.h10
2 files changed, 51 insertions, 3 deletions
diff --git a/lib/common/NamedLock.cpp b/lib/common/NamedLock.cpp
index e440408e..8e672ff5 100644
--- a/lib/common/NamedLock.cpp
+++ b/lib/common/NamedLock.cpp
@@ -36,7 +36,11 @@
//
// --------------------------------------------------------------------------
NamedLock::NamedLock()
- : mFileDescriptor(-1)
+#ifdef WIN32
+: mFileDescriptor(INVALID_HANDLE_VALUE)
+#else
+: mFileDescriptor(-1)
+#endif
{
}
@@ -50,7 +54,11 @@ NamedLock::NamedLock()
// --------------------------------------------------------------------------
NamedLock::~NamedLock()
{
+#ifdef WIN32
+ if(mFileDescriptor != INVALID_HANDLE_VALUE)
+#else
if(mFileDescriptor != -1)
+#endif
{
ReleaseLock();
}
@@ -69,7 +77,11 @@ NamedLock::~NamedLock()
bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode)
{
// Check
+#ifdef WIN32
+ if(mFileDescriptor != INVALID_HANDLE_VALUE)
+#else
if(mFileDescriptor != -1)
+#endif
{
THROW_EXCEPTION(CommonException, NamedLockAlreadyLockingSomething)
}
@@ -94,8 +106,13 @@ bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode)
BOX_TRACE("Trying to create lockfile " << rFilename << " without special flags");
#endif
+#ifdef WIN32
+ HANDLE fd = openfile(rFilename.c_str(), flags, mode);
+ if(fd == INVALID_HANDLE_VALUE)
+#else
int fd = ::open(rFilename.c_str(), flags, mode);
if(fd == -1)
+#endif
#if HAVE_DECL_O_EXLOCK
{ // if()
if(errno == EWOULDBLOCK)
@@ -114,7 +131,11 @@ bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode)
}
#else // !HAVE_DECL_O_EXLOCK
{ // if()
+# if defined BOX_OPEN_LOCK
+ if(errno == EBUSY)
+# else // !BOX_OPEN_LOCK
if(errno == EEXIST && (flags & O_EXCL))
+# endif
{
// Lockfile already exists, and we tried to open it
// exclusively, which means we failed to lock it.
@@ -174,7 +195,11 @@ bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode)
}
catch(BoxException &e)
{
+# ifdef WIN32
+ CloseHandle(fd);
+# else
::close(fd);
+# endif
BOX_NOTICE("Failed to lock lockfile " << rFilename << ": " << e.what());
throw;
}
@@ -184,7 +209,11 @@ bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode)
{
BOX_ERROR("Locked lockfile " << rFilename << ", but lockfile no longer "
"exists, bailing out");
+# ifdef WIN32
+ CloseHandle(fd);
+# else
::close(fd);
+# endif
return false;
}
@@ -206,7 +235,11 @@ bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode)
void NamedLock::ReleaseLock()
{
// Got a lock?
+#ifdef WIN32
+ if(mFileDescriptor == INVALID_HANDLE_VALUE)
+#else
if(mFileDescriptor == -1)
+#endif
{
THROW_EXCEPTION(CommonException, NamedLockNotHeld)
}
@@ -232,7 +265,11 @@ void NamedLock::ReleaseLock()
#endif // !WIN32
// Close the file
+# ifdef WIN32
+ if(!CloseHandle(mFileDescriptor))
+# else
if(::close(mFileDescriptor) != 0)
+# endif
{
THROW_EMU_ERROR(
BOX_FILE_MESSAGE(mFileName, "Failed to close lockfile"),
@@ -240,7 +277,11 @@ void NamedLock::ReleaseLock()
}
// Mark as unlocked, so we don't try to close it again if the unlink() fails.
+#ifdef WIN32
+ mFileDescriptor = INVALID_HANDLE_VALUE;
+#else
mFileDescriptor = -1;
+#endif
#ifdef WIN32
// On Windows we need to close the file before deleting it, otherwise
@@ -256,4 +297,3 @@ void NamedLock::ReleaseLock()
BOX_TRACE("Released lock and deleted lockfile " << mFileName);
}
-
diff --git a/lib/common/NamedLock.h b/lib/common/NamedLock.h
index 09f5001a..a7d0d778 100644
--- a/lib/common/NamedLock.h
+++ b/lib/common/NamedLock.h
@@ -29,12 +29,20 @@ private:
public:
bool TryAndGetLock(const std::string& rFilename, int mode = 0755);
+# ifdef WIN32
+ bool GotLock() {return mFileDescriptor != INVALID_HANDLE_VALUE;}
+# else
bool GotLock() {return mFileDescriptor != -1;}
+# endif
void ReleaseLock();
-
private:
+# ifdef WIN32
+ HANDLE mFileDescriptor;
+# else
int mFileDescriptor;
+# endif
+
std::string mFileName;
};