ActiveLock *lockList;
} LockValues;
+/*
+ * The lock token. This is returned by the lock operation and must be sent
+ * to the unlock operation.
+ */
+
+#define FILE_LOCK_TOKEN_SIGNATURE 0x4B434C46 // 'FLCK' in memory
+
+struct FileLockToken
+{
+ uint32 signature;
+ Unicode pathName;
+ Unicode lockFilePath; // &implicitReadToken for implicit read locks
+};
+
+typedef struct FileLockToken FileLockToken;
+
#include "file_extensions.h"
#define FILELOCK_SUFFIX "." LOCK_FILE_EXTENSION
uint32 requestedBytes,
uint32 *resultantBytes);
-EXTERN void *FileLockIntrinsic(ConstUnicode filePathName,
- Bool exclusivity,
- uint32 msecMaxWaitTime,
- const char *payload,
- int *err);
+EXTERN FileLockToken *FileLockIntrinsic(ConstUnicode filePathName,
+ Bool exclusivity,
+ uint32 msecMaxWaitTime,
+ const char *payload,
+ int *err);
-EXTERN int FileUnlockIntrinsic(ConstUnicode filePathName,
- const void *lockToken);
+EXTERN int FileUnlockIntrinsic(FileLockToken *tokenPtr);
EXTERN Bool FileLockIsLocked(ConstUnicode filePath,
int *err);
const uint32 msecMaxWaitTime, // IN:
int *err) // OUT:
{
- void *lockToken;
Unicode normalizedPath;
+ FileLockToken *tokenPtr;
ASSERT(filePath);
ASSERT(err);
if (normalizedPath == NULL) {
*err = EINVAL;
- lockToken = NULL;
+ tokenPtr = NULL;
} else {
char creationTimeString[32];
Str_Sprintf(creationTimeString, sizeof creationTimeString, "%"FMT64"u",
ProcessCreationTime(getpid()));
- lockToken = FileLockIntrinsic(normalizedPath, !readOnly, msecMaxWaitTime,
- creationTimeString, err);
+ tokenPtr = FileLockIntrinsic(normalizedPath, !readOnly, msecMaxWaitTime,
+ creationTimeString, err);
Unicode_Free(normalizedPath);
}
- return lockToken;
+ return (void *) tokenPtr;
}
FileLock_Unlock(ConstUnicode filePath, // IN:
const void *lockToken) // IN:
{
- int err;
- Unicode normalizedPath;
-
ASSERT(filePath);
ASSERT(lockToken);
- normalizedPath = FileLockNormalizePath(filePath);
- if (normalizedPath == NULL) {
- err = EINVAL;
- } else {
- err = FileUnlockIntrinsic(normalizedPath, lockToken);
-
- Unicode_Free(normalizedPath);
- }
-
- return err;
+ return FileUnlockIntrinsic((FileLockToken *) lockToken);
}
#include "fileInt.h"
#include "random.h"
#include "vm_atomic.h"
+#include "util.h"
#include "unicodeOperations.h"
*/
int
-FileUnlockIntrinsic(ConstUnicode pathName, // IN:
- const void *lockToken) // IN:
+FileUnlockIntrinsic(FileLockToken *tokenPtr) // IN:
{
int err;
- ASSERT(pathName);
- ASSERT(lockToken);
+ ASSERT(tokenPtr && (tokenPtr->signature == FILE_LOCK_TOKEN_SIGNATURE));
- LOG(1, ("Requesting unlock on %s\n", UTF8(pathName)));
+ LOG(1, ("Requesting unlock on %s\n", UTF8(tokenPtr->pathName)));
- if (lockToken == &implicitReadToken) {
- /*
- * The lock token is the fixed-address implicit read lock token.
- * Since no lock file was created no further action is required.
- */
+ /*
+ * If the lockFilePath (a pointer) is the fixed-address token representing
+ * an implicit read lock, there is no lock file and the token can simply
+ * be discarded.
+ */
+ if (tokenPtr->lockFilePath == &implicitReadToken) {
err = 0;
+
+ free(tokenPtr->pathName);
} else {
Unicode lockDir;
/* The lock directory path */
- lockDir = Unicode_Append(pathName, FILELOCK_SUFFIX);
+ lockDir = Unicode_Append(tokenPtr->pathName, FILELOCK_SUFFIX);
/*
- * The lock token is the (unicode) path of the lock file.
- *
* TODO: under vmx86_debug validate the contents of the lock file as
* matching the machineID and executionID.
*/
- err = FileDeletionRobust((Unicode) lockToken, FALSE);
+ err = FileDeletionRobust(tokenPtr->lockFilePath, FALSE);
if (err && vmx86_debug) {
Log(LGPFX" %s failed for '%s': %s\n",
- __FUNCTION__, (char *) lockToken, Err_Errno2String(err));
+ __FUNCTION__, tokenPtr->lockFilePath, Err_Errno2String(err));
}
/*
- * The lockToken (a unicode path) was allocated in FileLockIntrinsic
- * and returned to the caller hidden behind a "void *" pointer.
+ * Attempt to clean up the locking directory.
*/
- Unicode_Free((Unicode) lockToken);
-
FileRemoveDirectoryRobust(lockDir); // just in case we can clean up
Unicode_Free(lockDir);
+ free(tokenPtr->lockFilePath);
+ free(tokenPtr->pathName);
}
+ tokenPtr->signature = 0; // Just in case...
+ free(tokenPtr);
+
return err;
}
*-----------------------------------------------------------------------------
*/
-void *
+FileLockToken *
FileLockIntrinsic(ConstUnicode pathName, // IN:
Bool exclusivity, // IN:
uint32 msecMaxWaitTime, // IN:
FILELOCK_FILE_HANDLE handle;
LockValues myValues;
int createFlags;
+ FileLockToken *tokenPtr;
Unicode lockDir = NULL;
Unicode entryFilePath = NULL;
free(myValues.locationChecksum);
free(myValues.executionID);
- if (*err != 0) {
+ if (*err == 0) {
+ tokenPtr = Util_SafeMalloc(sizeof(FileLockToken));
+
+ tokenPtr->signature = FILE_LOCK_TOKEN_SIGNATURE;
+ tokenPtr->pathName = Unicode_Duplicate(pathName);
+ tokenPtr->lockFilePath = memberFilePath;
+ } else {
Unicode_Free(memberFilePath);
- memberFilePath = NULL;
+ tokenPtr = NULL;
if (*err == EAGAIN) {
*err = 0; // lock not acquired
}
}
- return (void *) memberFilePath;
+ return tokenPtr;
}