summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/handle_wrap.cc89
-rw-r--r--src/handle_wrap.h30
-rw-r--r--src/stream_wrap.cc59
-rw-r--r--src/stream_wrap.h13
-rw-r--r--src/tcp_wrap.cc7
-rw-r--r--src/timer_wrap.cc45
-rw-r--r--wscript1
7 files changed, 149 insertions, 95 deletions
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc
new file mode 100644
index 0000000000..c34c1c2e62
--- /dev/null
+++ b/src/handle_wrap.cc
@@ -0,0 +1,89 @@
+#include <node.h>
+#include <handle_wrap.h>
+
+namespace node {
+
+using v8::Object;
+using v8::Handle;
+using v8::Local;
+using v8::Persistent;
+using v8::Value;
+using v8::HandleScope;
+using v8::FunctionTemplate;
+using v8::String;
+using v8::Function;
+using v8::TryCatch;
+using v8::Context;
+using v8::Arguments;
+using v8::Integer;
+
+
+#define UNWRAP \
+ assert(!args.Holder().IsEmpty()); \
+ assert(args.Holder()->InternalFieldCount() > 0); \
+ HandleWrap* wrap = \
+ static_cast<HandleWrap*>(args.Holder()->GetPointerFromInternalField(0)); \
+ if (!wrap) { \
+ SetErrno(UV_EBADF); \
+ return scope.Close(Integer::New(-1)); \
+ }
+
+
+void HandleWrap::Initialize(Handle<Object> target) {
+ /* Doesn't do anything at the moment. */
+}
+
+
+Handle<Value> HandleWrap::Close(const Arguments& args) {
+ HandleScope scope;
+
+ UNWRAP
+
+ assert(!wrap->object_.IsEmpty());
+ int r = uv_close(wrap->handle__, OnClose);
+
+ wrap->StateChange();
+
+ if (r) {
+ SetErrno(uv_last_error().code);
+
+ wrap->object_->SetPointerInInternalField(0, NULL);
+ wrap->object_.Dispose();
+ wrap->object_.Clear();
+ }
+ return scope.Close(Integer::New(r));
+}
+
+
+HandleWrap::HandleWrap(Handle<Object> object, uv_handle_t* h) {
+ handle__ = h;
+ h->data = this;
+
+ HandleScope scope;
+ assert(object_.IsEmpty());
+ assert(object->InternalFieldCount() > 0);
+ object_ = v8::Persistent<v8::Object>::New(object);
+ object_->SetPointerInInternalField(0, this);
+}
+
+
+HandleWrap::~HandleWrap() {
+ assert(object_.IsEmpty());
+}
+
+
+void HandleWrap::OnClose(uv_handle_t* handle) {
+ HandleWrap* wrap = static_cast<HandleWrap*>(handle->data);
+
+ // The wrap object should still be there.
+ assert(wrap->object_.IsEmpty() == false);
+
+ wrap->object_->SetPointerInInternalField(0, NULL);
+ wrap->object_.Dispose();
+ wrap->object_.Clear();
+
+ delete wrap;
+}
+
+
+} // namespace node
diff --git a/src/handle_wrap.h b/src/handle_wrap.h
new file mode 100644
index 0000000000..2c51799a58
--- /dev/null
+++ b/src/handle_wrap.h
@@ -0,0 +1,30 @@
+#ifndef HANDLE_WRAP_H_
+#define HANDLE_WRAP_H_
+
+namespace node {
+
+class HandleWrap {
+ public:
+ static void Initialize(v8::Handle<v8::Object> target);
+ static v8::Handle<v8::Value> Close(const v8::Arguments& args);
+
+ protected:
+ HandleWrap(v8::Handle<v8::Object> object, uv_handle_t* handle);
+ virtual ~HandleWrap();
+
+ virtual void StateChange() {}
+
+ v8::Persistent<v8::Object> object_;
+
+ private:
+ static void OnClose(uv_handle_t* handle);
+ // Using double underscore due to handle_ member in tcp_wrap. Probably
+ // tcp_wrap should rename it's member to 'handle'.
+ uv_handle_t* handle__;
+};
+
+
+} // namespace node
+
+
+#endif // HANDLE_WRAP_H_
diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc
index df509c485b..3da51d9600 100644
--- a/src/stream_wrap.cc
+++ b/src/stream_wrap.cc
@@ -1,5 +1,6 @@
#include <node.h>
#include <node_buffer.h>
+#include <handle_wrap.h>
#include <stream_wrap.h>
#include <req_wrap.h>
@@ -43,10 +44,10 @@ typedef class ReqWrap<uv_write_t> WriteWrap;
static size_t slab_used;
static uv_stream_t* handle_that_last_alloced;
-Persistent<String> slab_sym;
-Persistent<String> buffer_sym;
-Persistent<String> write_queue_size_sym;
-bool initialized;
+static Persistent<String> slab_sym;
+static Persistent<String> buffer_sym;
+static Persistent<String> write_queue_size_sym;
+static bool initialized;
void StreamWrap::Initialize(Handle<Object> target) {
@@ -58,6 +59,8 @@ void StreamWrap::Initialize(Handle<Object> target) {
HandleScope scope;
+ HandleWrap::Initialize(target);
+
slab_sym = Persistent<String>::New(String::NewSymbol("slab"));
buffer_sym = Persistent<String>::New(String::NewSymbol("buffer"));
write_queue_size_sym =
@@ -65,40 +68,15 @@ void StreamWrap::Initialize(Handle<Object> target) {
}
-StreamWrap::StreamWrap(Handle<Object> object, uv_stream_t* stream) {
- HandleScope scope;
-
+StreamWrap::StreamWrap(Handle<Object> object, uv_stream_t* stream)
+ : HandleWrap(object, (uv_handle_t*)stream) {
stream_ = stream;
stream->data = this;
- assert(object_.IsEmpty());
- assert(object->InternalFieldCount() > 0);
- object_ = v8::Persistent<v8::Object>::New(object);
- object_->SetPointerInInternalField(0, this);
-
UpdateWriteQueueSize();
}
-StreamWrap::~StreamWrap() {
- assert(object_.IsEmpty());
-}
-
-
-// Free the C++ object on the close callback.
-void StreamWrap::OnClose(uv_handle_t* handle) {
- StreamWrap* wrap = static_cast<StreamWrap*>(handle->data);
-
- // The wrap object should still be there.
- assert(wrap->object_.IsEmpty() == false);
-
- wrap->object_->SetPointerInInternalField(0, NULL);
- wrap->object_.Dispose();
- wrap->object_.Clear();
- delete wrap;
-}
-
-
void StreamWrap::UpdateWriteQueueSize() {
object_->Set(write_queue_size_sym, Integer::New(stream_->write_queue_size));
}
@@ -224,25 +202,6 @@ void StreamWrap::OnRead(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
}
}
-// TODO: share me?
-Handle<Value> StreamWrap::Close(const Arguments& args) {
- HandleScope scope;
-
- UNWRAP
-
- assert(!wrap->object_.IsEmpty());
- int r = uv_close((uv_handle_t*) wrap->stream_, OnClose);
-
- if (r) {
- SetErrno(uv_last_error().code);
-
- wrap->object_->SetPointerInInternalField(0, NULL);
- wrap->object_.Dispose();
- wrap->object_.Clear();
- }
- return scope.Close(Integer::New(r));
-}
-
Handle<Value> StreamWrap::Write(const Arguments& args) {
HandleScope scope;
diff --git a/src/stream_wrap.h b/src/stream_wrap.h
index fb233a447d..d1b442fa87 100644
--- a/src/stream_wrap.h
+++ b/src/stream_wrap.h
@@ -1,9 +1,13 @@
#ifndef STREAM_WRAP_H_
#define STREAM_WRAP_H_
+#include <v8.h>
+#include <node.h>
+#include <handle_wrap.h>
+
namespace node {
-class StreamWrap {
+class StreamWrap : public HandleWrap {
public:
static void Initialize(v8::Handle<v8::Object> target);
@@ -12,13 +16,11 @@ class StreamWrap {
static v8::Handle<v8::Value> ReadStart(const v8::Arguments& args);
static v8::Handle<v8::Value> ReadStop(const v8::Arguments& args);
static v8::Handle<v8::Value> Shutdown(const v8::Arguments& args);
- static v8::Handle<v8::Value> Close(const v8::Arguments& args);
protected:
StreamWrap(v8::Handle<v8::Object> object, uv_stream_t* stream);
- ~StreamWrap();
-
- v8::Persistent<v8::Object> object_;
+ virtual ~StreamWrap() { }
+ void StateChange() { }
private:
void UpdateWriteQueueSize();
@@ -29,7 +31,6 @@ class StreamWrap {
static uv_buf_t OnAlloc(uv_stream_t* handle, size_t suggested_size);
static void OnRead(uv_stream_t* handle, ssize_t nread, uv_buf_t buf);
static void AfterShutdown(uv_shutdown_t* req, int status);
- static void OnClose(uv_handle_t* handle);
size_t slab_offset_;
uv_stream_t* stream_;
diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc
index cbeb4a3d7a..fd4552c970 100644
--- a/src/tcp_wrap.cc
+++ b/src/tcp_wrap.cc
@@ -1,6 +1,7 @@
#include <node.h>
#include <node_buffer.h>
#include <req_wrap.h>
+#include <handle_wrap.h>
#include <stream_wrap.h>
// Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop.
@@ -75,10 +76,11 @@ static Persistent<String> port_symbol;
typedef class ReqWrap<uv_connect_t> ConnectWrap;
-class TCPWrap : StreamWrap {
+class TCPWrap : public StreamWrap {
public:
static void Initialize(Handle<Object> target) {
+ HandleWrap::Initialize(target);
StreamWrap::Initialize(target);
HandleScope scope;
@@ -88,11 +90,12 @@ class TCPWrap : StreamWrap {
t->InstanceTemplate()->SetInternalFieldCount(1);
+ NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
+
NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
NODE_SET_PROTOTYPE_METHOD(t, "write", StreamWrap::Write);
NODE_SET_PROTOTYPE_METHOD(t, "shutdown", StreamWrap::Shutdown);
- NODE_SET_PROTOTYPE_METHOD(t, "close", StreamWrap::Close);
NODE_SET_PROTOTYPE_METHOD(t, "bind", Bind);
NODE_SET_PROTOTYPE_METHOD(t, "listen", Listen);
diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc
index 87ccbe224b..3d45946ce6 100644
--- a/src/timer_wrap.cc
+++ b/src/timer_wrap.cc
@@ -1,4 +1,5 @@
#include <node.h>
+#include <handle_wrap.h>
// Rules:
//
@@ -48,21 +49,24 @@ using v8::Arguments;
using v8::Integer;
-class TimerWrap {
+class TimerWrap : public HandleWrap {
public:
static void Initialize(Handle<Object> target) {
HandleScope scope;
+ HandleWrap::Initialize(target);
+
Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(String::NewSymbol("Timer"));
+ NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
+
NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);
NODE_SET_PROTOTYPE_METHOD(constructor, "setRepeat", SetRepeat);
NODE_SET_PROTOTYPE_METHOD(constructor, "getRepeat", GetRepeat);
NODE_SET_PROTOTYPE_METHOD(constructor, "again", Again);
- NODE_SET_PROTOTYPE_METHOD(constructor, "close", Close);
target->Set(String::NewSymbol("Timer"), constructor->GetFunction());
}
@@ -81,16 +85,11 @@ class TimerWrap {
return scope.Close(args.This());
}
- TimerWrap(Handle<Object> object) {
+ TimerWrap(Handle<Object> object)
+ : HandleWrap(object, (uv_handle_t*) &handle_) {
active_ = false;
int r = uv_timer_init(&handle_);
handle_.data = this;
- assert(r == 0); // How do we proxy this error up to javascript?
- // Suggestion: uv_timer_init() returns void.
- assert(object_.IsEmpty());
- assert(object->InternalFieldCount() > 0);
- object_ = v8::Persistent<v8::Object>::New(object);
- object_->SetPointerInInternalField(0, this);
// uv_timer_init adds a loop reference. (That is, it calls uv_ref.) This
// is not the behavior we want in Node. Timers should not increase the
@@ -100,7 +99,6 @@ class TimerWrap {
~TimerWrap() {
if (!active_) uv_ref();
- assert(object_.IsEmpty());
}
void StateChange() {
@@ -118,12 +116,6 @@ class TimerWrap {
}
}
- // Free the C++ object on the close callback.
- static void OnClose(uv_handle_t* handle) {
- TimerWrap* wrap = static_cast<TimerWrap*>(handle->data);
- delete wrap;
- }
-
static Handle<Value> Start(const Arguments& args) {
HandleScope scope;
@@ -194,26 +186,6 @@ class TimerWrap {
return scope.Close(Integer::New(repeat));
}
- // TODO: share me?
- static Handle<Value> Close(const Arguments& args) {
- HandleScope scope;
-
- UNWRAP
-
- int r = uv_close((uv_handle_t*) &wrap->handle_, OnClose);
-
- if (r) SetErrno(uv_last_error().code);
-
- wrap->StateChange();
-
- assert(!wrap->object_.IsEmpty());
- wrap->object_->SetPointerInInternalField(0, NULL);
- wrap->object_.Dispose();
- wrap->object_.Clear();
-
- return scope.Close(Integer::New(r));
- }
-
static void OnTimeout(uv_timer_t* handle, int status) {
HandleScope scope;
@@ -227,7 +199,6 @@ class TimerWrap {
}
uv_timer_t handle_;
- Persistent<Object> object_;
// This member is set false initially. When the timer is turned
// on uv_ref is called. When the timer is turned off uv_unref is
// called. Used to mirror libev semantics.
diff --git a/wscript b/wscript
index 7212a6adfc..65ee4115ee 100644
--- a/wscript
+++ b/wscript
@@ -846,6 +846,7 @@ def build(bld):
src/node_dtrace.cc
src/node_string.cc
src/timer_wrap.cc
+ src/handle_wrap.cc
src/stream_wrap.cc
src/tcp_wrap.cc
src/pipe_wrap.cc