… | |
… | |
351 | static void req_free (bdb_req req); |
351 | static void req_free (bdb_req req); |
352 | static void req_cancel (bdb_req req); |
352 | static void req_cancel (bdb_req req); |
353 | |
353 | |
354 | static int req_invoke (bdb_req req) |
354 | static int req_invoke (bdb_req req) |
355 | { |
355 | { |
356 | dSP; |
356 | switch (req->type) |
|
|
357 | { |
|
|
358 | case REQ_DB_CLOSE: |
|
|
359 | SvREFCNT_dec (req->sv1); |
|
|
360 | break; |
|
|
361 | |
|
|
362 | case REQ_DB_GET: |
|
|
363 | case REQ_DB_PGET: |
|
|
364 | dbt_to_sv (req->sv3, &req->dbt3); |
|
|
365 | break; |
|
|
366 | |
|
|
367 | case REQ_C_GET: |
|
|
368 | case REQ_C_PGET: |
|
|
369 | dbt_to_sv (req->sv1, &req->dbt1); |
|
|
370 | dbt_to_sv (req->sv2, &req->dbt2); |
|
|
371 | dbt_to_sv (req->sv3, &req->dbt3); |
|
|
372 | break; |
|
|
373 | |
|
|
374 | case REQ_DB_PUT: |
|
|
375 | case REQ_C_PUT: |
|
|
376 | dbt_to_sv (0, &req->dbt1); |
|
|
377 | dbt_to_sv (0, &req->dbt2); |
|
|
378 | break; |
|
|
379 | |
|
|
380 | case REQ_DB_KEY_RANGE: |
|
|
381 | { |
|
|
382 | AV *av = newAV (); |
|
|
383 | |
|
|
384 | av_push (av, newSVnv (req->key_range.less)); |
|
|
385 | av_push (av, newSVnv (req->key_range.equal)); |
|
|
386 | av_push (av, newSVnv (req->key_range.greater)); |
|
|
387 | |
|
|
388 | SvREADONLY_off (req->sv1); |
|
|
389 | sv_setsv_mg (req->sv1, newRV_noinc ((SV *)av)); |
|
|
390 | SvREFCNT_dec (req->sv1); |
|
|
391 | } |
|
|
392 | break; |
|
|
393 | |
|
|
394 | #if DB_VERSION_MINOR >= 3 |
|
|
395 | case REQ_SEQ_GET: |
|
|
396 | SvREADONLY_off (req->sv1); |
|
|
397 | |
|
|
398 | if (sizeof (IV) > 4) |
|
|
399 | sv_setiv_mg (req->sv1, (IV)req->seq_t); |
|
|
400 | else |
|
|
401 | sv_setnv_mg (req->sv1, (NV)req->seq_t); |
|
|
402 | |
|
|
403 | SvREFCNT_dec (req->sv1); |
|
|
404 | break; |
|
|
405 | #endif |
|
|
406 | } |
|
|
407 | |
|
|
408 | errno = req->result; |
357 | |
409 | |
358 | if (req->callback) |
410 | if (req->callback) |
359 | { |
411 | { |
|
|
412 | dSP; |
|
|
413 | |
360 | ENTER; |
414 | ENTER; |
361 | SAVETMPS; |
415 | SAVETMPS; |
362 | PUSHMARK (SP); |
416 | PUSHMARK (SP); |
363 | |
417 | |
364 | switch (req->type) |
|
|
365 | { |
|
|
366 | case REQ_DB_CLOSE: |
|
|
367 | SvREFCNT_dec (req->sv1); |
|
|
368 | break; |
|
|
369 | |
|
|
370 | case REQ_DB_GET: |
|
|
371 | case REQ_DB_PGET: |
|
|
372 | dbt_to_sv (req->sv3, &req->dbt3); |
|
|
373 | break; |
|
|
374 | |
|
|
375 | case REQ_C_GET: |
|
|
376 | case REQ_C_PGET: |
|
|
377 | dbt_to_sv (req->sv1, &req->dbt1); |
|
|
378 | dbt_to_sv (req->sv2, &req->dbt2); |
|
|
379 | dbt_to_sv (req->sv3, &req->dbt3); |
|
|
380 | break; |
|
|
381 | |
|
|
382 | case REQ_DB_PUT: |
|
|
383 | case REQ_C_PUT: |
|
|
384 | dbt_to_sv (0, &req->dbt1); |
|
|
385 | dbt_to_sv (0, &req->dbt2); |
|
|
386 | break; |
|
|
387 | |
|
|
388 | case REQ_DB_KEY_RANGE: |
|
|
389 | { |
|
|
390 | AV *av = newAV (); |
|
|
391 | |
|
|
392 | av_push (av, newSVnv (req->key_range.less)); |
|
|
393 | av_push (av, newSVnv (req->key_range.equal)); |
|
|
394 | av_push (av, newSVnv (req->key_range.greater)); |
|
|
395 | |
|
|
396 | SvREADONLY_off (req->sv1); |
|
|
397 | sv_setsv_mg (req->sv1, newRV_noinc ((SV *)av)); |
|
|
398 | SvREFCNT_dec (req->sv1); |
|
|
399 | } |
|
|
400 | break; |
|
|
401 | |
|
|
402 | #if DB_VERSION_MINOR >= 3 |
|
|
403 | case REQ_SEQ_GET: |
|
|
404 | SvREADONLY_off (req->sv1); |
|
|
405 | |
|
|
406 | if (sizeof (IV) > 4) |
|
|
407 | sv_setiv_mg (req->sv1, (IV)req->seq_t); |
|
|
408 | else |
|
|
409 | sv_setnv_mg (req->sv1, (NV)req->seq_t); |
|
|
410 | |
|
|
411 | SvREFCNT_dec (req->sv1); |
|
|
412 | break; |
|
|
413 | #endif |
|
|
414 | } |
|
|
415 | |
|
|
416 | errno = req->result; |
|
|
417 | |
|
|
418 | PUTBACK; |
418 | PUTBACK; |
419 | call_sv (req->callback, G_VOID | G_EVAL); |
419 | call_sv (req->callback, G_VOID | G_EVAL); |
420 | SPAGAIN; |
420 | SPAGAIN; |
421 | |
421 | |
422 | FREETMPS; |
422 | FREETMPS; |
423 | LEAVE; |
423 | LEAVE; |
|
|
424 | |
|
|
425 | return !SvTRUE (ERRSV); |
424 | } |
426 | } |
425 | |
427 | |
426 | return !SvTRUE (ERRSV); |
428 | return 1; |
427 | } |
429 | } |
428 | |
430 | |
429 | static void req_free (bdb_req req) |
431 | static void req_free (bdb_req req) |
430 | { |
432 | { |
431 | SvREFCNT_dec (req->callback); |
433 | SvREFCNT_dec (req->callback); |
… | |
… | |
485 | |
487 | |
486 | respipe_osf [0] = TO_SOCKET (respipe [0]); |
488 | respipe_osf [0] = TO_SOCKET (respipe [0]); |
487 | respipe_osf [1] = TO_SOCKET (respipe [1]); |
489 | respipe_osf [1] = TO_SOCKET (respipe [1]); |
488 | } |
490 | } |
489 | |
491 | |
|
|
492 | static void bdb_request (bdb_req req); |
490 | X_THREAD_PROC (bdb_proc); |
493 | X_THREAD_PROC (bdb_proc); |
491 | |
494 | |
492 | static void start_thread (void) |
495 | static void start_thread (void) |
493 | { |
496 | { |
494 | worker *wrk = calloc (1, sizeof (worker)); |
497 | worker *wrk = calloc (1, sizeof (worker)); |
… | |
… | |
541 | } |
544 | } |
542 | |
545 | |
543 | // synthesize callback if none given |
546 | // synthesize callback if none given |
544 | if (!req->callback) |
547 | if (!req->callback) |
545 | { |
548 | { |
|
|
549 | if (SvOK (prepare_cb)) |
|
|
550 | { |
546 | int count; |
551 | int count; |
547 | |
552 | |
548 | dSP; |
553 | dSP; |
549 | PUSHMARK (SP); |
554 | PUSHMARK (SP); |
550 | PUTBACK; |
555 | PUTBACK; |
551 | count = call_sv (prepare_cb, G_ARRAY); |
556 | count = call_sv (prepare_cb, G_ARRAY); |
552 | SPAGAIN; |
557 | SPAGAIN; |
553 | |
558 | |
554 | if (count != 2) |
559 | if (count != 2) |
555 | croak ("prepare callback must return exactly two values\n"); |
560 | croak ("prepare callback must return exactly two values\n"); |
556 | |
561 | |
557 | wait_callback = POPs; |
562 | wait_callback = POPs; |
558 | req->callback = SvREFCNT_inc (POPs); |
563 | req->callback = SvREFCNT_inc (POPs); |
|
|
564 | } |
|
|
565 | else |
|
|
566 | { |
|
|
567 | // execute request synchronously |
|
|
568 | bdb_request (req); |
|
|
569 | req_invoke (req); |
|
|
570 | req_free (req); |
|
|
571 | return; |
|
|
572 | } |
559 | } |
573 | } |
560 | |
574 | |
561 | ++nreqs; |
575 | ++nreqs; |
562 | |
576 | |
563 | X_LOCK (reqlock); |
577 | X_LOCK (reqlock); |
… | |
… | |
1328 | }; |
1342 | }; |
1329 | |
1343 | |
1330 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) |
1344 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) |
1331 | newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); |
1345 | newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); |
1332 | |
1346 | |
|
|
1347 | prepare_cb = &PL_sv_undef; |
|
|
1348 | |
1333 | { |
1349 | { |
1334 | /* we currently only allow version, minor-version and patchlevel to go up to 255 */ |
1350 | /* we currently only allow version, minor-version and patchlevel to go up to 255 */ |
1335 | char vstring[3] = { DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH }; |
1351 | char vstring[3] = { DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH }; |
1336 | |
1352 | |
1337 | newCONSTSUB (stash, "VERSION_v", newSVpvn (vstring, 3)); |
1353 | newCONSTSUB (stash, "VERSION_v", newSVpvn (vstring, 3)); |
… | |
… | |
1475 | RETVAL = started; |
1491 | RETVAL = started; |
1476 | if (WORDACCESS_UNSAFE) X_UNLOCK (wrklock); |
1492 | if (WORDACCESS_UNSAFE) X_UNLOCK (wrklock); |
1477 | OUTPUT: |
1493 | OUTPUT: |
1478 | RETVAL |
1494 | RETVAL |
1479 | |
1495 | |
1480 | void |
1496 | SV * |
1481 | set_sync_prepare (SV *cb) |
1497 | set_sync_prepare (SV *cb) |
1482 | PROTOTYPE: & |
1498 | PROTOTYPE: & |
1483 | CODE: |
1499 | CODE: |
1484 | SvREFCNT_dec (prepare_cb); |
1500 | RETVAL = prepare_cb; |
1485 | prepare_cb = newSVsv (cb); |
1501 | prepare_cb = newSVsv (cb); |
|
|
1502 | OUTPUT: |
|
|
1503 | RETVAL |
1486 | |
1504 | |
1487 | char * |
1505 | char * |
1488 | strerror (int errorno = errno) |
1506 | strerror (int errorno = errno) |
1489 | PROTOTYPE: ;$ |
1507 | PROTOTYPE: ;$ |
1490 | CODE: |
1508 | CODE: |