hhvm: implement awaitable cancelation for external thread events
[hiphop-php.git] / hphp / runtime / ext / asio / ext_asio.cpp
blobaf8d4156c915c88911894504c65815908c472835
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2015 Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1997-2010 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #include "hphp/runtime/ext/asio/ext_asio.h"
20 #include "hphp/runtime/ext/asio/asio-context.h"
21 #include "hphp/runtime/ext/asio/asio-session.h"
22 #include "hphp/runtime/ext/asio/ext_external-thread-event-wait-handle.h"
23 #include "hphp/runtime/ext/asio/ext_resumable-wait-handle.h"
24 #include "hphp/runtime/vm/vm-regs.h"
25 #include "hphp/system/systemlib.h"
27 namespace HPHP {
28 ///////////////////////////////////////////////////////////////////////////////
30 namespace {
32 int64_t HHVM_FUNCTION(asio_get_current_context_idx) {
33 return AsioSession::Get()->getCurrentContextIdx();
36 Object HHVM_FUNCTION(asio_get_running_in_context, int ctx_idx) {
37 auto session = AsioSession::Get();
39 if (ctx_idx <= 0) {
40 SystemLib::throwInvalidArgumentExceptionObject(
41 "Expected ctx_idx to be a positive integer");
43 if (ctx_idx > session->getCurrentContextIdx()) {
44 SystemLib::throwInvalidArgumentExceptionObject(
45 "Expected ctx_idx to be less than or equal to the current context index");
48 if (ctx_idx < session->getCurrentContextIdx()) {
49 auto fp = session->getContext(ctx_idx + 1)->getSavedFP();
50 return Object{c_ResumableWaitHandle::getRunning(fp)};
51 } else {
52 VMRegAnchor _;
53 return Object{c_ResumableWaitHandle::getRunning(vmfp())};
59 Object HHVM_FUNCTION(asio_get_running) {
60 VMRegAnchor _;
61 return Object{c_ResumableWaitHandle::getRunning(vmfp())};
64 bool HHVM_FUNCTION(cancel, const Object& obj, const Object& exception) {
65 if (!obj->instanceof(c_WaitHandle::classof())) {
66 SystemLib::throwInvalidArgumentExceptionObject(
67 "Cancellation unsupported for user-land Awaitable");
69 auto handle = wait_handle<c_WaitHandle>(obj.get());
71 switch(handle->getKind()) {
72 case c_WaitHandle::Kind::ExternalThreadEvent:
73 return handle->asExternalThreadEvent()->cancel(exception);
74 default:
75 SystemLib::throwInvalidArgumentExceptionObject(
76 "Cancellation unsupported for " +
77 HHVM_MN(WaitHandle, getName) (handle)
82 static AsioExtension s_asio_extension;
84 void AsioExtension::initFunctions() {
85 HHVM_FALIAS(
86 HH\\asio_get_current_context_idx,
87 asio_get_current_context_idx);
88 HHVM_FALIAS(HH\\asio_get_running_in_context, asio_get_running_in_context);
89 HHVM_FALIAS(HH\\asio_get_running, asio_get_running);
90 HHVM_FALIAS(HH\\Asio\\cancel, cancel);
93 ///////////////////////////////////////////////////////////////////////////////