Print this page
keith IIa
XXX keith II

Split Close
Expand all
Collapse all
          --- old/./v8plus_csup.c
          +++ new/./v8plus_csup.c
↓ open down ↓ 37 lines elided ↑ open up ↑
  38   38  
  39   39          pthread_cond_t vac_cv;
  40   40          pthread_mutex_t vac_mtx;
  41   41  
  42   42          boolean_t vac_run;
  43   43          nvlist_t *vac_return;
  44   44  
  45   45          STAILQ_ENTRY(v8plus_async_call) vac_callq_entry;
  46   46  } v8plus_async_call_t;
  47   47  
  48      -nvlist_t *v8plus_method_call_direct(void *, const char *, const nvlist_t *);
  49      -
  50   48  boolean_t
  51   49  v8plus_in_event_thread(void)
  52   50  {
  53   51          return (_v8plus_uv_event_thread == pthread_self() ? B_TRUE : B_FALSE);
  54   52  }
  55   53  
  56   54  static void
  57      -v8plus_async_callback(uv_async_t *async, __attribute__((unused)) int status)
       55 +v8plus_async_callback(uv_async_t *async, int status __UNUSED)
  58   56  {
  59   57          if (v8plus_in_event_thread() != B_TRUE)
  60   58                  v8plus_panic("async callback called outside of event loop");
  61   59  
  62   60          for (;;) {
  63   61                  v8plus_async_call_t *vac = NULL;
  64   62  
  65   63                  /*
  66   64                   * Fetch the next queued method:
  67   65                   */
↓ open down ↓ 5 lines elided ↑ open up ↑
  73   71                  }
  74   72                  if (pthread_mutex_unlock(&_v8plus_callq_mtx) != 0)
  75   73                          v8plus_panic("could not unlock async queue mutex");
  76   74  
  77   75                  if (vac == NULL)
  78   76                          break;
  79   77  
  80   78                  /*
  81   79                   * Run the queued method:
  82   80                   */
  83      -                if (pthread_mutex_lock(&vac->vac_mtx) != 0)
  84      -                        v8plus_panic("could not lock async call mutex");
  85      -
  86   81                  if (vac->vac_run == B_TRUE)
  87   82                          v8plus_panic("async call already run");
  88      -
  89   83                  vac->vac_return = v8plus_method_call_direct(vac->vac_cop,
  90   84                      vac->vac_name, vac->vac_lp);
  91      -                vac->vac_run = B_TRUE;
  92   85  
       86 +                if (pthread_mutex_lock(&vac->vac_mtx) != 0)
       87 +                        v8plus_panic("could not lock async call mutex");
       88 +                vac->vac_run = B_TRUE;
  93   89                  if (pthread_cond_broadcast(&vac->vac_cv) != 0)
  94   90                          v8plus_panic("could not signal async call condvar");
  95   91                  if (pthread_mutex_unlock(&vac->vac_mtx) != 0)
  96   92                          v8plus_panic("could not unlock async call mutex");
  97   93          }
  98   94  }
  99   95  
 100   96  nvlist_t *
 101   97  v8plus_method_call(void *cop, const char *name, const nvlist_t *lp)
 102   98  {
↓ open down ↓ 7 lines elided ↑ open up ↑
 110  106                  return (v8plus_method_call_direct(cop, name, lp));
 111  107          }
 112  108  
 113  109          /*
 114  110           * As we cannot manipulate v8plus/V8/Node structures directly from
 115  111           * outside the event loop thread, we push the call arguments onto a
 116  112           * queue and post to the event loop thread.  We then sleep on our
 117  113           * condition variable until the event loop thread makes the call
 118  114           * for us and wakes us up.
 119  115           */
      116 +        bzero(&vac, sizeof (vac));
 120  117          vac.vac_cop = cop;
 121  118          vac.vac_name = name;
 122  119          vac.vac_lp = lp;
 123  120          if (pthread_mutex_init(&vac.vac_mtx, NULL) != 0)
 124  121                  v8plus_panic("could not init async call mutex");
 125  122          if (pthread_cond_init(&vac.vac_cv, NULL) != 0)
 126  123                  v8plus_panic("could not init async call condvar");
 127  124          vac.vac_run = B_FALSE;
 128      -        vac.vac_return = NULL;
 129  125  
 130  126          /*
 131  127           * Post request to queue:
 132  128           */
 133  129          if (pthread_mutex_lock(&_v8plus_callq_mtx) != 0)
 134  130                  v8plus_panic("could not lock async queue mutex");
 135  131          STAILQ_INSERT_TAIL(&_v8plus_callq, &vac, vac_callq_entry);
 136  132          if (pthread_mutex_unlock(&_v8plus_callq_mtx) != 0)
 137  133                  v8plus_panic("could not unlock async queue mutex");
 138  134          uv_async_send(&_v8plus_uv_async);
 139  135  
 140  136          /*
 141      -         * Wait for our request to be serviced on the Event Loop thread:
      137 +         * Wait for our request to be serviced on the event loop thread:
 142  138           */
 143  139          if (pthread_mutex_lock(&vac.vac_mtx) != 0)
 144  140                  v8plus_panic("could not lock async call mutex");
 145  141          while (vac.vac_run == B_FALSE) {
 146  142                  if (pthread_cond_wait(&vac.vac_cv, &vac.vac_mtx) != 0)
 147  143                          v8plus_panic("could not wait on async call condvar");
 148  144          }
      145 +        if (pthread_mutex_unlock(&vac.vac_mtx) != 0)
      146 +                v8plus_panic("could not unlock async call mutex");
      147 +
      148 +        if (pthread_cond_destroy(&vac.vac_cv) != 0)
      149 +                v8plus_panic("could not destroy async call condvar");
      150 +        if (pthread_mutex_destroy(&vac.vac_mtx) != 0)
      151 +                v8plus_panic("could not destroy async call mutex");
 149  152  
 150  153          return (vac.vac_return);
 151  154  }
 152  155  
 153  156  
 154  157  /*
 155  158   * Initialise structures for off-event-loop method calls.
 156  159   *
 157      - * Note that uv_async_init() must be called inside the libuv Event Loop, so we
      160 + * Note that uv_async_init() must be called inside the libuv event loop, so we
 158  161   * do it here.  We also want to record the thread ID of the Event Loop thread
 159  162   * so as to determine what kind of method calls to make later.
 160  163   */
 161  164  void
 162  165  v8plus_crossthread_init(void)
 163  166  {
 164  167          _v8plus_uv_event_thread = pthread_self();
 165  168          if (uv_async_init(uv_default_loop(), &_v8plus_uv_async,
 166  169              v8plus_async_callback) != 0)
 167  170                  v8plus_panic("unable to initialise uv_async_t");
↓ open down ↓ 525 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX