1 Star 0 Fork 0

白一梓 / async-tutorial-code

Create your Gitee Account
Explore and code with more than 6 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Without author's permission, this code is only for learning and cannot be used for other purposes.
Clone or Download
hello.cc 4.15 KB
Copy Edit Web IDE Raw Blame History
白一梓 authored 2015-05-14 17:39 . 增加对于node0.12.x的扩展支持
#include <node.h>
#include <string>
#ifdef WINDOWS_SPECIFIC_DEFINE
#include <windows.h>
typedef DWORD ThreadId;
#else
#include <unistd.h>
#include <pthread.h>
typedef unsigned int ThreadId;
#endif
using namespace v8;
Handle<Value> async_hello(const Arguments& args);
//不在js主线程,,在uv线程池内被调用
void call_work(uv_work_t* req);
//回调函数
void call_work_after(uv_work_t* req);
static ThreadId __getThreadId() {
ThreadId nThreadID;
#ifdef WINDOWS_SPECIFIC_DEFINE
nThreadID = GetCurrentProcessId();
nThreadID = (nThreadID << 16) + GetCurrentThreadId();
#else
nThreadID = getpid();
nThreadID = (nThreadID << 16) + pthread_self();
#endif
return nThreadID;
}
static void __tsleep(unsigned int millisecond) {
#ifdef WINDOWS_SPECIFIC_DEFINE
::Sleep(millisecond);
#else
usleep(millisecond*1000);
#endif
}
//定义一个结构体,存储异步请求信息
struct Baton {
//存储回调函数,使用Persistent来声明,让系统不会在函数结束后自动回收
//当回调成功后,需要执行dispose释放空间
Persistent<Function> callback;
// 错误控制,保护错误信息和错误状态
bool error;
std::string error_message;
//存储js传入的参数,字符串
std::string input_string;
//存放返回参数,字符串
std::string result;
};
Handle<Value> async_hello(const Arguments& args) {
printf("\n%s Thread id : gettid() == %d\n",__FUNCTION__,__getThreadId());
HandleScope scope;
if(args.Length() < 2) {
ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
return scope.Close(Undefined());
}
if (!args[0]->IsString() || !args[1]->IsFunction()) {
return ThrowException(Exception::TypeError(
String::New("Wrong number of arguments")));
}
// 强制转换成函数变量
Local<Function> callback = Local<Function>::Cast(args[1]);
Baton* baton = new Baton();
baton->error = false;
baton->callback = Persistent<Function>::New(callback);
v8::String::Utf8Value param1(args[0]->ToString());
baton->input_string = std::string(*param1);
uv_work_t *req = new uv_work_t();
req->data = baton;
int status = uv_queue_work(uv_default_loop(), req, call_work,
(uv_after_work_cb)call_work_after);
assert(status == 0);
return Undefined();
}
//在该函数内模拟处理过程 ,如i/o阻塞或者cpu高消耗情形的处理。
// 注意不能使用v8 api,这个线程不是在js主线程内
void call_work(uv_work_t* req) {
printf("\n%s Thread id : gettid() == %d\n",__FUNCTION__,__getThreadId());
Baton* baton = static_cast<Baton*>(req->data);
for (int i=0;i<15;i++) {
__tsleep(1000);
printf("sleep 1 seconds in uv_work\n");
}
baton->result = baton->input_string+ "--->hello world from c++";
}
//执行完任务,进行回调的时候,返回到 js主线程
void call_work_after(uv_work_t* req) {
printf("\n%s Thread id : gettid() == %d\n",__FUNCTION__,__getThreadId());
HandleScope scope;
Baton* baton = static_cast<Baton*>(req->data);
if (baton->error) {
Local<Value> err = Exception::Error(String::New(baton->error_message.c_str()));
// 准备回调函数的参数
const unsigned argc = 1;
Local<Value> argv[argc] = { err };
//捕捉回调中的错误,在Node环境中可利用process.on('uncaughtException')捕捉错误
TryCatch try_catch;
baton->callback->Call(Context::GetCurrent()->Global(), argc, argv);
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
} else {
const unsigned argc = 2;
Local<Value> argv[argc] = {
Local<Value>::New(Null()),
Local<Value>::New(String::New(baton->result.c_str()))
};
TryCatch try_catch;
baton->callback->Call(Context::GetCurrent()->Global(), argc, argv);
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
}
//注意一定释放
baton->callback.Dispose();
// 处理完毕,清除对象和空间
delete baton;
delete req;
}
void RegisterModule(Handle<Object> target) {
target->Set(String::NewSymbol("async_hello"),FunctionTemplate::New(async_hello)->GetFunction());
}
NODE_MODULE(binding, RegisterModule);

Comment ( 0 )

Sign in to post a comment

JavaScript
1
https://git.oschina.net/yunnysunny/async-tutorial-code.git
git@git.oschina.net:yunnysunny/async-tutorial-code.git
yunnysunny
async-tutorial-code
async-tutorial-code
master

Search