Now can start any 'mongo program' from within mongo shell

This commit is contained in:
Aaron
2009-02-13 12:01:37 -05:00
parent ebc0e5d2f2
commit 8fc2c86e0a
8 changed files with 76 additions and 56 deletions

View File

@@ -240,46 +240,51 @@ char *copyString( const char *original ) {
return ret;
}
boost::mutex &mongodOutputMutex( *( new boost::mutex ) );
const v8::Arguments *mongodArgs = 0;
boost::mutex &mongoProgramOutputMutex( *( new boost::mutex ) );
const v8::Arguments *mongoProgramArgs = 0;
void writeMongodOutputLine( int port, const char *line ) {
boost::mutex::scoped_lock lk( mongodOutputMutex );
cout << "d" << port << "| " << line << endl;
void writeMongoProgramOutputLine( int port, const char *line ) {
boost::mutex::scoped_lock lk( mongoProgramOutputMutex );
cout << "m" << port << "| " << line << endl;
}
void mongodThread() {
void mongoProgramThread() {
assert( mongoProgramArgs->Length() > 0 );
v8::String::Utf8Value programParse( (*mongoProgramArgs)[ 0 ] );
assert( *programParse );
string program( *programParse );
assert( argv0 );
boost::filesystem::path mongod = ( boost::filesystem::path( argv0 ) ).branch_path() / "mongod";
assert( boost::filesystem::exists( mongod ) );
boost::filesystem::path programPath = ( boost::filesystem::path( argv0 ) ).branch_path() / program;
assert( boost::filesystem::exists( programPath ) );
int port = -1;
char * argv[ mongodArgs->Length() + 2 ];
char * argv[ mongoProgramArgs->Length() + 1 ];
{
string s = mongod.native_file_string();
if ( s == "mongod" )
string s = programPath.native_file_string();
if ( s == program )
s = "./" + s;
argv[ 0 ] = copyString( s.c_str() );
}
for( int i = 0; i < mongodArgs->Length(); ++i ) {
v8::String::Utf8Value str( (*mongodArgs)[ i ] );
for( int i = 1; i < mongoProgramArgs->Length(); ++i ) {
v8::String::Utf8Value str( (*mongoProgramArgs)[ i ] );
assert( *str );
char *s = copyString( *str );
if ( string( "--port" ) == s )
port = -2;
else if ( port == -2 )
port = strtol( s, 0, 10 );
argv[ 1 + i ] = s;
argv[ i ] = s;
}
argv[ mongodArgs->Length() + 1 ] = 0;
argv[ mongoProgramArgs->Length() ] = 0;
assert( port > 0 );
assert( dbs.count( port ) == 0 );
int pipeEnds[ 2 ];
assert( pipe( pipeEnds ) != -1 );
fflush( 0 );
pid_t pid = fork();
assert( pid != -1 );
@@ -298,9 +303,10 @@ void mongodThread() {
dbs.insert( make_pair( port, make_pair( pid, pipeEnds[ 1 ] ) ) );
// Allow caller to return -- this is our low rent lock
mongodArgs = 0;
mongoProgramArgs = 0;
// This assumes there aren't any 0's in the mongod output. Hope that's ok.
// This assumes there aren't any 0's in the mongo program output.
// Hope that's ok.
char buf[ 1024 ];
char temp[ 1024 ];
char *start = buf;
@@ -312,11 +318,11 @@ void mongodThread() {
char *last = buf;
for( char *i = strchr( buf, '\n' ); i; last = i + 1, i = strchr( last, '\n' ) ) {
*i = '\0';
writeMongodOutputLine( port, last );
writeMongoProgramOutputLine( port, last );
}
if ( ret == 0 ) {
if ( *last )
writeMongodOutputLine( port, last );
writeMongoProgramOutputLine( port, last );
break;
}
if ( last != buf ) {
@@ -329,12 +335,12 @@ void mongodThread() {
}
}
// Relies on global mongodArgs; not thread-safe
v8::Handle< v8::Value > StartMongod( const v8::Arguments &a ) {
assert( !mongodArgs );
mongodArgs = &a;
boost::thread t( mongodThread );
while( mongodArgs )
// Relies on global mongoProgramArgs; not thread-safe
v8::Handle< v8::Value > StartMongoProgram( const v8::Arguments &a ) {
assert( !mongoProgramArgs );
mongoProgramArgs = &a;
boost::thread t( mongoProgramThread );
while( mongoProgramArgs )
sleepms( 2 );
return v8::Undefined();
}
@@ -374,7 +380,7 @@ void killDb( int port ) {
dbs.erase( port );
}
v8::Handle< v8::Value > StopMongod( const v8::Arguments &a ) {
v8::Handle< v8::Value > StopMongoProgram( const v8::Arguments &a ) {
assert( a.Length() == 1 );
assert( a[ 0 ]->IsInt32() );
int port = a[ 0 ]->ToInt32()->Value();
@@ -382,22 +388,22 @@ v8::Handle< v8::Value > StopMongod( const v8::Arguments &a ) {
return v8::Undefined();
}
void KillMongodbInstances() {
void KillMongoProgramInstances() {
for( map< int, pair< pid_t, int > >::iterator i = dbs.begin(); i != dbs.end(); ++i )
killDb( i->first );
}
MongodScope::~MongodScope() {
MongoProgramScope::~MongoProgramScope() {
try {
KillMongodbInstances();
KillMongoProgramInstances();
} catch ( ... ) {
assert( false );
}
}
#else
MongodScope::~MongodScope() {}
void KillMongodbInstances() {}
MongoProgramScope::~MongoProgramScope() {}
void KillMongoProgramInstances() {}
#endif
void installShellUtils( Handle<v8::ObjectTemplate>& global ){
@@ -408,8 +414,9 @@ void installShellUtils( Handle<v8::ObjectTemplate>& global ){
global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
#if !defined(_WIN32)
global->Set(v8::String::New("_startMongod"), v8::FunctionTemplate::New(StartMongod));
global->Set(v8::String::New("stopMongod"), v8::FunctionTemplate::New(StopMongod));
global->Set(v8::String::New("_startMongoProgram"), v8::FunctionTemplate::New(StartMongoProgram));
global->Set(v8::String::New("stopMongod"), v8::FunctionTemplate::New(StopMongoProgram));
global->Set(v8::String::New("stopMongoProgram"), v8::FunctionTemplate::New(StopMongoProgram));
global->Set(v8::String::New("resetDbpath"), v8::FunctionTemplate::New(ResetDbpath));
#endif
}