From c1baa70fe5789de0c1eef7f2051a4e43fedced6e Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 7 Dec 2009 17:55:19 +0100 Subject: [PATCH] Attach/Detach -> Ref/Unref --- src/node_binary.cc | 71 ++++++++++++++++++++++++++++++++++++++ src/node_binary.h | 56 ++++++++++++++++++++++++++++++ src/node_child_process.cc | 4 +-- src/node_http.cc | 24 ++++++------- src/node_net.cc | 14 ++++---- src/node_net.h | 10 +++--- src/node_object_wrap.h | 26 +++++++------- src/node_signal_handler.cc | 4 +-- src/node_stat.cc | 4 +-- src/node_timer.cc | 6 ++-- 10 files changed, 173 insertions(+), 46 deletions(-) create mode 100644 src/node_binary.cc create mode 100644 src/node_binary.h diff --git a/src/node_binary.cc b/src/node_binary.cc new file mode 100644 index 0000000000..16fbd53996 --- /dev/null +++ b/src/node_binary.cc @@ -0,0 +1,71 @@ +// Copyright 2009, Ryan Dahl . All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +#include + +namespace node { + +using namespace v8; + +static v8::Persistent byte_string_template; + +// V8 contstructor +static Handle New(const Arguments& args) { + HandleScope scope; + + // somehow create the c object. + byte_string *bs = malloc(sizeof(byte_string) + length); + + + bs->handle = v8::Persistent::New(args.This()); + bs->handle->SetInternalField(0, v8::External::New(bs)); + + return args.This(); +} + + +byte_string* byte_string_new(size_t length) +{ + byte_string_template->GetFunction()->NewInstance(); + + // unwrap handle + + return bs; +} + + + +void byte_string_init(v8::Local target) { + HandleScope scope; + + Local t = FunctionTemplate::New(New); + + byte_string_template = Persistent::New(t); + byte_string_template->InstanceTemplate()->SetInternalFieldCount(1); + // Set class name for debugging output + byte_string_template->SetClassName(String::NewSymbol("Binary")); + + NODE_SET_PROTOTYPE_METHOD(byte_string_template, "toString", ToString); + + target->Set(String::NewSymbol("Binary"), + byte_string_template->GetFunction()); +} + +} // namespace node diff --git a/src/node_binary.h b/src/node_binary.h new file mode 100644 index 0000000000..ce8268b87b --- /dev/null +++ b/src/node_binary.h @@ -0,0 +1,56 @@ +// Copyright 2009, Ryan Dahl . All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +#ifndef NODE_BYTE_STRING_H_ +#define NODE_BYTE_STRING_H_ + +#include + +namespace node { + +void byte_string_init(v8::Local target); + +/* Byte string is an immutable chunk of data that can be created from C++ + * (byte_string_new()) or from Javascript (new ByteString(string, encoding)). It + * provides a means of passing data through javascript, usually from one C++ + * object (like a TCP socket) to another C++ object (like an HTTP parser). + * + * Byte strings are always destructed by the V8 GC. Do not store references + * to byte_string pointers, only create them and pass them into javascript, + * or receive them as arguments out of javascript. + */ + +typedef struct { + v8::Persistent handle; + size_t length; + char bytes[1]; +} byte_string; + +byte_string* byte_string_new(size_t length); + +byte_string* byte_string_unwrap(v8::Handle handle) { + assert(!handle.IsEmpty()); + assert(handle->InternalFieldCount() > 0); + return static_cast(v8::Handle::Cast( + handle->GetInternalField(0))->Value()); +} + +} // namespace node +#endif // NODE_BYTE_STRING_H_ diff --git a/src/node_child_process.cc b/src/node_child_process.cc index 68373fe9c9..9a78d32344 100644 --- a/src/node_child_process.cc +++ b/src/node_child_process.cc @@ -338,7 +338,7 @@ int ChildProcess::Spawn(const char *file, char *const args[], char *const env[]) evcom_writer_set(&stdin_writer_, stdin_fd_); evcom_writer_attach(EV_DEFAULT_UC_ &stdin_writer_); - Attach(); + Ref(); return 0; } @@ -382,7 +382,7 @@ void ChildProcess::MaybeShutdown(void) { Handle argv[1] = { Integer::New(exit_code_) }; Emit("exit", 1, argv); Shutdown(); - Detach(); + Unref(); } } diff --git a/src/node_http.cc b/src/node_http.cc index 4070819218..fffaf0c2ac 100644 --- a/src/node_http.cc +++ b/src/node_http.cc @@ -72,7 +72,7 @@ HTTPConnection::OnReceive (const void *buf, size_t len) { HandleScope scope; - assert(attached_); + assert(refs_); size_t nparsed; if (type_ == HTTP_REQUEST) { @@ -90,7 +90,7 @@ void HTTPConnection::OnEOF () { HandleScope scope; - assert(attached_); + assert(refs_); if (type_ == HTTP_REQUEST) { http_parse_requests(&parser_, NULL, 0); } else { @@ -103,7 +103,7 @@ int HTTPConnection::on_message_begin (http_parser *parser) { HTTPConnection *connection = static_cast (parser->data); - assert(connection->attached_); + assert(connection->refs_); connection->Emit("messageBegin", 0, NULL); return 0; } @@ -112,7 +112,7 @@ int HTTPConnection::on_message_complete (http_parser *parser) { HTTPConnection *connection = static_cast (parser->data); - assert(connection->attached_); + assert(connection->refs_); connection->Emit("messageComplete", 0, NULL); return 0; } @@ -122,7 +122,7 @@ HTTPConnection::on_url (http_parser *parser, const char *buf, size_t len) { HandleScope scope; HTTPConnection *connection = static_cast(parser->data); - assert(connection->attached_); + assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; connection->Emit("url", 1, argv); return 0; @@ -133,7 +133,7 @@ HTTPConnection::on_query_string (http_parser *parser, const char *buf, size_t le { HandleScope scope; HTTPConnection *connection = static_cast(parser->data); - assert(connection->attached_); + assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; connection->Emit("queryString", 1, argv); return 0; @@ -144,7 +144,7 @@ HTTPConnection::on_path (http_parser *parser, const char *buf, size_t len) { HandleScope scope; HTTPConnection *connection = static_cast(parser->data); - assert(connection->attached_); + assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; connection->Emit("path", 1, argv); return 0; @@ -155,7 +155,7 @@ HTTPConnection::on_fragment (http_parser *parser, const char *buf, size_t len) { HandleScope scope; HTTPConnection *connection = static_cast(parser->data); - assert(connection->attached_); + assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; connection->Emit("fragment", 1, argv); return 0; @@ -176,7 +176,7 @@ HTTPConnection::on_header_field (http_parser *parser, const char *buf, size_t le { HandleScope scope; HTTPConnection *connection = static_cast(parser->data); - assert(connection->attached_); + assert(connection->refs_); // NORMALIZE size_t i; @@ -193,7 +193,7 @@ HTTPConnection::on_header_value (http_parser *parser, const char *buf, size_t le { HandleScope scope; HTTPConnection *connection = static_cast(parser->data); - assert(connection->attached_); + assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; connection->Emit("headerValue", 1, argv); @@ -204,7 +204,7 @@ int HTTPConnection::on_headers_complete (http_parser *parser) { HTTPConnection *connection = static_cast (parser->data); - assert(connection->attached_); + assert(connection->refs_); HandleScope scope; Local message_info = Object::New(); @@ -251,7 +251,7 @@ HTTPConnection::on_body (http_parser *parser, const char *buf, size_t len) assert(len != 0); HTTPConnection *connection = static_cast (parser->data); - assert(connection->attached_); + assert(connection->refs_); HandleScope scope; // TODO each message should have their encoding. diff --git a/src/node_net.cc b/src/node_net.cc index 1387589917..51863cfe3f 100644 --- a/src/node_net.cc +++ b/src/node_net.cc @@ -233,8 +233,8 @@ Handle Connection::Connect(const Arguments& args) { // out. Thus we need to add ev_ref() until AfterResolve(). ev_ref(EV_DEFAULT_UC); - // Attach the object so it doesn't get garbage collected. - connection->Attach(); + // Ref the object so it doesn't get garbage collected. + connection->Ref(); // For the moment I will do DNS lookups in the eio thread pool. This is // sub-optimal and cannot handle massive numbers of requests. @@ -252,7 +252,7 @@ int Connection::Resolve(eio_req *req) { Connection *connection = static_cast (req->data); struct addrinfo *address = NULL; - assert(connection->attached_); + assert(connection->refs_); assert(connection->resolving_); req->result = getaddrinfo(connection->host_, connection->port_, @@ -281,7 +281,7 @@ int Connection::AfterResolve(eio_req *req) { Connection *connection = static_cast (req->data); assert(connection->resolving_); - assert(connection->attached_); + assert(connection->refs_); struct addrinfo *address = NULL, *address_list = static_cast(req->ptr2); @@ -311,7 +311,7 @@ int Connection::AfterResolve(eio_req *req) { connection->OnClose(); - connection->Detach(); + connection->Unref(); out: return 0; @@ -537,7 +537,7 @@ Handle Connection::ForceClose(const Arguments& args) { assert(connection); connection->ForceClose(); - connection->Detach(); + connection->Unref(); return Undefined(); } @@ -709,7 +709,7 @@ Connection* Server::OnConnection(struct sockaddr *addr) { } #endif - connection->Attach(); + connection->Ref(); return connection; } diff --git a/src/node_net.h b/src/node_net.h index 6eccec9aff..7ef6d4cd84 100644 --- a/src/node_net.h +++ b/src/node_net.h @@ -119,7 +119,7 @@ class Connection : public EventEmitter { static void on_read(evcom_stream *s, const void *buf, size_t len) { Connection *connection = static_cast(s->data); - assert(connection->attached_); + assert(connection->refs_); if (len == 0) connection->OnEOF(); else @@ -149,9 +149,9 @@ class Connection : public EventEmitter { connection->OnClose(); - assert(connection->attached_); + assert(connection->refs_); - connection->Detach(); + connection->Unref(); } static void on_timeout(evcom_stream *s) { @@ -204,7 +204,7 @@ class Server : public EventEmitter { int r = evcom_server_listen(&server_, address, backlog); if (r != 0) return r; evcom_server_attach(EV_DEFAULT_ &server_); - Attach(); + Ref(); return 0; } @@ -230,7 +230,7 @@ class Server : public EventEmitter { Server *server = static_cast(s->data); evcom_server_detach(s); server->OnClose(s->errorno); - server->Detach(); + server->Unref(); } evcom_server server_; diff --git a/src/node_object_wrap.h b/src/node_object_wrap.h index 686961406a..6656664bdf 100644 --- a/src/node_object_wrap.h +++ b/src/node_object_wrap.h @@ -9,7 +9,7 @@ namespace node { class ObjectWrap { public: ObjectWrap ( ) { - attached_ = 0; + refs_ = 0; } virtual ~ObjectWrap ( ) { @@ -45,42 +45,42 @@ class ObjectWrap { handle_.MakeWeak(this, WeakCallback); } - /* Attach() marks the object as being attached to an event loop. - * Attached objects will not be garbage collected, even if + /* Ref() marks the object as being attached to an event loop. + * Refed objects will not be garbage collected, even if * all references are lost. */ - virtual void Attach() { + virtual void Ref() { assert(!handle_.IsEmpty()); assert(handle_.IsWeak()); - attached_++; + refs_++; } - /* Detach() marks an object as detached from the event loop. This is its + /* Unref() marks an object as detached from the event loop. This is its * default state. When an object with a "weak" reference changes from * attached to detached state it will be freed. Be careful not to access * the object after making this call as it might be gone! - * (A "weak reference" is v8 terminology for an object that only has a + * (A "weak reference" means an object that only has a * persistant handle.) * * DO NOT CALL THIS FROM DESTRUCTOR */ - virtual void Detach() { + virtual void Unref() { assert(!handle_.IsEmpty()); assert(handle_.IsWeak()); - assert(attached_ > 0); - attached_--; - if (attached_ == 0 && handle_.IsNearDeath()) delete this; + assert(refs_ > 0); + refs_--; + if (refs_ == 0 && handle_.IsNearDeath()) delete this; } v8::Persistent handle_; // ro - int attached_; // ro + int refs_; // ro private: static void WeakCallback (v8::Persistent value, void *data) { ObjectWrap *obj = static_cast(data); assert(value == obj->handle_); - if (obj->attached_ == 0) { + if (obj->refs_ == 0) { delete obj; } else { obj->MakeWeak(); diff --git a/src/node_signal_handler.cc b/src/node_signal_handler.cc index ffe6300105..34e84141ef 100644 --- a/src/node_signal_handler.cc +++ b/src/node_signal_handler.cc @@ -56,7 +56,7 @@ Handle SignalHandler::New(const Arguments& args) { ev_signal_start(EV_DEFAULT_UC_ &handler->watcher_); ev_unref(EV_DEFAULT_UC); - handler->Attach(); + handler->Ref(); return args.This(); } @@ -67,7 +67,7 @@ Handle SignalHandler::Stop(const Arguments& args) { SignalHandler *handler = ObjectWrap::Unwrap(args.Holder()); ev_ref(EV_DEFAULT_UC); ev_signal_stop(EV_DEFAULT_UC_ &handler->watcher_); - handler->Detach(); + handler->Unref(); return Undefined(); } diff --git a/src/node_stat.cc b/src/node_stat.cc index 9ae82d75e8..5f864e6f23 100644 --- a/src/node_stat.cc +++ b/src/node_stat.cc @@ -74,7 +74,7 @@ Handle Stat::Start(const Arguments& args) { ev_unref(EV_DEFAULT_UC); } - handler->Attach(); + handler->Ref(); return Undefined(); } @@ -95,7 +95,7 @@ void Stat::Stop () { ev_stat_stop(EV_DEFAULT_UC_ &watcher_); free(path_); path_ = NULL; - Detach(); + Unref(); } } diff --git a/src/node_timer.cc b/src/node_timer.cc index 841f26c550..c0ab046cd8 100644 --- a/src/node_timer.cc +++ b/src/node_timer.cc @@ -64,7 +64,7 @@ Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents) timer->Emit("timeout", 0, NULL); - if (timer->watcher_.repeat == 0) timer->Detach(); + if (timer->watcher_.repeat == 0) timer->Unref(); } Timer::~Timer () @@ -99,7 +99,7 @@ Timer::Start (const Arguments& args) timer->watcher_.data = timer; ev_timer_start(EV_DEFAULT_UC_ &timer->watcher_); - timer->Attach(); + timer->Ref(); return Undefined(); } @@ -110,7 +110,7 @@ Timer::Stop (const Arguments& args) Timer *timer = ObjectWrap::Unwrap(args.Holder()); if (ev_is_active(&timer->watcher_)) { ev_timer_stop(EV_DEFAULT_UC_ &timer->watcher_); - timer->Detach(); + timer->Unref(); } return Undefined(); }