From 69ab87ca53faae52555b3ced7659ba6c2ad73db4 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 18 May 2009 13:38:15 +0200 Subject: [PATCH] Fix crash in oi_socket; add ready state reader to Connection objects. --- deps/liboi/oi_socket.c | 15 +++++++++++--- src/net.cc | 44 +++++++++++++++++++++++++++++++++++++++++- src/net.h | 10 ++++++++-- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/deps/liboi/oi_socket.c b/deps/liboi/oi_socket.c index dacf80321f..8a350d998d 100644 --- a/deps/liboi/oi_socket.c +++ b/deps/liboi/oi_socket.c @@ -914,9 +914,14 @@ void oi_socket_force_close (oi_socket *socket) void oi_socket_write(oi_socket *socket, oi_buf *buf) { - assert(socket->write_action != NULL && "Do not write to a closed socket"); - assert(socket->got_full_close == FALSE && "Do not write to a closing socket"); - assert(socket->got_half_close == FALSE && "Do not write to a closing socket"); + if (socket->write_action == NULL) { + assert(0 && "Do not write to a closed socket"); + goto error; + } + if (socket->got_full_close == TRUE || socket->got_half_close == TRUE) { + assert(0 && "Do not write to a closing socket"); + goto error; + } oi_queue_insert_head(&socket->out_stream, &buf->queue); buf->written = 0; @@ -924,6 +929,10 @@ oi_socket_write(oi_socket *socket, oi_buf *buf) if (socket->attached) { ev_io_start(SOCKET_LOOP_ &socket->write_watcher); } + return; + +error: + if (buf->release) buf->release(buf); } void diff --git a/src/net.cc b/src/net.cc index 2da99bb86e..99c88d3b9a 100644 --- a/src/net.cc +++ b/src/net.cc @@ -31,6 +31,12 @@ using namespace node; #define PROTOCOL_SYMBOL String::NewSymbol("protocol") #define CONNECTION_HANDLER_SYMBOL String::NewSymbol("connection_handler") +#define READY_STATE_SYMBOL String::NewSymbol("readyState") +#define OPEN_SYMBOL String::NewSymbol("open") +#define READ_ONLY_SYMBOL String::NewSymbol("readOnly") +#define WRITE_ONLY_SYMBOL String::NewSymbol("writeOnly") +#define CLOSED_SYMBOL String::NewSymbol("closed") + static const struct addrinfo tcp_hints = /* ai_flags */ { AI_PASSIVE /* ai_family */ , AF_UNSPEC @@ -62,13 +68,49 @@ Connection::Initialize (v8::Handle target) NODE_SET_PROTOTYPE_METHOD(constructor_template, "forceClose", ForceClose); constructor_template->PrototypeTemplate()->SetAccessor( - String::NewSymbol("encoding"), + ENCODING_SYMBOL, EncodingGetter, EncodingSetter); + constructor_template->PrototypeTemplate()->SetAccessor( + READY_STATE_SYMBOL, + ReadyStateGetter); + target->Set(String::NewSymbol("Connection"), constructor_template->GetFunction()); } +Handle +Connection::ReadyStateGetter (Local _, const AccessorInfo& info) +{ + Connection *connection = NODE_UNWRAP(Connection, info.This()); + if (!connection) return Handle(); + + HandleScope scope; + + if (connection->socket_.got_full_close) { + return CLOSED_SYMBOL; + } + + if (connection->socket_.got_half_close) { + if (connection->socket_.read_action) + return READ_ONLY_SYMBOL; + else + return CLOSED_SYMBOL; + } + + if (connection->socket_.read_action && connection->socket_.write_action) + return OPEN_SYMBOL; + else if (connection->socket_.write_action) + return WRITE_ONLY_SYMBOL; + else if (connection->socket_.read_action) + return READ_ONLY_SYMBOL; + else + return CLOSED_SYMBOL; + + assert(0 && "This shouldnt happen"); + return ThrowException(String::New("This shouldn't happen.")); +} + Handle Connection::EncodingGetter (Local _, const AccessorInfo& info) { diff --git a/src/net.h b/src/net.h index a500ebc3e9..985e7f5289 100644 --- a/src/net.h +++ b/src/net.h @@ -25,8 +25,14 @@ protected: static v8::Handle Close (const v8::Arguments& args); static v8::Handle FullClose (const v8::Arguments& args); static v8::Handle ForceClose (const v8::Arguments& args); - static v8::Handle EncodingGetter (v8::Local _, const v8::AccessorInfo& info); - static void EncodingSetter (v8::Local _, v8::Local value, const v8::AccessorInfo& info); + + static v8::Handle EncodingGetter (v8::Local _, + const v8::AccessorInfo& info); + static void EncodingSetter (v8::Local _, + v8::Local value, const v8::AccessorInfo& info); + + static v8::Handle ReadyStateGetter (v8::Local _, + const v8::AccessorInfo& info); Connection (v8::Handle handle); virtual ~Connection ();