boost::thread not started
Platform : Windows XP, Pentium 4, Visual C++ 6 sp5 I've traced down my problem with starting a thread from a DLL called from Java JNI. If you look at the source code thread.cpp in boost, you can see that a condition variable is used block the creating thread until the new thread function is started. Basically, what I am seeing is that if you wait on this condition variable, then the thread will never start. If I remove the call to param.wait() at the bottom of the constructor then everything works fine. I can't think of a logical explanation, but it's very repeatable. I was also able to recreate this problem using the latest source from CVS. The simple solution would be to remove the condition variable from thread_param code entirely. This would simplify everything, and I don't really see the value anyway. All that is currently guaranteed is that thread_proxy will be called before the boost::thread() constructor is finished. But it doesn't guarantee that threadfunc() will be called before the constructor is finished. Thanks, Justin Michel OCI
justin_michel said:
Platform : Windows XP, Pentium 4, Visual C++ 6 sp5
I've traced down my problem with starting a thread from a DLL called from Java JNI. If you look at the source code thread.cpp in boost, you can see that a condition variable is used block the creating thread until the new thread function is started. Basically, what I am seeing is that if you wait on this condition variable, then the thread will never start. If I remove the call to param.wait() at the bottom of the constructor then everything works fine. I can't think of a logical explanation, but it's very repeatable. I was also able to recreate this problem using the latest source from CVS.
I can't explain this. This has never been reported, and is not an issue with any of the tests or examples shipped with Boost.Threads. Can you create a simple example that reproduces this?
The simple solution would be to remove the condition variable from thread_param code entirely. This would simplify everything, and I don't really see the value anyway. All that is currently guaranteed is that thread_proxy will be called before the boost::thread() constructor is finished. But it doesn't guarantee that threadfunc() will be called before the constructor is finished.
It gaurantees that the function object is copied before the constructor finishes. With out this you have a race condition in which the user supplied function object may no longer exist by the time the thread goes to use it. Removing this wait is not an option. The only option available to you beyond using the wait is to dynamically allocate the proxie's parameter object, copying the user's function object at that time. This would require a fair amount of code changes, however, not just simply commenting out the wait. And *if* the wait is truly failing, then you have more issues than this approach will solve any way. So, let's fix the actual problem here, if we can determine what it is with a reproducable example. -- William E. Kempf
I can't explain it either. It seems to make no sense at all, and I'm
not sure if it is limited to calling from a JNI thread or just a
DLL. I will try to make a complete and simple test case to reproduce
the problem, but in the meantime I made the changes in thread.cpp
and everything seems to be working now. I'm even using condition
variables in my own code. Here's the changes I had to make to get my
code working:
Index: libs/thread/src/thread.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/thread.cpp,v
retrieving revision 1.11
diff -u -r1.11 thread.cpp
--- libs/thread/src/thread.cpp 4 Feb 2003 23:22:58 -0000 1.11
+++ libs/thread/src/thread.cpp 11 Mar 2003 16:56:59 -0000
@@ -27,32 +27,22 @@
#include "timeconv.inl"
+#include <memory>
+
namespace {
class thread_param
{
public:
thread_param(const boost::function0<void>& threadfunc)
- : m_threadfunc(threadfunc), m_started(false)
- {
- }
- void wait()
+ : m_threadfunc(threadfunc)
{
- boost::mutex::scoped_lock scoped_lock(m_mutex);
- while (!m_started)
- m_condition.wait(scoped_lock);
}
- void started()
- {
- boost::mutex::scoped_lock scoped_lock(m_mutex);
- m_started = true;
- m_condition.notify_one();
+ boost::function0<void> getfunc() {
+ return m_threadfunc;
}
-
- boost::mutex m_mutex;
- boost::condition m_condition;
- const boost::function0<void>& m_threadfunc;
- bool m_started;
+private:
+ const boost::function0<void> m_threadfunc;
};
} // unnamed namespace
@@ -66,16 +56,12 @@
static OSStatus thread_proxy(void* param)
#endif
{
- try
- {
- thread_param* p = static_cast
justin_michel said:
I can't explain it either. It seems to make no sense at all, and I'm not sure if it is limited to calling from a JNI thread or just a DLL. I will try to make a complete and simple test case to reproduce the problem, but in the meantime I made the changes in thread.cpp and everything seems to be working now. I'm even using condition variables in my own code. Here's the changes I had to make to get my code working:
I'm not comfortable making any changes with out a reproducable test case here. So I'll wait for you to produce one before proceding. But I'm glad you're able to work around the problem yourself in the interim. -- William E. Kempf
participants (2)
-
justin_michel
-
William E. Kempf