Print this page
XXX rework to avoid changing api
XXX well, it works now...

Split Close
Expand all
Collapse all
          --- old/./v8plus_objectwrap.cc
          +++ new/./v8plus_objectwrap.cc
↓ open down ↓ 10 lines elided ↑ open up ↑
  11   11  #include "v8plus_impl.h"
  12   12  #include "v8plus_glue.h"
  13   13  
  14   14  #define METHOD_NAME_FMT "__v8plus_%s_%s"
  15   15  
  16   16  v8::Persistent<v8::Function> v8plus::ObjectWrap::_constructor;
  17   17  v8plus_method_descr_t *v8plus::ObjectWrap::_mtbl;
  18   18  v8plus_static_descr_t *v8plus::ObjectWrap::_stbl;
  19   19  std::unordered_map<void *, v8plus::ObjectWrap *> v8plus::ObjectWrap::_objhash;
  20   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 +
  21   27  static char *
  22   28  function_name(const char *lambda)
  23   29  {
  24   30          char *fn;
  25   31          size_t len;
  26   32  
  27   33          len = snprintf(NULL, 0, METHOD_NAME_FMT,
  28   34              v8plus_js_class_name, lambda);
  29   35          if ((fn = (char *)malloc(len + 1)) == NULL)
  30   36                  v8plus_panic("out of memory for function name for %s", lambda);
↓ open down ↓ 75 lines elided ↑ open up ↑
 106  112  v8plus::ObjectWrap::_new(const v8::Arguments &args)
 107  113  {
 108  114          v8::HandleScope scope;
 109  115          v8plus::ObjectWrap *op = new v8plus::ObjectWrap();
 110  116          nvlist_t *c_excp;
 111  117          nvlist_t *c_args;
 112  118  
 113  119          if ((c_args = v8plus::v8_Arguments_to_nvlist(args)) == NULL)
 114  120                  return (V8PLUS_THROW_DEFAULT());
 115  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 +
 116  140          c_excp = v8plus_ctor(c_args, &op->_c_impl);
 117  141          nvlist_free(c_args);
 118  142          if (op->_c_impl == NULL) {
 119  143                  if (c_excp == NULL) {
 120  144                          return (V8PLUS_THROW_DEFAULT());
 121  145                  } else {
 122  146                          return (V8PLUS_THROW_DECORATED(c_excp));
 123  147                  }
 124  148          }
 125  149  
↓ open down ↓ 179 lines elided ↑ open up ↑
 305  329  {
 306  330          this->Ref();
 307  331  }
 308  332  
 309  333  void
 310  334  v8plus::ObjectWrap::public_Unref(void)
 311  335  {
 312  336          this->Unref();
 313  337  }
 314  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 +
 315  381  extern "C" void
 316  382  init(v8::Handle<v8::Object> target)
 317  383  {
 318  384          v8plus::ObjectWrap::init(target);
 319  385  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX