Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F620620
qtlockedfile_win.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None
qtlockedfile_win.cpp
View Options
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include
"qtlockedfile.h"
#include
<qt_windows.h>
#include
<QFileInfo>
#define MUTEX_PREFIX "QtLockedFile mutex "
// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS
#define MAX_READERS MAXIMUM_WAIT_OBJECTS
#if QT_VERSION >= 0x050000
#define QT_WA(unicode, ansi) unicode
#endif
Qt
::
HANDLE
QtLockedFile::getMutexHandle
(
int
idx
,
bool
doCreate
)
{
if
(
mutexname
.
isEmpty
())
{
QFileInfo
fi
(
*
this
);
mutexname
=
QString
::
fromLatin1
(
MUTEX_PREFIX
)
+
fi
.
absoluteFilePath
().
toLower
();
}
QString
mname
(
mutexname
);
if
(
idx
>=
0
)
mname
+=
QString
::
number
(
idx
);
Qt
::
HANDLE
mutex
;
if
(
doCreate
)
{
QT_WA
(
{
mutex
=
CreateMutexW
(
NULL
,
FALSE
,
(
TCHAR
*
)
mname
.
utf16
());
},
{
mutex
=
CreateMutexA
(
NULL
,
FALSE
,
mname
.
toLocal8Bit
().
constData
());
}
);
if
(
!
mutex
)
{
qErrnoWarning
(
"QtLockedFile::lock(): CreateMutex failed"
);
return
0
;
}
}
else
{
QT_WA
(
{
mutex
=
OpenMutexW
(
SYNCHRONIZE
|
MUTEX_MODIFY_STATE
,
FALSE
,
(
TCHAR
*
)
mname
.
utf16
());
},
{
mutex
=
OpenMutexA
(
SYNCHRONIZE
|
MUTEX_MODIFY_STATE
,
FALSE
,
mname
.
toLocal8Bit
().
constData
());
}
);
if
(
!
mutex
)
{
if
(
GetLastError
()
!=
ERROR_FILE_NOT_FOUND
)
qErrnoWarning
(
"QtLockedFile::lock(): OpenMutex failed"
);
return
0
;
}
}
return
mutex
;
}
bool
QtLockedFile::waitMutex
(
Qt
::
HANDLE
mutex
,
bool
doBlock
)
{
Q_ASSERT
(
mutex
);
DWORD
res
=
WaitForSingleObject
(
mutex
,
doBlock
?
INFINITE
:
0
);
switch
(
res
)
{
case
WAIT_OBJECT_0
:
case
WAIT_ABANDONED
:
return
true
;
break
;
case
WAIT_TIMEOUT
:
break
;
default
:
qErrnoWarning
(
"QtLockedFile::lock(): WaitForSingleObject failed"
);
}
return
false
;
}
bool
QtLockedFile::lock
(
LockMode
mode
,
bool
block
)
{
if
(
!
isOpen
())
{
qWarning
(
"QtLockedFile::lock(): file is not opened"
);
return
false
;
}
if
(
mode
==
NoLock
)
return
unlock
();
if
(
mode
==
m_lock_mode
)
return
true
;
if
(
m_lock_mode
!=
NoLock
)
unlock
();
if
(
!
wmutex
&&
!
(
wmutex
=
getMutexHandle
(
-1
,
true
)))
return
false
;
if
(
!
waitMutex
(
wmutex
,
block
))
return
false
;
if
(
mode
==
ReadLock
)
{
int
idx
=
0
;
for
(;
idx
<
MAX_READERS
;
idx
++
)
{
rmutex
=
getMutexHandle
(
idx
,
false
);
if
(
!
rmutex
||
waitMutex
(
rmutex
,
false
))
break
;
CloseHandle
(
rmutex
);
}
bool
ok
=
true
;
if
(
idx
>=
MAX_READERS
)
{
qWarning
(
"QtLockedFile::lock(): too many readers"
);
rmutex
=
0
;
ok
=
false
;
}
else
if
(
!
rmutex
)
{
rmutex
=
getMutexHandle
(
idx
,
true
);
if
(
!
rmutex
||
!
waitMutex
(
rmutex
,
false
))
ok
=
false
;
}
if
(
!
ok
&&
rmutex
)
{
CloseHandle
(
rmutex
);
rmutex
=
0
;
}
ReleaseMutex
(
wmutex
);
if
(
!
ok
)
return
false
;
}
else
{
Q_ASSERT
(
rmutexes
.
isEmpty
());
for
(
int
i
=
0
;
i
<
MAX_READERS
;
i
++
)
{
Qt
::
HANDLE
mutex
=
getMutexHandle
(
i
,
false
);
if
(
mutex
)
rmutexes
.
append
(
mutex
);
}
if
(
rmutexes
.
size
())
{
DWORD
res
=
WaitForMultipleObjects
(
rmutexes
.
size
(),
rmutexes
.
constData
(),
TRUE
,
block
?
INFINITE
:
0
);
if
(
res
!=
WAIT_OBJECT_0
&&
res
!=
WAIT_ABANDONED
)
{
if
(
res
!=
WAIT_TIMEOUT
)
qErrnoWarning
(
"QtLockedFile::lock(): WaitForMultipleObjects failed"
);
m_lock_mode
=
WriteLock
;
// trick unlock() to clean up - semiyucky
unlock
();
return
false
;
}
}
}
m_lock_mode
=
mode
;
return
true
;
}
bool
QtLockedFile::unlock
()
{
if
(
!
isOpen
())
{
qWarning
(
"QtLockedFile::unlock(): file is not opened"
);
return
false
;
}
if
(
!
isLocked
())
return
true
;
if
(
m_lock_mode
==
ReadLock
)
{
ReleaseMutex
(
rmutex
);
CloseHandle
(
rmutex
);
rmutex
=
0
;
}
else
{
foreach
(
Qt
::
HANDLE
mutex
,
rmutexes
)
{
ReleaseMutex
(
mutex
);
CloseHandle
(
mutex
);
}
rmutexes
.
clear
();
ReleaseMutex
(
wmutex
);
}
m_lock_mode
=
QtLockedFile
::
NoLock
;
return
true
;
}
QtLockedFile
::~
QtLockedFile
()
{
if
(
isOpen
())
unlock
();
if
(
wmutex
)
CloseHandle
(
wmutex
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Nov 14, 6:14 PM (16 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
132465
Default Alt Text
qtlockedfile_win.cpp (6 KB)
Attached To
Mode
R63 darkscreen
Attached
Detach File
Event Timeline