diff --git a/hphp/idl/asio.idl.json b/hphp/idl/asio.idl.json index c6e364fa6..817dee191 100644 --- a/hphp/idl/asio.idl.json +++ b/hphp/idl/asio.idl.json @@ -449,25 +449,6 @@ "args": [ ] }, - { - "name": "start", - "desc": "Start asynchronous execution of a given Continuation", - "flags": [ - "IsStatic", - "HasDocComment" - ], - "return": { - "type": "Object", - "desc": "A WaitHandle representing started Continuation" - }, - "args": [ - { - "name": "continuation", - "type": "Object", - "desc": "A Continuation to be started" - } - ] - }, { "name": "getPrivData", "desc": "Get user's private data", diff --git a/hphp/runtime/ext/asio/continuation_wait_handle.cpp b/hphp/runtime/ext/asio/continuation_wait_handle.cpp index e57ff1f7d..79066a6bc 100644 --- a/hphp/runtime/ext/asio/continuation_wait_handle.cpp +++ b/hphp/runtime/ext/asio/continuation_wait_handle.cpp @@ -43,18 +43,15 @@ c_ContinuationWaitHandle::~c_ContinuationWaitHandle() { void c_ContinuationWaitHandle::t___construct() { Object e(SystemLib::AllocInvalidOperationExceptionObject( - "Use ContinuationWaitHandle::start() instead of constructor")); + "Use $continuation->getWaitHandle() instead of constructor")); throw e; } -Object c_ContinuationWaitHandle::ti_start(const char* cls, CObjRef continuation) { - AsioSession* session = AsioSession::Get(); - if (UNLIKELY(!continuation.instanceof(SystemLib::s_ContinuationClass))) { - Object e(SystemLib::AllocInvalidArgumentExceptionObject( - "Expected continuation to be an instance of Continuation")); - throw e; - } +void c_ContinuationWaitHandle::Create(c_Continuation* continuation) { + assert(continuation); + assert(continuation->m_waitHandle.isNull()); + AsioSession* session = AsioSession::Get(); uint16_t depth = session->getCurrentWaitHandleDepth(); if (UNLIKELY(depth >= MAX_DEPTH)) { Object e(SystemLib::AllocInvalidOperationExceptionObject( @@ -62,29 +59,21 @@ Object c_ContinuationWaitHandle::ti_start(const char* cls, CObjRef continuation) throw e; } - c_Continuation* cont = static_cast(continuation.get()); - if (!cont->m_waitHandle.isNull()) { - if (session->isInContext()) { - // throws if cross-context cycle found - cont->m_waitHandle->enterContext(session->getCurrentContextIdx()); - } - return cont->m_waitHandle; - } - - if (UNLIKELY(cont->m_index != -1)) { + if (UNLIKELY(continuation->m_index != -1)) { Object e(SystemLib::AllocInvalidOperationExceptionObject( - cont->m_running + continuation->m_running ? "Encountered an attempt to start currently running continuation" : "Encountered an attempt to start tainted continuation")); throw e; } - p_ContinuationWaitHandle wh = NEWOBJ(c_ContinuationWaitHandle)(); - wh->start(cont, depth + 1); + continuation->m_waitHandle = NEWOBJ(c_ContinuationWaitHandle)(); + continuation->m_waitHandle->initialize(continuation, depth + 1); + + // needs to be called after continuation->m_waitHandle is set if (UNLIKELY(session->hasOnStartedCallback())) { - session->onStarted(wh); + session->onStarted(continuation->m_waitHandle); } - return wh; } Object c_ContinuationWaitHandle::t_getprivdata() { @@ -95,12 +84,11 @@ void c_ContinuationWaitHandle::t_setprivdata(CObjRef data) { m_privData = data; } -void c_ContinuationWaitHandle::start(c_Continuation* continuation, uint16_t depth) { +void c_ContinuationWaitHandle::initialize(c_Continuation* continuation, uint16_t depth) { m_continuation = continuation; m_child = nullptr; m_privData = nullptr; m_depth = depth; - continuation->m_waitHandle = this; setState(STATE_SCHEDULED); if (isInContext()) { diff --git a/hphp/runtime/ext/ext_asio.h b/hphp/runtime/ext/ext_asio.h index 4084115ad..d2d888d5d 100644 --- a/hphp/runtime/ext/ext_asio.h +++ b/hphp/runtime/ext/ext_asio.h @@ -280,15 +280,12 @@ class c_ContinuationWaitHandle : public c_BlockableWaitHandle { public: c_ContinuationWaitHandle(VM::Class* cls = c_ContinuationWaitHandle::s_cls); public: ~c_ContinuationWaitHandle(); public: void t___construct(); - public: static Object ti_start(const char* cls , CObjRef continuation); - public: static Object t_start(CObjRef continuation) { - return ti_start("continuationwaithandle", continuation); - } public: Object t_getprivdata(); public: void t_setprivdata(CObjRef data); public: + static void Create(c_Continuation* continuation); void run(); uint16_t getDepth() { return m_depth; } String getName(); @@ -300,7 +297,7 @@ class c_ContinuationWaitHandle : public c_BlockableWaitHandle { c_WaitableWaitHandle* getChild(); private: - void start(c_Continuation* continuation, uint16_t depth); + void initialize(c_Continuation* continuation, uint16_t depth); void markAsSucceeded(const TypedValue* result); void markAsFailed(CObjRef exception); diff --git a/hphp/runtime/ext/ext_continuation.cpp b/hphp/runtime/ext/ext_continuation.cpp index ab2de3f06..05dd51684 100644 --- a/hphp/runtime/ext/ext_continuation.cpp +++ b/hphp/runtime/ext/ext_continuation.cpp @@ -77,7 +77,11 @@ void c_Continuation::t_update(int64_t label, CVarRef value) { } Object c_Continuation::t_getwaithandle() { - return m_waitHandle.isNull() ? c_ContinuationWaitHandle::t_start(this) : m_waitHandle; + if (m_waitHandle.isNull()) { + c_ContinuationWaitHandle::Create(this); + assert(!m_waitHandle.isNull()); + } + return m_waitHandle; } int64_t c_Continuation::t_getlabel() { diff --git a/hphp/system/class_map.cpp b/hphp/system/class_map.cpp index c573cfe90..4d0b5bb22 100644 --- a/hphp/system/class_map.cpp +++ b/hphp/system/class_map.cpp @@ -24852,12 +24852,6 @@ const char *g_class_map[] = { (const char *)0x8 /* KindOfNull */, NULL, NULL, NULL, - (const char *)0x10006240, "start", "", (const char*)0, (const char*)0, - "/**\n * ( excerpt from http://php.net/manual/en/continuationwaithandle.start.php\n * )\n *\n * Start asynchronous execution of a given Continuation\n *\n * @continuation\n * object A Continuation to be started\n *\n * @return object A WaitHandle representing started Continuation\n */", - (const char *)0x40 /* KindOfObject */, (const char *)0x2000, "continuation", "", (const char *)0x40 /* KindOfObject */, "", (const char *)0, "", (const char *)0, NULL, - NULL, - NULL, - NULL, (const char *)0x10006040, "getPrivData", "", (const char*)0, (const char*)0, "/**\n * ( excerpt from\n * http://php.net/manual/en/continuationwaithandle.getprivdata.php )\n *\n * Get user's private data\n *\n * @return object An Object with user's private data\n */", (const char *)0x40 /* KindOfObject */, NULL,