Archived
This forum has been archived. Please start a new discussion on GitHub.
return value of pthread_mutex_trylock() not check properly
I'm trying to get Ice working under FreeBSD.
It builds fine but make test fails:
After some investigation it turned out that in Mutex.h the return value of pthread_mutex_trylock() is tested against EBUSY. But the new threading library in FreeBSD returns EDEADLK (which seems to be okay according to the standard).
This simple patch solves the problem:
Exactly the same problem occurs in StaticMutex.h.
After patching both header files make test just works fine.
It builds fine but make test fails:
running mutex test... ../../../include/IceUtil/Mutex.h:323: IceUtil::ThreadSyscallException: thread syscall exception: Resource deadlock avoided failed test mutex failed
After some investigation it turned out that in Mutex.h the return value of pthread_mutex_trylock() is tested against EBUSY. But the new threading library in FreeBSD returns EDEADLK (which seems to be okay according to the standard).
This simple patch solves the problem:
--- include/IceUtil/Mutex.h.orig Sun May 23 23:52:37 2004 +++ include/IceUtil/Mutex.h Sun May 23 23:54:30 2004 @@ -318,7 +318,7 @@ Mutex::tryLock() const { int rc = pthread_mutex_trylock(&_mutex); - if(rc != 0 && rc != EBUSY) + if(rc != 0 && rc != EBUSY && rc != EDEADLK) { throw ThreadSyscallException(__FILE__, __LINE__, rc); }
Exactly the same problem occurs in StaticMutex.h.
After patching both header files make test just works fine.
0
Comments
-
Welcome to the forum!
If Mutex::tryLock receives EDEADLK, it indicates an application error because it means an application thread is attempting to recursively lock a non-recursive mutex. It is appropriate for an exception to be raised in this case.
So, either there is a bug in the test suite, or the FreeBSD threading library is misbehaving. Can you build Ice in debug mode and provide a stack trace of the test failure? Note that you can run the test directly by executing test/IceUtil/thread/client.
Thanks,
- Mark0 -
Unfortunately gdb has troubles with the threading library and I'm unable to get a backtrace.
I put in some debug information to track the failing test down:
This is around line 126 in MutexTest.cpp:Mutex::TryLock lock2(mutex); std::cerr << "this get's printed\n"; test(lock.tryAcquire() == false); std::cerr << "we never reach this\n";
The return value of pthread_mutex_trylock() in Mutex.h is EDEADLK with the new threading library (it was EBUSY with the old one) which causes the ThreadSyscallException to be thrown.
Sorry again that I can't provide a backtrace but I hope this is information somewhat useful to you.0 -
Ok, now I strongly suspect a bug in the FreeBSD threading library you are using.
The C equivalent of the test to this point is pretty simple:pthread_mutex_init(...); pthread_mutex_lock(...); pthread_mutex_unlock(...); pthread_mutex_trylock(...);
The call to trylock should not be returning EDEADLK in this case, since the mutex has clearly been unlocked.
Perhaps you should submit this test to the FreeBSD folks as a bug report.
Take care,
- Mark0 -
Please ignore my previous reply. A colleague graciously pointed out that I was quite wrong. Thanks Benoit.
It appears from this link that pthread_mutex_trylock on FreeBSD raises EDEADLK in some circumstances and EBUSY in others.
At this point we would prefer not to mask the EDEADLK result by modifying Mutex::tryLock as you suggested, so we will modify the tests to trap IceUtil::ThreadSyscallException and check the result code.
Thanks,
- Mark0 -
Thanks for your quick replies and the inclusion of the fixes in Ice 1.4.
Unfortunately I missed that the monitor<mutex> test fails just for the same reason (because it was obscured by my Mutex.h patch).
The failing code is test/IceUtil/thread/MonitorMutexTest.cpp, line 111:Monitor<Mutex>::TryLock tlock(monitor);
Would be great if this could be integrated too for later releases.0