[BUG_FIXED] Lock some operations for data integrality.
Use mutex of Yuni library to lock critical operation for the compatibility of windows xp sp2. For more info of Yuni library: https://github.com/libyuni
This commit is contained in:
parent
acb713d9e6
commit
9ad71107e9
@ -25,19 +25,24 @@
|
|||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
#include "LongRunningOperation.h"
|
#include "LongRunningOperation.h"
|
||||||
|
#include "mutex.h"
|
||||||
|
|
||||||
|
using namespace Yuni;
|
||||||
|
|
||||||
|
|
||||||
// Due to retro-compatibility reason (with xp sp2), we use ::CreateMutex() instead of std::recursive_mutex
|
|
||||||
// TODO : use Windows Mutex to lock/unlock operations
|
|
||||||
|
|
||||||
|
|
||||||
LongRunningOperation::LongRunningOperation()
|
LongRunningOperation::LongRunningOperation()
|
||||||
{
|
{
|
||||||
//_operationMutex.lock();
|
Mutex::ClassLevelLockable<LongRunningOperation>::mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LongRunningOperation::~LongRunningOperation()
|
LongRunningOperation::~LongRunningOperation()
|
||||||
{
|
{
|
||||||
//_operationMutex.unlock();
|
Mutex::ClassLevelLockable<LongRunningOperation>::mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
181
PowerEditor/src/MISC/Common/mutex.cpp
Normal file
181
PowerEditor/src/MISC/Common/mutex.cpp
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
// YUNI's default license is the GNU Lesser Public License (LGPL), with some
|
||||||
|
// exclusions (see below). This basically means that you can get the full source
|
||||||
|
// code for nothing, so long as you adhere to a few rules.
|
||||||
|
//
|
||||||
|
// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you
|
||||||
|
// require, as long as you:
|
||||||
|
//
|
||||||
|
// Pass on the (modified) YUNI source code with your software, with original
|
||||||
|
// copyrights intact :
|
||||||
|
// * If you distribute electronically, the source can be a separate download
|
||||||
|
// (either from your own site if you modified YUNI, or to the official YUNI
|
||||||
|
// website if you used an unmodified version) – just include a link in your
|
||||||
|
// documentation
|
||||||
|
// * If you distribute physical media, the YUNI source that you used to build
|
||||||
|
// your application should be included on that media
|
||||||
|
// Make it clear where you have customised it.
|
||||||
|
//
|
||||||
|
// In addition to the LGPL license text, the following exceptions / clarifications
|
||||||
|
// to the LGPL conditions apply to YUNI:
|
||||||
|
//
|
||||||
|
// * Making modifications to YUNI configuration files, build scripts and
|
||||||
|
// configuration headers such as yuni/platform.h in order to create a
|
||||||
|
// customised build setup of YUNI with the otherwise unmodified source code,
|
||||||
|
// does not constitute a derived work
|
||||||
|
// * Building against YUNI headers which have inlined code does not constitute a
|
||||||
|
// derived work
|
||||||
|
// * Code which subclasses YUNI classes outside of the YUNI libraries does not
|
||||||
|
// form a derived work
|
||||||
|
// * Statically linking the YUNI libraries into a user application does not make
|
||||||
|
// the user application a derived work.
|
||||||
|
// * Using source code obsfucation on the YUNI source code when distributing it
|
||||||
|
// is not permitted.
|
||||||
|
// As per the terms of the LGPL, a "derived work" is one for which you have to
|
||||||
|
// distribute source code for, so when the clauses above define something as not
|
||||||
|
// a derived work, it means you don't have to distribute source code for it.
|
||||||
|
// However, the original YUNI source code with all modifications must always be
|
||||||
|
// made available.
|
||||||
|
|
||||||
|
#include "mutex.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
|
#if YUNI_ATOMIC_MUST_USE_MUTEX != 0
|
||||||
|
#warning Atomic types must ue mutex. the implementation should be checked YUNI_OS_GCC_VERSION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Yuni
|
||||||
|
{
|
||||||
|
|
||||||
|
enum // anonymous
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
** \brief The spin count for the critical section object
|
||||||
|
**
|
||||||
|
** On single-processor systems, the spin count is ignored and the critical section
|
||||||
|
** spin count is set to 0 (zero). On multiprocessor systems, if the critical section
|
||||||
|
** is unavailable, the calling thread spinsdwSpinCount times before performing a
|
||||||
|
** wait operation on a semaphore associated with the critical section. If the critical
|
||||||
|
** section becomes free during the spin operation, the calling thread avoids the
|
||||||
|
** wait operation.
|
||||||
|
** \see http://msdn.microsoft.com/en-us/library/ms683476%28v=vs.85%29.aspx
|
||||||
|
*/
|
||||||
|
spinCount = 3000,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Mutex::destroy()
|
||||||
|
{
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifdef YUNI_OS_WINDOWS
|
||||||
|
DeleteCriticalSection(&pSection);
|
||||||
|
# else
|
||||||
|
switch (::pthread_mutex_destroy(&pLock))
|
||||||
|
{
|
||||||
|
case 0: // Ok good
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// If an error happens, we will let the program continue but
|
||||||
|
// it can becaome ugly around here...
|
||||||
|
case EBUSY:
|
||||||
|
{
|
||||||
|
std::cerr << "\nattempt to destroy a mutex while it is locked or referenced\n";
|
||||||
|
assert(false and "attempt to destroy a mutex while it is locked or referenced");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
std::cerr << "\nfailed to destroy a mutex\n";
|
||||||
|
assert(false and "\nfailed to destroy a mutex\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::pthread_mutexattr_destroy(&pAttr);
|
||||||
|
# endif
|
||||||
|
# endif // no thread safe
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Mutex::copy(const Mutex& rhs)
|
||||||
|
{
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifdef YUNI_OS_WINDOWS
|
||||||
|
InitializeCriticalSectionAndSpinCount(&pSection, spinCount);
|
||||||
|
(void) rhs; // unused
|
||||||
|
# else
|
||||||
|
::pthread_mutexattr_init(&pAttr);
|
||||||
|
int type; // = PTHREAD_MUTEX_NORMAL;
|
||||||
|
if (0 == ::pthread_mutexattr_gettype(&rhs.pAttr, &type))
|
||||||
|
{
|
||||||
|
if (PTHREAD_MUTEX_RECURSIVE == type)
|
||||||
|
{
|
||||||
|
# if defined(YUNI_OS_DARWIN) or defined(YUNI_OS_FREEBSD) or defined(YUNI_OS_SOLARIS) or defined(YUNI_OS_SUNOS) or defined(YUNI_OS_HAIKU) or defined(YUNI_OS_CYGWIN)
|
||||||
|
::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
# else
|
||||||
|
::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::pthread_mutex_init(& pLock, &pAttr);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
(void) rhs; // unused
|
||||||
|
# endif // no thread safe
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mutex::Mutex(const Mutex& rhs)
|
||||||
|
{
|
||||||
|
copy(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mutex::~Mutex()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mutex::Mutex(bool recursive)
|
||||||
|
{
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifdef YUNI_OS_WINDOWS
|
||||||
|
(void) recursive; // already recursive on Windows
|
||||||
|
InitializeCriticalSectionAndSpinCount(&pSection, spinCount);
|
||||||
|
# else
|
||||||
|
::pthread_mutexattr_init(&pAttr);
|
||||||
|
if (recursive)
|
||||||
|
{
|
||||||
|
# if defined(YUNI_OS_DARWIN) or defined(YUNI_OS_FREEBSD) or defined(YUNI_OS_SOLARIS) or defined(YUNI_OS_SUNOS) or defined(YUNI_OS_HAIKU) or defined(YUNI_OS_CYGWIN)
|
||||||
|
::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
# else
|
||||||
|
::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
::pthread_mutex_init(&pLock, &pAttr);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
(void) recursive;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mutex& Mutex::operator = (const Mutex& rhs)
|
||||||
|
{
|
||||||
|
// We will recreate the mutex
|
||||||
|
destroy();
|
||||||
|
copy(rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Yuni
|
234
PowerEditor/src/MISC/Common/mutex.h
Normal file
234
PowerEditor/src/MISC/Common/mutex.h
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
// YUNI's default license is the GNU Lesser Public License (LGPL), with some
|
||||||
|
// exclusions (see below). This basically means that you can get the full source
|
||||||
|
// code for nothing, so long as you adhere to a few rules.
|
||||||
|
//
|
||||||
|
// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you
|
||||||
|
// require, as long as you:
|
||||||
|
//
|
||||||
|
// Pass on the (modified) YUNI source code with your software, with original
|
||||||
|
// copyrights intact :
|
||||||
|
// * If you distribute electronically, the source can be a separate download
|
||||||
|
// (either from your own site if you modified YUNI, or to the official YUNI
|
||||||
|
// website if you used an unmodified version) – just include a link in your
|
||||||
|
// documentation
|
||||||
|
// * If you distribute physical media, the YUNI source that you used to build
|
||||||
|
// your application should be included on that media
|
||||||
|
// Make it clear where you have customised it.
|
||||||
|
//
|
||||||
|
// In addition to the LGPL license text, the following exceptions / clarifications
|
||||||
|
// to the LGPL conditions apply to YUNI:
|
||||||
|
//
|
||||||
|
// * Making modifications to YUNI configuration files, build scripts and
|
||||||
|
// configuration headers such as yuni/platform.h in order to create a
|
||||||
|
// customised build setup of YUNI with the otherwise unmodified source code,
|
||||||
|
// does not constitute a derived work
|
||||||
|
// * Building against YUNI headers which have inlined code does not constitute a
|
||||||
|
// derived work
|
||||||
|
// * Code which subclasses YUNI classes outside of the YUNI libraries does not
|
||||||
|
// form a derived work
|
||||||
|
// * Statically linking the YUNI libraries into a user application does not make
|
||||||
|
// the user application a derived work.
|
||||||
|
// * Using source code obsfucation on the YUNI source code when distributing it
|
||||||
|
// is not permitted.
|
||||||
|
// As per the terms of the LGPL, a "derived work" is one for which you have to
|
||||||
|
// distribute source code for, so when the clauses above define something as not
|
||||||
|
// a derived work, it means you don't have to distribute source code for it.
|
||||||
|
// However, the original YUNI source code with all modifications must always be
|
||||||
|
// made available.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define YUNI_OS_WINDOWS
|
||||||
|
#define YUNI_HAS_CPP_MOVE
|
||||||
|
#define YUNI_DECL
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Yuni
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
** \brief Mechanism to avoid the simultaneous use of a common resource
|
||||||
|
**
|
||||||
|
** \ingroup Threads
|
||||||
|
*/
|
||||||
|
class YUNI_DECL Mutex final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
** \brief A class-level locking mechanism
|
||||||
|
**
|
||||||
|
** A class-level locking operation locks all objects in a given class during that operation
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class ClassLevelLockable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! A dedicated mutex for the class T
|
||||||
|
static Mutex mutex;
|
||||||
|
|
||||||
|
}; // class ClassLevelLockable
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! \name Constructor & Destructor
|
||||||
|
//@{
|
||||||
|
/*!
|
||||||
|
** \brief Default constructor
|
||||||
|
**
|
||||||
|
** Recursive by default to keep homogeneous behavior between
|
||||||
|
** platforms.
|
||||||
|
*/
|
||||||
|
explicit Mutex(bool recursive = true);
|
||||||
|
/*!
|
||||||
|
** \brief Copy constructor
|
||||||
|
**
|
||||||
|
** This constructor does actually nothing but it allows the compilation
|
||||||
|
** of other classes which would implement a copy constructor
|
||||||
|
*/
|
||||||
|
Mutex(const Mutex&);
|
||||||
|
|
||||||
|
# ifdef YUNI_HAS_CPP_MOVE
|
||||||
|
// an OS's native mutex must have invariant address and thus can not be moved
|
||||||
|
Mutex(Mutex&&) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
** \brief Destructor
|
||||||
|
*/
|
||||||
|
~Mutex();
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Lock & Unlock
|
||||||
|
//@{
|
||||||
|
/*!
|
||||||
|
** \brief Lock the mutex
|
||||||
|
*/
|
||||||
|
void lock();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
** \brief Try to lock the mutex
|
||||||
|
**
|
||||||
|
** \return True if the mutex has been locked, false otherwise
|
||||||
|
*/
|
||||||
|
bool trylock();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
** \brief Release the lock
|
||||||
|
*/
|
||||||
|
void unlock();
|
||||||
|
//@}
|
||||||
|
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifndef YUNI_OS_WINDOWS
|
||||||
|
//! \name Native
|
||||||
|
//@{
|
||||||
|
//! Get the original PThread mutex
|
||||||
|
::pthread_mutex_t& pthreadMutex();
|
||||||
|
//! Get the original PThread mutex (const)
|
||||||
|
const ::pthread_mutex_t& pthreadMutex() const;
|
||||||
|
//@}
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
//! \name Operators
|
||||||
|
//@{
|
||||||
|
//! Operator = (do nothing)
|
||||||
|
Mutex& operator = (const Mutex&);
|
||||||
|
# ifdef YUNI_HAS_CPP_MOVE
|
||||||
|
// an OS's native mutex must have invariant address and thus can not be moved
|
||||||
|
Mutex& operator = (Mutex&&) = delete;
|
||||||
|
#endif
|
||||||
|
//@}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Destroy the current mutex
|
||||||
|
inline void destroy();
|
||||||
|
//! Create the mutex with settings from another mutex
|
||||||
|
inline void copy(const Mutex& rhs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifdef YUNI_OS_WINDOWS
|
||||||
|
//! The critical section
|
||||||
|
CRITICAL_SECTION pSection;
|
||||||
|
# else
|
||||||
|
//! The PThread mutex
|
||||||
|
::pthread_mutex_t pLock;
|
||||||
|
::pthread_mutexattr_t pAttr;
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
}; // class Mutex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
** \brief Locks a mutex in the constructor and unlocks it in the destructor (RAII).
|
||||||
|
**
|
||||||
|
** This class is especially usefull for `get` accessor` and/or returned values
|
||||||
|
** which have to be thread-safe.
|
||||||
|
** This is a very common C++ idiom, known as "Resource Acquisition Is Initialization" (RAII).
|
||||||
|
**
|
||||||
|
** \code
|
||||||
|
** class Foo
|
||||||
|
** {
|
||||||
|
** public:
|
||||||
|
** Foo() : pValue(42) {}
|
||||||
|
** ~Foo() {}
|
||||||
|
** int getValue()
|
||||||
|
** {
|
||||||
|
** MutexLocker locker(pMutex);
|
||||||
|
** return pValue;
|
||||||
|
** }
|
||||||
|
** void setValue(const int i)
|
||||||
|
** {
|
||||||
|
** pMutex.lock();
|
||||||
|
** pValue = i;
|
||||||
|
** pMutex.unlock();
|
||||||
|
** }
|
||||||
|
** private:
|
||||||
|
** int pValue;
|
||||||
|
** Mutex pMutex;
|
||||||
|
** };
|
||||||
|
** \endcode
|
||||||
|
*/
|
||||||
|
class MutexLocker final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! \name Constructor & Destructor
|
||||||
|
//@{
|
||||||
|
/*!
|
||||||
|
** \brief Constructor
|
||||||
|
**
|
||||||
|
** \param m The mutex to lock
|
||||||
|
*/
|
||||||
|
MutexLocker(Mutex& m);
|
||||||
|
//! Destructor
|
||||||
|
~MutexLocker();
|
||||||
|
//@}
|
||||||
|
|
||||||
|
MutexLocker& operator = (const MutexLocker&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Reference to the real mutex
|
||||||
|
Mutex& pMutex;
|
||||||
|
|
||||||
|
}; // MutexLocker
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//! All mutexes for each class
|
||||||
|
template<class T> Mutex Mutex::ClassLevelLockable<T>::mutex;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Yuni
|
||||||
|
|
||||||
|
# include "mutex.hxx"
|
116
PowerEditor/src/MISC/Common/mutex.hxx
Normal file
116
PowerEditor/src/MISC/Common/mutex.hxx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// YUNI's default license is the GNU Lesser Public License (LGPL), with some
|
||||||
|
// exclusions (see below). This basically means that you can get the full source
|
||||||
|
// code for nothing, so long as you adhere to a few rules.
|
||||||
|
|
||||||
|
// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you
|
||||||
|
// require, as long as you:
|
||||||
|
//
|
||||||
|
// Pass on the (modified) YUNI source code with your software, with original
|
||||||
|
// copyrights intact :
|
||||||
|
// * If you distribute electronically, the source can be a separate download
|
||||||
|
// (either from your own site if you modified YUNI, or to the official YUNI
|
||||||
|
// website if you used an unmodified version) – just include a link in your
|
||||||
|
// documentation
|
||||||
|
// * If you distribute physical media, the YUNI source that you used to build
|
||||||
|
// your application should be included on that media
|
||||||
|
// Make it clear where you have customised it.
|
||||||
|
//
|
||||||
|
// In addition to the LGPL license text, the following exceptions / clarifications
|
||||||
|
// to the LGPL conditions apply to YUNI:
|
||||||
|
//
|
||||||
|
// * Making modifications to YUNI configuration files, build scripts and
|
||||||
|
// configuration headers such as yuni/platform.h in order to create a
|
||||||
|
// customised build setup of YUNI with the otherwise unmodified source code,
|
||||||
|
// does not constitute a derived work
|
||||||
|
// * Building against YUNI headers which have inlined code does not constitute a
|
||||||
|
// derived work
|
||||||
|
// * Code which subclasses YUNI classes outside of the YUNI libraries does not
|
||||||
|
// form a derived work
|
||||||
|
// * Statically linking the YUNI libraries into a user application does not make
|
||||||
|
// the user application a derived work.
|
||||||
|
// * Using source code obsfucation on the YUNI source code when distributing it
|
||||||
|
// is not permitted.
|
||||||
|
// As per the terms of the LGPL, a "derived work" is one for which you have to
|
||||||
|
// distribute source code for, so when the clauses above define something as not
|
||||||
|
// a derived work, it means you don't have to distribute source code for it.
|
||||||
|
// However, the original YUNI source code with all modifications must always be
|
||||||
|
// made available.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "mutex.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Yuni
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void Mutex::lock()
|
||||||
|
{
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifdef YUNI_OS_WINDOWS
|
||||||
|
EnterCriticalSection(&pSection);
|
||||||
|
# else
|
||||||
|
::pthread_mutex_lock(&pLock);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Mutex::trylock()
|
||||||
|
{
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifdef YUNI_OS_WINDOWS
|
||||||
|
return (0 != TryEnterCriticalSection(&pSection));
|
||||||
|
# else
|
||||||
|
return (0 == ::pthread_mutex_trylock(&pLock));
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
return false;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Mutex::unlock()
|
||||||
|
{
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifdef YUNI_OS_WINDOWS
|
||||||
|
LeaveCriticalSection(&pSection);
|
||||||
|
# else
|
||||||
|
::pthread_mutex_unlock(&pLock);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ifndef YUNI_NO_THREAD_SAFE
|
||||||
|
# ifndef YUNI_OS_WINDOWS
|
||||||
|
inline pthread_mutex_t& Mutex::pthreadMutex()
|
||||||
|
{
|
||||||
|
return pLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const pthread_mutex_t& Mutex::pthreadMutex() const
|
||||||
|
{
|
||||||
|
return pLock;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline MutexLocker::MutexLocker(Mutex& m) :
|
||||||
|
pMutex(m)
|
||||||
|
{
|
||||||
|
m.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline MutexLocker::~MutexLocker()
|
||||||
|
{
|
||||||
|
pMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Yuni
|
@ -139,6 +139,7 @@ copy ..\src\contextMenu.xml ..\bin\contextMenu.xml
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\src\MISC\Common\LongRunningOperation.cpp" />
|
<ClCompile Include="..\src\MISC\Common\LongRunningOperation.cpp" />
|
||||||
|
<ClCompile Include="..\src\MISC\Common\mutex.cpp" />
|
||||||
<ClCompile Include="..\src\WinControls\AboutDlg\AboutDlg.cpp" />
|
<ClCompile Include="..\src\WinControls\AboutDlg\AboutDlg.cpp" />
|
||||||
<ClCompile Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.cpp" />
|
<ClCompile Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.cpp" />
|
||||||
<ClCompile Include="..\src\ScitillaComponent\AutoCompletion.cpp" />
|
<ClCompile Include="..\src\ScitillaComponent\AutoCompletion.cpp" />
|
||||||
@ -409,6 +410,8 @@ copy ..\src\contextMenu.xml ..\bin\contextMenu.xml
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\src\MISC\Common\LongRunningOperation.h" />
|
<ClInclude Include="..\src\MISC\Common\LongRunningOperation.h" />
|
||||||
|
<ClInclude Include="..\src\MISC\Common\mutex.h" />
|
||||||
|
<ClInclude Include="..\src\MISC\Common\mutex.hxx" />
|
||||||
<ClInclude Include="..\src\ScitillaComponent\resource.h" />
|
<ClInclude Include="..\src\ScitillaComponent\resource.h" />
|
||||||
<ClInclude Include="..\src\WinControls\AboutDlg\AboutDlg.h" />
|
<ClInclude Include="..\src\WinControls\AboutDlg\AboutDlg.h" />
|
||||||
<ClInclude Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.h" />
|
<ClInclude Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.h" />
|
||||||
|
Loading…
Reference in New Issue
Block a user