added wxMutex::LockTimeout() (modified patch 1671637)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44671 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -35,6 +35,7 @@ All:
|
||||
- Fixed tab-related drawing and hit-testing bugs in wxRichTextCtrl.
|
||||
- Implemented background colour in wxRichTextCtrl.
|
||||
- Fixed crashes in helpview when opening a file.
|
||||
- Added wxMutex::LockTimeout() (Aleksandr Napylov)
|
||||
|
||||
wxGTK:
|
||||
|
||||
|
@@ -93,23 +93,27 @@ None.
|
||||
|
||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
||||
|
||||
|
||||
\membersection{wxMutex::wxMutex}\label{wxmutexctor}
|
||||
|
||||
\func{}{wxMutex}{\param{wxMutexType }{type = {\tt wxMUTEX\_DEFAULT}}}
|
||||
|
||||
Default constructor.
|
||||
|
||||
|
||||
\membersection{wxMutex::\destruct{wxMutex}}\label{wxmutexdtor}
|
||||
|
||||
\func{}{\destruct{wxMutex}}{\void}
|
||||
|
||||
Destroys the wxMutex object.
|
||||
|
||||
|
||||
\membersection{wxMutex::Lock}\label{wxmutexlock}
|
||||
|
||||
\func{wxMutexError}{Lock}{\void}
|
||||
|
||||
Locks the mutex object.
|
||||
Locks the mutex object. This is equivalent to
|
||||
\helpref{LockTimeout}{wxmutexlocktimeout} with infinite timeout.
|
||||
|
||||
\wxheading{Return value}
|
||||
|
||||
@@ -121,6 +125,25 @@ One of:
|
||||
\twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
|
||||
\end{twocollist}
|
||||
|
||||
|
||||
\membersection{wxMutex::LockTimeout}\label{wxmutexlocktimeout}
|
||||
|
||||
\func{wxMutexError}{LockTimeout}{\param{unsigned long}{ msec}}
|
||||
|
||||
Try to lock the mutex object during the specified time interval.
|
||||
|
||||
\wxheading{Return value}
|
||||
|
||||
One of:
|
||||
|
||||
\twocolwidtha{7cm}
|
||||
\begin{twocollist}\itemsep=0pt
|
||||
\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{Mutex successfully locked.}
|
||||
\twocolitem{{\bf wxMUTEX\_TIMEOUT}}{Mutex couldn't be acquired before timeout expiration.}
|
||||
\twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
|
||||
\end{twocollist}
|
||||
|
||||
|
||||
\membersection{wxMutex::TryLock}\label{wxmutextrylock}
|
||||
|
||||
\func{wxMutexError}{TryLock}{\void}
|
||||
@@ -137,6 +160,7 @@ One of:
|
||||
\twocolitem{{\bf wxMUTEX\_BUSY}}{The mutex is already locked by another thread.}
|
||||
\end{twocollist}
|
||||
|
||||
|
||||
\membersection{wxMutex::Unlock}\label{wxmutexunlock}
|
||||
|
||||
\func{wxMutexError}{Unlock}{\void}
|
||||
|
@@ -38,6 +38,7 @@ enum wxMutexError
|
||||
wxMUTEX_DEAD_LOCK, // mutex is already locked by the calling thread
|
||||
wxMUTEX_BUSY, // mutex is already locked by another thread
|
||||
wxMUTEX_UNLOCKED, // attempt to unlock a mutex which is not locked
|
||||
wxMUTEX_TIMEOUT, // LockTimeout() has timed out
|
||||
wxMUTEX_MISC_ERROR // any other error
|
||||
};
|
||||
|
||||
@@ -149,6 +150,10 @@ public:
|
||||
// The caller must call Unlock() later if Lock() returned wxMUTEX_NO_ERROR.
|
||||
wxMutexError Lock();
|
||||
|
||||
// Same as Lock() but return wxMUTEX_TIMEOUT if the mutex can't be locked
|
||||
// during the given number of milliseconds
|
||||
wxMutexError LockTimeout(unsigned long ms);
|
||||
|
||||
// Try to lock the mutex: if it is currently locked, return immediately
|
||||
// with an error. Otherwise the caller must call Unlock().
|
||||
wxMutexError TryLock();
|
||||
|
@@ -44,6 +44,14 @@ wxMutexError wxMutex::Lock()
|
||||
return m_internal->Lock();
|
||||
}
|
||||
|
||||
wxMutexError wxMutex::LockTimeout(unsigned long ms)
|
||||
{
|
||||
wxCHECK_MSG( m_internal, wxMUTEX_INVALID,
|
||||
_T("wxMutex::Lock(): not initialized") );
|
||||
|
||||
return m_internal->Lock(ms);
|
||||
}
|
||||
|
||||
wxMutexError wxMutex::TryLock()
|
||||
{
|
||||
wxCHECK_MSG( m_internal, wxMUTEX_INVALID,
|
||||
|
@@ -178,7 +178,8 @@ public:
|
||||
bool IsOk() const { return m_mutex != NULL; }
|
||||
|
||||
wxMutexError Lock() { return LockTimeout(INFINITE); }
|
||||
wxMutexError TryLock() { return LockTimeout(0); }
|
||||
wxMutexError Lock(unsigned long ms) { return LockTimeout(ms); }
|
||||
wxMutexError TryLock();
|
||||
wxMutexError Unlock();
|
||||
|
||||
private:
|
||||
@@ -196,7 +197,7 @@ wxMutexInternal::wxMutexInternal(wxMutexType WXUNUSED(mutexType))
|
||||
m_mutex = ::CreateMutex
|
||||
(
|
||||
NULL, // default secutiry attributes
|
||||
false, // not initially locked
|
||||
FALSE, // not initially locked
|
||||
NULL // no name
|
||||
);
|
||||
|
||||
@@ -217,6 +218,14 @@ wxMutexInternal::~wxMutexInternal()
|
||||
}
|
||||
}
|
||||
|
||||
wxMutexError wxMutexInternal::TryLock()
|
||||
{
|
||||
const wxMutexError rc = LockTimeout(0);
|
||||
|
||||
// we have a special return code for timeout in this case
|
||||
return rc == wxMUTEX_TIMEOUT ? wxMUTEX_BUSY : rc;
|
||||
}
|
||||
|
||||
wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds)
|
||||
{
|
||||
DWORD rc = ::WaitForSingleObject(m_mutex, milliseconds);
|
||||
@@ -237,7 +246,7 @@ wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds)
|
||||
break;
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
return wxMUTEX_BUSY;
|
||||
return wxMUTEX_TIMEOUT;
|
||||
|
||||
case WAIT_ABANDONED: // checked for above
|
||||
default:
|
||||
|
@@ -163,11 +163,16 @@ public:
|
||||
~wxMutexInternal();
|
||||
|
||||
wxMutexError Lock();
|
||||
wxMutexError Lock(unsigned long ms);
|
||||
wxMutexError TryLock();
|
||||
wxMutexError Unlock();
|
||||
|
||||
bool IsOk() const { return m_isOk; }
|
||||
|
||||
private:
|
||||
// convert the result of pthread_mutex_[timed]lock() call to wx return code
|
||||
wxMutexError HandleLockResult(int err);
|
||||
|
||||
private:
|
||||
pthread_mutex_t m_mutex;
|
||||
bool m_isOk;
|
||||
@@ -245,7 +250,41 @@ wxMutexInternal::~wxMutexInternal()
|
||||
|
||||
wxMutexError wxMutexInternal::Lock()
|
||||
{
|
||||
int err = pthread_mutex_lock(&m_mutex);
|
||||
return HandleLockResult(pthread_mutex_lock(&m_mutex));
|
||||
}
|
||||
|
||||
wxMutexError wxMutexInternal::Lock(unsigned long ms)
|
||||
{
|
||||
static const long MSEC_IN_SEC = 1000;
|
||||
static const long NSEC_IN_MSEC = 1000000;
|
||||
static const long NSEC_IN_SEC = MSEC_IN_SEC * NSEC_IN_MSEC;
|
||||
|
||||
time_t seconds = ms/MSEC_IN_SEC;
|
||||
long nanoseconds = (ms % MSEC_IN_SEC) * NSEC_IN_MSEC;
|
||||
timespec ts = { 0, 0 };
|
||||
|
||||
if ( clock_gettime(CLOCK_REALTIME, &ts) == 0 )
|
||||
{
|
||||
ts.tv_sec += seconds;
|
||||
ts.tv_nsec += nanoseconds;
|
||||
if ( ts.tv_nsec > NSEC_IN_SEC )
|
||||
{
|
||||
ts.tv_sec += 1;
|
||||
ts.tv_nsec -= NSEC_IN_SEC;
|
||||
}
|
||||
}
|
||||
else // fall back on system timer
|
||||
{
|
||||
wxLogDebug(_T("clock_gettime(CLOCK_REALTIME) failed"));
|
||||
ts.tv_sec = time(NULL) + seconds;
|
||||
ts.tv_nsec = nanoseconds;
|
||||
}
|
||||
|
||||
return HandleLockResult(pthread_mutex_timedlock(&m_mutex, &ts));
|
||||
}
|
||||
|
||||
wxMutexError wxMutexInternal::HandleLockResult(int err)
|
||||
{
|
||||
switch ( err )
|
||||
{
|
||||
case EDEADLK:
|
||||
@@ -255,19 +294,23 @@ wxMutexError wxMutexInternal::Lock()
|
||||
return wxMUTEX_DEAD_LOCK;
|
||||
|
||||
case EINVAL:
|
||||
wxLogDebug(_T("pthread_mutex_lock(): mutex not initialized."));
|
||||
wxLogDebug(_T("pthread_mutex_[timed]lock(): mutex not initialized"));
|
||||
break;
|
||||
|
||||
case ETIMEDOUT:
|
||||
return wxMUTEX_TIMEOUT;
|
||||
|
||||
case 0:
|
||||
return wxMUTEX_NO_ERROR;
|
||||
|
||||
default:
|
||||
wxLogApiError(_T("pthread_mutex_lock()"), err);
|
||||
wxLogApiError(_T("pthread_mutex_[timed]lock()"), err);
|
||||
}
|
||||
|
||||
return wxMUTEX_MISC_ERROR;
|
||||
}
|
||||
|
||||
|
||||
wxMutexError wxMutexInternal::TryLock()
|
||||
{
|
||||
int err = pthread_mutex_trylock(&m_mutex);
|
||||
|
Reference in New Issue
Block a user