Print this page
joyent/v8plus#7 v8plus should not hold the event loop open forever

Split Close
Expand all
Collapse all
          --- old/./v8plus_subr.cc
          +++ new/./v8plus_subr.cc
↓ open down ↓ 515 lines elided ↑ open up ↑
 516  516  
 517  517          if ((it = cbhash.find(f)) == cbhash.end())
 518  518                  v8plus_panic("callback hash tag %llu not found", f);
 519  519  
 520  520          if (!it->second.ch_persist) {
 521  521                  pfh = v8::Persistent<v8::Function>::New(it->second.ch_hdl);
 522  522                  it->second.ch_hdl = pfh;
 523  523                  it->second.ch_persist = _B_TRUE;
 524  524          }
 525  525          ++it->second.ch_refs;
      526 +
      527 +        /*
      528 +         * If the consumer puts a hold on a callback, we should also put a hold
      529 +         * on the V8 event loop to prevent it dematerialising beneath us.
      530 +         */
      531 +        v8plus_eventloop_hold();
 526  532  }
 527  533  
 528  534  extern "C" void
 529  535  v8plus_jsfunc_rele_direct(v8plus_jsfunc_t f)
 530  536  {
 531  537          v8::Local<v8::Function> lfh;
 532  538          std::unordered_map<uint64_t, cb_hdl_t>::iterator it;
 533  539  
 534  540          if ((it = cbhash.find(f)) == cbhash.end())
 535  541                  v8plus_panic("callback hash tag %llu not found", f);
↓ open down ↓ 1 lines elided ↑ open up ↑
 537  543          if (it->second.ch_refs == 0)
 538  544                  v8plus_panic("releasing unheld callback hash tag %llu", f);
 539  545  
 540  546          if (--it->second.ch_refs == 0) {
 541  547                  if (it->second.ch_persist) {
 542  548                          v8::Persistent<v8::Function> pfh(it->second.ch_hdl);
 543  549                          pfh.Dispose();
 544  550                  }
 545  551                  cbhash.erase(it);
 546  552          }
      553 +
      554 +        /*
      555 +         * Release the event loop hold we took in v8plus_jsfunc_hold():
      556 +         */
      557 +        v8plus_eventloop_rele_direct();
 547  558  }
 548  559  
 549  560  static size_t
 550  561  library_name(const char *base, const char *version, char *buf, size_t len)
 551  562  {
 552  563  #ifdef __MACH__
 553  564          return (snprintf(buf, len, "lib%s.%s%sdylib", base,
 554  565              version ? version : "", version ? "." : ""));
 555  566  #else
 556  567          return (snprintf(buf, len, "lib%s.so%s%s", base,
↓ open down ↓ 73 lines elided ↑ open up ↑
 630  641          *vp = *lvp;
 631  642  
 632  643          return (0);
 633  644  }
 634  645  
 635  646  extern "C" void
 636  647  v8plus_obj_hold(const void *cop)
 637  648  {
 638  649          v8plus::ObjectWrap *op = v8plus::ObjectWrap::objlookup(cop);
 639  650          op->public_Ref();
      651 +
      652 +        /*
      653 +         * If the consumer puts a hold on an object, we should also put a hold
      654 +         * on the V8 event loop to prevent it dematerialising beneath us.
      655 +         */
      656 +        v8plus_eventloop_hold();
 640  657  }
 641  658  
 642  659  extern "C" void
 643  660  v8plus_obj_rele_direct(const void *cop)
 644  661  {
 645  662          v8plus::ObjectWrap *op = v8plus::ObjectWrap::objlookup(cop);
 646  663          op->public_Unref();
      664 +
      665 +        /*
      666 +         * Release the event loop hold we took in v8plus_obj_hold():
      667 +         */
      668 +        v8plus_eventloop_rele_direct();
 647  669  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX