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_HANDLE_WRAP_H_ 23 #define SRC_HANDLE_WRAP_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "async_wrap.h" 28 #include "util.h" 29 #include "uv.h" 30 #include "v8.h" 31 32 namespace node { 33 34 class Environment; 35 class ExternalReferenceRegistry; 36 37 // Rules: 38 // 39 // - Do not throw from handle methods. Set errno. 40 // 41 // - MakeCallback may only be made directly off the event loop. 42 // That is there can be no JavaScript stack frames underneath it. 43 // (Is there any way to assert that?) 44 // 45 // - No use of v8::WeakReferenceCallback. The close callback signifies that 46 // we're done with a handle - external resources can be freed. 47 // 48 // - Reusable? 49 // 50 // - The uv_close_cb is used to free the c++ object. The close callback 51 // is not made into javascript land. 52 // 53 // - uv_ref, uv_unref counts are managed at this layer to avoid needless 54 // js/c++ boundary crossing. At the javascript layer that should all be 55 // taken care of. 56 57 class HandleWrap : public AsyncWrap { 58 public: 59 static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); 60 static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args); 61 static void Unref(const v8::FunctionCallbackInfo<v8::Value>& args); 62 static void HasRef(const v8::FunctionCallbackInfo<v8::Value>& args); 63 IsAlive(const HandleWrap * wrap)64 static inline bool IsAlive(const HandleWrap* wrap) { 65 return wrap != nullptr && 66 wrap->IsDoneInitializing() && 67 wrap->state_ != kClosed; 68 } 69 HasRef(const HandleWrap * wrap)70 static inline bool HasRef(const HandleWrap* wrap) { 71 return IsAlive(wrap) && uv_has_ref(wrap->GetHandle()); 72 } 73 GetHandle()74 inline uv_handle_t* GetHandle() const { return handle_; } 75 76 virtual void Close( 77 v8::Local<v8::Value> close_callback = v8::Local<v8::Value>()); 78 79 static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( 80 Environment* env); 81 static void RegisterExternalReferences(ExternalReferenceRegistry* registry); 82 83 protected: 84 HandleWrap(Environment* env, 85 v8::Local<v8::Object> object, 86 uv_handle_t* handle, 87 AsyncWrap::ProviderType provider); OnClose()88 virtual void OnClose() {} 89 void OnGCCollect() final; 90 bool IsNotIndicativeOfMemoryLeakAtExit() const override; 91 92 void MarkAsInitialized(); 93 void MarkAsUninitialized(); 94 IsHandleClosing()95 inline bool IsHandleClosing() const { 96 return state_ == kClosing || state_ == kClosed; 97 } 98 99 static void OnClose(uv_handle_t* handle); 100 enum { kInitialized, kClosing, kClosed } state_; 101 102 private: 103 friend class Environment; 104 friend void GetActiveHandles(const v8::FunctionCallbackInfo<v8::Value>&); 105 106 // handle_wrap_queue_ needs to be at a fixed offset from the start of the 107 // class because it is used by src/node_postmortem_metadata.cc to calculate 108 // offsets and generate debug symbols for HandleWrap, which assumes that the 109 // position of members in memory are predictable. For more information please 110 // refer to `doc/contributing/node-postmortem-support.md` 111 friend int GenDebugSymbols(); 112 ListNode<HandleWrap> handle_wrap_queue_; 113 uv_handle_t* const handle_; 114 }; 115 116 117 } // namespace node 118 119 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 120 121 #endif // SRC_HANDLE_WRAP_H_ 122