Skip to content

Commit 1790666

Browse files
committed
Fix so that C++ destructors can be called again when wrapper objects are garbage collected.
1 parent df44882 commit 1790666

File tree

3 files changed

+46
-17
lines changed

3 files changed

+46
-17
lines changed

jones-ndb/impl/include/common/JsWrapper.h

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,42 @@ inline void check_class_id(const char *a, const char *b) {
9090
#define CHECK_CLASS_ID(env, PTR)
9191
#endif
9292

93-
///* Delete a native C++ object when the Garbage Collector reclaims its
94-
// JavaScript handle.
95-
//*/
96-
//template<typename PTR>
97-
//void onGcReclaim(const WeakCallbackData<Object, PTR> data) {
98-
// PTR ptr = data.GetParameter();
99-
// if(ptr) delete ptr;
100-
//}
93+
/* Delete a native C++ object when the Garbage Collector reclaims its
94+
JavaScript handle.
95+
The GcReclaimer holds the pointer to be deleted, its classname for
96+
debugging output, and the weak JS reference (which should be Reset).
97+
*/
98+
template<typename CPP_OBJECT> class GcReclaimer; // forward declaration
99+
100+
template<typename CPP_OBJECT>
101+
void onGcReclaim(const WeakCallbackData<Value, GcReclaimer<CPP_OBJECT> > & data) {
102+
GcReclaimer<CPP_OBJECT> * reclaimer = data.GetParameter();
103+
reclaimer->reclaim();
104+
delete reclaimer;
105+
}
106+
107+
template<typename CPP_OBJECT> class GcReclaimer {
108+
public:
109+
GcReclaimer(const char * cls, CPP_OBJECT * p) : classname(cls), ptr(p) { }
110+
111+
void SetWeakReference(Isolate *isolate, Handle<Value> obj) {
112+
notifier.Reset(isolate, obj);
113+
notifier.MarkIndependent();
114+
notifier.SetWeak(this, onGcReclaim<CPP_OBJECT>);
115+
}
116+
117+
void reclaim() {
118+
delete ptr;
119+
DEBUG_PRINT_DETAIL("GC Reclaim %s %p", classname, ptr);
120+
notifier.Reset();
121+
}
122+
123+
private:
124+
const char * classname;
125+
CPP_OBJECT * ptr;
126+
Persistent<Value> notifier;
127+
};
128+
101129

102130
/*****************************************************************
103131
An Envelope is a simple structure providing some safety
@@ -190,14 +218,11 @@ class Envelope {
190218
(if you hold a const pointer to something, you probably don't own its
191219
memory allocation).
192220
******************************************************************/
193-
template<typename PTR>
194-
void freeFromGC(PTR ptr, Handle<Value> obj) {
221+
template<typename P>
222+
void freeFromGC(P * ptr, Handle<Value> obj) {
195223
if(ptr) {
196-
Persistent<Object> notifier;
197-
notifier.Reset(isolate, obj->ToObject());
198-
notifier.MarkIndependent();
199-
// TODO: Figure this out
200-
// notifier.SetWeak((void *) ptr, onGcReclaim<PTR>);
224+
GcReclaimer<P> * reclaimer = new GcReclaimer<P>(classname, ptr);
225+
reclaimer->SetWeakReference(isolate, obj);
201226
}
202227
}
203228
};

jones-ndb/impl/include/ndb/ColumnProxy.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ inline ColumnProxy::ColumnProxy() :
5050
jsValue(), blobBuffer(), isNull(false), isLoaded(false), isDirty(false)
5151
{}
5252

53+
inline ColumnProxy::~ColumnProxy() {
54+
jsValue.Reset();
55+
blobBuffer.Reset();
56+
}
57+
5358
inline void ColumnProxy::setHandler(const ColumnHandler *h) {
5459
handler = h;
5560
}

jones-ndb/impl/src/ndb/Record_wrapper.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ V8WrapperFn getColumnOffset_wrapper,
4040

4141
class RecordEnvelopeClass : public Envelope {
4242
public:
43-
RecordEnvelopeClass() : Envelope("Record") {
43+
RecordEnvelopeClass() : Envelope("const Record") {
4444
addMethod("getColumnOffset", getColumnOffset_wrapper);
4545
addMethod("getBufferSize", getBufferSize_wrapper);
4646
addMethod("setNull", setNull_wrapper);
@@ -57,7 +57,6 @@ RecordEnvelopeClass RecordEnvelope;
5757
*****/
5858
Local<Value> Record_Wrapper(const Record *rec) {
5959
Local<Value> js_record = RecordEnvelope.wrap(rec);
60-
RecordEnvelope.freeFromGC(rec, js_record);
6160
return js_record;
6261
}
6362

0 commit comments

Comments
 (0)