--- BDB/BDB.xs 2008/09/25 13:44:44 1.52 +++ BDB/BDB.xs 2008/09/25 22:09:02 1.53 @@ -353,67 +353,67 @@ static int req_invoke (bdb_req req) { - dSP; - - if (req->callback) + switch (req->type) { - ENTER; - SAVETMPS; - PUSHMARK (SP); - - switch (req->type) - { - case REQ_DB_CLOSE: - SvREFCNT_dec (req->sv1); - break; + case REQ_DB_CLOSE: + SvREFCNT_dec (req->sv1); + break; - case REQ_DB_GET: - case REQ_DB_PGET: - dbt_to_sv (req->sv3, &req->dbt3); - break; + case REQ_DB_GET: + case REQ_DB_PGET: + dbt_to_sv (req->sv3, &req->dbt3); + break; - case REQ_C_GET: - case REQ_C_PGET: - dbt_to_sv (req->sv1, &req->dbt1); - dbt_to_sv (req->sv2, &req->dbt2); - dbt_to_sv (req->sv3, &req->dbt3); - break; + case REQ_C_GET: + case REQ_C_PGET: + dbt_to_sv (req->sv1, &req->dbt1); + dbt_to_sv (req->sv2, &req->dbt2); + dbt_to_sv (req->sv3, &req->dbt3); + break; - case REQ_DB_PUT: - case REQ_C_PUT: - dbt_to_sv (0, &req->dbt1); - dbt_to_sv (0, &req->dbt2); - break; + case REQ_DB_PUT: + case REQ_C_PUT: + dbt_to_sv (0, &req->dbt1); + dbt_to_sv (0, &req->dbt2); + break; - case REQ_DB_KEY_RANGE: - { - AV *av = newAV (); + case REQ_DB_KEY_RANGE: + { + AV *av = newAV (); - av_push (av, newSVnv (req->key_range.less)); - av_push (av, newSVnv (req->key_range.equal)); - av_push (av, newSVnv (req->key_range.greater)); - - SvREADONLY_off (req->sv1); - sv_setsv_mg (req->sv1, newRV_noinc ((SV *)av)); - SvREFCNT_dec (req->sv1); - } - break; + av_push (av, newSVnv (req->key_range.less)); + av_push (av, newSVnv (req->key_range.equal)); + av_push (av, newSVnv (req->key_range.greater)); + + SvREADONLY_off (req->sv1); + sv_setsv_mg (req->sv1, newRV_noinc ((SV *)av)); + SvREFCNT_dec (req->sv1); + } + break; #if DB_VERSION_MINOR >= 3 - case REQ_SEQ_GET: - SvREADONLY_off (req->sv1); + case REQ_SEQ_GET: + SvREADONLY_off (req->sv1); - if (sizeof (IV) > 4) - sv_setiv_mg (req->sv1, (IV)req->seq_t); - else - sv_setnv_mg (req->sv1, (NV)req->seq_t); + if (sizeof (IV) > 4) + sv_setiv_mg (req->sv1, (IV)req->seq_t); + else + sv_setnv_mg (req->sv1, (NV)req->seq_t); - SvREFCNT_dec (req->sv1); - break; + SvREFCNT_dec (req->sv1); + break; #endif - } + } + + errno = req->result; - errno = req->result; + if (req->callback) + { + dSP; + + ENTER; + SAVETMPS; + PUSHMARK (SP); PUTBACK; call_sv (req->callback, G_VOID | G_EVAL); @@ -421,9 +421,11 @@ FREETMPS; LEAVE; + + return !SvTRUE (ERRSV); } - return !SvTRUE (ERRSV); + return 1; } static void req_free (bdb_req req) @@ -487,6 +489,7 @@ respipe_osf [1] = TO_SOCKET (respipe [1]); } +static void bdb_request (bdb_req req); X_THREAD_PROC (bdb_proc); static void start_thread (void) @@ -543,19 +546,30 @@ // synthesize callback if none given if (!req->callback) { - int count; + if (SvOK (prepare_cb)) + { + int count; - dSP; - PUSHMARK (SP); - PUTBACK; - count = call_sv (prepare_cb, G_ARRAY); - SPAGAIN; + dSP; + PUSHMARK (SP); + PUTBACK; + count = call_sv (prepare_cb, G_ARRAY); + SPAGAIN; - if (count != 2) - croak ("prepare callback must return exactly two values\n"); + if (count != 2) + croak ("prepare callback must return exactly two values\n"); - wait_callback = POPs; - req->callback = SvREFCNT_inc (POPs); + wait_callback = POPs; + req->callback = SvREFCNT_inc (POPs); + } + else + { + // execute request synchronously + bdb_request (req); + req_invoke (req); + req_free (req); + return; + } } ++nreqs; @@ -1330,6 +1344,8 @@ for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); + prepare_cb = &PL_sv_undef; + { /* we currently only allow version, minor-version and patchlevel to go up to 255 */ char vstring[3] = { DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH }; @@ -1477,12 +1493,14 @@ OUTPUT: RETVAL -void +SV * set_sync_prepare (SV *cb) PROTOTYPE: & CODE: - SvREFCNT_dec (prepare_cb); + RETVAL = prepare_cb; prepare_cb = newSVsv (cb); + OUTPUT: + RETVAL char * strerror (int errorno = errno)