Print this page
XXX review feedback from keith
Split |
Close |
Expand all |
Collapse all |
--- old/./v8plus_csup.c
+++ new/./v8plus_csup.c
1 1 /*
2 2 * Copyright (c) 2012 Joyent, Inc. All rights reserved.
3 3 */
4 4
5 5 #include <sys/ccompile.h>
6 6 #include <sys/debug.h>
7 +#include <sys/queue.h>
8 +#include <sys/types.h>
7 9 #include <stdarg.h>
8 10 #include <string.h>
9 11 #include <strings.h>
10 12 #include <errno.h>
11 13 #include <uv.h>
14 +#include <pthread.h>
12 15 #include "v8plus_glue.h"
13 16
14 17 __thread v8plus_errno_t _v8plus_errno;
15 18 __thread char _v8plus_errmsg[V8PLUS_ERRMSG_LEN];
16 19
17 20 typedef struct v8plus_uv_ctx {
18 21 void *vuc_obj;
19 22 void *vuc_ctx;
20 23 void *vuc_result;
21 24 v8plus_worker_f vuc_worker;
22 25 v8plus_completion_f vuc_completion;
23 26 } v8plus_uv_ctx_t;
24 27
28 +static STAILQ_HEAD(v8plus_callq_head, v8plus_async_call) _v8plus_callq =
29 + STAILQ_HEAD_INITIALIZER(_v8plus_callq);
30 +static pthread_mutex_t _v8plus_callq_mtx;
31 +static pthread_t _v8plus_uv_event_thread;
32 +static uv_async_t _v8plus_uv_async;
33 +
34 +typedef struct v8plus_async_call {
35 + void *vac_cop;
36 + const char *vac_name;
37 + const nvlist_t *vac_lp;
38 +
39 + pthread_cond_t vac_cv;
40 + pthread_mutex_t vac_mtx;
41 +
42 + boolean_t vac_run;
43 + nvlist_t *vac_return;
44 +
45 + STAILQ_ENTRY(v8plus_async_call) vac_callq_entry;
46 +} v8plus_async_call_t;
47 +
48 +nvlist_t *v8plus_method_call_direct(void *, const char *, const nvlist_t *);
49 +
50 +boolean_t
51 +v8plus_in_event_thread(void)
52 +{
53 + return (_v8plus_uv_event_thread == pthread_self() ? B_TRUE : B_FALSE);
54 +}
55 +
56 +static void
57 +v8plus_async_callback(uv_async_t *async, __attribute__((unused)) int status)
58 +{
59 + if (v8plus_in_event_thread() != B_TRUE)
60 + v8plus_panic("async callback called outside of event loop");
61 +
62 + for (;;) {
63 + v8plus_async_call_t *vac = NULL;
64 +
65 + /*
66 + * Fetch the next queued method:
67 + */
68 + if (pthread_mutex_lock(&_v8plus_callq_mtx) != 0)
69 + v8plus_panic("could not lock async queue mutex");
70 + if (!STAILQ_EMPTY(&_v8plus_callq)) {
71 + vac = STAILQ_FIRST(&_v8plus_callq);
72 + STAILQ_REMOVE_HEAD(&_v8plus_callq, vac_callq_entry);
73 + }
74 + if (pthread_mutex_unlock(&_v8plus_callq_mtx) != 0)
75 + v8plus_panic("could not unlock async queue mutex");
76 +
77 + if (vac == NULL)
78 + break;
79 +
80 + /*
81 + * Run the queued method:
82 + */
83 + if (pthread_mutex_lock(&vac->vac_mtx) != 0)
84 + v8plus_panic("could not lock async call mutex");
85 +
86 + if (vac->vac_run == B_TRUE)
87 + v8plus_panic("async call already run");
88 +
89 + vac->vac_return = v8plus_method_call_direct(vac->vac_cop,
90 + vac->vac_name, vac->vac_lp);
91 + vac->vac_run = B_TRUE;
92 +
93 + if (pthread_cond_broadcast(&vac->vac_cv) != 0)
94 + v8plus_panic("could not signal async call condvar");
95 + if (pthread_mutex_unlock(&vac->vac_mtx) != 0)
96 + v8plus_panic("could not unlock async call mutex");
97 + }
98 +}
99 +
100 +nvlist_t *
101 +v8plus_method_call(void *cop, const char *name, const nvlist_t *lp)
102 +{
103 + v8plus_async_call_t vac;
104 +
105 + if (v8plus_in_event_thread() == B_TRUE) {
106 + /*
107 + * We're running in the event loop thread, so we can make the
108 + * call directly.
109 + */
110 + return (v8plus_method_call_direct(cop, name, lp));
111 + }
112 +
113 + /*
114 + * As we cannot manipulate v8plus/V8/Node structures directly from
115 + * outside the event loop thread, we push the call arguments onto a
116 + * queue and post to the event loop thread. We then sleep on our
117 + * condition variable until the event loop thread makes the call
118 + * for us and wakes us up.
119 + */
120 + vac.vac_cop = cop;
121 + vac.vac_name = name;
122 + vac.vac_lp = lp;
123 + if (pthread_mutex_init(&vac.vac_mtx, NULL) != 0)
124 + v8plus_panic("could not init async call mutex");
125 + if (pthread_cond_init(&vac.vac_cv, NULL) != 0)
126 + v8plus_panic("could not init async call condvar");
127 + vac.vac_run = B_FALSE;
128 + vac.vac_return = NULL;
129 +
130 + /*
131 + * Post request to queue:
132 + */
133 + if (pthread_mutex_lock(&_v8plus_callq_mtx) != 0)
134 + v8plus_panic("could not lock async queue mutex");
135 + STAILQ_INSERT_TAIL(&_v8plus_callq, &vac, vac_callq_entry);
136 + if (pthread_mutex_unlock(&_v8plus_callq_mtx) != 0)
137 + v8plus_panic("could not unlock async queue mutex");
138 + uv_async_send(&_v8plus_uv_async);
139 +
140 + /*
141 + * Wait for our request to be serviced on the Event Loop thread:
142 + */
143 + if (pthread_mutex_lock(&vac.vac_mtx) != 0)
144 + v8plus_panic("could not lock async call mutex");
145 + while (vac.vac_run == B_FALSE) {
146 + if (pthread_cond_wait(&vac.vac_cv, &vac.vac_mtx) != 0)
147 + v8plus_panic("could not wait on async call condvar");
148 + }
149 +
150 + return (vac.vac_return);
151 +}
152 +
153 +
154 +/*
155 + * Initialise structures for off-event-loop method calls.
156 + *
157 + * Note that uv_async_init() must be called inside the libuv Event Loop, so we
158 + * do it here. We also want to record the thread ID of the Event Loop thread
159 + * so as to determine what kind of method calls to make later.
160 + */
161 +void
162 +v8plus_crossthread_init(void)
163 +{
164 + _v8plus_uv_event_thread = pthread_self();
165 + if (uv_async_init(uv_default_loop(), &_v8plus_uv_async,
166 + v8plus_async_callback) != 0)
167 + v8plus_panic("unable to initialise uv_async_t");
168 + if (pthread_mutex_init(&_v8plus_callq_mtx, NULL) != 0)
169 + v8plus_panic("unable to initialise mutex");
170 +}
171 +
25 172 nvlist_t *
26 173 v8plus_verror(v8plus_errno_t e, const char *fmt, va_list ap)
27 174 {
28 175 if (fmt == NULL) {
29 176 if (e == V8PLUSERR_NOERROR) {
30 177 *_v8plus_errmsg = '\0';
31 178 } else {
32 179 (void) snprintf(_v8plus_errmsg, V8PLUS_ERRMSG_LEN,
33 180 "%s", v8plus_strerror(e));
34 181 }
35 182 } else {
36 183 (void) vsnprintf(_v8plus_errmsg, V8PLUS_ERRMSG_LEN, fmt, ap);
37 184 }
38 185 _v8plus_errno = e;
39 186
40 187 return (NULL);
41 188 }
42 189
43 190 nvlist_t *
44 191 v8plus_error(v8plus_errno_t e, const char *fmt, ...)
45 192 {
46 193 va_list ap;
47 194
48 195 va_start(ap, fmt);
49 196 (void) v8plus_verror(e, fmt, ap);
50 197 va_end(ap);
51 198
52 199 return (NULL);
53 200 }
54 201
55 202 static void __NORETURN
56 203 v8plus_vpanic(const char *fmt, va_list ap)
57 204 {
58 205 (void) vfprintf(stderr, fmt, ap);
59 206 (void) fflush(stderr);
60 207 abort();
61 208 }
62 209
63 210 void
64 211 v8plus_panic(const char *fmt, ...)
65 212 {
66 213 va_list ap;
67 214
68 215 va_start(ap, fmt);
69 216 v8plus_vpanic(fmt, ap);
70 217 va_end(ap);
71 218 }
72 219
73 220 nvlist_t *
74 221 v8plus_nverr(int nverr, const char *member)
75 222 {
76 223 (void) snprintf(_v8plus_errmsg, V8PLUS_ERRMSG_LEN,
77 224 "nvlist manipulation error on member %s: %s",
78 225 member == NULL ? "<none>" : member, strerror(nverr));
79 226
80 227 switch (nverr) {
81 228 case ENOMEM:
82 229 _v8plus_errno = V8PLUSERR_NOMEM;
83 230 break;
84 231 case EINVAL:
85 232 _v8plus_errno = V8PLUSERR_YOUSUCK;
86 233 break;
87 234 default:
88 235 _v8plus_errno = V8PLUSERR_UNKNOWN;
89 236 break;
90 237 }
91 238
92 239 return (NULL);
93 240 }
94 241
95 242 nvlist_t *
96 243 v8plus_syserr(int syserr, const char *fmt, ...)
97 244 {
98 245 v8plus_errno_t e;
99 246 va_list ap;
100 247
101 248 switch (syserr) {
102 249 case ENOMEM:
103 250 e = V8PLUSERR_NOMEM;
104 251 break;
105 252 case EBADF:
106 253 e = V8PLUSERR_BADF;
107 254 break;
108 255 default:
109 256 e = V8PLUSERR_UNKNOWN;
110 257 break;
111 258 }
112 259
113 260 va_start(ap, fmt);
114 261 (void) v8plus_verror(e, fmt, ap);
115 262 va_end(ap);
116 263
117 264 return (NULL);
118 265 }
119 266
120 267 /*
121 268 * The NULL nvlist with V8PLUSERR_NOERROR means we are returning void.
122 269 */
123 270 nvlist_t *
124 271 v8plus_void(void)
125 272 {
126 273 return (v8plus_error(V8PLUSERR_NOERROR, NULL));
127 274 }
128 275
129 276 v8plus_type_t
130 277 v8plus_typeof(const nvpair_t *pp)
131 278 {
132 279 data_type_t t = nvpair_type((nvpair_t *)pp);
133 280
134 281 switch (t) {
135 282 case DATA_TYPE_DOUBLE:
136 283 return (V8PLUS_TYPE_NUMBER);
137 284 case DATA_TYPE_STRING:
138 285 return (V8PLUS_TYPE_STRING);
139 286 case DATA_TYPE_NVLIST:
140 287 return (V8PLUS_TYPE_OBJECT);
141 288 case DATA_TYPE_BOOLEAN_VALUE:
142 289 return (V8PLUS_TYPE_BOOLEAN);
143 290 case DATA_TYPE_BOOLEAN:
144 291 return (V8PLUS_TYPE_UNDEFINED);
145 292 case DATA_TYPE_BYTE:
146 293 {
147 294 uchar_t v;
148 295 if (nvpair_value_byte((nvpair_t *)pp, &v) != 0 || v != 0)
149 296 return (V8PLUS_TYPE_INVALID);
150 297 return (V8PLUS_TYPE_NULL);
151 298 }
152 299 case DATA_TYPE_UINT64_ARRAY:
153 300 {
154 301 uint64_t *vp;
155 302 uint_t nv;
156 303 if (nvpair_value_uint64_array((nvpair_t *)pp, &vp, &nv) != 0 ||
157 304 nv != 1) {
158 305 return (V8PLUS_TYPE_INVALID);
159 306 }
160 307 return (V8PLUS_TYPE_JSFUNC);
161 308 }
162 309 default:
163 310 return (V8PLUS_TYPE_INVALID);
164 311 }
165 312 }
166 313
167 314 static int
168 315 v8plus_arg_value(v8plus_type_t t, const nvpair_t *pp, void *vp)
169 316 {
170 317 data_type_t dt = nvpair_type((nvpair_t *)pp);
171 318
172 319 switch (t) {
173 320 case V8PLUS_TYPE_NONE:
174 321 return (-1);
175 322 case V8PLUS_TYPE_STRING:
176 323 if (dt == DATA_TYPE_STRING) {
177 324 if (vp != NULL) {
178 325 (void) nvpair_value_string((nvpair_t *)pp,
179 326 (char **)vp);
180 327 }
181 328 return (0);
182 329 }
183 330 return (-1);
184 331 case V8PLUS_TYPE_NUMBER:
185 332 if (dt == DATA_TYPE_DOUBLE) {
186 333 if (vp != NULL) {
187 334 (void) nvpair_value_double((nvpair_t *)pp,
188 335 (double *)vp);
189 336 }
190 337 return (0);
191 338 }
192 339 return (-1);
193 340 case V8PLUS_TYPE_BOOLEAN:
194 341 if (dt == DATA_TYPE_BOOLEAN_VALUE) {
195 342 if (vp != NULL) {
196 343 (void) nvpair_value_boolean_value(
197 344 (nvpair_t *)pp, (boolean_t *)vp);
198 345 }
199 346 return (0);
200 347 }
201 348 return (-1);
202 349 case V8PLUS_TYPE_JSFUNC:
203 350 if (dt == DATA_TYPE_UINT64_ARRAY) {
204 351 uint_t nv;
205 352 uint64_t *vpp;
206 353
207 354 if (nvpair_value_uint64_array((nvpair_t *)pp,
208 355 &vpp, &nv) == 0 && nv == 1) {
209 356 if (vp != NULL)
210 357 *(v8plus_jsfunc_t *)vp = vpp[0];
211 358 return (0);
212 359 }
213 360 }
214 361 return (-1);
215 362 case V8PLUS_TYPE_OBJECT:
216 363 if (dt == DATA_TYPE_NVLIST) {
217 364 if (vp != NULL) {
218 365 (void) nvpair_value_nvlist((nvpair_t *)pp,
219 366 (nvlist_t **)vp);
220 367 }
221 368 return (0);
222 369 }
223 370 return (-1);
224 371 case V8PLUS_TYPE_NULL:
225 372 if (dt == DATA_TYPE_BYTE) {
226 373 uchar_t v;
227 374
228 375 if (nvpair_value_byte((nvpair_t *)pp, &v) == 0 &&
229 376 v == 0)
230 377 return (0);
231 378 }
232 379 return (-1);
233 380 case V8PLUS_TYPE_UNDEFINED:
234 381 return (dt == DATA_TYPE_BOOLEAN ? 0 : -1);
235 382 case V8PLUS_TYPE_ANY:
236 383 if (vp != NULL)
237 384 *(const nvpair_t **)vp = pp;
238 385 return (0);
239 386 case V8PLUS_TYPE_INVALID:
240 387 if (vp != NULL)
241 388 *(data_type_t *)vp = dt;
242 389 return (0);
243 390 case V8PLUS_TYPE_STRNUMBER64:
244 391 if (dt == DATA_TYPE_STRING) {
245 392 char *s;
246 393 uint64_t v;
247 394
248 395 (void) nvpair_value_string((nvpair_t *)pp, &s);
249 396 errno = 0;
250 397 v = (uint64_t)strtoull(s, NULL, 0);
251 398 if (errno != 0)
252 399 return (-1);
253 400 if (vp != NULL)
254 401 *(uint64_t *)vp = v;
255 402 return (0);
256 403 }
257 404 return (-1);
258 405 default:
259 406 return (-1);
260 407 }
261 408 }
262 409
263 410 int
264 411 v8plus_args(const nvlist_t *lp, uint_t flags, v8plus_type_t t, ...)
265 412 {
266 413 v8plus_type_t nt;
267 414 nvpair_t *pp;
268 415 void *vp;
269 416 va_list ap;
270 417 uint_t i;
271 418 char buf[32];
272 419
273 420 va_start(ap, t);
274 421
275 422 for (i = 0, nt = t; nt != V8PLUS_TYPE_NONE; i++) {
276 423 switch (nt) {
277 424 case V8PLUS_TYPE_UNDEFINED:
278 425 case V8PLUS_TYPE_NULL:
279 426 break;
280 427 default:
281 428 (void) va_arg(ap, void *);
282 429 }
283 430
284 431 (void) snprintf(buf, sizeof (buf), "%u", i);
285 432 if (nvlist_lookup_nvpair((nvlist_t *)lp, buf, &pp) != 0) {
286 433 (void) v8plus_error(V8PLUSERR_MISSINGARG,
287 434 "argument %u is required", i);
288 435 return (-1);
289 436 }
290 437
291 438 if (v8plus_arg_value(nt, pp, NULL) != 0) {
292 439 (void) v8plus_error(V8PLUSERR_BADARG,
293 440 "argument %u is of incorrect type", i);
294 441 return (-1);
295 442 }
296 443
297 444 nt = va_arg(ap, data_type_t);
298 445 }
299 446
300 447 va_end(ap);
301 448
302 449 if (flags & V8PLUS_ARG_F_NOEXTRA) {
303 450 (void) snprintf(buf, sizeof (buf), "%u", i);
304 451 if (nvlist_lookup_nvpair((nvlist_t *)lp, buf, &pp) == 0) {
305 452 (void) v8plus_error(V8PLUSERR_EXTRAARG,
306 453 "superfluous extra argument(s) detected");
307 454 return (-1);
308 455 }
309 456 }
310 457
311 458 va_start(ap, t);
312 459
313 460 for (i = 0, nt = t; nt != V8PLUS_TYPE_NONE; i++) {
314 461 switch (nt) {
315 462 case V8PLUS_TYPE_UNDEFINED:
316 463 case V8PLUS_TYPE_NULL:
317 464 vp = NULL;
318 465 break;
319 466 default:
320 467 vp = va_arg(ap, void *);
321 468 }
322 469
323 470 (void) snprintf(buf, sizeof (buf), "%u", i);
324 471 VERIFY(nvlist_lookup_nvpair((nvlist_t *)lp, buf, &pp) == 0);
325 472 VERIFY(v8plus_arg_value(nt, pp, vp) == 0);
326 473
327 474 nt = va_arg(ap, data_type_t);
328 475 }
329 476
330 477 va_end(ap);
331 478
332 479 return (0);
333 480 }
334 481
335 482 static int
336 483 v8plus_obj_vsetprops(nvlist_t *lp, v8plus_type_t t, va_list *ap)
337 484 {
338 485 v8plus_type_t nt = t;
339 486 char *name;
340 487 int err;
341 488
342 489 /*
343 490 * Do not call va_start() or va_end() in this function! We are limited
344 491 * to a single traversal of the arguments so that we can recurse to
345 492 * handle embedded object definitions.
346 493 */
347 494
348 495 while (nt != V8PLUS_TYPE_NONE) {
349 496 name = va_arg(*ap, char *);
350 497
351 498 switch (nt) {
352 499 case V8PLUS_TYPE_STRING:
353 500 {
354 501 char *s = va_arg(*ap, char *);
355 502 if ((err = nvlist_add_string(lp, name, s)) != 0) {
356 503 (void) v8plus_nverr(err, name);
357 504 return (-1);
358 505 }
359 506 break;
360 507 }
361 508 case V8PLUS_TYPE_NUMBER:
362 509 {
363 510 double d = va_arg(*ap, double);
364 511 if ((err = nvlist_add_double(lp, name, d)) != 0) {
365 512 (void) v8plus_nverr(err, name);
366 513 return (-1);
367 514 }
368 515 break;
369 516 }
370 517 case V8PLUS_TYPE_BOOLEAN:
371 518 {
372 519 boolean_t b = va_arg(*ap, boolean_t);
373 520 if ((err = nvlist_add_boolean_value(lp,
374 521 name, b)) != 0) {
375 522 (void) v8plus_nverr(err, name);
376 523 return (-1);
377 524 }
378 525 break;
379 526 }
380 527 case V8PLUS_TYPE_JSFUNC:
381 528 {
382 529 v8plus_jsfunc_t j = va_arg(*ap, v8plus_jsfunc_t);
383 530 if ((err = nvlist_add_uint64_array(lp,
384 531 name, &j, 1)) != 0) {
385 532 (void) v8plus_nverr(err, name);
386 533 return (-1);
387 534 }
388 535 if ((err = nvlist_add_string_array(lp,
389 536 V8PLUS_JSF_COOKIE, NULL, 0)) != 0) {
390 537 (void) v8plus_nverr(err, V8PLUS_JSF_COOKIE);
391 538 return (-1);
392 539 }
393 540 v8plus_jsfunc_hold(j);
394 541 break;
395 542 }
396 543 case V8PLUS_TYPE_OBJECT:
397 544 {
398 545 const nvlist_t *op = va_arg(*ap, const nvlist_t *);
399 546 if ((err = nvlist_add_nvlist(lp, name,
400 547 (nvlist_t *)op)) != 0) {
401 548 (void) v8plus_nverr(err, name);
402 549 return (-1);
403 550 }
404 551 break;
405 552 }
406 553 case V8PLUS_TYPE_NULL:
407 554 if ((err = nvlist_add_byte(lp, name, 0)) != 0) {
408 555 (void) v8plus_nverr(err, name);
409 556 return (-1);
410 557 }
411 558 break;
412 559 case V8PLUS_TYPE_UNDEFINED:
413 560 if ((err = nvlist_add_boolean(lp, name)) != 0) {
414 561 (void) v8plus_nverr(err, name);
415 562 return (-1);
416 563 }
417 564 break;
418 565 case V8PLUS_TYPE_ANY:
419 566 {
420 567 nvpair_t *pp = va_arg(*ap, nvpair_t *);
421 568 if ((err = nvlist_add_nvpair(lp, pp)) != 0) {
422 569 (void) v8plus_nverr(err, name);
423 570 return (-1);
424 571 }
425 572 break;
426 573 }
427 574 case V8PLUS_TYPE_STRNUMBER64:
428 575 {
429 576 uint64_t v = va_arg(*ap, uint64_t);
430 577 char s[32];
431 578 (void) snprintf(s, sizeof (s), "%" PRIu64, v);
432 579 if ((err = nvlist_add_string(lp, name, s)) != 0) {
433 580 (void) v8plus_nverr(err, name);
434 581 return (-1);
435 582 }
436 583 break;
437 584 }
438 585 case V8PLUS_TYPE_INL_OBJECT:
439 586 {
440 587 nvlist_t *slp;
441 588
442 589 nt = va_arg(*ap, v8plus_type_t);
443 590 err = nvlist_alloc(&slp, NV_UNIQUE_NAME, 0);
444 591 if (err != 0) {
445 592 (void) v8plus_nverr(err, name);
446 593 return (-1);
447 594 }
448 595 if (v8plus_obj_vsetprops(slp, nt, ap) != 0)
449 596 return (-1);
450 597
451 598 err = nvlist_add_nvlist(lp, name, slp);
452 599 nvlist_free(slp);
453 600 if (err != 0) {
454 601 (void) v8plus_nverr(err, name);
455 602 return (-1);
456 603 }
457 604 break;
458 605 }
459 606 case V8PLUS_TYPE_INVALID:
460 607 default:
461 608 (void) v8plus_error(V8PLUSERR_YOUSUCK,
462 609 "invalid property type %d", nt);
463 610 return (-1);
464 611 }
465 612
466 613 nt = va_arg(*ap, v8plus_type_t);
467 614 }
468 615
469 616 return (0);
470 617 }
471 618
472 619 nvlist_t *
473 620 v8plus_obj(v8plus_type_t t, ...)
474 621 {
475 622 nvlist_t *rp;
476 623 va_list ap;
477 624 int err;
478 625
479 626 if ((err = nvlist_alloc(&rp, NV_UNIQUE_NAME, 0)) != 0)
480 627 return (v8plus_nverr(err, NULL));
481 628
482 629 va_start(ap, t);
483 630 err = v8plus_obj_vsetprops(rp, t, &ap);
484 631 va_end(ap);
485 632
486 633 if (err != 0) {
487 634 nvlist_free(rp);
488 635 rp = NULL;
489 636 }
490 637
491 638 return (rp);
492 639 }
493 640
494 641 int
495 642 v8plus_obj_setprops(nvlist_t *lp, v8plus_type_t t, ...)
496 643 {
497 644 va_list ap;
498 645 int err;
499 646
500 647 va_start(ap, t);
501 648 err = v8plus_obj_vsetprops(lp, t, &ap);
502 649 va_end(ap);
503 650
504 651 return (err);
505 652 }
506 653
507 654 static void
508 655 v8plus_uv_worker(uv_work_t *wp)
509 656 {
510 657 v8plus_uv_ctx_t *cp = wp->data;
511 658
512 659 cp->vuc_result = cp->vuc_worker(cp->vuc_obj, cp->vuc_ctx);
513 660 }
514 661
515 662 static void
516 663 v8plus_uv_completion(uv_work_t *wp)
517 664 {
518 665 v8plus_uv_ctx_t *cp = wp->data;
519 666
520 667 cp->vuc_completion(cp->vuc_obj, cp->vuc_ctx, cp->vuc_result);
521 668 v8plus_obj_rele(cp->vuc_obj);
522 669 free(cp);
523 670 free(wp);
524 671 }
525 672
526 673 void
527 674 v8plus_defer(void *cop, void *ctxp, v8plus_worker_f worker,
528 675 v8plus_completion_f completion)
529 676 {
530 677 uv_work_t *wp = malloc(sizeof (uv_work_t));
531 678 v8plus_uv_ctx_t *cp = malloc(sizeof (v8plus_uv_ctx_t));
532 679
533 680 bzero(wp, sizeof (uv_work_t));
534 681 bzero(cp, sizeof (v8plus_uv_ctx_t));
535 682
536 683 v8plus_obj_hold(cop);
537 684 cp->vuc_obj = cop;
538 685 cp->vuc_ctx = ctxp;
539 686 cp->vuc_worker = worker;
540 687 cp->vuc_completion = completion;
541 688 wp->data = cp;
542 689
543 690 uv_queue_work(uv_default_loop(), wp, v8plus_uv_worker,
544 691 v8plus_uv_completion);
545 692 }
↓ open down ↓ |
511 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX