Print this page
XXX rework to avoid changing api
XXX well, it works now...
   1 /*
   2  * Copyright (c) 2012 Joyent, Inc.  All rights reserved.
   3  */
   4 
   5 #include <sys/types.h>
   6 #include <string.h>
   7 #include <new>
   8 #include <unordered_map>
   9 #include <stdlib.h>
  10 #include <node.h>
  11 #include "v8plus_impl.h"
  12 #include "v8plus_glue.h"
  13 
  14 #define METHOD_NAME_FMT "__v8plus_%s_%s"
  15 
  16 v8::Persistent<v8::Function> v8plus::ObjectWrap::_constructor;
  17 v8plus_method_descr_t *v8plus::ObjectWrap::_mtbl;
  18 v8plus_static_descr_t *v8plus::ObjectWrap::_stbl;
  19 std::unordered_map<void *, v8plus::ObjectWrap *> v8plus::ObjectWrap::_objhash;
  20 






  21 static char *
  22 function_name(const char *lambda)
  23 {
  24         char *fn;
  25         size_t len;
  26 
  27         len = snprintf(NULL, 0, METHOD_NAME_FMT,
  28             v8plus_js_class_name, lambda);
  29         if ((fn = (char *)malloc(len + 1)) == NULL)
  30                 v8plus_panic("out of memory for function name for %s", lambda);
  31 
  32         (void) snprintf(fn, len + 1, METHOD_NAME_FMT,
  33                     v8plus_js_class_name, lambda);
  34 
  35         return (fn);
  36 }
  37 
  38 void
  39 v8plus::ObjectWrap::init(v8::Handle<v8::Object> target)
  40 {


  96                 _constructor =
  97                     v8::Persistent<v8::Function>::New(tpl->GetFunction());
  98 
  99                 target->Set(v8::String::NewSymbol(v8plus_js_factory_name),
 100                     v8::FunctionTemplate::New(
 101                     v8plus::ObjectWrap::cons)->GetFunction());
 102         }
 103 }
 104 
 105 v8::Handle<v8::Value>
 106 v8plus::ObjectWrap::_new(const v8::Arguments &args)
 107 {
 108         v8::HandleScope scope;
 109         v8plus::ObjectWrap *op = new v8plus::ObjectWrap();
 110         nvlist_t *c_excp;
 111         nvlist_t *c_args;
 112 
 113         if ((c_args = v8plus::v8_Arguments_to_nvlist(args)) == NULL)
 114                 return (V8PLUS_THROW_DEFAULT());
 115 


















 116         c_excp = v8plus_ctor(c_args, &op->_c_impl);
 117         nvlist_free(c_args);
 118         if (op->_c_impl == NULL) {
 119                 if (c_excp == NULL) {
 120                         return (V8PLUS_THROW_DEFAULT());
 121                 } else {
 122                         return (V8PLUS_THROW_DECORATED(c_excp));
 123                 }
 124         }
 125 
 126         _objhash.insert(std::make_pair(op->_c_impl, op));
 127         op->Wrap(args.This());
 128 
 129         return (args.This());
 130 }
 131 
 132 v8plus::ObjectWrap::~ObjectWrap()
 133 {
 134         v8plus_dtor(_c_impl);
 135         (void) _objhash.erase(_c_impl);


 295 #ifdef NODE_MAKECALLBACK_RETURN
 296         v =
 297 #endif
 298         node::MakeCallback(handle_, name, argc, argv);
 299 
 300         return (v);
 301 }
 302 
 303 void
 304 v8plus::ObjectWrap::public_Ref(void)
 305 {
 306         this->Ref();
 307 }
 308 
 309 void
 310 v8plus::ObjectWrap::public_Unref(void)
 311 {
 312         this->Unref();
 313 }
 314 










































 315 extern "C" void
 316 init(v8::Handle<v8::Object> target)
 317 {
 318         v8plus::ObjectWrap::init(target);
 319 }
   1 /*
   2  * Copyright (c) 2012 Joyent, Inc.  All rights reserved.
   3  */
   4 
   5 #include <sys/types.h>
   6 #include <string.h>
   7 #include <new>
   8 #include <unordered_map>
   9 #include <stdlib.h>
  10 #include <node.h>
  11 #include "v8plus_impl.h"
  12 #include "v8plus_glue.h"
  13 
  14 #define METHOD_NAME_FMT "__v8plus_%s_%s"
  15 
  16 v8::Persistent<v8::Function> v8plus::ObjectWrap::_constructor;
  17 v8plus_method_descr_t *v8plus::ObjectWrap::_mtbl;
  18 v8plus_static_descr_t *v8plus::ObjectWrap::_stbl;
  19 std::unordered_map<void *, v8plus::ObjectWrap *> v8plus::ObjectWrap::_objhash;
  20 
  21 uv_async_t v8plus::ObjectWrap::_uv_async;
  22 pthread_mutex_t v8plus::ObjectWrap::_callq_mutex;
  23 std::queue<v8plus_async_call_t *> v8plus::ObjectWrap::_callq;
  24 boolean_t v8plus::ObjectWrap::_crossthread_init_done = _B_FALSE;
  25 unsigned long v8plus::ObjectWrap::_uv_event_thread;
  26 
  27 static char *
  28 function_name(const char *lambda)
  29 {
  30         char *fn;
  31         size_t len;
  32 
  33         len = snprintf(NULL, 0, METHOD_NAME_FMT,
  34             v8plus_js_class_name, lambda);
  35         if ((fn = (char *)malloc(len + 1)) == NULL)
  36                 v8plus_panic("out of memory for function name for %s", lambda);
  37 
  38         (void) snprintf(fn, len + 1, METHOD_NAME_FMT,
  39                     v8plus_js_class_name, lambda);
  40 
  41         return (fn);
  42 }
  43 
  44 void
  45 v8plus::ObjectWrap::init(v8::Handle<v8::Object> target)
  46 {


 102                 _constructor =
 103                     v8::Persistent<v8::Function>::New(tpl->GetFunction());
 104 
 105                 target->Set(v8::String::NewSymbol(v8plus_js_factory_name),
 106                     v8::FunctionTemplate::New(
 107                     v8plus::ObjectWrap::cons)->GetFunction());
 108         }
 109 }
 110 
 111 v8::Handle<v8::Value>
 112 v8plus::ObjectWrap::_new(const v8::Arguments &args)
 113 {
 114         v8::HandleScope scope;
 115         v8plus::ObjectWrap *op = new v8plus::ObjectWrap();
 116         nvlist_t *c_excp;
 117         nvlist_t *c_args;
 118 
 119         if ((c_args = v8plus::v8_Arguments_to_nvlist(args)) == NULL)
 120                 return (V8PLUS_THROW_DEFAULT());
 121 
 122         if (_crossthread_init_done == _B_FALSE) {
 123                 /*
 124                  * Initialise structures for off-event-loop method calls.
 125                  *
 126                  * Note that uv_async_init() must be called inside the libuv
 127                  * Event Loop, so we do it here.  We also want to record the
 128                  * thread ID of the Event Loop thread so as to determine what
 129                  * kind of method calls to make later.
 130                  */
 131                 _uv_event_thread = pthread_self();
 132                 if (uv_async_init(uv_default_loop(), &_uv_async,
 133                     v8plus_async_callback) != 0)
 134                         v8plus_panic("unable to initialise uv_async_t");
 135                 if (pthread_mutex_init(&_callq_mutex, NULL) != 0)
 136                         v8plus_panic("unable to initialise mutex");
 137                 _crossthread_init_done = _B_TRUE;
 138         }
 139 
 140         c_excp = v8plus_ctor(c_args, &op->_c_impl);
 141         nvlist_free(c_args);
 142         if (op->_c_impl == NULL) {
 143                 if (c_excp == NULL) {
 144                         return (V8PLUS_THROW_DEFAULT());
 145                 } else {
 146                         return (V8PLUS_THROW_DECORATED(c_excp));
 147                 }
 148         }
 149 
 150         _objhash.insert(std::make_pair(op->_c_impl, op));
 151         op->Wrap(args.This());
 152 
 153         return (args.This());
 154 }
 155 
 156 v8plus::ObjectWrap::~ObjectWrap()
 157 {
 158         v8plus_dtor(_c_impl);
 159         (void) _objhash.erase(_c_impl);


 319 #ifdef NODE_MAKECALLBACK_RETURN
 320         v =
 321 #endif
 322         node::MakeCallback(handle_, name, argc, argv);
 323 
 324         return (v);
 325 }
 326 
 327 void
 328 v8plus::ObjectWrap::public_Ref(void)
 329 {
 330         this->Ref();
 331 }
 332 
 333 void
 334 v8plus::ObjectWrap::public_Unref(void)
 335 {
 336         this->Unref();
 337 }
 338 
 339 boolean_t
 340 v8plus::ObjectWrap::in_event_thread(void)
 341 {
 342         if (_crossthread_init_done != _B_TRUE)
 343                 v8plus_panic("cross thread call init not done!");
 344 
 345         return (_uv_event_thread == pthread_self() ? _B_TRUE : _B_FALSE);
 346 }
 347 
 348 v8plus_async_call_t *
 349 v8plus::ObjectWrap::next_async_call(void)
 350 {
 351         v8plus_async_call_t *ret = NULL;
 352 
 353         if (pthread_mutex_lock(&_callq_mutex) != 0)
 354                 v8plus_panic("could not lock callq mutex");
 355 
 356         if (!_callq.empty()) {
 357                 ret = _callq.front();
 358                 _callq.pop();
 359         }
 360 
 361         if (pthread_mutex_unlock(&_callq_mutex) != 0)
 362                 v8plus_panic("could not release callq mutex");
 363 
 364         return (ret);
 365 }
 366 
 367 void
 368 v8plus::ObjectWrap::post_async_call(v8plus_async_call_t *ac)
 369 {
 370         if (pthread_mutex_lock(&_callq_mutex) != 0)
 371                 v8plus_panic("could not lock callq mutex");
 372 
 373         _callq.push(ac);
 374 
 375         if (pthread_mutex_unlock(&_callq_mutex) != 0)
 376                 v8plus_panic("could not release callq mutex");
 377 
 378         uv_async_send(&_uv_async);
 379 }
 380 
 381 extern "C" void
 382 init(v8::Handle<v8::Object> target)
 383 {
 384         v8plus::ObjectWrap::init(target);
 385 }