2 #include <qt_windows.h>
5 #define MUTEX_PREFIX "TTKLockedFile mutex "
7 #define MAX_READERS MAXIMUM_WAIT_OBJECTS
9 Qt::HANDLE TTKLockedFile::getMutexHandle(
int idx,
bool doCreate)
11 if (m_mutexname.isEmpty()) {
12 const QFileInfo fin(*
this);
13 m_mutexname = QString::fromLatin1(
MUTEX_PREFIX) + fin.absoluteFilePath().toLower();
15 QString mname(m_mutexname);
17 mname += QString::number(idx);
21 mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData());
23 qErrnoWarning(
"TTKLockedFile::lock(): CreateMutex failed");
28 mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData());
30 if (GetLastError() != ERROR_FILE_NOT_FOUND)
31 qErrnoWarning(
"TTKLockedFile::lock(): OpenMutex failed");
38 bool TTKLockedFile::waitMutex(Qt::HANDLE mutex,
bool doBlock)
41 DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
50 qErrnoWarning(
"TTKLockedFile::lock(): WaitForSingleObject failed");
55 bool TTKLockedFile::lock(LockMode
mode,
bool block)
58 qWarning(
"TTKLockedFile::lock(): file is not opened");
65 if (mode == m_lock_mode)
68 if (m_lock_mode != NoLock)
71 if (!m_wmutex && !(m_wmutex = getMutexHandle(-1,
true)))
74 if (!waitMutex(m_wmutex, block))
77 if (mode == ReadLock) {
80 m_rmutex = getMutexHandle(idx,
false);
81 if (!m_rmutex || waitMutex(m_rmutex,
false))
83 CloseHandle(m_rmutex);
86 if (idx >= MAX_READERS) {
87 qWarning(
"TTKLockedFile::lock(): too many readers");
92 m_rmutex = getMutexHandle(idx,
true);
93 if (!m_rmutex || !waitMutex(m_rmutex,
false))
96 if (!ok && m_rmutex) {
97 CloseHandle(m_rmutex);
100 ReleaseMutex(m_wmutex);
105 Q_ASSERT(m_rmutexes.isEmpty());
107 Qt::HANDLE mutex = getMutexHandle(i,
false);
109 m_rmutexes.append(mutex);
111 if (!m_rmutexes.isEmpty()) {
112 DWORD res = WaitForMultipleObjects(m_rmutexes.count(), m_rmutexes.constData(), TRUE, block ? INFINITE : 0);
113 if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
114 if (res != WAIT_TIMEOUT)
115 qErrnoWarning(
"TTKLockedFile::lock(): WaitForMultipleObjects failed");
116 m_lock_mode = WriteLock;
127 bool TTKLockedFile::unlock()
130 qWarning(
"TTKLockedFile::unlock(): file is not opened");
137 if (m_lock_mode == ReadLock) {
138 ReleaseMutex(m_rmutex);
139 CloseHandle(m_rmutex);
143 foreach(Qt::HANDLE mutex, m_rmutexes) {
148 ReleaseMutex(m_wmutex);
151 m_lock_mode = TTKLockedFile::NoLock;
155 TTKLockedFile::~TTKLockedFile()
160 CloseHandle(m_wmutex);