Potential deadlock in event loop in one-thread application
Added by Trigve Siver almost 10 years ago
Hi,
I'm using Wt with 1 process per session, with 2 threads per session, with Application class based on the threaded example (SingleThreadedApplication - STApplication in my application) so only 1 main thread could be used to dispatch the request.
I'm showing just 1 modial dialog using exec() function. I don't have any code to show for now. When the button is clicked, dialog should be closed. But in rare cases, if I click the button, dialog isn't closed (the signal for closing the dialog that is attached to all the buttons isn't even called) and the application is "dead" then. When I close the browser tab, session isn't destroyed (and so the process). If CTRL+C main process, it is hanging there forever. So apparently there is some dead lock or something like that.
Here is callstack from thread that are using the STApplication in the time of the deadlock:
ntdll.dll!_NtWaitForMultipleObjects@20() Unknown
KernelBase.dll!_WaitForMultipleObjectsEx@20() Unknown
kernel32.dll!_WaitForMultipleObjectsExImplementation@20() Unknown
kernel32.dll!_WaitForMultipleObjects@16() Unknown
boost_thread-vc120-mt-gd-1_55.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for=0x000003ac, boost::detail::timeout target_time={...}) Line 554 C++
pluginWt.dll!boost::detail::basic_cv_list_entry::wait(boost::detail::timeout abs_time={...}) Line 94 C++
pluginWt.dll!boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & lock={...}, boost::detail::timeout abs_time={...}) Line 227 C++
pluginWt.dll!boost::condition_variable_any::wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & m={...}) Line 435 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::waitDone() Line 107 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::notify(const Wt::WEvent & event={...}) Line 82 C++
wtd.dll!Wt::WebSession::handleRequest(Wt::WebSession::Handler & handler={...}) Line 1638 C++
wtd.dll!Wt::WebController::handleRequest(Wt::WebRequest * request=0x0b8f7988) Line 715 C++
wthttpd.dll!boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>::operator()(Wt::WebController * p=0x00707e28, Wt::WebRequest * a1=0x0b8f7988) Line 165 C++
wthttpd.dll!boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> >::operator()<boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list0>(boost::_bi::type<void> __formal={...}, boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *> & f={...}, boost::_bi::list0 & a={...}, int __formal=0) Line 314 C++
wthttpd.dll!boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > >::operator()() Line 21 C++
wthttpd.dll!boost::asio::asio_handler_invoke<boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > >(boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > & function={...}, ...) Line 70 C++
wthttpd.dll!boost_asio_handler_invoke_helpers::invoke<boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > >,boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > >(boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > & function={...}, boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > & context={...}) Line 37 C++
wthttpd.dll!boost::asio::detail::completion_handler<boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > >::do_complete(boost::asio::detail::win_iocp_io_service * owner=0x006d7278, boost::asio::detail::win_iocp_operation * base=0x0b8ee3a8, const boost::system::error_code & __formal={...}, unsigned int __formal=0) Line 68 C++
wtd.dll!boost::asio::detail::win_iocp_operation::complete(boost::asio::detail::win_iocp_io_service & owner={...}, const boost::system::error_code & ec={...}, unsigned int bytes_transferred=0) Line 46 C++
wtd.dll!boost::asio::detail::win_iocp_io_service::do_one(bool block=true, boost::system::error_code & ec={...}) Line 404 C++
wtd.dll!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec={...}) Line 162 C++
wtd.dll!boost::asio::io_service::run() Line 59 C++
wtd.dll!Wt::WIOService::run() Line 181 C++
wtd.dll!boost::_mfi::mf0<void,Wt::WIOService>::operator()(Wt::WIOService * p=0x006f3b68) Line 49 C++
wtd.dll!boost::_bi::list1<boost::_bi::value<Wt::WIOService *> >::operator()<boost::_mfi::mf0<void,Wt::WIOService>,boost::_bi::list0>(boost::_bi::type<void> __formal={...}, boost::_mfi::mf0<void,Wt::WIOService> & f={...}, boost::_bi::list0 & a={...}, int __formal=0) Line 254 C++
wtd.dll!boost::_bi::bind_t<void,boost::_mfi::mf0<void,Wt::WIOService>,boost::_bi::list1<boost::_bi::value<Wt::WIOService *> > >::operator()() Line 21 C++
wtd.dll!boost::detail::thread_data<boost::_bi::bind_t<void,boost::_mfi::mf0<void,Wt::WIOService>,boost::_bi::list1<boost::_bi::value<Wt::WIOService *> > > >::run() Line 118 C++
boost_thread-vc120-mt-gd-1_55.dll!boost::`anonymous namespace'::thread_start_function(void * param=0x006e46c8) Line 217 C++
msvcr120d.dll!_callthreadstartex() Line 376 C
msvcr120d.dll!_threadstartex(void * ptd=0x0071f358) Line 359 C
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!___RtlUserThreadStart@8() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
ntdll.dll!_NtWaitForMultipleObjects@20() Unknown
KernelBase.dll!_WaitForMultipleObjectsEx@20() Unknown
kernel32.dll!_WaitForMultipleObjectsExImplementation@20() Unknown
kernel32.dll!_WaitForMultipleObjects@16() Unknown
boost_thread-vc120-mt-gd-1_55.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for=0x000003ac, boost::detail::timeout target_time={...}) Line 554 C++
pluginWt.dll!boost::detail::basic_cv_list_entry::wait(boost::detail::timeout abs_time={...}) Line 94 C++
pluginWt.dll!boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & lock={...}, boost::detail::timeout abs_time={...}) Line 227 C++
pluginWt.dll!boost::condition_variable_any::wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & m={...}) Line 435 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::waitDone() Line 107 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::notify(const Wt::WEvent & event={...}) Line 82 C++
wtd.dll!Wt::WebSession::handleRequest(Wt::WebSession::Handler & handler={...}) Line 1638 C++
wtd.dll!Wt::WebController::handleRequest(Wt::WebRequest * request=0x0071f280) Line 715 C++
wthttpd.dll!boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>::operator()(Wt::WebController * p=0x00707e28, Wt::WebRequest * a1=0x0071f280) Line 165 C++
wthttpd.dll!boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> >::operator()<boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list0>(boost::_bi::type<void> __formal={...}, boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *> & f={...}, boost::_bi::list0 & a={...}, int __formal=0) Line 314 C++
wthttpd.dll!boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > >::operator()() Line 21 C++
wthttpd.dll!boost::asio::asio_handler_invoke<boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > >(boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > & function={...}, ...) Line 70 C++
wthttpd.dll!boost_asio_handler_invoke_helpers::invoke<boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > >,boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > >(boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > & function={...}, boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > & context={...}) Line 37 C++
wthttpd.dll!boost::asio::detail::completion_handler<boost::_bi::bind_t<void,boost::_mfi::mf1<void,Wt::WebController,Wt::WebRequest *>,boost::_bi::list2<boost::_bi::value<Wt::WebController *>,boost::_bi::value<http::server::HTTPRequest *> > > >::do_complete(boost::asio::detail::win_iocp_io_service * owner=0x006d7278, boost::asio::detail::win_iocp_operation * base=0x0070a2c8, const boost::system::error_code & __formal={...}, unsigned int __formal=0) Line 68 C++
wtd.dll!boost::asio::detail::win_iocp_operation::complete(boost::asio::detail::win_iocp_io_service & owner={...}, const boost::system::error_code & ec={...}, unsigned int bytes_transferred=0) Line 46 C++
wtd.dll!boost::asio::detail::win_iocp_io_service::do_one(bool block=true, boost::system::error_code & ec={...}) Line 404 C++
wtd.dll!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec={...}) Line 162 C++
wtd.dll!boost::asio::io_service::run() Line 59 C++
wtd.dll!Wt::WIOService::run() Line 181 C++
wtd.dll!boost::_mfi::mf0<void,Wt::WIOService>::operator()(Wt::WIOService * p=0x006f3b68) Line 49 C++
wtd.dll!boost::_bi::list1<boost::_bi::value<Wt::WIOService *> >::operator()<boost::_mfi::mf0<void,Wt::WIOService>,boost::_bi::list0>(boost::_bi::type<void> __formal={...}, boost::_mfi::mf0<void,Wt::WIOService> & f={...}, boost::_bi::list0 & a={...}, int __formal=0) Line 254 C++
wtd.dll!boost::_bi::bind_t<void,boost::_mfi::mf0<void,Wt::WIOService>,boost::_bi::list1<boost::_bi::value<Wt::WIOService *> > >::operator()() Line 21 C++
wtd.dll!boost::detail::thread_data<boost::_bi::bind_t<void,boost::_mfi::mf0<void,Wt::WIOService>,boost::_bi::list1<boost::_bi::value<Wt::WIOService *> > > >::run() Line 118 C++
boost_thread-vc120-mt-gd-1_55.dll!boost::`anonymous namespace'::thread_start_function(void * param=0x006e4728) Line 217 C++
msvcr120d.dll!_callthreadstartex() Line 376 C
msvcr120d.dll!_threadstartex(void * ptd=0x0071f740) Line 359 C
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!___RtlUserThreadStart@8() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
ntdll.dll!_NtWaitForMultipleObjects@20() Unknown
KernelBase.dll!_WaitForMultipleObjectsEx@20() Unknown
kernel32.dll!_WaitForMultipleObjectsExImplementation@20() Unknown
kernel32.dll!_WaitForMultipleObjects@16() Unknown
boost_thread-vc120-mt-gd-1_55.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for=0x000003f4, boost::detail::timeout target_time={...}) Line 554 C++
wtd.dll!boost::detail::basic_cv_list_entry::wait(boost::detail::timeout abs_time={...}) Line 94 C++
wtd.dll!boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & lock={...}, boost::detail::timeout abs_time={...}) Line 227 C++
wtd.dll!boost::condition_variable_any::wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & m={...}) Line 435 C++
wtd.dll!Wt::WebSession::doRecursiveEventLoop() Line 1174 C++
wtd.dll!Wt::WApplication::waitForEvent() Line 1497 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::waitForEvent() Line 165 C++
wtd.dll!Wt::WDialog::exec(const Wt::WAnimation & animation={...}) Line 497 C++
pluginWt.dll!xxx::gui::wtplugin::Application::create() Line 140 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::initialize() Line 26 C++
wtd.dll!Wt::WebSession::notify(const Wt::WEvent & event={...}) Line 2095 C++
wtd.dll!Wt::WApplication::notify(const Wt::WEvent & e={...}) Line 1482 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::threadNotify(const Wt::WEvent & event={...}) Line 155 C++
pluginWt.dll!xxx::gui::wtplugin::STApplication::run() Line 129 C++
pluginWt.dll!boost::_mfi::mf0<void,xxx::gui::wtplugin::STApplication>::operator()(xxx::gui::wtplugin::STApplication * p=0x0b8d4ce0) Line 49 C++
pluginWt.dll!boost::_bi::list1<boost::_bi::value<xxx::gui::wtplugin::STApplication *> >::operator()<boost::_mfi::mf0<void,xxx::gui::wtplugin::STApplication>,boost::_bi::list0>(boost::_bi::type<void> __formal={...}, boost::_mfi::mf0<void,xxx::gui::wtplugin::STApplication> & f={...}, boost::_bi::list0 & a={...}, int __formal=0) Line 254 C++
pluginWt.dll!boost::_bi::bind_t<void,boost::_mfi::mf0<void,xxx::gui::wtplugin::STApplication>,boost::_bi::list1<boost::_bi::value<xxx::gui::wtplugin::STApplication *> > >::operator()() Line 21 C++
pluginWt.dll!boost::detail::thread_data<boost::_bi::bind_t<void,boost::_mfi::mf0<void,xxx::gui::wtplugin::STApplication>,boost::_bi::list1<boost::_bi::value<xxx::gui::wtplugin::STApplication *> > > >::run() Line 118 C++
boost_thread-vc120-mt-gd-1_55.dll!boost::`anonymous namespace'::thread_start_function(void * param=0x0070a2a8) Line 217 C++
msvcr120d.dll!_callthreadstartex() Line 376 C
msvcr120d.dll!_threadstartex(void * ptd=0x0b8d95e8) Line 359 C
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!___RtlUserThreadStart@8() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
Log:
[2015-Aug-27 08:56:39.377043] 10076 - [info] "config: reading Wt config file: wt_config.xml (location = 'xxx.exe')"
[2015-Aug-27 08:56:39.395044] 10076 - [info] "wthttp: reading wthttpd configuration from: wt_http.cfg"
[2015-Aug-27 08:56:39.407045] 10076 - [info] "WServer/wthttp: initializing built-in wthttpd"
[2015-Aug-27 08:56:39.416046] 10076 - [info] "wthttp: started server: http://0.0.0.0:63070"
[2015-Aug-27 08:56:39.430046] 10076 - [info] "Wt: session created (#sessions = 1)"
[2015-Aug-27 08:56:39.437047] 10076 [/ JYq3LTQ1m9IWZzVy] [info] "WEnvironment: UserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"
[2015-Aug-27 08:56:39.452048] 10076 - [info] "WebRequest: took 23.002ms"127.0.0.1 - - [2015-Aug-27 08:56:39.461048] "GET / HTTP/1.1" 200 2219
[2015-Aug-27 08:56:39.516051] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: startingthread"
[2015-Aug-27 08:56:39.519052] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: waiting for event done"
[2015-Aug-27 08:56:39.519052] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: [thread]signaling event done"
[2015-Aug-27 08:56:39.527052] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: [thread]waiting for event"
[2015-Aug-27 08:56:39.527052] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: notifying thread"
[2015-Aug-27 08:56:39.532052] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: [thread]handling event"
[2015-Aug-27 08:56:39.532052] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: waiting for event done"
[2015-Aug-27 08:56:39.535052] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: initialize()"
[2015-Aug-27 08:56:39.659060] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: [thread]waitForEvent()"
[2015-Aug-27 08:56:39.665060] 10076 - [info] "WebRequest: took 159.009ms"127.0.0.1 - - [2015-Aug-27 08:56:39.668060] "GET /?wtd=JYq3LTQ1m9IWZzVy&request=style&page=1 HTTP/1.1" 200 106
127.0.0.1 - - [2015-Aug-27 08:56:39.673060] "GET /plugin.css HTTP/1.1" 404 85[2015-Aug-27 08:56:39.683061] 10076 - [info] "WebRequest: took 170.01ms"
127.0.0.1 - - [2015-Aug-27 08:56:39.748065] "GET /?wtd=JYq3LTQ1m9IWZzVy&sid=2115408357&webGL=true&scrW=1680&scrH=1050&tz=120&htmlHistory=true&deployPath=%2F&request=script&rand=587812377 HTTP/1.1" 200 43993
[2015-Aug-27 08:56:39.822069] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: notify()called within app thread"
[2015-Aug-27 08:56:39.828069] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: [thread]returning from waitForEvent()"
[2015-Aug-27 08:56:39.832069] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: [thread]waitForEvent()"
[2015-Aug-27 08:56:39.836070] 10076 - [info] "WebRequest: took 15.001ms"
127.0.0.1 - - [2015-Aug-27 08:56:39.840070] "POST /?wtd=JYq3LTQ1m9IWZzVy HTTP/1.1" 200 50
[2015-Aug-27 08:56:39.844070] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: notifying thread"
[2015-Aug-27 08:56:39.846070] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: waiting for event done"
[2015-Aug-27 08:56:39.846070] 10076 [/ JYq3LTQ1m9IWZzVy] [debug] "STA: waiting for event done"
Anyone knows what's going on?
Thank You
Replies (1)
RE: Potential deadlock in event loop in one-thread application - Added by Trigve Siver almost 10 years ago
After a small investigation, the problem is with recursive event loop, I think.
That is, dialog is run in the main* thread, recursive event loop is started in Wt, waiting for some event. Some event arrives, main thread is resumed. Then new event arrives but it is processed by another thread. Meantime main thread goes to the recursive event loop. The event from another thread is "passed" to the main thread, but main thread is blocked, so waiting. Another event arrives in another thread. Event is "passed" to the main thread, but main thread is blocked, so waiting. The problem is, that recursive event loop cannot be breaked. The only possibility to break it is when the new event would be process by the main thread.
Maybe the only solution is to not to use recursive event loops.
Maybe I'm totally wrong :)
- - main in the sense that the thread responsible for handling the events.