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