From 935011733c7d4025fd2fc0cf63b2763eabb499fa Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Tue, 28 May 2013 15:10:03 -0700 Subject: [PATCH] Make AsioExternalThreadEvent::abandon() not hit assertion error Destructor of AsioExternalThreadEvent uses assert() to check whether the state is legal. Introduction of abandon() mechanism makes it possible to destroy the AsioExternalThreadEvent in the Waiting state and hit the assertion error. This diff solves the problem by introducing Abandoned state. --- .../ext/asio/asio_external_thread_event.cpp | 3 ++- hphp/runtime/ext/asio/asio_external_thread_event.h | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hphp/runtime/ext/asio/asio_external_thread_event.cpp b/hphp/runtime/ext/asio/asio_external_thread_event.cpp index 56d40f0eb..c519b143a 100644 --- a/hphp/runtime/ext/asio/asio_external_thread_event.cpp +++ b/hphp/runtime/ext/asio/asio_external_thread_event.cpp @@ -15,9 +15,9 @@ +----------------------------------------------------------------------+ */ +#include "hphp/runtime/ext/asio/asio_external_thread_event.h" #include #include "hphp/runtime/ext/ext_asio.h" -#include "hphp/runtime/ext/asio/asio_external_thread_event.h" #include "hphp/runtime/ext/asio/asio_session.h" namespace HPHP { @@ -32,6 +32,7 @@ AsioExternalThreadEvent::AsioExternalThreadEvent(ObjectData* priv_data) void AsioExternalThreadEvent::abandon() { assert(m_state.load() == Waiting); assert(m_waitHandle->getCount() == 1); + m_state.store(Abandoned); m_waitHandle->abandon(false); } diff --git a/hphp/runtime/ext/asio/asio_external_thread_event.h b/hphp/runtime/ext/asio/asio_external_thread_event.h index 6c067a45c..00a628d43 100644 --- a/hphp/runtime/ext/asio/asio_external_thread_event.h +++ b/hphp/runtime/ext/asio/asio_external_thread_event.h @@ -214,7 +214,11 @@ class AsioExternalThreadEvent { * is eventually called. */ virtual ~AsioExternalThreadEvent() { - assert(m_state.load() == Finished || m_state.load() == Canceled); + assert( + m_state.load() == Finished || + m_state.load() == Canceled || + m_state.load() == Abandoned + ); }; /** @@ -267,6 +271,14 @@ class AsioExternalThreadEvent { * eventually calling markAsFinished() that will destruct this object. */ Canceled, + + /** + * Web request thread abandoned event before passing to processing thread. + * + * This object is owned by web request thread, which is trying to abandon + * it prior to passing ownership to processing thread. + */ + Abandoned, }; AsioSession* m_session;