implement windows locking for atomic functions

This commit is contained in:
David Rose 2006-06-20 15:49:52 +00:00
parent 9814a2bbc4
commit 696a0afb0b
1 changed files with 109 additions and 5 deletions

View File

@ -1953,8 +1953,70 @@ atomic_compare_and_exchange_contents(string &orig_contents,
const string &old_contents,
const string &new_contents) const {
#ifdef WIN32_VC
// Todo.
return false;
string os_specific = to_os_specific();
HANDLE hfile = CreateFile(os_specific.c_str(), GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
while (hfile == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
if (error == ERROR_SHARING_VIOLATION) {
// If the file is locked by another process, yield and try again.
Sleep(0);
hfile = CreateFile(os_specific.c_str(), GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
} else {
cerr << "Couldn't open file: " << os_specific
<< ", error " << error << "\n";
return false;
}
}
if (hfile == INVALID_HANDLE_VALUE) {
cerr << "Couldn't open file: " << os_specific
<< ", error " << GetLastError() << "\n";
return false;
}
static const size_t buf_size = 512;
char buf[buf_size];
orig_contents = string();
DWORD bytes_read;
if (!ReadFile(hfile, buf, buf_size, &bytes_read, NULL)) {
cerr << "Error reading file: " << os_specific
<< ", error " << GetLastError() << "\n";
CloseHandle(hfile);
return false;
}
while (bytes_read > 0) {
orig_contents += string(buf, bytes_read);
if (!ReadFile(hfile, buf, buf_size, &bytes_read, NULL)) {
cerr << "Error reading file: " << os_specific
<< ", error " << GetLastError() << "\n";
CloseHandle(hfile);
return false;
}
}
bool match = false;
if (orig_contents == old_contents) {
match = true;
SetFilePointer(hfile, 0, 0, FILE_BEGIN);
DWORD bytes_written;
if (!WriteFile(hfile, new_contents.data(), new_contents.size(),
&bytes_written, NULL)) {
cerr << "Error writing file: " << os_specific
<< ", error " << GetLastError() << "\n";
CloseHandle(hfile);
return false;
}
}
CloseHandle(hfile);
return match;
#else // WIN32_VC
string os_specific = to_os_specific();
@ -2005,7 +2067,7 @@ atomic_compare_and_exchange_contents(string &orig_contents,
}
////////////////////////////////////////////////////////////////////
// Function: Filename::atomic_compare_and_exchange_contents
// Function: Filename::atomic_read_contents
// Access: Public
// Description: Uses native file-locking mechanisms to atomically
// read the contents of a (small) file. This is the
@ -2024,8 +2086,50 @@ atomic_compare_and_exchange_contents(string &orig_contents,
bool Filename::
atomic_read_contents(string &contents) const {
#ifdef WIN32_VC
// Todo.
return false;
string os_specific = to_os_specific();
HANDLE hfile = CreateFile(os_specific.c_str(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
while (hfile == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
if (error == ERROR_SHARING_VIOLATION) {
// If the file is locked by another process, yield and try again.
Sleep(0);
hfile = CreateFile(os_specific.c_str(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
} else {
cerr << "Couldn't open file: " << os_specific
<< ", error " << error << "\n";
return false;
}
}
static const size_t buf_size = 512;
char buf[buf_size];
contents = string();
DWORD bytes_read;
if (!ReadFile(hfile, buf, buf_size, &bytes_read, NULL)) {
cerr << "Error reading file: " << os_specific
<< ", error " << GetLastError() << "\n";
CloseHandle(hfile);
return false;
}
while (bytes_read > 0) {
contents += string(buf, bytes_read);
if (!ReadFile(hfile, buf, buf_size, &bytes_read, NULL)) {
cerr << "Error reading file: " << os_specific
<< ", error " << GetLastError() << "\n";
CloseHandle(hfile);
return false;
}
}
CloseHandle(hfile);
return true;
#else // WIN32_VC
string os_specific = to_os_specific();