diff --git a/helloworld_eio/helloworld_eio.cc b/helloworld_eio/helloworld_eio.cc new file mode 100644 index 0000000..ac8c97e --- /dev/null +++ b/helloworld_eio/helloworld_eio.cc @@ -0,0 +1,151 @@ +/* + * Licensed to Paul Querna under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * Paul Querna licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +using namespace node; +using namespace v8; + +#define REQ_FUN_ARG(I, VAR) \ + if (args.Length() <= (I) || !args[I]->IsFunction()) \ + return ThrowException(Exception::TypeError( \ + String::New("Argument " #I " must be a function"))); \ + Local VAR = Local::Cast(args[I]); + +class HelloWorldEio: ObjectWrap +{ +private: + int m_count; +public: + + static Persistent s_ct; + static void Init(Handle target) + { + HandleScope scope; + + Local t = FunctionTemplate::New(New); + + s_ct = Persistent::New(t); + s_ct->InstanceTemplate()->SetInternalFieldCount(1); + s_ct->SetClassName(String::NewSymbol("HelloWorldEio")); + + NODE_SET_PROTOTYPE_METHOD(s_ct, "hello", Hello); + + target->Set(String::NewSymbol("HelloWorldEio"), + s_ct->GetFunction()); + } + + HelloWorldEio() : + m_count(0) + { + } + + ~HelloWorldEio() + { + } + + static Handle New(const Arguments& args) + { + HandleScope scope; + HelloWorldEio* hw = new HelloWorldEio(); + hw->Wrap(args.This()); + return args.This(); + } + + struct hello_baton_t { + HelloWorldEio *hw; + int increment_by; + int sleep_for; + Persistent cb; + }; + + static Handle Hello(const Arguments& args) + { + HandleScope scope; + + REQ_FUN_ARG(0, cb); + + HelloWorldEio* hw = ObjectWrap::Unwrap(args.This()); + + hello_baton_t *baton = new hello_baton_t(); + baton->hw = hw; + baton->increment_by = 2; + baton->sleep_for = 1; + baton->cb = Persistent::New(cb); + + hw->Ref(); + + eio_custom(EIO_Hello, EIO_PRI_DEFAULT, EIO_AfterHello, baton); + ev_ref(EV_DEFAULT_UC); + + return Undefined(); + } + + + static int EIO_Hello(eio_req *req) + { + hello_baton_t *baton = static_cast(req->data); + + sleep(baton->sleep_for); + + baton->hw->m_count += baton->increment_by; + + return 0; + } + + static int EIO_AfterHello(eio_req *req) + { + HandleScope scope; + ev_unref(EV_DEFAULT_UC); + hello_baton_t *baton = static_cast(req->data); + + Local argv[1]; + + argv[0] = String::New("Hello World"); + + TryCatch try_catch; + + baton->hw->Unref(); + baton->cb->Call(Context::GetCurrent()->Global(), 1, argv); + + if (try_catch.HasCaught()) { + FatalException(try_catch); + } + + baton->cb.Dispose(); + + delete baton; + return 0; + } + +}; + +Persistent HelloWorldEio::s_ct; + +extern "C" { + static void init (Handle target) + { + HelloWorldEio::Init(target); + } + + NODE_MODULE(helloworld_eio, init); +} diff --git a/helloworld_eio/wscript b/helloworld_eio/wscript new file mode 100644 index 0000000..3ea3388 --- /dev/null +++ b/helloworld_eio/wscript @@ -0,0 +1,14 @@ + + +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.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall"] + obj.target = "helloworld_eio" + obj.source = "helloworld_eio.cc"