- 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:
\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}
\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}
\twocolitem{{\bf wxMUTEX\_BUSY}}{The mutex is already locked by another thread.}
\end{twocollist}
+
\membersection{wxMutex::Unlock}\label{wxmutexunlock}
\func{wxMutexError}{Unlock}{\void}
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
};
// 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();
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,
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:
m_mutex = ::CreateMutex
(
NULL, // default secutiry attributes
- false, // not initially locked
+ FALSE, // not initially locked
NULL // no name
);
}
}
+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);
break;
case WAIT_TIMEOUT:
- return wxMUTEX_BUSY;
+ return wxMUTEX_TIMEOUT;
case WAIT_ABANDONED: // checked for above
default:
~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;
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:
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);