|
@@ -5,6 +5,8 @@
|
|
|
#ifndef SHELL_COMMON_NODE_BINDINGS_H_
|
|
|
#define SHELL_COMMON_NODE_BINDINGS_H_
|
|
|
|
|
|
+#include <type_traits>
|
|
|
+
|
|
|
#include "base/files/file_path.h"
|
|
|
#include "base/macros.h"
|
|
|
#include "base/memory/weak_ptr.h"
|
|
@@ -24,6 +26,54 @@ class IsolateData;
|
|
|
|
|
|
namespace electron {
|
|
|
|
|
|
+// A helper class to manage uv_handle_t types, e.g. uv_async_t.
|
|
|
+//
|
|
|
+// As per the uv docs: "uv_close() MUST be called on each handle before
|
|
|
+// memory is released. Moreover, the memory can only be released in
|
|
|
+// close_cb or after it has returned." This class encapsulates the work
|
|
|
+// needed to follow those requirements.
|
|
|
+template <typename T,
|
|
|
+ typename std::enable_if<
|
|
|
+ // these are the C-style 'subclasses' of uv_handle_t
|
|
|
+ std::is_same<T, uv_async_t>::value ||
|
|
|
+ std::is_same<T, uv_check_t>::value ||
|
|
|
+ std::is_same<T, uv_fs_event_t>::value ||
|
|
|
+ std::is_same<T, uv_fs_poll_t>::value ||
|
|
|
+ std::is_same<T, uv_idle_t>::value ||
|
|
|
+ std::is_same<T, uv_pipe_t>::value ||
|
|
|
+ std::is_same<T, uv_poll_t>::value ||
|
|
|
+ std::is_same<T, uv_prepare_t>::value ||
|
|
|
+ std::is_same<T, uv_process_t>::value ||
|
|
|
+ std::is_same<T, uv_signal_t>::value ||
|
|
|
+ std::is_same<T, uv_stream_t>::value ||
|
|
|
+ std::is_same<T, uv_tcp_t>::value ||
|
|
|
+ std::is_same<T, uv_timer_t>::value ||
|
|
|
+ std::is_same<T, uv_tty_t>::value ||
|
|
|
+ std::is_same<T, uv_udp_t>::value>::type* = nullptr>
|
|
|
+class UvHandle {
|
|
|
+ public:
|
|
|
+ UvHandle() : t_(new T) {}
|
|
|
+ ~UvHandle() { reset(); }
|
|
|
+ T* get() { return t_; }
|
|
|
+ uv_handle_t* handle() { return reinterpret_cast<uv_handle_t*>(t_); }
|
|
|
+
|
|
|
+ void reset() {
|
|
|
+ auto* h = handle();
|
|
|
+ if (h != nullptr) {
|
|
|
+ DCHECK_EQ(0, uv_is_closing(h));
|
|
|
+ uv_close(h, OnClosed);
|
|
|
+ t_ = nullptr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private:
|
|
|
+ static void OnClosed(uv_handle_t* handle) {
|
|
|
+ delete reinterpret_cast<T*>(handle);
|
|
|
+ }
|
|
|
+
|
|
|
+ T* t_ = {};
|
|
|
+};
|
|
|
+
|
|
|
class NodeBindings {
|
|
|
public:
|
|
|
enum class BrowserEnvironment {
|
|
@@ -99,7 +149,7 @@ class NodeBindings {
|
|
|
uv_loop_t worker_loop_;
|
|
|
|
|
|
// Dummy handle to make uv's loop not quit.
|
|
|
- uv_async_t dummy_uv_handle_;
|
|
|
+ UvHandle<uv_async_t> dummy_uv_handle_;
|
|
|
|
|
|
// Thread for polling events.
|
|
|
uv_thread_t embed_thread_;
|