From 56359f4bf3d0f6f68f1eb95ca1d3c7722e621424 Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Tue, 21 Jun 2011 09:36:07 -0500 Subject: [PATCH] extract v8 handle objects into a payload wrapper so that it can be detached separately --- ext/v8/v8_handle.cpp | 33 ++++++++++++++++++++++----------- ext/v8/v8_handle.h | 14 +++++++++++--- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ext/v8/v8_handle.cpp b/ext/v8/v8_handle.cpp index 9021ad7..a9ec76d 100644 --- a/ext/v8/v8_handle.cpp +++ b/ext/v8/v8_handle.cpp @@ -8,14 +8,25 @@ using namespace v8; * Creates a new Persistent storage cell for `handle` * so that we can reference it from Ruby. */ -v8_handle::v8_handle(Handle handle) : handle(Persistent::New(handle)) { +v8_handle::v8_handle(Handle object) { this->weakref_callback = Qnil; this->weakref_callback_parameters = Qnil; this->dead = false; + this->payload = new Payload(object); } v8_handle::~v8_handle() {} +v8_handle::Payload::Payload(Handle object) { + handle = Persistent::New(object); +} + +v8_handle::Payload::~Payload() {} +void v8_handle::Payload::release() { + handle.Dispose(); + handle.Clear(); +} + namespace { /** * Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected @@ -37,8 +48,8 @@ namespace { * Deallocates this handle. This function is invoked on Zombie handles after they have * been released from V8 and finally */ - void v8_handle_free(v8_handle* handle) { - delete handle; + void v8_handle_free(v8_handle::Payload* payload) { + delete payload; } /** @@ -49,8 +60,8 @@ namespace { */ void v8_handle_enqueue(v8_handle* handle) { handle->dead = true; - VALUE zombie = Data_Wrap_Struct(rr_v8_handle_class(), 0, v8_handle_free, handle); - rb_ary_unshift(handle_queue, zombie); + VALUE payload = Data_Wrap_Struct(rb_cObject, 0, v8_handle_free, handle->payload); + rb_ary_unshift(handle_queue, payload); } /** @@ -63,10 +74,9 @@ namespace { */ void v8_handle_dequeue(GCType type, GCCallbackFlags flags) { for (VALUE handle = rb_ary_pop(handle_queue); RTEST(handle); handle = rb_ary_pop(handle_queue)) { - v8_handle* dead = NULL; - Data_Get_Struct(handle, struct v8_handle, dead); - dead->handle.Dispose(); - dead->handle.Clear(); + v8_handle::Payload* payload = NULL; + Data_Get_Struct(handle, struct v8_handle::Payload, payload); + payload->release(); } } @@ -102,8 +112,9 @@ namespace { rb_funcall(callback, rb_intern("call"), 2, self, parameters); } value.Dispose(); - handle->handle.Dispose(); - handle->handle.Clear(); + handle->payload->release(); + // handle->handle.Dispose(); + // handle->handle.Clear(); handle->dead = true; } diff --git a/ext/v8/v8_handle.h b/ext/v8/v8_handle.h index cfc147c..8c34b7e 100644 --- a/ext/v8/v8_handle.h +++ b/ext/v8/v8_handle.h @@ -1,5 +1,5 @@ #ifndef _RR_V8_HANDLE_ -#define _RR_V8_HANDLE_ +#define _RR_V8_HANDLE_ #include #include "ruby.h" @@ -9,10 +9,18 @@ * class for all of the low-level proxies that reference into V8 */ struct v8_handle { + + struct Payload { + Payload(v8::Handle object); + virtual ~Payload(); + void release(); + v8::Persistent handle; + }; + v8_handle(v8::Handle object); virtual ~v8_handle(); - v8::Persistent handle; + Payload* payload; bool dead; VALUE weakref_callback; VALUE weakref_callback_parameters; @@ -23,7 +31,7 @@ void rr_init_handle(); v8_handle* rr_v8_handle_raw(VALUE value); template v8::Persistent& rr_v8_handle(VALUE value) { - return (v8::Persistent&)(rr_v8_handle_raw(value)->handle); + return (v8::Persistent&)(rr_v8_handle_raw(value)->payload->handle); } VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle handle); VALUE rr_v8_handle_class();