diff options
author | Eliot Horowitz <eliot@10gen.com> | 2010-07-05 00:54:17 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2010-07-05 00:54:17 -0400 |
commit | f7288ef41020bcafdb7b1d7ad4da28e8421ecccf (patch) | |
tree | 9cfc86ca72b95bd7b54a6784e0b730fd1d890d24 /scripting | |
parent | 3908a13a6e0dde818e4799ea1347cd669ca54e00 (diff) | |
download | mongo-f7288ef41020bcafdb7b1d7ad4da28e8421ecccf.tar.gz |
fix v8 cursor closing
Diffstat (limited to 'scripting')
-rw-r--r-- | scripting/engine_v8.cpp | 8 | ||||
-rw-r--r-- | scripting/v8_db.cpp | 47 | ||||
-rw-r--r-- | scripting/v8_utils.cpp | 7 | ||||
-rw-r--r-- | scripting/v8_utils.h | 1 |
4 files changed, 44 insertions, 19 deletions
diff --git a/scripting/engine_v8.cpp b/scripting/engine_v8.cpp index d62726834de..08826b1964c 100644 --- a/scripting/engine_v8.cpp +++ b/scripting/engine_v8.cpp @@ -57,9 +57,12 @@ namespace mongo { _global->Set(v8::String::New("load"), v8::FunctionTemplate::New(loadCallback, v8::External::New(this))->GetFunction() ); - - _wrapper = Persistent< v8::Function >::New( getObjectWrapperTemplate()->GetFunction() ); + _wrapper = Persistent< v8::Function >::New( getObjectWrapperTemplate()->GetFunction() ); + + _global->Set(v8::String::New("gc"), v8::FunctionTemplate::New(GCV8)->GetFunction() ); + + installDBTypes( _global ); } @@ -383,6 +386,7 @@ namespace mongo { } void V8Scope::gc() { + cout << "in gc" << endl; Locker l; while( V8::IdleNotification() ); } diff --git a/scripting/v8_db.cpp b/scripting/v8_db.cpp index 57dbe32c2a0..361d5ea8a80 100644 --- a/scripting/v8_db.cpp +++ b/scripting/v8_db.cpp @@ -29,12 +29,11 @@ using namespace v8; namespace mongo { -#define CONN_STRING (v8::String::New( "_conn" )) - #define DDD(x) v8::Handle<v8::FunctionTemplate> getMongoFunctionTemplate( bool local ){ v8::Local<v8::FunctionTemplate> mongo = FunctionTemplate::New( local ? mongoConsLocal : mongoConsExternal ); + mongo->InstanceTemplate()->SetInternalFieldCount( 1 ); v8::Local<v8::Template> proto = mongo->PrototypeTemplate(); @@ -44,9 +43,12 @@ namespace mongo { proto->Set( v8::String::New( "update" ) , FunctionTemplate::New( mongoUpdate ) ); Local<FunctionTemplate> ic = FunctionTemplate::New( internalCursorCons ); + ic->InstanceTemplate()->SetInternalFieldCount( 1 ); ic->PrototypeTemplate()->Set( v8::String::New("next") , FunctionTemplate::New( internalCursorNext ) ); ic->PrototypeTemplate()->Set( v8::String::New("hasNext") , FunctionTemplate::New( internalCursorHasNext ) ); proto->Set( v8::String::New( "internalCursor" ) , ic ); + + return mongo; } @@ -132,9 +134,10 @@ namespace mongo { global->Get( v8::String::New( "Object" ) )->ToObject()->Set( v8::String::New("bsonsize") , FunctionTemplate::New( bsonsize )->GetFunction() ); } - void destroyConnection( Persistent<Value> object, void* parameter){ - // TODO - cout << "warning: destroyConnection not implemented" << endl; + void destroyConnection( Persistent<Value> self, void* parameter){ + delete static_cast<DBClientBase*>(parameter); + self.Dispose(); + self.Clear(); } Handle<Value> mongoConsExternal(const Arguments& args){ @@ -183,13 +186,13 @@ namespace mongo { else { return v8::ThrowException( v8::String::New( "too many commas" ) ); } - - Persistent<v8::Object> self = Persistent<v8::Object>::New( args.This() ); + + Persistent<v8::Object> self = Persistent<v8::Object>::New( args.Holder() ); self.MakeWeak( conn , destroyConnection ); ScriptEngine::runConnectCallback( *conn ); - // NOTE I don't believe the conn object will ever be freed. - args.This()->Set( CONN_STRING , External::New( conn ) ); + + args.This()->SetInternalField( 0 , External::New( conn ) ); args.This()->Set( v8::String::New( "slaveOk" ) , Boolean::New( false ) ); args.This()->Set( v8::String::New( "host" ) , v8::String::New( host ) ); @@ -207,7 +210,7 @@ namespace mongo { self.MakeWeak( conn , destroyConnection ); // NOTE I don't believe the conn object will ever be freed. - args.This()->Set( CONN_STRING , External::New( conn ) ); + args.This()->SetInternalField( 0 , External::New( conn ) ); args.This()->Set( v8::String::New( "slaveOk" ) , Boolean::New( false ) ); args.This()->Set( v8::String::New( "host" ) , v8::String::New( "EMBEDDED" ) ); @@ -224,7 +227,7 @@ namespace mongo { #endif DBClientBase * getConnection( const Arguments& args ){ - Local<External> c = External::Cast( *(args.This()->Get( CONN_STRING )) ); + Local<External> c = External::Cast( *(args.This()->GetInternalField( 0 )) ); DBClientBase * conn = (DBClientBase*)(c->Value()); assert( conn ); return conn; @@ -232,6 +235,12 @@ namespace mongo { // ---- real methods + void destroyCursor( Persistent<Value> self, void* parameter){ + delete static_cast<mongo::DBClientCursor*>(parameter); + self.Dispose(); + self.Clear(); + } + /** 0 - namespace 1 - query @@ -240,6 +249,8 @@ namespace mongo { 4 - skip */ Handle<Value> mongoFind(const Arguments& args){ + HandleScope handle_scope; + jsassert( args.Length() == 6 , "find needs 6 args" ); jsassert( args[1]->IsObject() , "needs to be an object" ); DBClientBase * conn = getConnection( args ); @@ -269,11 +280,12 @@ namespace mongo { } v8::Function * cons = (v8::Function*)( *( mongo->Get( v8::String::New( "internalCursor" ) ) ) ); assert( cons ); - Local<v8::Object> c = cons->NewInstance(); - - // NOTE I don't believe the cursor object will ever be freed. - c->Set( v8::String::New( "cursor" ) , External::New( cursor.release() ) ); - return c; + + Persistent<v8::Object> c = Persistent<v8::Object>::New( cons->NewInstance() ); + c.MakeWeak( cursor.get() , destroyCursor ); + + c->SetInternalField( 0 , External::New( cursor.release() ) ); + return handle_scope.Close(c); } catch ( ... ){ return v8::ThrowException( v8::String::New( "socket error on query" ) ); @@ -363,7 +375,8 @@ namespace mongo { // --- cursor --- mongo::DBClientCursor * getCursor( const Arguments& args ){ - Local<External> c = External::Cast( *(args.This()->Get( v8::String::New( "cursor" ) ) ) ); + Local<External> c = External::Cast( *(args.This()->GetInternalField( 0 ) ) ); + mongo::DBClientCursor * cursor = (mongo::DBClientCursor*)(c->Value()); return cursor; } diff --git a/scripting/v8_utils.cpp b/scripting/v8_utils.cpp index 5e56245ba7d..5a07a802dc1 100644 --- a/scripting/v8_utils.cpp +++ b/scripting/v8_utils.cpp @@ -302,4 +302,11 @@ namespace mongo { global->Set( v8::String::New( "_scopedThreadInject" ), FunctionTemplate::New( ScopedThreadInject )->GetFunction() ); } + Handle<v8::Value> GCV8(const Arguments& args) { + Locker l; + while( V8::IdleNotification() ); + return v8::Undefined(); + } + + } diff --git a/scripting/v8_utils.h b/scripting/v8_utils.h index 82184556864..bc4b5244184 100644 --- a/scripting/v8_utils.h +++ b/scripting/v8_utils.h @@ -29,6 +29,7 @@ namespace mongo { v8::Handle<v8::Value> Print(const v8::Arguments& args); v8::Handle<v8::Value> Version(const v8::Arguments& args); + v8::Handle<v8::Value> GCV8(const v8::Arguments& args); void ReportException(v8::TryCatch* handler); |