Print this page
enable v8plus_call to be used in any thread

Split Close
Expand all
Collapse all
          --- old/./README.md
          +++ new/./README.md
↓ open down ↓ 551 lines elided ↑ open up ↑
 552  552          async_worker(void *cop, void *ctxp)
 553  553          {
 554  554                  my_object_t *op = cop;
 555  555                  my_context_t *cp = ctxp;
 556  556                  my_result_t *rp = ...;
 557  557  
 558  558                  /*
 559  559                   * In thread pool context -- do not call any of the
 560  560                   * following functions:
 561  561                   * v8plus_obj_hold()
 562      -                 * v8plus_obj_rele()
      562 +                 * v8plus_obj_rele_direct()
 563  563                   * v8plus_jsfunc_hold()
 564      -                 * v8plus_jsfunc_rele()
 565      -                 * v8plus_call()
      564 +                 * v8plus_jsfunc_rele_direct()
      565 +                 * v8plus_call_direct()
 566  566                   * v8plus_method_call_direct()
 567  567                   * v8plus_defer()
 568  568                   *
 569  569                   * If you touch anything inside op, you may need locking to
 570  570                   * protect against functions called in the main thread.
 571  571                   */
 572  572                  ...
 573  573  
 574  574                  return (rp);
 575  575          }
↓ open down ↓ 105 lines elided ↑ open up ↑
 681  681  
 682  682  Places a hold on the V8 representation of the specified C object.  This is
 683  683  rarely necessary; `v8plus_defer()` performs this action for you, but other
 684  684  asynchronous mechanisms may require it.  If you are returning from a method
 685  685  call but have stashed a reference to the object somewhere and are not
 686  686  calling `v8plus_defer()`, you must call this first.  Holds and releases must
 687  687  be balanced.  Use of the object within a thread after releasing is a bug.
 688  688  
 689  689  ### void v8plus_obj_rele(const void *op)
 690  690  
 691      -Releases a hold placed by `v8plus_obj_hold()`.
      691 +Releases a hold placed by `v8plus_obj_hold()`.  This function may be called
      692 +safely from any thread; releases from threads other than the main event loop
      693 +are non-blocking and will occur some time in the future.
 692  694  
 693  695  ### void v8plus_jsfunc_hold(v8plus_jsfunc_t f)
 694  696  
 695  697  Places a hold on the V8 representation of the specified JavaScript function.
 696  698  This is required when returning from a C function that has stashed a
 697  699  reference to the function, typically to use it asynchronously as a callback.
 698  700  All holds must be balanced with a release.  Because a single hold is placed
 699  701  on such objects when passed to you in an argument list (and released for you
 700  702  when you return), it is legal to reference and even to invoke such a
 701  703  function without first placing an additional hold on it.
 702  704  
 703  705  ### void v8plus_jsfunc_rele(v8plus_jsfunc_t f)
 704  706  
 705      -Releases a hold placed by `v8plus_jsfunc_hold()`.
      707 +Releases a hold placed by `v8plus_jsfunc_hold()`.  This function may be called
      708 +safely from any thread; releases from threads other than the main event loop
      709 +thread are non-blocking and will occur some time in the future.
 706  710  
 707  711  ### void v8plus_defer(void *op, void *ctx, worker, completion)
 708  712  
 709  713  Enqueues work to be performed in the Node.js shared thread pool.  The object
 710  714  `op` and context `ctx` are passed as arguments to `worker` executing in a
 711  715  thread from that pool.  The same two arguments, along with the worker's
 712  716  return value, are passed to `completion` executing in the main event loop
 713  717  thread.  See example above.
 714  718  
 715  719  ### nvlist_t *v8plus_call(v8plus_jsfunc_t f, const nvlist_t *ap)
 716  720  
 717  721  Calls the JavaScript function referred to by `f` with encoded arguments
 718  722  `ap`.  The return value is the encoded return value of the function.  The
 719  723  argument and return value encoding match the encodings that are used by C
 720  724  functions that provide methods.
 721  725  
      726 +As JavaScript functions must be called from the event loop thread,
      727 +`v8plus_call()` contains logic to determine whether we are in the
      728 +correct context or not.  If we are running on some other thread we will
      729 +queue the request and sleep, waiting for the event loop thread to make the
      730 +call.  In the simple case, where we are already in the correct thread, we
      731 +make the call directly.
      732 +
      733 +Note that when passing JavaScript functions around as callbacks, you must use
      734 +first use `v8plus_jsfunc_hold()` from within the main event loop thread.  Once
      735 +finished with the function, you may pass it to `v8plus_jsfunc_rele()` from any
      736 +thread to clean up.
      737 +
 722  738  ### nvlist_t *v8plus_method_call(void *op, const char *name, const nvlist_t *ap)
 723  739  
 724  740  Calls the method named by `name` in the native object `op` with encoded
 725  741  argument list `ap`.  The method must exist and must be a JavaScript
 726  742  function.  Such functions may be attached by JavaScript code as in the event
 727  743  emitter example above.  The effects of using this function to call a native
 728  744  method are undefined.
 729  745  
 730      -As JavaScript functions must be called from the event loop thread,
 731      -`v8plus_method_call()` contains logic to determine whether we are in the
 732      -correct context or not.  If we are running on some other thread we will
 733      -queue the request and sleep, waiting for the event loop thread to make the
 734      -call.  In the simple case, where we are already in the correct thread, we
 735      -make the call directly.
      746 +When called from threads other than the main event loop thread,
      747 +`v8plus_method_call()` uses the same queue-and-block logic as described above
      748 +in `v8plus_call()`.
 736  749  
 737  750  ## FAQ
 738  751  
 739  752  - Why?
 740  753  
 741  754  Because C++ is garbage.  Writing good software is challenging enough without
 742  755  trying to understand a bunch of implicit side effects or typing templated
 743  756  identifiers that can't fit in 80 columns without falling afoul of the
 744  757  language's ambiguous grammar.  Don't get me started.
 745  758  
↓ open down ↓ 113 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX