1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

extract v8 handle objects into a payload wrapper so that it can be detached separately

This commit is contained in:
Charles Lowell 2011-06-21 09:36:07 -05:00
parent edc8eb7086
commit 56359f4bf3
2 changed files with 33 additions and 14 deletions

View file

@ -8,14 +8,25 @@ using namespace v8;
* Creates a new Persistent storage cell for `handle` * Creates a new Persistent storage cell for `handle`
* so that we can reference it from Ruby. * so that we can reference it from Ruby.
*/ */
v8_handle::v8_handle(Handle<void> handle) : handle(Persistent<void>::New(handle)) { v8_handle::v8_handle(Handle<void> object) {
this->weakref_callback = Qnil; this->weakref_callback = Qnil;
this->weakref_callback_parameters = Qnil; this->weakref_callback_parameters = Qnil;
this->dead = false; this->dead = false;
this->payload = new Payload(object);
} }
v8_handle::~v8_handle() {} v8_handle::~v8_handle() {}
v8_handle::Payload::Payload(Handle<void> object) {
handle = Persistent<void>::New(object);
}
v8_handle::Payload::~Payload() {}
void v8_handle::Payload::release() {
handle.Dispose();
handle.Clear();
}
namespace { namespace {
/** /**
* Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected * 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 * Deallocates this handle. This function is invoked on Zombie handles after they have
* been released from V8 and finally * been released from V8 and finally
*/ */
void v8_handle_free(v8_handle* handle) { void v8_handle_free(v8_handle::Payload* payload) {
delete handle; delete payload;
} }
/** /**
@ -49,8 +60,8 @@ namespace {
*/ */
void v8_handle_enqueue(v8_handle* handle) { void v8_handle_enqueue(v8_handle* handle) {
handle->dead = true; handle->dead = true;
VALUE zombie = Data_Wrap_Struct(rr_v8_handle_class(), 0, v8_handle_free, handle); VALUE payload = Data_Wrap_Struct(rb_cObject, 0, v8_handle_free, handle->payload);
rb_ary_unshift(handle_queue, zombie); rb_ary_unshift(handle_queue, payload);
} }
/** /**
@ -63,10 +74,9 @@ namespace {
*/ */
void v8_handle_dequeue(GCType type, GCCallbackFlags flags) { void v8_handle_dequeue(GCType type, GCCallbackFlags flags) {
for (VALUE handle = rb_ary_pop(handle_queue); RTEST(handle); handle = rb_ary_pop(handle_queue)) { for (VALUE handle = rb_ary_pop(handle_queue); RTEST(handle); handle = rb_ary_pop(handle_queue)) {
v8_handle* dead = NULL; v8_handle::Payload* payload = NULL;
Data_Get_Struct(handle, struct v8_handle, dead); Data_Get_Struct(handle, struct v8_handle::Payload, payload);
dead->handle.Dispose(); payload->release();
dead->handle.Clear();
} }
} }
@ -102,8 +112,9 @@ namespace {
rb_funcall(callback, rb_intern("call"), 2, self, parameters); rb_funcall(callback, rb_intern("call"), 2, self, parameters);
} }
value.Dispose(); value.Dispose();
handle->handle.Dispose(); handle->payload->release();
handle->handle.Clear(); // handle->handle.Dispose();
// handle->handle.Clear();
handle->dead = true; handle->dead = true;
} }

View file

@ -1,5 +1,5 @@
#ifndef _RR_V8_HANDLE_ #ifndef _RR_V8_HANDLE_
#define _RR_V8_HANDLE_ #define _RR_V8_HANDLE_
#include <v8.h> #include <v8.h>
#include "ruby.h" #include "ruby.h"
@ -9,10 +9,18 @@
* class for all of the low-level proxies that reference into V8 * class for all of the low-level proxies that reference into V8
*/ */
struct v8_handle { struct v8_handle {
struct Payload {
Payload(v8::Handle<void> object);
virtual ~Payload();
void release();
v8::Persistent<void> handle;
};
v8_handle(v8::Handle<void> object); v8_handle(v8::Handle<void> object);
virtual ~v8_handle(); virtual ~v8_handle();
v8::Persistent<void> handle; Payload* payload;
bool dead; bool dead;
VALUE weakref_callback; VALUE weakref_callback;
VALUE weakref_callback_parameters; VALUE weakref_callback_parameters;
@ -23,7 +31,7 @@ void rr_init_handle();
v8_handle* rr_v8_handle_raw(VALUE value); v8_handle* rr_v8_handle_raw(VALUE value);
template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) { template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) {
return (v8::Persistent<T>&)(rr_v8_handle_raw(value)->handle); return (v8::Persistent<T>&)(rr_v8_handle_raw(value)->payload->handle);
} }
VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle); VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle);
VALUE rr_v8_handle_class(); VALUE rr_v8_handle_class();