Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created August 16, 2011 01:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mizchi/1148261 to your computer and use it in GitHub Desktop.
Save mizchi/1148261 to your computer and use it in GitHub Desktop.
C++による非同期node用拡張
#include <node.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
using namespace v8;
using namespace node;
class AsyncObject : ObjectWrap {
public:
static void
Initialize (const Handle<Object> target) {
HandleScope scope;
Local<FunctionTemplate> tmpl = FunctionTemplate::New(New);
tmpl->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(tmpl, "exec", Exec);
target->Set(String::New("AsyncObject"), tmpl->GetFunction());
}
~AsyncObject () {}
private:
AsyncObject (const char *refername) {}
struct BufferedData {
AsyncObject *refer;
char *ret_param;
Persistent<Value> callback;
};
// called at new AsyncObject();
static Handle<Value> New(const Arguments& args) {
if (!args.IsConstructCall()) return args.Callee()->NewInstance();
try {
(new AsyncObject(*String::Utf8Value(args[0])))->Wrap(args.This());
} catch (const char *msg) {
return ThrowException(Exception::Error(String::New(msg)));
}
return args.This();
}
static Handle<Value> Exec (const Arguments& args) {
HandleScope scope;
BufferedData *buff = (BufferedData *)malloc(sizeof(BufferedData));
buff->refer = Unwrap<AsyncObject>(args.This());
buff->ret_param = strdup(*String::Utf8Value(args[0]));
buff->callback = Persistent<Value>::New(args[1]);
eio_custom(EIO_Exec, EIO_PRI_DEFAULT, Callback, buff);
buff->refer->Ref();
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
int Exec (const char *arg) {
return 1;
}
static int EIO_Exec(eio_req *req) {
sleep(1);
BufferedData *buff = (BufferedData*)(req->data);
req->result = buff->refer->Exec(buff->ret_param);
// sprintf( buff->arg ,strcat( buff->arg, " " ) );
sprintf( buff->ret_param , "%s%s", buff->ret_param,buff->ret_param);
return 0;
}
// called as callback
static int Callback(eio_req *req) {
ev_unref(EV_DEFAULT_UC);
BufferedData *buff = (BufferedData*)(req->data);
if (buff->callback->IsFunction()) {
Local<Value> argv[2];
argv[0] = req->result < 0 ?
Local<Value>::New(String::New("Error")) :
Local<Value>::New(Undefined());
argv[1] = Local<Value>::New( String::New(buff->ret_param) ) ;
Persistent<Function>::Cast(buff->callback)->Call(
buff->refer->handle_, 2, argv);
}
buff->refer->Unref();
buff->callback.Dispose();
free(buff->ret_param);
free(buff);
return 0;
}
};
extern "C" void init (Handle<Object> target) {
AsyncObject::Initialize(target);
}
var AsyncObject = require('./build/default/async_c_class').AsyncObject;
var obj = new AsyncObject('foo.txt');
obj.exec( "a", function(e1,d1){
console.log([1,d1]);
if(e1) console.log("err");
obj.exec( d1, function(e2,d2){
console.log([2,d2]);
});
});
obj.exec( "b", function(e1,d1){
console.log([1,d1]);
if(e1) console.log("err");
obj.exec( d1, function(e2,d2){
console.log([2,d2]);
});
});
console.log([0,"through check"]);
srcdir = "."
blddir = "build"
VERSION = "0.0.1"
def set_options(opt):
opt.tool_options("compiler_cxx")
def configure(conf):
conf.check_tool("compiler_cxx")
conf.check_tool("node_addon")
def build(bld):
obj = bld.new_task_gen("cxx", "shlib", "node_addon")
obj.source = "async_class.cc"
obj.target = "async_c_class"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment