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

*** 16,25 **** --- 16,31 ---- v8::Persistent<v8::Function> v8plus::ObjectWrap::_constructor; v8plus_method_descr_t *v8plus::ObjectWrap::_mtbl; v8plus_static_descr_t *v8plus::ObjectWrap::_stbl; std::unordered_map<void *, v8plus::ObjectWrap *> v8plus::ObjectWrap::_objhash; + uv_async_t v8plus::ObjectWrap::_uv_async; + pthread_mutex_t v8plus::ObjectWrap::_callq_mutex; + std::queue<v8plus_async_call_t *> v8plus::ObjectWrap::_callq; + boolean_t v8plus::ObjectWrap::_crossthread_init_done = _B_FALSE; + unsigned long v8plus::ObjectWrap::_uv_event_thread; + static char * function_name(const char *lambda) { char *fn; size_t len;
*** 111,120 **** --- 117,144 ---- nvlist_t *c_args; if ((c_args = v8plus::v8_Arguments_to_nvlist(args)) == NULL) return (V8PLUS_THROW_DEFAULT()); + if (_crossthread_init_done == _B_FALSE) { + /* + * Initialise structures for off-event-loop method calls. + * + * Note that uv_async_init() must be called inside the libuv + * Event Loop, so we do it here. We also want to record the + * thread ID of the Event Loop thread so as to determine what + * kind of method calls to make later. + */ + _uv_event_thread = pthread_self(); + if (uv_async_init(uv_default_loop(), &_uv_async, + v8plus_async_callback) != 0) + v8plus_panic("unable to initialise uv_async_t"); + if (pthread_mutex_init(&_callq_mutex, NULL) != 0) + v8plus_panic("unable to initialise mutex"); + _crossthread_init_done = _B_TRUE; + } + c_excp = v8plus_ctor(c_args, &op->_c_impl); nvlist_free(c_args); if (op->_c_impl == NULL) { if (c_excp == NULL) { return (V8PLUS_THROW_DEFAULT());
*** 310,319 **** --- 334,385 ---- v8plus::ObjectWrap::public_Unref(void) { this->Unref(); } + boolean_t + v8plus::ObjectWrap::in_event_thread(void) + { + if (_crossthread_init_done != _B_TRUE) + v8plus_panic("cross thread call init not done!"); + + return (_uv_event_thread == pthread_self() ? _B_TRUE : _B_FALSE); + } + + v8plus_async_call_t * + v8plus::ObjectWrap::next_async_call(void) + { + v8plus_async_call_t *ret = NULL; + + if (pthread_mutex_lock(&_callq_mutex) != 0) + v8plus_panic("could not lock callq mutex"); + + if (!_callq.empty()) { + ret = _callq.front(); + _callq.pop(); + } + + if (pthread_mutex_unlock(&_callq_mutex) != 0) + v8plus_panic("could not release callq mutex"); + + return (ret); + } + + void + v8plus::ObjectWrap::post_async_call(v8plus_async_call_t *ac) + { + if (pthread_mutex_lock(&_callq_mutex) != 0) + v8plus_panic("could not lock callq mutex"); + + _callq.push(ac); + + if (pthread_mutex_unlock(&_callq_mutex) != 0) + v8plus_panic("could not release callq mutex"); + + uv_async_send(&_uv_async); + } + extern "C" void init(v8::Handle<v8::Object> target) { v8plus::ObjectWrap::init(target); }