2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 #ifndef incl_HPHP_EXT_ASIO_SESSION_H_
19 #define incl_HPHP_EXT_ASIO_SESSION_H_
21 #include "hphp/runtime/ext/extension.h"
22 #include "hphp/runtime/base/thread-info.h"
23 #include "hphp/runtime/ext/asio/asio-context.h"
24 #include "hphp/runtime/ext/asio/asio-external-thread-event-queue.h"
27 ///////////////////////////////////////////////////////////////////////////////
31 struct c_AwaitAllWaitHandle
;
32 struct c_ConditionWaitHandle
;
33 struct c_ResumableWaitHandle
;
35 struct AsioSession final
{
37 static AsioSession
* Get() { return s_current
.get(); }
40 void enterContext(ActRec
* savedFP
);
44 return !m_contexts
.empty();
47 AsioContext
* getContext(context_idx_t ctx_idx
) {
48 assertx(ctx_idx
<= m_contexts
.size());
49 return ctx_idx
? m_contexts
[ctx_idx
- 1] : nullptr;
52 AsioContext
* getCurrentContext() {
53 assertx(isInContext());
54 return m_contexts
.back();
57 context_idx_t
getCurrentContextIdx() {
58 assertx(static_cast<context_idx_t
>(m_contexts
.size()) == m_contexts
.size());
59 return static_cast<context_idx_t
>(m_contexts
.size());
62 // External thread events.
63 AsioExternalThreadEventQueue
* getExternalThreadEventQueue() {
64 return &m_externalThreadEventQueue
;
67 // Meager time abstractions.
68 typedef std::chrono::time_point
<std::chrono::steady_clock
> TimePoint
;
70 // The latest time we will wait for an I/O operation to complete. If this
71 // time is exceeded, onIOWaitExit will throw after checking surprise.
72 static TimePoint
getLatestWakeTime() {
73 auto now
= std::chrono::steady_clock::now();
74 auto info
= ThreadInfo::s_threadInfo
.getNoCheck();
75 auto& data
= info
->m_reqInjectionData
;
76 if (!data
.getTimeout()) {
77 // Don't wait for over nine thousand hours.
78 return now
+ std::chrono::hours(9000);
80 auto remaining
= int64_t(data
.getRemainingTime());
81 return now
+ std::chrono::seconds(remaining
);
84 // Sleep event management.
85 void enqueueSleepEvent(c_SleepWaitHandle
* h
);
86 bool processSleepEvents();
87 // Wakeup time of next sleep wait handle or request timeout time.
88 // The returned timestamp may correspond to canceled wait handle.
89 TimePoint
sleepWakeTime();
90 // The next wait handle to wake up. The wait handle may be cancled
91 c_SleepWaitHandle
* nextSleepEvent();
93 // Abrupt interrupt exception.
94 ObjectData
* getAbruptInterruptException() {
95 return m_abruptInterruptException
.get();
97 bool hasAbruptInterruptException() { return !!m_abruptInterruptException
; }
98 void initAbruptInterruptException();
100 // Awaitable callbacks:
101 void setOnIOWaitEnter(const Variant
& callback
);
102 void setOnIOWaitExit(const Variant
& callback
);
103 void setOnJoin(const Variant
& callback
);
104 bool hasOnIOWaitEnter() { return !!m_onIOWaitEnter
; }
105 bool hasOnIOWaitExit() { return !!m_onIOWaitExit
; }
106 bool hasOnJoin() { return !!m_onJoin
; }
107 void onIOWaitEnter();
109 void onJoin(c_Awaitable
* waitHandle
);
111 // ResumableWaitHandle callbacks:
112 void setOnResumableCreate(const Variant
& callback
);
113 void setOnResumableAwait(const Variant
& callback
);
114 void setOnResumableSuccess(const Variant
& callback
);
115 void setOnResumableFail(const Variant
& callback
);
116 bool hasOnResumableCreate() { return !!m_onResumableCreate
; }
117 bool hasOnResumableAwait() { return !!m_onResumableAwait
; }
118 bool hasOnResumableSuccess() { return !!m_onResumableSuccess
; }
119 bool hasOnResumableFail() { return !!m_onResumableFail
; }
120 void onResumableCreate(c_ResumableWaitHandle
*, c_WaitableWaitHandle
* child
);
121 void onResumableAwait(c_ResumableWaitHandle
*, c_WaitableWaitHandle
* child
);
122 void onResumableSuccess(c_ResumableWaitHandle
* cont
, const Variant
& result
);
123 void onResumableFail(c_ResumableWaitHandle
* cont
, const Object
& exception
);
124 void updateEventHookState();
126 // AwaitAllWaitHandle callbacks:
127 void setOnAwaitAllCreate(const Variant
& callback
);
128 bool hasOnAwaitAllCreate() { return !!m_onAwaitAllCreate
; }
129 void onAwaitAllCreate(c_AwaitAllWaitHandle
* wh
, const Variant
& dependencies
);
131 // ConditionWaitHandle callbacks:
132 void setOnConditionCreate(const Variant
& callback
);
133 bool hasOnConditionCreate() { return !!m_onConditionCreate
; }
134 void onConditionCreate(c_ConditionWaitHandle
* wh
, c_WaitableWaitHandle
*);
136 // ExternalThreadEventWaitHandle callbacks:
137 void setOnExternalThreadEventCreate(const Variant
& callback
);
138 void setOnExternalThreadEventSuccess(const Variant
& callback
);
139 void setOnExternalThreadEventFail(const Variant
& callback
);
140 bool hasOnExternalThreadEventCreate() { return !!m_onExtThreadEventCreate
; }
141 bool hasOnExternalThreadEventSuccess() { return !!m_onExtThreadEventSuccess
; }
142 bool hasOnExternalThreadEventFail() { return !!m_onExtThreadEventFail
; }
143 void onExternalThreadEventCreate(c_ExternalThreadEventWaitHandle
* waitHandle
);
144 void onExternalThreadEventSuccess(c_ExternalThreadEventWaitHandle
* waitHandle
,
145 const Variant
& result
, int64_t finish_time
);
146 void onExternalThreadEventFail(c_ExternalThreadEventWaitHandle
* waitHandle
,
147 const Object
& exception
, int64_t finish_time
);
149 // SleepWaitHandle callbacks:
150 void setOnSleepCreate(const Variant
& callback
);
151 void setOnSleepSuccess(const Variant
& callback
);
152 bool hasOnSleepCreate() { return !!m_onSleepCreate
; }
153 bool hasOnSleepSuccess() { return !!m_onSleepSuccess
; }
154 void onSleepCreate(c_SleepWaitHandle
* waitHandle
);
155 void onSleepSuccess(c_SleepWaitHandle
* waitHandle
, int64_t finish_time
);
159 friend AsioSession
* req::make_raw
<AsioSession
>();
162 static THREAD_LOCAL_PROXY(AsioSession
, s_current
);
163 req::vector
<AsioContext
*> m_contexts
;
164 req::vector
<c_SleepWaitHandle
*> m_sleepEvents
;
165 AsioExternalThreadEventQueue m_externalThreadEventQueue
;
167 Object m_abruptInterruptException
;
168 Object m_onIOWaitEnter
;
169 Object m_onIOWaitExit
;
171 Object m_onResumableCreate
;
172 Object m_onResumableAwait
;
173 Object m_onResumableSuccess
;
174 Object m_onResumableFail
;
175 Object m_onAwaitAllCreate
;
176 Object m_onConditionCreate
;
177 Object m_onExtThreadEventCreate
;
178 Object m_onExtThreadEventSuccess
;
179 Object m_onExtThreadEventFail
;
180 Object m_onSleepCreate
;
181 Object m_onSleepSuccess
;
184 ///////////////////////////////////////////////////////////////////////////////
187 #endif // incl_HPHP_EXT_ASIO_SESSION_H_