[Box Backup-commit] COMMIT r3549 - in box/trunk: lib/common test/common

subversion at boxbackup.org subversion at boxbackup.org
Mon Apr 13 18:59:31 BST 2015


Author: chris
Date: 2015-04-13 17:59:30 +0000 (Mon, 13 Apr 2015)
New Revision: 3549

Modified:
   box/trunk/lib/common/NamedLock.cpp
   box/trunk/lib/common/NamedLock.h
   box/trunk/test/common/testcommon.cpp
Log:
Fix file locking on Windows.

NamedLock simply didn't work before. This may cause test failures, but the
tests are already failing on Windows, and must be fixed.

Modified: box/trunk/lib/common/NamedLock.cpp
===================================================================
--- box/trunk/lib/common/NamedLock.cpp	2015-04-06 19:41:30 UTC (rev 3548)
+++ box/trunk/lib/common/NamedLock.cpp	2015-04-13 17:59:30 UTC (rev 3549)
@@ -73,6 +73,8 @@
 		THROW_EXCEPTION(CommonException, NamedLockAlreadyLockingSomething)
 	}
 
+	mFileName = rFilename;
+
 	// See if the lock can be got
 #if HAVE_DECL_O_EXLOCK
 	int fd = ::open(rFilename.c_str(),
@@ -94,11 +96,28 @@
 
 	return false;
 #else
-	int fd = ::open(rFilename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode);
+	int flags = O_WRONLY | O_CREAT | O_TRUNC;
+
+# if !HAVE_DECL_F_SETLK && !defined HAVE_FLOCK
+	// We have no other way to get a lock, so all we can do is fail if
+	// the file already exists, and take the risk of stale locks.
+	flags |= O_EXCL;
+# endif
+
+	int fd = ::open(rFilename.c_str(), flags, mode);
 	if(fd == -1)
 	{
-		THROW_SYS_FILE_ERROR("Failed to open lockfile", rFilename,
-			CommonException, OSFileError);
+		if(errno == EEXIST && (flags & O_EXCL))
+		{
+			// Lockfile already exists, and we tried to open it
+			// exclusively, which means we failed to lock it.
+			return false;
+		}
+		else
+		{
+			THROW_SYS_FILE_ERROR("Failed to open lockfile",
+				rFilename, CommonException, OSFileError);
+		}
 	}
 
 #ifdef HAVE_FLOCK
@@ -162,8 +181,20 @@
 	// Close the file
 	if(::close(mFileDescriptor) != 0)
 	{
-		THROW_EXCEPTION(CommonException, OSFileError)
+		THROW_EMU_ERROR(
+			BOX_FILE_MESSAGE(mFileName, "Failed to close lockfile"),
+			CommonException, OSFileError);
 	}
+
+	// Delete the file
+	if(::unlink(mFileName.c_str()) != 0)
+	{
+		THROW_EMU_ERROR(
+			BOX_FILE_MESSAGE(mFileName,
+				"Failed to delete lockfile"),
+			CommonException, OSFileError);
+	}
+
 	// Mark as unlocked
 	mFileDescriptor = -1;
 }

Modified: box/trunk/lib/common/NamedLock.h
===================================================================
--- box/trunk/lib/common/NamedLock.h	2015-04-06 19:41:30 UTC (rev 3548)
+++ box/trunk/lib/common/NamedLock.h	2015-04-13 17:59:30 UTC (rev 3549)
@@ -35,6 +35,7 @@
 	
 private:
 	int mFileDescriptor;
+	std::string mFileName;
 };
 
 #endif // NAMEDLOCK__H

Modified: box/trunk/test/common/testcommon.cpp
===================================================================
--- box/trunk/test/common/testcommon.cpp	2015-04-06 19:41:30 UTC (rev 3548)
+++ box/trunk/test/common/testcommon.cpp	2015-04-13 17:59:30 UTC (rev 3549)
@@ -262,6 +262,18 @@
 		TEST_THAT(!TestFileExists(tempfile.c_str()));
 	}
 
+	// Test that named locks work as expected
+	{
+		NamedLock lock1;
+		TEST_THAT(lock1.TryAndGetLock("testfiles/locktest"));
+		// With a lock held, we should not be able to acquire another.
+		TEST_THAT(!NamedLock().TryAndGetLock("testfiles/locktest"));
+	}
+	{
+		// But with the lock released, we should be able to.
+		TEST_THAT(NamedLock().TryAndGetLock("testfiles/locktest"));
+	}
+
 	// Test that memory leak detection doesn't crash
 	{
 		char *test = new char[1024];




More information about the Boxbackup-commit mailing list