This is the mail archive of the
pthreads-win32@sources.redhat.com
mailing list for the pthreas-win32 project.
Re: Problem with recursive mutex : pthread_mutex_unlock() returnsEPERM code
- From: Ross Johnson <rpj at callisto dot canberra dot edu dot au>
- To: Konstantin Voronkov <beowinkle at yahoo dot com>
- Cc: pthreads-win32 at sources dot redhat dot com
- Date: Sat, 01 Jan 2005 12:15:20 +1100
- Subject: Re: Problem with recursive mutex : pthread_mutex_unlock() returnsEPERM code
- References: <20041230152716.42907.qmail@web13523.mail.yahoo.com>
This appears to be a bug in pthread_mutex_lock.c. It affects both
recursive and errorcheck mutex types.
It was already known that the new atomic exchange based mutex algorithm
sometimes allows a thread to steal the lock from the next FIFO waiter.
This should be a rare occurrence and is tolerated in the interests of
faster locks overall, simplified timedlock operations, and other
potential advantages.
A stolen lock causes a spurious unblock of the next FIFO waiter, which
then must attempt to re-acquire the lock. The bug is that this thread is
setting the lock ownership to itself immediately on waking, before the
attempt to re-acquire. The real lock holder thread then continues on to
perform the unlock, where it mistakenly returns EPERM.
In pthread_mutex_lock.c, near the end, the code is currently:
{
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) -1) != 0)
{
if (WAIT_OBJECT_0 == WaitForSingleObject (mx->event, INFINITE))
{
mx->recursive_count = 1;
mx->ownerThread = self;
}
else
{
result = EINVAL;
break;
}
}
}
This should be rearranged to:
{
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
(LPLONG) &mx->lock_idx,
(LONG) -1) != 0)
{
if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
{
result = EINVAL;
break;
}
}
if (0 == result)
{
mx->recursive_count = 1;
mx->ownerThread = self;
}
}
It looks like pthread_mutex_timedlock is ok though.
This will be fixed in CVS ASAP and a new snapshot will be available as
well, by Tuesday.
Thanks.
Ross
On Thu, 2004-12-30 at 07:27 -0800, Konstantin Voronkov wrote:
> Hello All!
>
> I have problem with recursive mutex.
> pthread_mutex_unlock()
> returns 1 EPERM code. I do not understan what I'm
> doing wrong,
> can you help me, please?
>
> I'm using pthread-win32 snapshot 2004-11-22 pre-build
> library. The library taken from here:
> http://sources.redhat.com/pthreads-win32/
>
>
> I managed to reproduce problem in simple test
> application.
> Abort happens here after some time of work of this
> program:
>
> #include <pthread.h>
> #include <windows.h>
>
> class MutexWrapper
> {
> public:
> // mutex initialization
> MutexWrapper()
> : m_reg_mutex(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
> {
> }
>
> // mutex freeing
> ~MutexWrapper()
> {
> pthread_mutex_destroy(&m_reg_mutex);
> }
>
> // locks the mutex
> void Lock()
> {
> pthread_mutex_lock(&m_reg_mutex);
> }
>
> void UnLock()
> {
> const int retCode =
> pthread_mutex_unlock(&m_reg_mutex);
> if(retCode)
> // abort happens here after
> some time of work of program
> abort();
> }
>
> private:
> pthread_mutex_t m_reg_mutex; // mutex object
> member
> };
>
> unsigned long WINAPI threadFunc(void *mux)
> {
> while(true)
> {
> reinterpret_cast<MutexWrapper *>(mux)->Lock();
> reinterpret_cast<MutexWrapper *>(mux)->UnLock();
> }
> return 0;
> }
>
> int main(int argc, char* argv[])
> {
> MutexWrapper mux;
> CreateThread(0, 0, threadFunc, &mux, 0, 0);
>
> while(true)
> {
> mux.Lock();
> mux.UnLock();
> }
>
> return 0;
> }
>
>
> ================
> the project settings of test application:
> linker options: pthreadVC1.lib /nologo
> /subsystem:console /incremental:no
> /pdb:"Release/CsuByteArrayTest.pdb" /machine:I386
> compiler options: /nologo /MD /W3 /GX /O2 /D "WIN32"
> /D "NDEBUG" /D "_CONSOLE"
> /D "_MBCS" /Fo"Release/" /Fd"Release/" /FD /c
>
> problem reproduces with MSVC 6.0 sp5 compiler
>
> problem reproduces on WinXP sp2, and on Windows 2000
> sp4
>
> Best Regards,
> Voronkov Konstantin
>
>
>
> __________________________________
> Do you Yahoo!?
> All your favorites on one personal page Try My Yahoo!
> http://my.yahoo.com
>