ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/BDB/BDB.xs
Revision: 1.34
Committed: Sun Mar 30 06:28:08 2008 UTC (16 years, 1 month ago) by root
Branch: MAIN
CVS Tags: rel-1_44
Changes since 1.33: +22 -8 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.11 #include "xthread.h"
2 root 1.1
3     #include <errno.h>
4    
5     #include "EXTERN.h"
6     #include "perl.h"
7     #include "XSUB.h"
8    
9 root 1.13 // perl stupidly defines these as macros, breaking
10     // lots and lots of code.
11     #undef open
12     #undef close
13     #undef abort
14     #undef malloc
15     #undef free
16     #undef send
17    
18 root 1.1 #include <stddef.h>
19     #include <stdlib.h>
20     #include <errno.h>
21     #include <sys/types.h>
22     #include <limits.h>
23     #include <fcntl.h>
24 root 1.2
25 root 1.13 #ifndef _WIN32
26     # include <sys/time.h>
27     # include <unistd.h>
28     #endif
29    
30 root 1.2 #include <db.h>
31 root 1.1
32 root 1.13 #if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 4)
33     # error you need Berkeley DB 4.4 or newer installed
34 root 1.10 #endif
35    
36 root 1.1 /* number of seconds after which idle threads exit */
37     #define IDLE_TIMEOUT 10
38    
39 root 1.8 typedef DB_ENV DB_ENV_ornull;
40     typedef DB_TXN DB_TXN_ornull;
41     typedef DBC DBC_ornull;
42     typedef DB DB_ornull;
43     typedef DB_SEQUENCE DB_SEQUENCE_ornull;
44 root 1.5
45 root 1.30 typedef DB_ENV DB_ENV_ornuked;
46     typedef DB_TXN DB_TXN_ornuked;
47     typedef DBC DBC_ornuked;
48     typedef DB DB_ornuked;
49     typedef DB_SEQUENCE DB_SEQUENCE_ornuked;
50    
51 root 1.1 typedef SV SV8; /* byte-sv, used for argument-checking */
52 root 1.33 typedef char *bdb_filename;
53 root 1.1
54 root 1.3 static SV *prepare_cb;
55    
56 root 1.16 #if DB_VERSION_MINOR >= 6
57     # define c_close close
58     # define c_count count
59     # define c_del del
60     # define c_dup dup
61     # define c_get get
62     # define c_pget pget
63     # define c_put put
64     #endif
65    
66 root 1.34 static char *
67     get_bdb_filename (SV *sv)
68     {
69     return !SvOK (sv)
70     ? 0
71     :
72     #if WIN32
73     SvPVutf8_nolen (sv)
74     #else
75     SvPVbyte_nolen (sv)
76     #endif
77     ;
78     }
79    
80 root 1.14 static void
81     debug_errcall (const DB_ENV *dbenv, const char *errpfx, const char *msg)
82     {
83     printf ("err[%s]\n", msg);
84     }
85    
86     static void
87     debug_msgcall (const DB_ENV *dbenv, const char *msg)
88     {
89     printf ("msg[%s]\n", msg);
90     }
91    
92 root 1.13 static char *
93 root 1.3 strdup_ornull (const char *s)
94 root 1.2 {
95 root 1.3 return s ? strdup (s) : 0;
96     }
97    
98 root 1.13 static void
99 root 1.5 sv_to_dbt (DBT *dbt, SV *sv)
100     {
101     STRLEN len;
102     char *data = SvPVbyte (sv, len);
103    
104     dbt->data = malloc (len);
105     memcpy (dbt->data, data, len);
106     dbt->size = len;
107 root 1.6 dbt->flags = DB_DBT_REALLOC;
108 root 1.5 }
109    
110 root 1.13 static void
111 root 1.5 dbt_to_sv (SV *sv, DBT *dbt)
112     {
113 root 1.6 if (sv)
114     {
115     SvREADONLY_off (sv);
116     sv_setpvn_mg (sv, dbt->data, dbt->size);
117     SvREFCNT_dec (sv);
118     }
119 root 1.5
120     free (dbt->data);
121     }
122    
123 root 1.3 enum {
124 root 1.1 REQ_QUIT,
125 root 1.8 REQ_ENV_OPEN, REQ_ENV_CLOSE, REQ_ENV_TXN_CHECKPOINT, REQ_ENV_LOCK_DETECT,
126     REQ_ENV_MEMP_SYNC, REQ_ENV_MEMP_TRICKLE,
127 root 1.26 REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC, REQ_DB_UPGRADE,
128 root 1.8 REQ_DB_PUT, REQ_DB_GET, REQ_DB_PGET, REQ_DB_DEL, REQ_DB_KEY_RANGE,
129 root 1.17 REQ_TXN_COMMIT, REQ_TXN_ABORT, REQ_TXN_FINISH,
130 root 1.6 REQ_C_CLOSE, REQ_C_COUNT, REQ_C_PUT, REQ_C_GET, REQ_C_PGET, REQ_C_DEL,
131 root 1.8 REQ_SEQ_OPEN, REQ_SEQ_CLOSE, REQ_SEQ_GET, REQ_SEQ_REMOVE,
132 root 1.1 };
133    
134 root 1.28 typedef struct bdb_cb
135 root 1.1 {
136 root 1.28 struct bdb_cb *volatile next;
137 root 1.2 SV *callback;
138 root 1.3 int type, pri, result;
139 root 1.2
140     DB_ENV *env;
141     DB *db;
142     DB_TXN *txn;
143 root 1.6 DBC *dbc;
144    
145     UV uv1;
146 root 1.2 int int1, int2;
147     U32 uint1, uint2;
148     char *buf1, *buf2;
149 root 1.6 SV *sv1, *sv2, *sv3;
150 root 1.3
151     DBT dbt1, dbt2, dbt3;
152 root 1.8 DB_KEY_RANGE key_range;
153     DB_SEQUENCE *seq;
154     db_seq_t seq_t;
155 root 1.28 } bdb_cb;
156 root 1.1
157 root 1.28 typedef bdb_cb *bdb_req;
158 root 1.1
159     enum {
160     PRI_MIN = -4,
161     PRI_MAX = 4,
162    
163     DEFAULT_PRI = 0,
164     PRI_BIAS = -PRI_MIN,
165     NUM_PRI = PRI_MAX + PRI_BIAS + 1,
166     };
167    
168     #define AIO_TICKS ((1000000 + 1023) >> 10)
169    
170     static unsigned int max_poll_time = 0;
171     static unsigned int max_poll_reqs = 0;
172    
173     /* calculcate time difference in ~1/AIO_TICKS of a second */
174     static int tvdiff (struct timeval *tv1, struct timeval *tv2)
175     {
176     return (tv2->tv_sec - tv1->tv_sec ) * AIO_TICKS
177     + ((tv2->tv_usec - tv1->tv_usec) >> 10);
178     }
179    
180     static int next_pri = DEFAULT_PRI + PRI_BIAS;
181    
182     static unsigned int started, idle, wanted;
183    
184     /* worker threads management */
185 root 1.12 static mutex_t wrklock = X_MUTEX_INIT;
186 root 1.1
187     typedef struct worker {
188     /* locked by wrklock */
189     struct worker *prev, *next;
190    
191 root 1.11 thread_t tid;
192 root 1.1
193     /* locked by reslock, reqlock or wrklock */
194 root 1.28 bdb_req req; /* currently processed request */
195 root 1.1 void *dbuf;
196     DIR *dirp;
197     } worker;
198    
199     static worker wrk_first = { &wrk_first, &wrk_first, 0 };
200    
201     static void worker_clear (worker *wrk)
202     {
203     }
204    
205     static void worker_free (worker *wrk)
206     {
207     wrk->next->prev = wrk->prev;
208     wrk->prev->next = wrk->next;
209    
210     free (wrk);
211     }
212    
213     static volatile unsigned int nreqs, nready, npending;
214     static volatile unsigned int max_idle = 4;
215     static volatile unsigned int max_outstanding = 0xffffffff;
216 root 1.19 static int respipe_osf [2], respipe [2] = { -1, -1 };
217 root 1.1
218 root 1.12 static mutex_t reslock = X_MUTEX_INIT;
219     static mutex_t reqlock = X_MUTEX_INIT;
220     static cond_t reqwait = X_COND_INIT;
221 root 1.1
222     #if WORDACCESS_UNSAFE
223    
224 root 1.34 static unsigned int get_nready (void)
225 root 1.1 {
226     unsigned int retval;
227    
228 root 1.12 X_LOCK (reqlock);
229 root 1.1 retval = nready;
230 root 1.12 X_UNLOCK (reqlock);
231 root 1.1
232     return retval;
233     }
234    
235 root 1.34 static unsigned int get_npending (void)
236 root 1.1 {
237     unsigned int retval;
238    
239 root 1.12 X_LOCK (reslock);
240 root 1.1 retval = npending;
241 root 1.12 X_UNLOCK (reslock);
242 root 1.1
243     return retval;
244     }
245    
246 root 1.34 static unsigned int get_nthreads (void)
247 root 1.1 {
248     unsigned int retval;
249    
250 root 1.12 X_LOCK (wrklock);
251 root 1.1 retval = started;
252 root 1.12 X_UNLOCK (wrklock);
253 root 1.1
254     return retval;
255     }
256    
257     #else
258    
259     # define get_nready() nready
260     # define get_npending() npending
261     # define get_nthreads() started
262    
263     #endif
264    
265     /*
266     * a somewhat faster data structure might be nice, but
267     * with 8 priorities this actually needs <20 insns
268     * per shift, the most expensive operation.
269     */
270     typedef struct {
271 root 1.28 bdb_req qs[NUM_PRI], qe[NUM_PRI]; /* qstart, qend */
272 root 1.1 int size;
273     } reqq;
274    
275     static reqq req_queue;
276     static reqq res_queue;
277    
278 root 1.28 int reqq_push (reqq *q, bdb_req req)
279 root 1.1 {
280     int pri = req->pri;
281     req->next = 0;
282    
283     if (q->qe[pri])
284     {
285     q->qe[pri]->next = req;
286     q->qe[pri] = req;
287     }
288     else
289     q->qe[pri] = q->qs[pri] = req;
290    
291     return q->size++;
292     }
293    
294 root 1.28 bdb_req reqq_shift (reqq *q)
295 root 1.1 {
296     int pri;
297    
298     if (!q->size)
299     return 0;
300    
301     --q->size;
302    
303     for (pri = NUM_PRI; pri--; )
304     {
305 root 1.28 bdb_req req = q->qs[pri];
306 root 1.1
307     if (req)
308     {
309     if (!(q->qs[pri] = req->next))
310     q->qe[pri] = 0;
311    
312     return req;
313     }
314     }
315    
316     abort ();
317     }
318    
319 root 1.34 static int poll_cb (void);
320 root 1.28 static void req_free (bdb_req req);
321     static void req_cancel (bdb_req req);
322 root 1.1
323 root 1.28 static int req_invoke (bdb_req req)
324 root 1.1 {
325     dSP;
326    
327     if (SvOK (req->callback))
328     {
329     ENTER;
330     SAVETMPS;
331     PUSHMARK (SP);
332    
333     switch (req->type)
334     {
335 root 1.6 case REQ_DB_CLOSE:
336     SvREFCNT_dec (req->sv1);
337     break;
338    
339 root 1.5 case REQ_DB_GET:
340     case REQ_DB_PGET:
341 root 1.6 dbt_to_sv (req->sv3, &req->dbt3);
342 root 1.5 break;
343    
344 root 1.6 case REQ_C_GET:
345     case REQ_C_PGET:
346     dbt_to_sv (req->sv1, &req->dbt1);
347     dbt_to_sv (req->sv2, &req->dbt2);
348     dbt_to_sv (req->sv3, &req->dbt3);
349 root 1.5 break;
350 root 1.8
351 root 1.23 case REQ_DB_PUT:
352     case REQ_C_PUT:
353     dbt_to_sv (0, &req->dbt1);
354     dbt_to_sv (0, &req->dbt2);
355     break;
356    
357 root 1.8 case REQ_DB_KEY_RANGE:
358     {
359     AV *av = newAV ();
360    
361     av_push (av, newSVnv (req->key_range.less));
362     av_push (av, newSVnv (req->key_range.equal));
363     av_push (av, newSVnv (req->key_range.greater));
364    
365     SvREADONLY_off (req->sv1);
366     sv_setsv_mg (req->sv1, newRV_noinc ((SV *)av));
367     SvREFCNT_dec (req->sv1);
368     }
369     break;
370    
371     case REQ_SEQ_GET:
372     SvREADONLY_off (req->sv1);
373    
374     if (sizeof (IV) > 4)
375 root 1.21 sv_setiv_mg (req->sv1, (IV)req->seq_t);
376 root 1.8 else
377 root 1.21 sv_setnv_mg (req->sv1, (NV)req->seq_t);
378 root 1.8
379     SvREFCNT_dec (req->sv1);
380     break;
381 root 1.1 }
382    
383 root 1.3 errno = req->result;
384    
385 root 1.1 PUTBACK;
386     call_sv (req->callback, G_VOID | G_EVAL);
387     SPAGAIN;
388    
389     FREETMPS;
390     LEAVE;
391     }
392    
393     return !SvTRUE (ERRSV);
394     }
395    
396 root 1.28 static void req_free (bdb_req req)
397 root 1.1 {
398 root 1.2 free (req->buf1);
399     free (req->buf2);
400 root 1.1 Safefree (req);
401     }
402    
403 root 1.13 #ifdef USE_SOCKETS_AS_HANDLES
404     # define TO_SOCKET(x) (win32_get_osfhandle (x))
405     #else
406     # define TO_SOCKET(x) (x)
407     #endif
408    
409     static void
410 root 1.34 create_respipe (void)
411 root 1.13 {
412 root 1.21 #ifdef _WIN32
413     int arg; /* argg */
414     #endif
415 root 1.19 int old_readfd = respipe [0];
416    
417     if (respipe [1] >= 0)
418     respipe_close (TO_SOCKET (respipe [1]));
419    
420     #ifdef _WIN32
421     if (PerlSock_socketpair (AF_UNIX, SOCK_STREAM, 0, respipe))
422     #else
423     if (pipe (respipe))
424     #endif
425     croak ("unable to initialize result pipe");
426    
427     if (old_readfd >= 0)
428     {
429     if (dup2 (TO_SOCKET (respipe [0]), TO_SOCKET (old_readfd)) < 0)
430     croak ("unable to initialize result pipe(2)");
431    
432     respipe_close (respipe [0]);
433     respipe [0] = old_readfd;
434     }
435    
436 root 1.13 #ifdef _WIN32
437 root 1.21 arg = 1;
438 root 1.19 if (ioctlsocket (TO_SOCKET (respipe [0]), FIONBIO, &arg)
439     || ioctlsocket (TO_SOCKET (respipe [1]), FIONBIO, &arg))
440 root 1.13 #else
441 root 1.19 if (fcntl (respipe [0], F_SETFL, O_NONBLOCK)
442     || fcntl (respipe [1], F_SETFL, O_NONBLOCK))
443 root 1.13 #endif
444 root 1.19 croak ("unable to initialize result pipe(3)");
445 root 1.13
446     respipe_osf [0] = TO_SOCKET (respipe [0]);
447     respipe_osf [1] = TO_SOCKET (respipe [1]);
448     }
449    
450     X_THREAD_PROC (bdb_proc);
451 root 1.1
452     static void start_thread (void)
453     {
454     worker *wrk = calloc (1, sizeof (worker));
455    
456     if (!wrk)
457     croak ("unable to allocate worker thread data");
458    
459 root 1.12 X_LOCK (wrklock);
460 root 1.13 if (thread_create (&wrk->tid, bdb_proc, (void *)wrk))
461 root 1.1 {
462     wrk->prev = &wrk_first;
463     wrk->next = wrk_first.next;
464     wrk_first.next->prev = wrk;
465     wrk_first.next = wrk;
466     ++started;
467     }
468     else
469     free (wrk);
470    
471 root 1.12 X_UNLOCK (wrklock);
472 root 1.1 }
473    
474 root 1.34 static void maybe_start_thread (void)
475 root 1.1 {
476     if (get_nthreads () >= wanted)
477     return;
478    
479     /* todo: maybe use idle here, but might be less exact */
480     if (0 <= (int)get_nthreads () + (int)get_npending () - (int)nreqs)
481     return;
482    
483     start_thread ();
484     }
485    
486 root 1.28 static void req_send (bdb_req req)
487 root 1.1 {
488 root 1.3 SV *wait_callback = 0;
489    
490     // synthesize callback if none given
491     if (!SvOK (req->callback))
492     {
493 root 1.13 int count;
494    
495 root 1.3 dSP;
496     PUSHMARK (SP);
497     PUTBACK;
498 root 1.13 count = call_sv (prepare_cb, G_ARRAY);
499 root 1.3 SPAGAIN;
500    
501     if (count != 2)
502     croak ("prepare callback must return exactly two values\n");
503    
504 root 1.27 wait_callback = POPs;
505 root 1.3 SvREFCNT_dec (req->callback);
506     req->callback = SvREFCNT_inc (POPs);
507     }
508    
509 root 1.1 ++nreqs;
510    
511 root 1.12 X_LOCK (reqlock);
512 root 1.1 ++nready;
513     reqq_push (&req_queue, req);
514 root 1.12 X_COND_SIGNAL (reqwait);
515     X_UNLOCK (reqlock);
516 root 1.1
517     maybe_start_thread ();
518 root 1.3
519     if (wait_callback)
520     {
521     dSP;
522     PUSHMARK (SP);
523     PUTBACK;
524     call_sv (wait_callback, G_DISCARD);
525     }
526 root 1.1 }
527    
528     static void end_thread (void)
529     {
530 root 1.28 bdb_req req;
531 root 1.1
532 root 1.28 Newz (0, req, 1, bdb_cb);
533 root 1.1
534     req->type = REQ_QUIT;
535     req->pri = PRI_MAX + PRI_BIAS;
536    
537 root 1.12 X_LOCK (reqlock);
538 root 1.1 reqq_push (&req_queue, req);
539 root 1.12 X_COND_SIGNAL (reqwait);
540     X_UNLOCK (reqlock);
541 root 1.1
542 root 1.12 X_LOCK (wrklock);
543 root 1.1 --started;
544 root 1.12 X_UNLOCK (wrklock);
545 root 1.1 }
546    
547     static void set_max_idle (int nthreads)
548     {
549 root 1.12 if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
550 root 1.1 max_idle = nthreads <= 0 ? 1 : nthreads;
551 root 1.12 if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
552 root 1.1 }
553    
554     static void min_parallel (int nthreads)
555     {
556     if (wanted < nthreads)
557     wanted = nthreads;
558     }
559    
560     static void max_parallel (int nthreads)
561     {
562     if (wanted > nthreads)
563     wanted = nthreads;
564    
565     while (started > wanted)
566     end_thread ();
567     }
568    
569 root 1.34 static void poll_wait (void)
570 root 1.1 {
571     fd_set rfd;
572    
573     while (nreqs)
574     {
575     int size;
576 root 1.12 if (WORDACCESS_UNSAFE) X_LOCK (reslock);
577 root 1.1 size = res_queue.size;
578 root 1.12 if (WORDACCESS_UNSAFE) X_UNLOCK (reslock);
579 root 1.1
580     if (size)
581     return;
582    
583     maybe_start_thread ();
584    
585 root 1.13 FD_ZERO (&rfd);
586     FD_SET (respipe [0], &rfd);
587 root 1.1
588 root 1.13 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0);
589 root 1.1 }
590     }
591    
592 root 1.34 static int poll_cb (void)
593 root 1.1 {
594     dSP;
595     int count = 0;
596     int maxreqs = max_poll_reqs;
597     int do_croak = 0;
598     struct timeval tv_start, tv_now;
599 root 1.28 bdb_req req;
600 root 1.1
601     if (max_poll_time)
602     gettimeofday (&tv_start, 0);
603    
604     for (;;)
605     {
606     for (;;)
607     {
608     maybe_start_thread ();
609    
610 root 1.12 X_LOCK (reslock);
611 root 1.1 req = reqq_shift (&res_queue);
612    
613     if (req)
614     {
615     --npending;
616    
617     if (!res_queue.size)
618     {
619     /* read any signals sent by the worker threads */
620     char buf [4];
621 root 1.13 while (respipe_read (respipe [0], buf, 4) == 4)
622 root 1.1 ;
623     }
624     }
625    
626 root 1.12 X_UNLOCK (reslock);
627 root 1.1
628     if (!req)
629     break;
630    
631     --nreqs;
632    
633     if (!req_invoke (req))
634     {
635     req_free (req);
636     croak (0);
637     }
638    
639     count++;
640    
641     req_free (req);
642    
643     if (maxreqs && !--maxreqs)
644     break;
645    
646     if (max_poll_time)
647     {
648     gettimeofday (&tv_now, 0);
649    
650     if (tvdiff (&tv_start, &tv_now) >= max_poll_time)
651     break;
652     }
653     }
654    
655     if (nreqs <= max_outstanding)
656     break;
657    
658     poll_wait ();
659    
660     ++maxreqs;
661     }
662    
663     return count;
664     }
665    
666     /*****************************************************************************/
667    
668 root 1.13 X_THREAD_PROC (bdb_proc)
669 root 1.1 {
670 root 1.28 bdb_req req;
671 root 1.1 struct timespec ts;
672     worker *self = (worker *)thr_arg;
673    
674     /* try to distribute timeouts somewhat evenly */
675 root 1.13 ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL);
676 root 1.1
677     for (;;)
678     {
679     ts.tv_sec = time (0) + IDLE_TIMEOUT;
680    
681 root 1.12 X_LOCK (reqlock);
682 root 1.1
683     for (;;)
684     {
685     self->req = req = reqq_shift (&req_queue);
686    
687     if (req)
688     break;
689    
690     ++idle;
691    
692 root 1.12 if (X_COND_TIMEDWAIT (reqwait, reqlock, ts)
693 root 1.1 == ETIMEDOUT)
694     {
695     if (idle > max_idle)
696     {
697     --idle;
698 root 1.12 X_UNLOCK (reqlock);
699     X_LOCK (wrklock);
700 root 1.1 --started;
701 root 1.12 X_UNLOCK (wrklock);
702 root 1.1 goto quit;
703     }
704    
705     /* we are allowed to idle, so do so without any timeout */
706 root 1.12 X_COND_WAIT (reqwait, reqlock);
707 root 1.1 ts.tv_sec = time (0) + IDLE_TIMEOUT;
708     }
709    
710     --idle;
711     }
712    
713     --nready;
714    
715 root 1.12 X_UNLOCK (reqlock);
716 root 1.1
717     switch (req->type)
718     {
719     case REQ_QUIT:
720 root 1.17 req->result = ENOSYS;
721 root 1.1 goto quit;
722    
723 root 1.3 case REQ_ENV_OPEN:
724     req->result = req->env->open (req->env, req->buf1, req->uint1, req->int1);
725     break;
726    
727     case REQ_ENV_CLOSE:
728     req->result = req->env->close (req->env, req->uint1);
729     break;
730    
731 root 1.8 case REQ_ENV_TXN_CHECKPOINT:
732     req->result = req->env->txn_checkpoint (req->env, req->uint1, req->int1, req->uint2);
733     break;
734    
735     case REQ_ENV_LOCK_DETECT:
736     req->result = req->env->lock_detect (req->env, req->uint1, req->uint2, &req->int1);
737     break;
738    
739     case REQ_ENV_MEMP_SYNC:
740     req->result = req->env->memp_sync (req->env, 0);
741     break;
742    
743     case REQ_ENV_MEMP_TRICKLE:
744     req->result = req->env->memp_trickle (req->env, req->int1, &req->int2);
745     break;
746    
747 root 1.3 case REQ_DB_OPEN:
748     req->result = req->db->open (req->db, req->txn, req->buf1, req->buf2, req->int1, req->uint1, req->int2);
749     break;
750    
751     case REQ_DB_CLOSE:
752     req->result = req->db->close (req->db, req->uint1);
753     break;
754    
755     case REQ_DB_COMPACT:
756     req->result = req->db->compact (req->db, req->txn, &req->dbt1, &req->dbt2, 0, req->uint1, 0);
757     break;
758    
759     case REQ_DB_SYNC:
760     req->result = req->db->sync (req->db, req->uint1);
761     break;
762    
763 root 1.26 case REQ_DB_UPGRADE:
764     req->result = req->db->upgrade (req->db, req->buf1, req->uint1);
765     break;
766    
767 root 1.3 case REQ_DB_PUT:
768     req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1);
769     break;
770    
771 root 1.5 case REQ_DB_GET:
772     req->result = req->db->get (req->db, req->txn, &req->dbt1, &req->dbt3, req->uint1);
773     break;
774    
775     case REQ_DB_PGET:
776     req->result = req->db->pget (req->db, req->txn, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1);
777     break;
778    
779 root 1.6 case REQ_DB_DEL:
780     req->result = req->db->del (req->db, req->txn, &req->dbt1, req->uint1);
781     break;
782    
783 root 1.8 case REQ_DB_KEY_RANGE:
784     req->result = req->db->key_range (req->db, req->txn, &req->dbt1, &req->key_range, req->uint1);
785     break;
786    
787 root 1.5 case REQ_TXN_COMMIT:
788     req->result = req->txn->commit (req->txn, req->uint1);
789     break;
790    
791     case REQ_TXN_ABORT:
792     req->result = req->txn->abort (req->txn);
793     break;
794    
795 root 1.17 case REQ_TXN_FINISH:
796     if (req->txn->flags & TXN_DEADLOCK)
797     {
798     req->result = req->txn->abort (req->txn);
799     if (!req->result)
800     req->result = DB_LOCK_DEADLOCK;
801     }
802 root 1.18 else
803     req->result = req->txn->commit (req->txn, req->uint1);
804 root 1.17 break;
805    
806 root 1.6 case REQ_C_CLOSE:
807     req->result = req->dbc->c_close (req->dbc);
808     break;
809    
810     case REQ_C_COUNT:
811     {
812     db_recno_t recno;
813     req->result = req->dbc->c_count (req->dbc, &recno, req->uint1);
814     req->uv1 = recno;
815     }
816     break;
817    
818     case REQ_C_PUT:
819     req->result = req->dbc->c_put (req->dbc, &req->dbt1, &req->dbt2, req->uint1);
820     break;
821    
822     case REQ_C_GET:
823     req->result = req->dbc->c_get (req->dbc, &req->dbt1, &req->dbt3, req->uint1);
824     break;
825    
826     case REQ_C_PGET:
827     req->result = req->dbc->c_pget (req->dbc, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1);
828     break;
829    
830     case REQ_C_DEL:
831     req->result = req->dbc->c_del (req->dbc, req->uint1);
832     break;
833    
834 root 1.8 case REQ_SEQ_OPEN:
835     req->result = req->seq->open (req->seq, req->txn, &req->dbt1, req->uint1);
836     break;
837    
838     case REQ_SEQ_CLOSE:
839     req->result = req->seq->close (req->seq, req->uint1);
840     break;
841    
842     case REQ_SEQ_GET:
843     req->result = req->seq->get (req->seq, req->txn, req->int1, &req->seq_t, req->uint1);
844     break;
845    
846     case REQ_SEQ_REMOVE:
847     req->result = req->seq->remove (req->seq, req->txn, req->uint1);
848     break;
849    
850 root 1.1 default:
851 root 1.3 req->result = ENOSYS;
852 root 1.1 break;
853     }
854    
855 root 1.17 if (req->txn && (req->result > 0 || req->result == DB_LOCK_NOTGRANTED))
856     req->txn->flags |= TXN_DEADLOCK;
857    
858 root 1.12 X_LOCK (reslock);
859 root 1.1
860     ++npending;
861    
862     if (!reqq_push (&res_queue, req))
863     /* write a dummy byte to the pipe so fh becomes ready */
864 root 1.13 respipe_write (respipe_osf [1], (const void *)&respipe_osf, 1);
865 root 1.1
866     self->req = 0;
867     worker_clear (self);
868    
869 root 1.12 X_UNLOCK (reslock);
870 root 1.1 }
871    
872     quit:
873 root 1.12 X_LOCK (wrklock);
874 root 1.1 worker_free (self);
875 root 1.12 X_UNLOCK (wrklock);
876 root 1.1
877     return 0;
878     }
879    
880     /*****************************************************************************/
881    
882     static void atfork_prepare (void)
883     {
884 root 1.12 X_LOCK (wrklock);
885     X_LOCK (reqlock);
886     X_LOCK (reslock);
887 root 1.1 }
888    
889     static void atfork_parent (void)
890     {
891 root 1.12 X_UNLOCK (reslock);
892     X_UNLOCK (reqlock);
893     X_UNLOCK (wrklock);
894 root 1.1 }
895    
896     static void atfork_child (void)
897     {
898 root 1.28 bdb_req prv;
899 root 1.1
900     while (prv = reqq_shift (&req_queue))
901     req_free (prv);
902    
903     while (prv = reqq_shift (&res_queue))
904     req_free (prv);
905    
906     while (wrk_first.next != &wrk_first)
907     {
908     worker *wrk = wrk_first.next;
909    
910     if (wrk->req)
911     req_free (wrk->req);
912    
913     worker_clear (wrk);
914     worker_free (wrk);
915     }
916    
917     started = 0;
918     idle = 0;
919     nreqs = 0;
920     nready = 0;
921     npending = 0;
922    
923 root 1.19 create_respipe ();
924 root 1.1
925     atfork_parent ();
926     }
927    
928 root 1.2 #define dREQ(reqtype) \
929 root 1.28 bdb_req req; \
930 root 1.1 int req_pri = next_pri; \
931     next_pri = DEFAULT_PRI + PRI_BIAS; \
932     \
933     if (SvOK (callback) && !SvROK (callback)) \
934     croak ("callback must be undef or of reference type"); \
935     \
936 root 1.28 Newz (0, req, 1, bdb_cb); \
937 root 1.1 if (!req) \
938 root 1.28 croak ("out of memory during bdb_req allocation"); \
939 root 1.1 \
940     req->callback = newSVsv (callback); \
941 root 1.2 req->type = (reqtype); \
942 root 1.1 req->pri = req_pri
943    
944     #define REQ_SEND \
945 root 1.2 req_send (req)
946    
947 root 1.30 #define SvPTR(var, arg, type, class, nullok) \
948 root 1.5 if (!SvOK (arg)) \
949     { \
950 root 1.30 if (nullok != 1) \
951 root 1.7 croak (# var " must be a " # class " object, not undef"); \
952 root 1.5 \
953     (var) = 0; \
954     } \
955     else if (sv_derived_from ((arg), # class)) \
956     { \
957     IV tmp = SvIV ((SV*) SvRV (arg)); \
958     (var) = INT2PTR (type, tmp); \
959 root 1.30 if (!var && nullok != 2) \
960 root 1.7 croak (# var " is not a valid " # class " object anymore"); \
961 root 1.5 } \
962     else \
963 root 1.7 croak (# var " is not of type " # class); \
964 root 1.5 \
965 root 1.3
966 root 1.5 static void
967     ptr_nuke (SV *sv)
968 root 1.3 {
969 root 1.5 assert (SvROK (sv));
970     sv_setiv (SvRV (sv), 0);
971     }
972 root 1.3
973 root 1.31 static int
974     errno_get (pTHX_ SV *sv, MAGIC *mg)
975     {
976     if (*mg->mg_ptr == '!') // should always be the case
977     if (-30999 <= errno && errno <= -30800)
978     {
979 root 1.32 sv_setnv (sv, (NV)errno);
980 root 1.31 sv_setpv (sv, db_strerror (errno));
981 root 1.32 SvNOK_on (sv); /* what a wonderful hack! */
982     // ^^^ copied from perl sources
983 root 1.31 return 0;
984     }
985    
986     return PL_vtbl_sv.svt_get (aTHX_ sv, mg);
987     }
988    
989     static MGVTBL vtbl_errno;
990    
991     // this wonderful hack :( patches perl's $! variable to support our errno values
992     static void
993     patch_errno (void)
994     {
995     SV *sv;
996     MAGIC *mg;
997    
998     if (!(sv = get_sv ("!", 1)))
999     return;
1000    
1001     if (!(mg = mg_find (sv, PERL_MAGIC_sv)))
1002     return;
1003    
1004     if (mg->mg_virtual != &PL_vtbl_sv)
1005     return;
1006    
1007     vtbl_errno = PL_vtbl_sv;
1008     vtbl_errno.svt_get = errno_get;
1009     mg->mg_virtual = &vtbl_errno;
1010     }
1011    
1012 root 1.2 MODULE = BDB PACKAGE = BDB
1013 root 1.1
1014     PROTOTYPES: ENABLE
1015    
1016     BOOT:
1017     {
1018 root 1.2 HV *stash = gv_stashpv ("BDB", 1);
1019    
1020     static const struct {
1021     const char *name;
1022     IV iv;
1023     } *civ, const_iv[] = {
1024     #define const_iv(name) { # name, (IV)DB_ ## name },
1025     const_iv (RPCCLIENT)
1026     const_iv (INIT_CDB)
1027     const_iv (INIT_LOCK)
1028     const_iv (INIT_LOG)
1029     const_iv (INIT_MPOOL)
1030     const_iv (INIT_REP)
1031     const_iv (INIT_TXN)
1032     const_iv (RECOVER)
1033     const_iv (INIT_TXN)
1034     const_iv (RECOVER_FATAL)
1035     const_iv (CREATE)
1036 root 1.20 const_iv (RDONLY)
1037 root 1.2 const_iv (USE_ENVIRON)
1038     const_iv (USE_ENVIRON_ROOT)
1039     const_iv (LOCKDOWN)
1040     const_iv (PRIVATE)
1041     const_iv (REGISTER)
1042     const_iv (SYSTEM_MEM)
1043     const_iv (AUTO_COMMIT)
1044     const_iv (CDB_ALLDB)
1045     const_iv (DIRECT_DB)
1046     const_iv (DIRECT_LOG)
1047     const_iv (DSYNC_DB)
1048     const_iv (DSYNC_LOG)
1049     const_iv (LOG_AUTOREMOVE)
1050     const_iv (LOG_INMEMORY)
1051     const_iv (NOLOCKING)
1052     const_iv (NOMMAP)
1053     const_iv (NOPANIC)
1054     const_iv (OVERWRITE)
1055     const_iv (PANIC_ENVIRONMENT)
1056     const_iv (REGION_INIT)
1057     const_iv (TIME_NOTGRANTED)
1058     const_iv (TXN_NOSYNC)
1059 root 1.20 const_iv (TXN_NOT_DURABLE)
1060 root 1.2 const_iv (TXN_WRITE_NOSYNC)
1061 root 1.5 const_iv (WRITECURSOR)
1062 root 1.2 const_iv (YIELDCPU)
1063     const_iv (ENCRYPT_AES)
1064     const_iv (XA_CREATE)
1065     const_iv (BTREE)
1066     const_iv (HASH)
1067     const_iv (QUEUE)
1068     const_iv (RECNO)
1069     const_iv (UNKNOWN)
1070     const_iv (EXCL)
1071 root 1.4 const_iv (READ_COMMITTED)
1072 root 1.2 const_iv (READ_UNCOMMITTED)
1073     const_iv (TRUNCATE)
1074     const_iv (NOSYNC)
1075     const_iv (CHKSUM)
1076     const_iv (ENCRYPT)
1077     const_iv (DUP)
1078     const_iv (DUPSORT)
1079     const_iv (RECNUM)
1080     const_iv (RENUMBER)
1081     const_iv (REVSPLITOFF)
1082     const_iv (INORDER)
1083     const_iv (CONSUME)
1084     const_iv (CONSUME_WAIT)
1085 root 1.5 const_iv (GET_BOTH)
1086 root 1.6 const_iv (GET_BOTH_RANGE)
1087 root 1.5 //const_iv (SET_RECNO)
1088     //const_iv (MULTIPLE)
1089 root 1.2 const_iv (SNAPSHOT)
1090     const_iv (JOIN_ITEM)
1091 root 1.27 const_iv (JOIN_NOSORT)
1092 root 1.2 const_iv (RMW)
1093    
1094     const_iv (NOTFOUND)
1095     const_iv (KEYEMPTY)
1096     const_iv (LOCK_DEADLOCK)
1097     const_iv (LOCK_NOTGRANTED)
1098     const_iv (RUNRECOVERY)
1099 root 1.3 const_iv (OLD_VERSION)
1100     const_iv (REP_HANDLE_DEAD)
1101     const_iv (REP_LOCKOUT)
1102 root 1.6 const_iv (SECONDARY_BAD)
1103 root 1.3
1104     const_iv (FREE_SPACE)
1105     const_iv (FREELIST_ONLY)
1106    
1107     const_iv (APPEND)
1108     const_iv (NODUPDATA)
1109     const_iv (NOOVERWRITE)
1110    
1111 root 1.4 const_iv (TXN_NOWAIT)
1112     const_iv (TXN_SYNC)
1113    
1114 root 1.3 const_iv (SET_LOCK_TIMEOUT)
1115     const_iv (SET_TXN_TIMEOUT)
1116 root 1.6
1117     const_iv (FIRST)
1118     const_iv (NEXT)
1119     const_iv (NEXT_DUP)
1120     const_iv (NEXT_NODUP)
1121     const_iv (PREV)
1122     const_iv (PREV_NODUP)
1123     const_iv (SET)
1124     const_iv (SET_RANGE)
1125     const_iv (LAST)
1126     const_iv (BEFORE)
1127     const_iv (AFTER)
1128     const_iv (CURRENT)
1129     const_iv (KEYFIRST)
1130     const_iv (KEYLAST)
1131     const_iv (NODUPDATA)
1132 root 1.8
1133     const_iv (FORCE)
1134    
1135     const_iv (LOCK_DEFAULT)
1136     const_iv (LOCK_EXPIRE)
1137     const_iv (LOCK_MAXLOCKS)
1138     const_iv (LOCK_MAXWRITE)
1139     const_iv (LOCK_MINLOCKS)
1140     const_iv (LOCK_MINWRITE)
1141     const_iv (LOCK_OLDEST)
1142     const_iv (LOCK_RANDOM)
1143     const_iv (LOCK_YOUNGEST)
1144    
1145     const_iv (SEQ_DEC)
1146     const_iv (SEQ_INC)
1147     const_iv (SEQ_WRAP)
1148 root 1.14
1149     const_iv (BUFFER_SMALL)
1150     const_iv (DONOTINDEX)
1151     const_iv (KEYEMPTY )
1152     const_iv (KEYEXIST )
1153     const_iv (LOCK_DEADLOCK)
1154     const_iv (LOCK_NOTGRANTED)
1155     const_iv (LOG_BUFFER_FULL)
1156     const_iv (NOSERVER)
1157     const_iv (NOSERVER_HOME)
1158     const_iv (NOSERVER_ID)
1159     const_iv (NOTFOUND)
1160     const_iv (PAGE_NOTFOUND)
1161     const_iv (REP_DUPMASTER)
1162     const_iv (REP_HANDLE_DEAD)
1163     const_iv (REP_HOLDELECTION)
1164     const_iv (REP_IGNORE)
1165     const_iv (REP_ISPERM)
1166     const_iv (REP_JOIN_FAILURE)
1167     const_iv (REP_LOCKOUT)
1168     const_iv (REP_NEWMASTER)
1169     const_iv (REP_NEWSITE)
1170     const_iv (REP_NOTPERM)
1171     const_iv (REP_UNAVAIL)
1172     const_iv (RUNRECOVERY)
1173     const_iv (SECONDARY_BAD)
1174     const_iv (VERIFY_BAD)
1175     const_iv (VERSION_MISMATCH)
1176    
1177     const_iv (VERB_DEADLOCK)
1178     const_iv (VERB_RECOVERY)
1179     const_iv (VERB_REGISTER)
1180     const_iv (VERB_REPLICATION)
1181     const_iv (VERB_WAITSFOR)
1182    
1183     const_iv (VERSION_MAJOR)
1184     const_iv (VERSION_MINOR)
1185     const_iv (VERSION_PATCH)
1186 root 1.13 #if DB_VERSION_MINOR >= 5
1187     const_iv (MULTIVERSION)
1188     const_iv (TXN_SNAPSHOT)
1189     #endif
1190 root 1.15 #if DB_VERSION_MINOR >= 6
1191 root 1.16 const_iv (PREV_DUP)
1192     const_iv (PRIORITY_UNCHANGED)
1193     const_iv (PRIORITY_VERY_LOW)
1194     const_iv (PRIORITY_LOW)
1195     const_iv (PRIORITY_DEFAULT)
1196     const_iv (PRIORITY_HIGH)
1197     const_iv (PRIORITY_VERY_HIGH)
1198 root 1.15 #endif
1199 root 1.2 };
1200    
1201     for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1202     newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1203 root 1.1
1204 root 1.24 newCONSTSUB (stash, "VERSION", newSVnv (DB_VERSION_MAJOR + DB_VERSION_MINOR * .1));
1205     newCONSTSUB (stash, "VERSION_STRING", newSVpv (DB_VERSION_STRING, 0));
1206 root 1.14
1207 root 1.19 create_respipe ();
1208 root 1.12
1209     X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child);
1210     #ifdef _WIN32
1211     X_MUTEX_CHECK (wrklock);
1212     X_MUTEX_CHECK (reslock);
1213     X_MUTEX_CHECK (reqlock);
1214    
1215     X_COND_CHECK (reqwait);
1216     #endif
1217 root 1.31 patch_errno ();
1218 root 1.1 }
1219    
1220     void
1221     max_poll_reqs (int nreqs)
1222     PROTOTYPE: $
1223     CODE:
1224     max_poll_reqs = nreqs;
1225    
1226     void
1227     max_poll_time (double nseconds)
1228     PROTOTYPE: $
1229     CODE:
1230     max_poll_time = nseconds * AIO_TICKS;
1231    
1232     void
1233     min_parallel (int nthreads)
1234     PROTOTYPE: $
1235    
1236     void
1237     max_parallel (int nthreads)
1238     PROTOTYPE: $
1239    
1240     void
1241     max_idle (int nthreads)
1242     PROTOTYPE: $
1243     CODE:
1244     set_max_idle (nthreads);
1245    
1246     int
1247     max_outstanding (int maxreqs)
1248     PROTOTYPE: $
1249     CODE:
1250     RETVAL = max_outstanding;
1251     max_outstanding = maxreqs;
1252     OUTPUT:
1253     RETVAL
1254    
1255     int
1256 root 1.3 dbreq_pri (int pri = 0)
1257 root 1.1 PROTOTYPE: ;$
1258     CODE:
1259     RETVAL = next_pri - PRI_BIAS;
1260     if (items > 0)
1261     {
1262     if (pri < PRI_MIN) pri = PRI_MIN;
1263     if (pri > PRI_MAX) pri = PRI_MAX;
1264     next_pri = pri + PRI_BIAS;
1265     }
1266     OUTPUT:
1267     RETVAL
1268    
1269     void
1270 root 1.3 dbreq_nice (int nice = 0)
1271 root 1.1 CODE:
1272     nice = next_pri - nice;
1273     if (nice < PRI_MIN) nice = PRI_MIN;
1274     if (nice > PRI_MAX) nice = PRI_MAX;
1275     next_pri = nice + PRI_BIAS;
1276    
1277     void
1278     flush ()
1279     PROTOTYPE:
1280     CODE:
1281     while (nreqs)
1282     {
1283     poll_wait ();
1284     poll_cb ();
1285     }
1286    
1287     int
1288 root 1.3 poll ()
1289 root 1.1 PROTOTYPE:
1290     CODE:
1291     poll_wait ();
1292     RETVAL = poll_cb ();
1293     OUTPUT:
1294     RETVAL
1295    
1296     int
1297 root 1.3 poll_fileno ()
1298 root 1.1 PROTOTYPE:
1299     CODE:
1300     RETVAL = respipe [0];
1301     OUTPUT:
1302     RETVAL
1303    
1304     int
1305 root 1.3 poll_cb (...)
1306 root 1.1 PROTOTYPE:
1307     CODE:
1308     RETVAL = poll_cb ();
1309     OUTPUT:
1310     RETVAL
1311    
1312     void
1313 root 1.3 poll_wait ()
1314 root 1.1 PROTOTYPE:
1315     CODE:
1316     poll_wait ();
1317    
1318     int
1319 root 1.3 nreqs ()
1320 root 1.1 PROTOTYPE:
1321     CODE:
1322     RETVAL = nreqs;
1323     OUTPUT:
1324     RETVAL
1325    
1326     int
1327 root 1.3 nready ()
1328 root 1.1 PROTOTYPE:
1329     CODE:
1330     RETVAL = get_nready ();
1331     OUTPUT:
1332     RETVAL
1333    
1334     int
1335 root 1.3 npending ()
1336 root 1.1 PROTOTYPE:
1337     CODE:
1338     RETVAL = get_npending ();
1339     OUTPUT:
1340     RETVAL
1341    
1342     int
1343 root 1.3 nthreads ()
1344 root 1.1 PROTOTYPE:
1345     CODE:
1346 root 1.12 if (WORDACCESS_UNSAFE) X_LOCK (wrklock);
1347 root 1.1 RETVAL = started;
1348 root 1.12 if (WORDACCESS_UNSAFE) X_UNLOCK (wrklock);
1349 root 1.1 OUTPUT:
1350     RETVAL
1351    
1352 root 1.3 void
1353     set_sync_prepare (SV *cb)
1354     PROTOTYPE: &
1355     CODE:
1356     SvREFCNT_dec (prepare_cb);
1357     prepare_cb = newSVsv (cb);
1358    
1359 root 1.14 char *
1360     strerror (int errorno = errno)
1361     PROTOTYPE: ;$
1362     CODE:
1363     RETVAL = db_strerror (errorno);
1364     OUTPUT:
1365     RETVAL
1366 root 1.8
1367 root 1.2 DB_ENV *
1368 root 1.3 db_env_create (U32 env_flags = 0)
1369 root 1.2 CODE:
1370     {
1371 root 1.3 errno = db_env_create (&RETVAL, env_flags);
1372     if (errno)
1373     croak ("db_env_create: %s", db_strerror (errno));
1374 root 1.14
1375     if (0)
1376     {
1377     RETVAL->set_errcall (RETVAL, debug_errcall);
1378     RETVAL->set_msgcall (RETVAL, debug_msgcall);
1379     }
1380 root 1.2 }
1381 root 1.3 OUTPUT:
1382     RETVAL
1383 root 1.2
1384     void
1385 root 1.33 db_env_open (DB_ENV *env, bdb_filename db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef)
1386 root 1.2 CODE:
1387     {
1388 root 1.13 dREQ (REQ_ENV_OPEN);
1389    
1390 root 1.2 req->env = env;
1391 root 1.3 req->uint1 = open_flags | DB_THREAD;
1392 root 1.2 req->int1 = mode;
1393 root 1.3 req->buf1 = strdup_ornull (db_home);
1394 root 1.2 REQ_SEND;
1395     }
1396    
1397     void
1398 root 1.3 db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = &PL_sv_undef)
1399 root 1.2 CODE:
1400     {
1401     dREQ (REQ_ENV_CLOSE);
1402     req->env = env;
1403     req->uint1 = flags;
1404     REQ_SEND;
1405 root 1.5 ptr_nuke (ST (0));
1406 root 1.2 }
1407    
1408 root 1.8 void
1409     db_env_txn_checkpoint (DB_ENV *env, U32 kbyte = 0, U32 min = 0, U32 flags = 0, SV *callback = &PL_sv_undef)
1410     CODE:
1411     {
1412     dREQ (REQ_ENV_TXN_CHECKPOINT);
1413     req->env = env;
1414     req->uint1 = kbyte;
1415     req->int1 = min;
1416     req->uint2 = flags;
1417     REQ_SEND;
1418     }
1419    
1420     void
1421     db_env_lock_detect (DB_ENV *env, U32 flags = 0, U32 atype = DB_LOCK_DEFAULT, SV *dummy = 0, SV *callback = &PL_sv_undef)
1422     CODE:
1423     {
1424     dREQ (REQ_ENV_LOCK_DETECT);
1425     req->env = env;
1426     req->uint1 = flags;
1427     req->uint2 = atype;
1428     REQ_SEND;
1429     }
1430    
1431     void
1432     db_env_memp_sync (DB_ENV *env, SV *dummy = 0, SV *callback = &PL_sv_undef)
1433     CODE:
1434     {
1435     dREQ (REQ_ENV_MEMP_SYNC);
1436     req->env = env;
1437     REQ_SEND;
1438     }
1439    
1440     void
1441     db_env_memp_trickle (DB_ENV *env, int percent, SV *dummy = 0, SV *callback = &PL_sv_undef)
1442     CODE:
1443     {
1444     dREQ (REQ_ENV_MEMP_TRICKLE);
1445     req->env = env;
1446     req->int1 = percent;
1447     REQ_SEND;
1448     }
1449    
1450    
1451 root 1.2 DB *
1452 root 1.3 db_create (DB_ENV *env = 0, U32 flags = 0)
1453 root 1.2 CODE:
1454     {
1455 root 1.3 errno = db_create (&RETVAL, env, flags);
1456     if (errno)
1457 root 1.6 croak ("db_create: %s", db_strerror (errno));
1458 root 1.5
1459     if (RETVAL)
1460     RETVAL->app_private = (void *)newSVsv (ST (0));
1461 root 1.2 }
1462 root 1.3 OUTPUT:
1463     RETVAL
1464 root 1.2
1465     void
1466 root 1.33 db_open (DB *db, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef)
1467 root 1.2 CODE:
1468     {
1469     dREQ (REQ_DB_OPEN);
1470     req->db = db;
1471     req->txn = txnid;
1472 root 1.3 req->buf1 = strdup_ornull (file);
1473     req->buf2 = strdup_ornull (database);
1474 root 1.2 req->int1 = type;
1475 root 1.3 req->uint1 = flags | DB_THREAD;
1476 root 1.2 req->int2 = mode;
1477     REQ_SEND;
1478     }
1479    
1480     void
1481 root 1.3 db_close (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1482 root 1.2 CODE:
1483     {
1484     dREQ (REQ_DB_CLOSE);
1485     req->db = db;
1486     req->uint1 = flags;
1487 root 1.5 req->sv1 = (SV *)db->app_private;
1488 root 1.2 REQ_SEND;
1489 root 1.5 ptr_nuke (ST (0));
1490 root 1.2 }
1491    
1492 root 1.3 void
1493 root 1.5 db_compact (DB *db, DB_TXN_ornull *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = &PL_sv_undef)
1494 root 1.3 CODE:
1495     {
1496     dREQ (REQ_DB_COMPACT);
1497     req->db = db;
1498     req->txn = txn;
1499 root 1.5 sv_to_dbt (&req->dbt1, start);
1500     sv_to_dbt (&req->dbt2, stop);
1501 root 1.3 req->uint1 = flags;
1502     REQ_SEND;
1503     }
1504    
1505     void
1506     db_sync (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1507     CODE:
1508     {
1509     dREQ (REQ_DB_SYNC);
1510     req->db = db;
1511     req->uint1 = flags;
1512     REQ_SEND;
1513     }
1514    
1515     void
1516 root 1.33 db_upgrade (DB *db, bdb_filename file, U32 flags = 0, SV *callback = &PL_sv_undef)
1517 root 1.26 CODE:
1518     {
1519     dREQ (REQ_DB_SYNC);
1520     req->db = db;
1521     req->buf1 = strdup (file);
1522     req->uint1 = flags;
1523     REQ_SEND;
1524     }
1525    
1526     void
1527 root 1.8 db_key_range (DB *db, DB_TXN_ornull *txn, SV *key, SV *key_range, U32 flags = 0, SV *callback = &PL_sv_undef)
1528     CODE:
1529     {
1530     dREQ (REQ_DB_KEY_RANGE);
1531     req->db = db;
1532     req->txn = txn;
1533     sv_to_dbt (&req->dbt1, key);
1534     req->uint1 = flags;
1535     req->sv1 = SvREFCNT_inc (key_range); SvREADONLY_on (key_range);
1536     REQ_SEND;
1537     }
1538    
1539     void
1540 root 1.5 db_put (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1541 root 1.3 CODE:
1542     {
1543     dREQ (REQ_DB_PUT);
1544     req->db = db;
1545 root 1.5 req->txn = txn;
1546     sv_to_dbt (&req->dbt1, key);
1547     sv_to_dbt (&req->dbt2, data);
1548 root 1.3 req->uint1 = flags;
1549     REQ_SEND;
1550     }
1551    
1552 root 1.5 void
1553     db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1554     CODE:
1555 root 1.27 if (SvREADONLY (data))
1556     croak ("can't modify read-only data scalar in db_get");
1557 root 1.28 {
1558 root 1.5 dREQ (REQ_DB_GET);
1559     req->db = db;
1560     req->txn = txn;
1561 root 1.6 req->uint1 = flags;
1562 root 1.5 sv_to_dbt (&req->dbt1, key);
1563     req->dbt3.flags = DB_DBT_MALLOC;
1564 root 1.6 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1565 root 1.5 REQ_SEND;
1566     }
1567    
1568     void
1569     db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1570     CODE:
1571 root 1.27 if (SvREADONLY (data))
1572     croak ("can't modify read-only data scalar in db_pget");
1573 root 1.28 {
1574 root 1.5 dREQ (REQ_DB_PGET);
1575     req->db = db;
1576     req->txn = txn;
1577 root 1.6 req->uint1 = flags;
1578 root 1.5 sv_to_dbt (&req->dbt1, key);
1579     sv_to_dbt (&req->dbt2, pkey);
1580     req->dbt3.flags = DB_DBT_MALLOC;
1581 root 1.6 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1582     REQ_SEND;
1583     }
1584    
1585     void
1586     db_del (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef)
1587     CODE:
1588     {
1589     dREQ (REQ_DB_DEL);
1590     req->db = db;
1591     req->txn = txn;
1592 root 1.5 req->uint1 = flags;
1593 root 1.6 sv_to_dbt (&req->dbt1, key);
1594 root 1.5 REQ_SEND;
1595     }
1596    
1597     void
1598     db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = &PL_sv_undef)
1599     CODE:
1600     {
1601     dREQ (REQ_TXN_COMMIT);
1602     req->txn = txn;
1603     req->uint1 = flags;
1604     REQ_SEND;
1605     ptr_nuke (ST (0));
1606     }
1607    
1608     void
1609     db_txn_abort (DB_TXN *txn, SV *callback = &PL_sv_undef)
1610     CODE:
1611     {
1612     dREQ (REQ_TXN_ABORT);
1613     req->txn = txn;
1614     REQ_SEND;
1615     ptr_nuke (ST (0));
1616     }
1617    
1618 root 1.6 void
1619 root 1.17 db_txn_finish (DB_TXN *txn, U32 flags = 0, SV *callback = &PL_sv_undef)
1620     CODE:
1621     {
1622     dREQ (REQ_TXN_FINISH);
1623     req->txn = txn;
1624     req->uint1 = flags;
1625     REQ_SEND;
1626     ptr_nuke (ST (0));
1627     }
1628    
1629     void
1630 root 1.6 db_c_close (DBC *dbc, SV *callback = &PL_sv_undef)
1631     CODE:
1632     {
1633     dREQ (REQ_C_CLOSE);
1634     req->dbc = dbc;
1635     REQ_SEND;
1636     ptr_nuke (ST (0));
1637     }
1638    
1639     void
1640     db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = &PL_sv_undef)
1641     CODE:
1642     {
1643     dREQ (REQ_C_COUNT);
1644     req->dbc = dbc;
1645     req->sv1 = SvREFCNT_inc (count);
1646     REQ_SEND;
1647     }
1648    
1649     void
1650     db_c_put (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1651     CODE:
1652     {
1653     dREQ (REQ_C_PUT);
1654     req->dbc = dbc;
1655     sv_to_dbt (&req->dbt1, key);
1656     sv_to_dbt (&req->dbt2, data);
1657     req->uint1 = flags;
1658     REQ_SEND;
1659     }
1660    
1661     void
1662     db_c_get (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1663     CODE:
1664     {
1665     dREQ (REQ_C_GET);
1666     req->dbc = dbc;
1667     req->uint1 = flags;
1668     if ((flags & DB_SET) == DB_SET
1669     || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1670     sv_to_dbt (&req->dbt1, key);
1671     else
1672     req->dbt1.flags = DB_DBT_MALLOC;
1673    
1674     req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1675    
1676     if ((flags & DB_GET_BOTH) == DB_GET_BOTH
1677     || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE)
1678     sv_to_dbt (&req->dbt3, data);
1679     else
1680     req->dbt3.flags = DB_DBT_MALLOC;
1681    
1682     req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1683     REQ_SEND;
1684     }
1685    
1686     void
1687     db_c_pget (DBC *dbc, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1688     CODE:
1689     {
1690     dREQ (REQ_C_PGET);
1691     req->dbc = dbc;
1692     req->uint1 = flags;
1693     if ((flags & DB_SET) == DB_SET
1694     || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1695     sv_to_dbt (&req->dbt1, key);
1696     else
1697     req->dbt1.flags = DB_DBT_MALLOC;
1698    
1699     req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1700    
1701     req->dbt2.flags = DB_DBT_MALLOC;
1702     req->sv2 = SvREFCNT_inc (pkey); SvREADONLY_on (pkey);
1703    
1704     if ((flags & DB_GET_BOTH) == DB_GET_BOTH
1705     || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE)
1706     sv_to_dbt (&req->dbt3, data);
1707     else
1708     req->dbt3.flags = DB_DBT_MALLOC;
1709    
1710     req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1711     REQ_SEND;
1712     }
1713    
1714     void
1715     db_c_del (DBC *dbc, U32 flags = 0, SV *callback = &PL_sv_undef)
1716     CODE:
1717     {
1718     dREQ (REQ_C_DEL);
1719     req->dbc = dbc;
1720     req->uint1 = flags;
1721     REQ_SEND;
1722     }
1723    
1724 root 1.2
1725 root 1.8 void
1726     db_sequence_open (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef)
1727     CODE:
1728     {
1729     dREQ (REQ_SEQ_OPEN);
1730     req->seq = seq;
1731     req->txn = txnid;
1732     req->uint1 = flags | DB_THREAD;
1733     sv_to_dbt (&req->dbt1, key);
1734     REQ_SEND;
1735     }
1736    
1737     void
1738     db_sequence_close (DB_SEQUENCE *seq, U32 flags = 0, SV *callback = &PL_sv_undef)
1739     CODE:
1740     {
1741     dREQ (REQ_SEQ_CLOSE);
1742     req->seq = seq;
1743     req->uint1 = flags;
1744     REQ_SEND;
1745     ptr_nuke (ST (0));
1746     }
1747    
1748     void
1749     db_sequence_get (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, int delta, SV *seq_value, U32 flags = DB_TXN_NOSYNC, SV *callback = &PL_sv_undef)
1750     CODE:
1751     {
1752     dREQ (REQ_SEQ_GET);
1753     req->seq = seq;
1754     req->txn = txnid;
1755     req->int1 = delta;
1756     req->uint1 = flags;
1757     req->sv1 = SvREFCNT_inc (seq_value); SvREADONLY_on (seq_value);
1758     REQ_SEND;
1759     }
1760    
1761     void
1762     db_sequence_remove (DB_SEQUENCE *seq, DB_TXN_ornull *txnid = 0, U32 flags = 0, SV *callback = &PL_sv_undef)
1763     CODE:
1764     {
1765     dREQ (REQ_SEQ_REMOVE);
1766     req->seq = seq;
1767     req->txn = txnid;
1768     req->uint1 = flags;
1769     REQ_SEND;
1770     }
1771    
1772    
1773 root 1.2 MODULE = BDB PACKAGE = BDB::Env
1774    
1775 root 1.5 void
1776 root 1.30 DESTROY (DB_ENV_ornuked *env)
1777 root 1.5 CODE:
1778     if (env)
1779     env->close (env, 0);
1780    
1781 root 1.8 int set_data_dir (DB_ENV *env, const char *dir)
1782     CODE:
1783     RETVAL = env->set_data_dir (env, dir);
1784     OUTPUT:
1785     RETVAL
1786    
1787     int set_tmp_dir (DB_ENV *env, const char *dir)
1788     CODE:
1789     RETVAL = env->set_tmp_dir (env, dir);
1790     OUTPUT:
1791     RETVAL
1792    
1793     int set_lg_dir (DB_ENV *env, const char *dir)
1794     CODE:
1795     RETVAL = env->set_lg_dir (env, dir);
1796     OUTPUT:
1797     RETVAL
1798    
1799     int set_shm_key (DB_ENV *env, long shm_key)
1800     CODE:
1801     RETVAL = env->set_shm_key (env, shm_key);
1802     OUTPUT:
1803     RETVAL
1804    
1805 root 1.2 int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0)
1806 root 1.3 CODE:
1807     RETVAL = env->set_cachesize (env, gbytes, bytes, ncache);
1808     OUTPUT:
1809     RETVAL
1810 root 1.2
1811 root 1.25 int set_flags (DB_ENV *env, U32 flags, int onoff = 1)
1812 root 1.3 CODE:
1813     RETVAL = env->set_flags (env, flags, onoff);
1814     OUTPUT:
1815     RETVAL
1816    
1817 root 1.16 void set_errfile (DB_ENV *env, FILE *errfile = 0)
1818 root 1.14 CODE:
1819     env->set_errfile (env, errfile);
1820    
1821 root 1.16 void set_msgfile (DB_ENV *env, FILE *msgfile = 0)
1822 root 1.14 CODE:
1823     env->set_msgfile (env, msgfile);
1824    
1825 root 1.25 int set_verbose (DB_ENV *env, U32 which = -1, int onoff = 1)
1826 root 1.14 CODE:
1827     RETVAL = env->set_verbose (env, which, onoff);
1828     OUTPUT:
1829     RETVAL
1830    
1831 root 1.3 int set_encrypt (DB_ENV *env, const char *password, U32 flags = 0)
1832     CODE:
1833     RETVAL = env->set_encrypt (env, password, flags);
1834     OUTPUT:
1835     RETVAL
1836    
1837 root 1.17 int set_timeout (DB_ENV *env, NV timeout, U32 flags = DB_SET_TXN_TIMEOUT)
1838 root 1.3 CODE:
1839     RETVAL = env->set_timeout (env, timeout * 1000000, flags);
1840     OUTPUT:
1841     RETVAL
1842 root 1.2
1843 root 1.8 int set_mp_max_openfd (DB_ENV *env, int maxopenfd);
1844     CODE:
1845     RETVAL = env->set_mp_max_openfd (env, maxopenfd);
1846     OUTPUT:
1847     RETVAL
1848    
1849     int set_mp_max_write (DB_ENV *env, int maxwrite, int maxwrite_sleep);
1850     CODE:
1851     RETVAL = env->set_mp_max_write (env, maxwrite, maxwrite_sleep);
1852     OUTPUT:
1853     RETVAL
1854    
1855     int set_mp_mmapsize (DB_ENV *env, int mmapsize_mb)
1856     CODE:
1857     RETVAL = env->set_mp_mmapsize (env, ((size_t)mmapsize_mb) << 20);
1858     OUTPUT:
1859     RETVAL
1860    
1861 root 1.9 int set_lk_detect (DB_ENV *env, U32 detect = DB_LOCK_DEFAULT)
1862 root 1.8 CODE:
1863     RETVAL = env->set_lk_detect (env, detect);
1864     OUTPUT:
1865     RETVAL
1866    
1867     int set_lk_max_lockers (DB_ENV *env, U32 max)
1868     CODE:
1869     RETVAL = env->set_lk_max_lockers (env, max);
1870     OUTPUT:
1871     RETVAL
1872    
1873     int set_lk_max_locks (DB_ENV *env, U32 max)
1874     CODE:
1875     RETVAL = env->set_lk_max_locks (env, max);
1876     OUTPUT:
1877     RETVAL
1878    
1879     int set_lk_max_objects (DB_ENV *env, U32 max)
1880     CODE:
1881     RETVAL = env->set_lk_max_objects (env, max);
1882     OUTPUT:
1883     RETVAL
1884    
1885     int set_lg_bsize (DB_ENV *env, U32 max)
1886     CODE:
1887     RETVAL = env->set_lg_bsize (env, max);
1888     OUTPUT:
1889     RETVAL
1890    
1891     int set_lg_max (DB_ENV *env, U32 max)
1892     CODE:
1893     RETVAL = env->set_lg_max (env, max);
1894     OUTPUT:
1895     RETVAL
1896    
1897 root 1.22 int mutex_set_max (DB_ENV *env, U32 max)
1898     CODE:
1899     RETVAL = env->mutex_set_max (env, max);
1900     OUTPUT:
1901     RETVAL
1902    
1903     int mutex_set_increment (DB_ENV *env, U32 increment)
1904     CODE:
1905     RETVAL = env->mutex_set_increment (env, increment);
1906     OUTPUT:
1907     RETVAL
1908    
1909     int mutex_set_tas_spins (DB_ENV *env, U32 tas_spins)
1910     CODE:
1911     RETVAL = env->mutex_set_tas_spins (env, tas_spins);
1912     OUTPUT:
1913     RETVAL
1914    
1915     int mutex_set_align (DB_ENV *env, U32 align)
1916     CODE:
1917     RETVAL = env->mutex_set_align (env, align);
1918     OUTPUT:
1919     RETVAL
1920    
1921 root 1.5 DB_TXN *
1922     txn_begin (DB_ENV *env, DB_TXN_ornull *parent = 0, U32 flags = 0)
1923     CODE:
1924     errno = env->txn_begin (env, parent, &RETVAL, flags);
1925     if (errno)
1926 root 1.6 croak ("DB_ENV->txn_begin: %s", db_strerror (errno));
1927 root 1.5 OUTPUT:
1928     RETVAL
1929 root 1.2
1930     MODULE = BDB PACKAGE = BDB::Db
1931    
1932 root 1.5 void
1933 root 1.30 DESTROY (DB_ornuked *db)
1934 root 1.5 CODE:
1935     if (db)
1936     {
1937     SV *env = (SV *)db->app_private;
1938     db->close (db, 0);
1939     SvREFCNT_dec (env);
1940     }
1941    
1942 root 1.2 int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0)
1943 root 1.3 CODE:
1944     RETVAL = db->set_cachesize (db, gbytes, bytes, ncache);
1945     OUTPUT:
1946     RETVAL
1947 root 1.2
1948 root 1.16 int set_flags (DB *db, U32 flags)
1949 root 1.3 CODE:
1950     RETVAL = db->set_flags (db, flags);
1951     OUTPUT:
1952     RETVAL
1953 root 1.2
1954     int set_encrypt (DB *db, const char *password, U32 flags)
1955 root 1.3 CODE:
1956     RETVAL = db->set_encrypt (db, password, flags);
1957     OUTPUT:
1958     RETVAL
1959 root 1.2
1960     int set_lorder (DB *db, int lorder)
1961 root 1.3 CODE:
1962     RETVAL = db->set_lorder (db, lorder);
1963     OUTPUT:
1964     RETVAL
1965 root 1.2
1966     int set_bt_minkey (DB *db, U32 minkey)
1967 root 1.3 CODE:
1968     RETVAL = db->set_bt_minkey (db, minkey);
1969     OUTPUT:
1970     RETVAL
1971 root 1.2
1972 root 1.16 int set_re_delim (DB *db, int delim)
1973 root 1.3 CODE:
1974     RETVAL = db->set_re_delim (db, delim);
1975     OUTPUT:
1976     RETVAL
1977 root 1.2
1978     int set_re_pad (DB *db, int re_pad)
1979 root 1.3 CODE:
1980     RETVAL = db->set_re_pad (db, re_pad);
1981     OUTPUT:
1982     RETVAL
1983 root 1.2
1984     int set_re_source (DB *db, char *source)
1985 root 1.3 CODE:
1986     RETVAL = db->set_re_source (db, source);
1987     OUTPUT:
1988     RETVAL
1989 root 1.2
1990     int set_re_len (DB *db, U32 re_len)
1991 root 1.3 CODE:
1992     RETVAL = db->set_re_len (db, re_len);
1993     OUTPUT:
1994     RETVAL
1995 root 1.2
1996     int set_h_ffactor (DB *db, U32 h_ffactor)
1997 root 1.3 CODE:
1998     RETVAL = db->set_h_ffactor (db, h_ffactor);
1999     OUTPUT:
2000     RETVAL
2001 root 1.2
2002     int set_h_nelem (DB *db, U32 h_nelem)
2003 root 1.3 CODE:
2004     RETVAL = db->set_h_nelem (db, h_nelem);
2005     OUTPUT:
2006     RETVAL
2007 root 1.2
2008     int set_q_extentsize (DB *db, U32 extentsize)
2009 root 1.3 CODE:
2010     RETVAL = db->set_q_extentsize (db, extentsize);
2011     OUTPUT:
2012     RETVAL
2013 root 1.2
2014 root 1.6 DBC *
2015     cursor (DB *db, DB_TXN_ornull *txn = 0, U32 flags = 0)
2016     CODE:
2017     errno = db->cursor (db, txn, &RETVAL, flags);
2018     if (errno)
2019     croak ("DB->cursor: %s", db_strerror (errno));
2020     OUTPUT:
2021     RETVAL
2022    
2023 root 1.8 DB_SEQUENCE *
2024     sequence (DB *db, U32 flags = 0)
2025     CODE:
2026     {
2027     errno = db_sequence_create (&RETVAL, db, flags);
2028     if (errno)
2029     croak ("db_sequence_create: %s", db_strerror (errno));
2030     }
2031     OUTPUT:
2032     RETVAL
2033    
2034 root 1.6
2035 root 1.5 MODULE = BDB PACKAGE = BDB::Txn
2036    
2037     void
2038 root 1.30 DESTROY (DB_TXN_ornuked *txn)
2039 root 1.5 CODE:
2040     if (txn)
2041     txn->abort (txn);
2042    
2043 root 1.17 int set_timeout (DB_TXN *txn, NV timeout, U32 flags = DB_SET_TXN_TIMEOUT)
2044 root 1.5 CODE:
2045     RETVAL = txn->set_timeout (txn, timeout * 1000000, flags);
2046     OUTPUT:
2047     RETVAL
2048    
2049 root 1.17 int failed (DB_TXN *txn)
2050     CODE:
2051     RETVAL = !!(txn->flags & TXN_DEADLOCK);
2052     OUTPUT:
2053     RETVAL
2054    
2055 root 1.1
2056 root 1.6 MODULE = BDB PACKAGE = BDB::Cursor
2057    
2058     void
2059 root 1.30 DESTROY (DBC_ornuked *dbc)
2060 root 1.6 CODE:
2061     if (dbc)
2062     dbc->c_close (dbc);
2063    
2064 root 1.27 #if DB_VERSION_MINOR >= 6
2065    
2066     int set_priority (DBC *dbc, int priority)
2067     CODE:
2068     dbc->set_priority (dbc, priority);
2069    
2070     #endif
2071    
2072 root 1.8 MODULE = BDB PACKAGE = BDB::Sequence
2073    
2074     void
2075 root 1.30 DESTROY (DB_SEQUENCE_ornuked *seq)
2076 root 1.8 CODE:
2077     if (seq)
2078     seq->close (seq, 0);
2079    
2080     int initial_value (DB_SEQUENCE *seq, db_seq_t value)
2081     CODE:
2082     RETVAL = seq->initial_value (seq, value);
2083     OUTPUT:
2084     RETVAL
2085    
2086     int set_cachesize (DB_SEQUENCE *seq, U32 size)
2087     CODE:
2088     RETVAL = seq->set_cachesize (seq, size);
2089     OUTPUT:
2090     RETVAL
2091    
2092     int set_flags (DB_SEQUENCE *seq, U32 flags)
2093     CODE:
2094     RETVAL = seq->set_flags (seq, flags);
2095     OUTPUT:
2096     RETVAL
2097    
2098     int set_range (DB_SEQUENCE *seq, db_seq_t min, db_seq_t max)
2099     CODE:
2100     RETVAL = seq->set_range (seq, min, max);
2101     OUTPUT:
2102     RETVAL
2103    
2104 root 1.31