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:
Vadim Zeitlin
2007-03-08 00:22:11 +00:00
parent 4738d6746b
commit 696d13ee0e
6 changed files with 97 additions and 7 deletions

View File

@@ -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:

View File

@@ -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}

View File

@@ -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();

View File

@@ -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,

View File

@@ -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:

View File

@@ -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);