41 #include "qtlockedfile.h" 42 #include <qt_windows.h> 45 #define MUTEX_PREFIX "QtLockedFile mutex " 47 #define MAX_READERS MAXIMUM_WAIT_OBJECTS 49 #if QT_VERSION >= 0x050000 50 #define QT_WA(unicode, ansi) unicode 53 Qt::HANDLE QtLockedFile::getMutexHandle(
int idx,
bool doCreate)
55 if (mutexname.isEmpty()) {
57 mutexname = QString::fromLatin1(MUTEX_PREFIX)
58 + fi.absoluteFilePath().toLower();
60 QString mname(mutexname);
62 mname += QString::number(idx);
66 QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); },
67 { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
69 qErrnoWarning(
"QtLockedFile::lock(): CreateMutex failed");
74 QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); },
75 { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
77 if (GetLastError() != ERROR_FILE_NOT_FOUND)
78 qErrnoWarning(
"QtLockedFile::lock(): OpenMutex failed");
85 bool QtLockedFile::waitMutex(Qt::HANDLE mutex,
bool doBlock)
88 DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
97 qErrnoWarning(
"QtLockedFile::lock(): WaitForSingleObject failed");
104 bool QtLockedFile::lock(LockMode mode,
bool block)
107 qWarning(
"QtLockedFile::lock(): file is not opened");
114 if (mode == m_lock_mode)
117 if (m_lock_mode != NoLock)
120 if (!wmutex && !(wmutex = getMutexHandle(-1,
true)))
123 if (!waitMutex(wmutex, block))
126 if (mode == ReadLock) {
128 for (; idx < MAX_READERS; idx++) {
129 rmutex = getMutexHandle(idx,
false);
130 if (!rmutex || waitMutex(rmutex,
false))
135 if (idx >= MAX_READERS) {
136 qWarning(
"QtLockedFile::lock(): too many readers");
141 rmutex = getMutexHandle(idx,
true);
142 if (!rmutex || !waitMutex(rmutex,
false))
149 ReleaseMutex(wmutex);
154 Q_ASSERT(rmutexes.isEmpty());
155 for (
int i = 0; i < MAX_READERS; i++) {
156 Qt::HANDLE mutex = getMutexHandle(i,
false);
158 rmutexes.append(mutex);
160 if (rmutexes.size()) {
161 DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
162 TRUE, block ? INFINITE : 0);
163 if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
164 if (res != WAIT_TIMEOUT)
165 qErrnoWarning(
"QtLockedFile::lock(): WaitForMultipleObjects failed");
166 m_lock_mode = WriteLock;
177 bool QtLockedFile::unlock()
180 qWarning(
"QtLockedFile::unlock(): file is not opened");
187 if (m_lock_mode == ReadLock) {
188 ReleaseMutex(rmutex);
193 foreach(Qt::HANDLE mutex, rmutexes) {
198 ReleaseMutex(wmutex);
201 m_lock_mode = QtLockedFile::NoLock;
205 QtLockedFile::~QtLockedFile()