Boost C++ Libraries: Ticket #9284: WaitForSingleObject(mutex) must handle WAIT_ABANDONED https://svn.boost.org/trac10/ticket/9284 <p> boost-1_54\boost\interprocess\sync\windows\winapi_mutex_wrapper.hpp line 53 </p> <blockquote> <p> void lock() { </p> <blockquote> <p> if(winapi::wait_for_single_object(m_mtx_hnd, winapi::infinite_time) != winapi::wait_object_0){ </p> <blockquote> <p> error_info err = system_error_code(); throw interprocess_exception(err); </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> <p> The wait_for_single_object maybe return wait_abandon which means the mutex holder thread exited and did not release the mutex. Normally, this should never happen, but if the mutext holder process crash, this will happen. </p> <p> So the code should change to: unsigned long ret = winapi::wait_for(...); if(ret != winapi::wait_object_0 &amp;&amp; ret != winapi::wait_abondon) { </p> <blockquote> <p> error_info err = system_error_code(); throw interprocess_exception(err); </p> </blockquote> <p> } </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9284 Trac 1.4.3 anonymous Tue, 22 Oct 2013 07:40:43 GMT <link>https://svn.boost.org/trac10/ticket/9284#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9284#comment:1</guid> <description> </description> <category>Ticket</category> </item> <item> <author>huyuguang@…</author> <pubDate>Mon, 28 Oct 2013 02:00:21 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9284#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9284#comment:2</guid> <description> <p> I think maybe I am wrong. Here the code should not handle the wait_abondon and should throw a exception. The caller can catch the exception and check if it should handle the exception or just ignore it. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Mon, 28 Oct 2013 16:30:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9284#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9284#comment:3</guid> <description> <p> Thanks for the report. I think it should treat wait_abandoned specially, because the mutex will be locked, so it should detect wait_abandoned and unlock the mutex before throwing the exception. Otherwise, the client might try to lock() again and it would deadlock. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Tue, 29 Oct 2013 02:26:29 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9284#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9284#comment:4</guid> <description> <blockquote> <p> void lock() { </p> <blockquote> <p> unsigned long ret = winapi::wait_for_single_object(m_mtx_hnd, winapi::infinite_time); if(ret != winapi::wait_object_0){ </p> <blockquote> <p> if(ret != winapi::wait_abandoned) { </p> <blockquote> <p> error_info err = system_error_code(); throw interprocess_exception(err); </p> </blockquote> <p> } else { </p> <blockquote> <p> winapi::release_mutex(m_mtx_hnd); throw interprocess_exception(0, "wait_abandoned"); </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> <blockquote> <p> bool try_lock() { </p> <blockquote> <p> unsigned long ret = winapi::wait_for_single_object(m_mtx_hnd, 0); if(ret == winapi::wait_object_0){ </p> <blockquote> <p> return true; </p> </blockquote> <p> } else if(ret == winapi::wait_timeout){ </p> <blockquote> <p> return false; </p> </blockquote> <p> } else if(ret == winapi::wait_abandoned){ </p> <blockquote> <p> winapi::release_mutex(m_mtx_hnd); throw interprocess_exception(0, "wait_abandoned"); </p> </blockquote> <p> } else{ </p> <blockquote> <p> error_info err = system_error_code(); throw interprocess_exception(err); </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> <blockquote> <p> bool timed_lock(const boost::posix_time::ptime &amp;abs_time) { </p> <blockquote> <p> if(abs_time == boost::posix_time::pos_infin){ </p> <blockquote> <p> this-&gt;lock(); return true; </p> </blockquote> <p> } </p> </blockquote> </blockquote> <blockquote> <blockquote> <p> boost::posix_time::ptime now = microsec_clock::universal_time(); if(now &gt;= abs_time){ </p> <blockquote> <p> return false; </p> </blockquote> <p> } </p> </blockquote> </blockquote> <blockquote> <blockquote> <p> unsigned long ret = winapi::wait_for_single_object </p> <blockquote> <p> (m_mtx_hnd, (abs_time - now).total_milliseconds()); </p> </blockquote> <p> if(ret == winapi::wait_object_0){ </p> <blockquote> <p> return true; </p> </blockquote> <p> } else if(ret == winapi::wait_timeout){ </p> <blockquote> <p> return false; </p> </blockquote> <p> } else if(ret == winapi::wait_abandoned){ </p> <blockquote> <p> winapi::release_mutex(m_mtx_hnd); throw interprocess_exception(0, "wait_abandoned"); </p> </blockquote> <p> } else{ </p> <blockquote> <p> error_info err = system_error_code(); throw interprocess_exception(err); </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Tue, 29 Oct 2013 08:05:29 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/9284#comment:5 https://svn.boost.org/trac10/ticket/9284#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/86512" title="Fixes #9284 (&#34;WaitForSingleObject(mutex) must handle WAIT_ABANDONED&#34;)">[86512]</a>) Fixes <a class="reopened ticket" href="https://svn.boost.org/trac10/ticket/9284" title="#9284: Bugs: WaitForSingleObject(mutex) must handle WAIT_ABANDONED (reopened)">#9284</a> ("<a class="missing wiki">WaitForSingleObject</a>(mutex) must handle WAIT_ABANDONED") </p> Ticket megaposer Thu, 30 Jul 2015 09:35:44 GMT status, version changed; resolution deleted https://svn.boost.org/trac10/ticket/9284#comment:6 https://svn.boost.org/trac10/ticket/9284#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.54.0</span> → <span class="trac-field-new">Boost 1.58.0</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> The fix is incomplete and should have been applied to all <em>wait_for_single_object</em> API wrapper methods in <em>boost_1_58_0/boost/interprocess/sync/windows/winapi_wrapper_common.hpp</em>: </p> <pre class="wiki">line 49 : inline bool winapi_wrapper_try_wait_for_single_object(void *handle) ... line 64 : inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const boost::posix_time::ptime &amp;abs_time) ... </pre><p> In both cases, the state <em>WAIT_ABANDONED =&gt; winapi::wait_abandoned</em> can occur and is not properly handled. </p> <p> That means the <em>orphaned</em> synchronization object will be acquired, but the code would throw an exception without previously releasing the synchronization object. </p> <p> Next time another thread tries to acquire the synchronization object, the object would still be locked. If the same thread tries to acquire the object, it would succeed, but the number of releases would not correctly offset the number of acquisitions. </p> Ticket megaposer <hp@…> Fri, 31 Jul 2015 12:30:03 GMT attachment set https://svn.boost.org/trac10/ticket/9284 https://svn.boost.org/trac10/ticket/9284 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_interprocess_1_58_0.patch</span> </li> </ul> <p> Patch to fix remaining synchronization object WAIT_ABANDONDED issues </p> Ticket Vizor <sid@…> Thu, 08 Mar 2018 15:13:50 GMT <link>https://svn.boost.org/trac10/ticket/9284#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9284#comment:7</guid> <description> <p> Created pull request, that fixes this: <a class="ext-link" href="https://github.com/boostorg/interprocess/pull/51"><span class="icon">​</span>https://github.com/boostorg/interprocess/pull/51</a> </p> </description> <category>Ticket</category> </item> </channel> </rss>