Created
February 7, 2012 16:01
-
-
Save kkaefer/1760397 to your computer and use it in GitHub Desktop.
child processes don't terminate after longjmp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <node.h> | |
// C standard library | |
#include <cstdlib> | |
#include <ctime> | |
#include <setjmp.h> | |
using namespace v8; | |
Handle<Value> Longjmp(const Arguments& args); | |
void LongjmpWork(uv_work_t* req); | |
void LongjmpAfter(uv_work_t* req); | |
struct Baton { | |
Baton(Handle<Function> fn) : value(0) { | |
request.data = this; | |
callback = Persistent<Function>::New(fn); | |
} | |
uv_work_t request; | |
Persistent<Function> callback; | |
int value; | |
}; | |
Handle<Value> Longjmp(const Arguments& args) { | |
HandleScope scope; | |
Baton* baton = new Baton(Local<Function>::Cast(args[0])); | |
int status = uv_queue_work(uv_default_loop(), &baton->request, LongjmpWork, LongjmpAfter); | |
assert(status == 0); | |
return Undefined(); | |
} | |
void LongjmpWork(uv_work_t* req) { | |
Baton* baton = static_cast<Baton*>(req->data); | |
jmp_buf buf; | |
if (setjmp(buf)) { | |
baton->value = 1; | |
} else { | |
longjmp(buf, 1); | |
baton->value = 2; | |
} | |
} | |
void LongjmpAfter(uv_work_t* req) { | |
HandleScope scope; | |
Baton* baton = static_cast<Baton*>(req->data); | |
Local<Value> argv[1] = { Local<Value>::New(Integer::New(baton->value)) }; | |
TryCatch try_catch; | |
baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); | |
if (try_catch.HasCaught()) node::FatalException(try_catch); | |
baton->callback.Dispose(); | |
delete baton; | |
} | |
void RegisterModule(Handle<Object> target) { | |
// target is the module object you see when require()ing the .node file. | |
target->Set(String::NewSymbol("longjmp"), | |
FunctionTemplate::New(Longjmp)->GetFunction()); | |
} | |
NODE_MODULE(longjmp, RegisterModule); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var longjmp = require('./build/Release/longjmp').longjmp; | |
var util = require('util'); | |
var spawn = require('child_process').spawn; | |
// Should be true. | |
longjmp(function(integer) { | |
console.warn(integer); | |
var date = spawn('date'); | |
date.on('exit', function(code, signal) { console.warn('EXIT ' + code); }); | |
date.stdout.on('data', function(data) { console.warn('STDOUT: ' + util.inspect(data.toString())); }); | |
date.stderr.on('data', function(data) { console.warn('STDERR: ' + util.inspect(data.toString())); }); | |
date.stdout.on('end', function() { console.warn('STDOUT end'); }); | |
date.stderr.on('end', function() { console.warn('STDERR end'); }); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
def set_options(ctx): | |
ctx.tool_options('compiler_cxx') | |
def configure(ctx): | |
ctx.check_tool('compiler_cxx') | |
ctx.check_tool('node_addon') | |
def build(ctx): | |
t = ctx.new_task_gen('cxx', 'shlib', 'node_addon') | |
t.source = ['longjmp.cpp'] | |
t.target = 'longjmp' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment