-
Notifications
You must be signed in to change notification settings - Fork 859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deadlock in BindToContext #395
Conversation
I had the same problem in issue #393 and implemented context sharing via the mentioned recursive lock in PR #389. |
Yes. However, I think using This PR keeps using |
I see, you are basically removing the |
I didn't measure the performance because this PR is not for performance issue but deadlock. Sorry for missing your issue #393. |
Are you using |
This is the code I used to find where's the blocking point. I used gdb to get backtrace and it says #include <pangolin/pangolin.h>
#include <thread>
#include <iostream>
using namespace std;
namespace
{
void task()
{
pangolin::CreateWindowAndBind( "foo", 640, 480 );
glEnable( GL_DEPTH_TEST );
pangolin::OpenGlRenderState s_cam(
pangolin::ProjectionMatrix(640,480,420,420,320,240,0.2,100),
pangolin::ModelViewLookAt(-2,2,-2, 0,0,0, pangolin::AxisY)
);
pangolin::Handler3D handler(s_cam);
pangolin::View& d_cam = pangolin::CreateDisplay()
.SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f)
.SetHandler(&handler);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
d_cam.Activate(s_cam);
pangolin::glDrawColouredCube();
pangolin::FinishFrame();
std::this_thread::sleep_for( std::chrono::milliseconds(100) );
cout << "line." << __LINE__ << endl;
}
}
int main()
{
std::thread th( task );
th.join();
cout << "line." << __LINE__ << endl;
auto& interface = pangolin::BindToContext( "foo" );
cout << "line." << __LINE__ << endl;
return 0;
} |
When debugging, I got the same blocking at Does your example work on my I was looking for a nicer way to switch contexts without the need to manually call |
How about using thread local storage (TLS)? For example: #include <thread>
#include <chrono>
#include <iostream>
using namespace std;
namespace{
class Foo
{
public:
Foo()
: ptr_( nullptr )
{
cout << "Foo::" << __func__ << " this:" << this << endl;
}
~Foo() noexcept
{
cout << "Foo::" << __func__ << " this:" << this << endl;
release();
}
int* make( size_t len )
{
cout << "Foo::" << __func__ << "(" << len << ") this:" << this << endl;
ptr_ = new int[len];
return ptr_;
}
void release()
{
cout << "Foo::" << __func__ << " this:" << this << endl;
delete[] ptr_;
ptr_ = nullptr;
}
private:
int* ptr_;
};
Foo& foo()
{
static thread_local Foo foo;
return foo;
}
int* make( size_t len )
{
cout << __func__ << "(" << len << ")" << endl;
return foo().make(len);
}
void task( int i )
{
cout << __func__ << "(" << i << ") entry" << endl;
auto ptr = make( i );
this_thread::sleep_for( chrono::milliseconds( i * 10 ) );
cout << __func__ << "(" << i << ") exit. ** Foo is not explicitly released **" << endl;
}
}
int main()
{
cout << __func__ << " line." << __LINE__ << endl;
thread th1( task, 16 );
this_thread::sleep_for( chrono::milliseconds( 500 ) );
cout << __func__ << " line." << __LINE__ << endl;
th1.join();
cout << __func__ << " line." << __LINE__ << endl;
return 0;
} |
Thanks, I forgot about the thread local variables. I think this is what is currently done with the Maybe for this, you would need a structure that keeps track of the parent contexts to unbind/bind them. |
No, TLS does not work to move contexts among threads freely. It is the same as the mutex. Anyway, I understand that I have to unbind the context to move context between threads, thank you. |
@daisuke-nagao Is this issue resolved by #398 ? |
Thanks for the good discussion here. Closing it out as it seems to be resolved. |
FindContext called from BindToContext try to lock contexs_mutex, but it is already locked before and deadlock.