1 // Copyright Joyent, Inc. and other Node contributors. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a 4 // copy of this software and associated documentation files (the 5 // "Software"), to deal in the Software without restriction, including 6 // without limitation the rights to use, copy, modify, merge, publish, 7 // distribute, sublicense, and/or sell copies of the Software, and to permit 8 // persons to whom the Software is furnished to do so, subject to the 9 // following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included 12 // in all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 #ifndef SRC_ASYNC_WRAP_H_ 23 #define SRC_ASYNC_WRAP_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "base_object.h" 28 #include "v8.h" 29 30 #include <cstdint> 31 32 namespace node { 33 34 #define NODE_ASYNC_NON_CRYPTO_PROVIDER_TYPES(V) \ 35 V(NONE) \ 36 V(DIRHANDLE) \ 37 V(DNSCHANNEL) \ 38 V(ELDHISTOGRAM) \ 39 V(FILEHANDLE) \ 40 V(FILEHANDLECLOSEREQ) \ 41 V(FSEVENTWRAP) \ 42 V(FSREQCALLBACK) \ 43 V(FSREQPROMISE) \ 44 V(GETADDRINFOREQWRAP) \ 45 V(GETNAMEINFOREQWRAP) \ 46 V(HEAPSNAPSHOT) \ 47 V(HTTP2SESSION) \ 48 V(HTTP2STREAM) \ 49 V(HTTP2PING) \ 50 V(HTTP2SETTINGS) \ 51 V(HTTPINCOMINGMESSAGE) \ 52 V(HTTPCLIENTREQUEST) \ 53 V(JSSTREAM) \ 54 V(JSUDPWRAP) \ 55 V(MESSAGEPORT) \ 56 V(PIPECONNECTWRAP) \ 57 V(PIPESERVERWRAP) \ 58 V(PIPEWRAP) \ 59 V(PROCESSWRAP) \ 60 V(PROMISE) \ 61 V(QUERYWRAP) \ 62 V(SHUTDOWNWRAP) \ 63 V(SIGNALWRAP) \ 64 V(STATWATCHER) \ 65 V(STREAMPIPE) \ 66 V(TCPCONNECTWRAP) \ 67 V(TCPSERVERWRAP) \ 68 V(TCPWRAP) \ 69 V(TTYWRAP) \ 70 V(UDPSENDWRAP) \ 71 V(UDPWRAP) \ 72 V(SIGINTWATCHDOG) \ 73 V(WORKER) \ 74 V(WORKERHEAPSNAPSHOT) \ 75 V(WRITEWRAP) \ 76 V(ZLIB) 77 78 #if HAVE_OPENSSL 79 #define NODE_ASYNC_CRYPTO_PROVIDER_TYPES(V) \ 80 V(PBKDF2REQUEST) \ 81 V(KEYPAIRGENREQUEST) \ 82 V(RANDOMBYTESREQUEST) \ 83 V(SCRYPTREQUEST) \ 84 V(TLSWRAP) 85 #else 86 #define NODE_ASYNC_CRYPTO_PROVIDER_TYPES(V) 87 #endif // HAVE_OPENSSL 88 89 #if HAVE_INSPECTOR 90 #define NODE_ASYNC_INSPECTOR_PROVIDER_TYPES(V) \ 91 V(INSPECTORJSBINDING) 92 #else 93 #define NODE_ASYNC_INSPECTOR_PROVIDER_TYPES(V) 94 #endif // HAVE_INSPECTOR 95 96 #define NODE_ASYNC_PROVIDER_TYPES(V) \ 97 NODE_ASYNC_NON_CRYPTO_PROVIDER_TYPES(V) \ 98 NODE_ASYNC_CRYPTO_PROVIDER_TYPES(V) \ 99 NODE_ASYNC_INSPECTOR_PROVIDER_TYPES(V) 100 101 class Environment; 102 class DestroyParam; 103 104 class AsyncWrap : public BaseObject { 105 public: 106 enum ProviderType { 107 #define V(PROVIDER) \ 108 PROVIDER_ ## PROVIDER, 109 NODE_ASYNC_PROVIDER_TYPES(V) 110 #undef V 111 PROVIDERS_LENGTH, 112 }; 113 114 AsyncWrap(Environment* env, 115 v8::Local<v8::Object> object, 116 ProviderType provider, 117 double execution_async_id = kInvalidAsyncId); 118 119 // This constructor creates a reusable instance where user is responsible 120 // to call set_provider_type() and AsyncReset() before use. 121 AsyncWrap(Environment* env, v8::Local<v8::Object> object); 122 123 ~AsyncWrap() override; 124 125 AsyncWrap() = delete; 126 127 static constexpr double kInvalidAsyncId = -1; 128 129 static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( 130 Environment* env); 131 132 static void Initialize(v8::Local<v8::Object> target, 133 v8::Local<v8::Value> unused, 134 v8::Local<v8::Context> context, 135 void* priv); 136 137 static void GetAsyncId(const v8::FunctionCallbackInfo<v8::Value>& args); 138 static void PushAsyncContext(const v8::FunctionCallbackInfo<v8::Value>& args); 139 static void PopAsyncContext(const v8::FunctionCallbackInfo<v8::Value>& args); 140 static void ExecutionAsyncResource( 141 const v8::FunctionCallbackInfo<v8::Value>& args); 142 static void ClearAsyncIdStack( 143 const v8::FunctionCallbackInfo<v8::Value>& args); 144 static void AsyncReset(const v8::FunctionCallbackInfo<v8::Value>& args); 145 static void GetProviderType(const v8::FunctionCallbackInfo<v8::Value>& args); 146 static void QueueDestroyAsyncId( 147 const v8::FunctionCallbackInfo<v8::Value>& args); 148 static void SetCallbackTrampoline( 149 const v8::FunctionCallbackInfo<v8::Value>& args); 150 151 static void EmitAsyncInit(Environment* env, 152 v8::Local<v8::Object> object, 153 v8::Local<v8::String> type, 154 double async_id, 155 double trigger_async_id); 156 157 static void EmitDestroy(Environment* env, double async_id); 158 static void EmitBefore(Environment* env, double async_id); 159 static void EmitAfter(Environment* env, double async_id); 160 static void EmitPromiseResolve(Environment* env, double async_id); 161 162 void EmitDestroy(bool from_gc = false); 163 164 void EmitTraceEventBefore(); 165 static void EmitTraceEventAfter(ProviderType type, double async_id); 166 void EmitTraceEventDestroy(); 167 168 static void DestroyAsyncIdsCallback(Environment* env); 169 170 inline ProviderType provider_type() const; 171 inline ProviderType set_provider_type(ProviderType provider); 172 173 inline double get_async_id() const; 174 inline double get_trigger_async_id() const; 175 176 void AsyncReset(v8::Local<v8::Object> resource, 177 double execution_async_id = kInvalidAsyncId, 178 bool silent = false); 179 180 // Only call these within a valid HandleScope. 181 v8::MaybeLocal<v8::Value> MakeCallback(const v8::Local<v8::Function> cb, 182 int argc, 183 v8::Local<v8::Value>* argv); 184 inline v8::MaybeLocal<v8::Value> MakeCallback( 185 const v8::Local<v8::Symbol> symbol, 186 int argc, 187 v8::Local<v8::Value>* argv); 188 inline v8::MaybeLocal<v8::Value> MakeCallback( 189 const v8::Local<v8::String> symbol, 190 int argc, 191 v8::Local<v8::Value>* argv); 192 inline v8::MaybeLocal<v8::Value> MakeCallback( 193 const v8::Local<v8::Name> symbol, 194 int argc, 195 v8::Local<v8::Value>* argv); 196 197 virtual std::string diagnostic_name() const; 198 std::string MemoryInfoName() const override; 199 200 static void WeakCallback(const v8::WeakCallbackInfo<DestroyParam> &info); 201 202 // Returns the object that 'owns' an async wrap. For example, for a 203 // TCP connection handle, this is the corresponding net.Socket. 204 v8::Local<v8::Object> GetOwner(); 205 static v8::Local<v8::Object> GetOwner(Environment* env, 206 v8::Local<v8::Object> obj); 207 208 bool IsDoneInitializing() const override; 209 210 private: 211 friend class PromiseWrap; 212 213 AsyncWrap(Environment* env, 214 v8::Local<v8::Object> promise, 215 ProviderType provider, 216 double execution_async_id, 217 bool silent); 218 ProviderType provider_type_ = PROVIDER_NONE; 219 bool init_hook_ran_ = false; 220 // Because the values may be Reset(), cannot be made const. 221 double async_id_ = kInvalidAsyncId; 222 double trigger_async_id_; 223 }; 224 225 } // namespace node 226 227 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 228 229 #endif // SRC_ASYNC_WRAP_H_ 230