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


 506 
 507         *vp = *lvp;
 508         return (0);
 509 }
 510 
 511 extern "C" void
 512 v8plus_jsfunc_hold(v8plus_jsfunc_t f)
 513 {
 514         v8::Persistent<v8::Function> pfh;
 515         std::unordered_map<uint64_t, cb_hdl_t>::iterator it;
 516 
 517         if ((it = cbhash.find(f)) == cbhash.end())
 518                 v8plus_panic("callback hash tag %llu not found", f);
 519 
 520         if (!it->second.ch_persist) {
 521                 pfh = v8::Persistent<v8::Function>::New(it->second.ch_hdl);
 522                 it->second.ch_hdl = pfh;
 523                 it->second.ch_persist = _B_TRUE;
 524         }
 525         ++it->second.ch_refs;






 526 }
 527 
 528 extern "C" void
 529 v8plus_jsfunc_rele_direct(v8plus_jsfunc_t f)
 530 {
 531         v8::Local<v8::Function> lfh;
 532         std::unordered_map<uint64_t, cb_hdl_t>::iterator it;
 533 
 534         if ((it = cbhash.find(f)) == cbhash.end())
 535                 v8plus_panic("callback hash tag %llu not found", f);
 536 
 537         if (it->second.ch_refs == 0)
 538                 v8plus_panic("releasing unheld callback hash tag %llu", f);
 539 
 540         if (--it->second.ch_refs == 0) {
 541                 if (it->second.ch_persist) {
 542                         v8::Persistent<v8::Function> pfh(it->second.ch_hdl);
 543                         pfh.Dispose();
 544                 }
 545                 cbhash.erase(it);
 546         }





 547 }
 548 
 549 static size_t
 550 library_name(const char *base, const char *version, char *buf, size_t len)
 551 {
 552 #ifdef __MACH__
 553         return (snprintf(buf, len, "lib%s.%s%sdylib", base,
 554             version ? version : "", version ? "." : ""));
 555 #else
 556         return (snprintf(buf, len, "lib%s.so%s%s", base,
 557             version ? "." : "", version ? version : ""));
 558 #endif
 559 }
 560 
 561 /*
 562  * This is really gross: we need to free up JS function slots when then list
 563  * is freed, but there's no way for us to know that's happening.  So we
 564  * interpose on nvlist_free() here, checking for function slots to free iff
 565  * this is a list that has a V8 JS function handle in it.  Lists created by
 566  * someone else, even if they have uint64 arrays in them, are passed through.


 620 extern "C" int
 621 nvpair_value_v8plus_jsfunc(const nvpair_t *pp, v8plus_jsfunc_t *vp)
 622 {
 623         uint64_t *lvp;
 624         uint_t nv;
 625         int err;
 626 
 627         if ((err = nvpair_value_uint64_array((nvpair_t *)pp, &lvp, &nv)) != 0)
 628                 return (err);
 629 
 630         *vp = *lvp;
 631 
 632         return (0);
 633 }
 634 
 635 extern "C" void
 636 v8plus_obj_hold(const void *cop)
 637 {
 638         v8plus::ObjectWrap *op = v8plus::ObjectWrap::objlookup(cop);
 639         op->public_Ref();






 640 }
 641 
 642 extern "C" void
 643 v8plus_obj_rele_direct(const void *cop)
 644 {
 645         v8plus::ObjectWrap *op = v8plus::ObjectWrap::objlookup(cop);
 646         op->public_Unref();





 647 }


 506 
 507         *vp = *lvp;
 508         return (0);
 509 }
 510 
 511 extern "C" void
 512 v8plus_jsfunc_hold(v8plus_jsfunc_t f)
 513 {
 514         v8::Persistent<v8::Function> pfh;
 515         std::unordered_map<uint64_t, cb_hdl_t>::iterator it;
 516 
 517         if ((it = cbhash.find(f)) == cbhash.end())
 518                 v8plus_panic("callback hash tag %llu not found", f);
 519 
 520         if (!it->second.ch_persist) {
 521                 pfh = v8::Persistent<v8::Function>::New(it->second.ch_hdl);
 522                 it->second.ch_hdl = pfh;
 523                 it->second.ch_persist = _B_TRUE;
 524         }
 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();
 532 }
 533 
 534 extern "C" void
 535 v8plus_jsfunc_rele_direct(v8plus_jsfunc_t f)
 536 {
 537         v8::Local<v8::Function> lfh;
 538         std::unordered_map<uint64_t, cb_hdl_t>::iterator it;
 539 
 540         if ((it = cbhash.find(f)) == cbhash.end())
 541                 v8plus_panic("callback hash tag %llu not found", f);
 542 
 543         if (it->second.ch_refs == 0)
 544                 v8plus_panic("releasing unheld callback hash tag %llu", f);
 545 
 546         if (--it->second.ch_refs == 0) {
 547                 if (it->second.ch_persist) {
 548                         v8::Persistent<v8::Function> pfh(it->second.ch_hdl);
 549                         pfh.Dispose();
 550                 }
 551                 cbhash.erase(it);
 552         }
 553 
 554         /*
 555          * Release the event loop hold we took in v8plus_jsfunc_hold():
 556          */
 557         v8plus_eventloop_rele_direct();
 558 }
 559 
 560 static size_t
 561 library_name(const char *base, const char *version, char *buf, size_t len)
 562 {
 563 #ifdef __MACH__
 564         return (snprintf(buf, len, "lib%s.%s%sdylib", base,
 565             version ? version : "", version ? "." : ""));
 566 #else
 567         return (snprintf(buf, len, "lib%s.so%s%s", base,
 568             version ? "." : "", version ? version : ""));
 569 #endif
 570 }
 571 
 572 /*
 573  * This is really gross: we need to free up JS function slots when then list
 574  * is freed, but there's no way for us to know that's happening.  So we
 575  * interpose on nvlist_free() here, checking for function slots to free iff
 576  * this is a list that has a V8 JS function handle in it.  Lists created by
 577  * someone else, even if they have uint64 arrays in them, are passed through.


 631 extern "C" int
 632 nvpair_value_v8plus_jsfunc(const nvpair_t *pp, v8plus_jsfunc_t *vp)
 633 {
 634         uint64_t *lvp;
 635         uint_t nv;
 636         int err;
 637 
 638         if ((err = nvpair_value_uint64_array((nvpair_t *)pp, &lvp, &nv)) != 0)
 639                 return (err);
 640 
 641         *vp = *lvp;
 642 
 643         return (0);
 644 }
 645 
 646 extern "C" void
 647 v8plus_obj_hold(const void *cop)
 648 {
 649         v8plus::ObjectWrap *op = v8plus::ObjectWrap::objlookup(cop);
 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();
 657 }
 658 
 659 extern "C" void
 660 v8plus_obj_rele_direct(const void *cop)
 661 {
 662         v8plus::ObjectWrap *op = v8plus::ObjectWrap::objlookup(cop);
 663         op->public_Unref();
 664 
 665         /*
 666          * Release the event loop hold we took in v8plus_obj_hold():
 667          */
 668         v8plus_eventloop_rele_direct();
 669 }