Skip to content

Instantly share code, notes, and snippets.

@kkaefer
Created February 7, 2012 16:01
Show Gist options
  • Save kkaefer/1760397 to your computer and use it in GitHub Desktop.
Save kkaefer/1760397 to your computer and use it in GitHub Desktop.
child processes don't terminate after longjmp
#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);
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'); });
});
#!/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