ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/BDB/BDB.xs
(Generate patch)

Comparing BDB/BDB.xs (file contents):
Revision 1.29 by root, Tue Dec 25 14:23:21 2007 UTC vs.
Revision 1.38 by root, Wed May 21 19:13:43 2008 UTC

40typedef DB_TXN DB_TXN_ornull; 40typedef DB_TXN DB_TXN_ornull;
41typedef DBC DBC_ornull; 41typedef DBC DBC_ornull;
42typedef DB DB_ornull; 42typedef DB DB_ornull;
43typedef DB_SEQUENCE DB_SEQUENCE_ornull; 43typedef DB_SEQUENCE DB_SEQUENCE_ornull;
44 44
45typedef DB_ENV DB_ENV_ornuked;
46typedef DB_TXN DB_TXN_ornuked;
47typedef DBC DBC_ornuked;
48typedef DB DB_ornuked;
49typedef DB_SEQUENCE DB_SEQUENCE_ornuked;
50
45typedef SV SV8; /* byte-sv, used for argument-checking */ 51typedef SV SV8; /* byte-sv, used for argument-checking */
46typedef char *octetstring; 52typedef char *bdb_filename;
47 53
48static SV *prepare_cb; 54static SV *prepare_cb;
49 55
50#if DB_VERSION_MINOR >= 6 56#if DB_VERSION_MINOR >= 6
51# define c_close close 57# define c_close close
54# define c_dup dup 60# define c_dup dup
55# define c_get get 61# define c_get get
56# define c_pget pget 62# define c_pget pget
57# define c_put put 63# define c_put put
58#endif 64#endif
65
66static char *
67get_bdb_filename (SV *sv)
68{
69 if (!SvOK (sv))
70 return 0;
71
72#if _WIN32
73 /* win32 madness + win32 perl absolutely brokenness make for horrible hacks */
74 {
75 STRLEN len;
76 char *src = SvPVbyte (sv, len);
77 SV *t1 = sv_newmortal ();
78 SV *t2 = sv_newmortal ();
79
80 sv_upgrade (t1, SVt_PV); SvPOK_only (t1); SvGROW (t1, len * 16 + 1);
81 sv_upgrade (t2, SVt_PV); SvPOK_only (t2); SvGROW (t2, len * 16 + 1);
82
83 len = MultiByteToWideChar (CP_ACP, 0, src, len, (WCHAR *)SvPVX (t1), SvLEN (t1) / sizeof (WCHAR));
84 len = WideCharToMultiByte (CP_UTF8, 0, (WCHAR *)SvPVX (t1), len, SvPVX (t2), SvLEN (t2), 0, 0);
85 SvPOK_only (t2);
86 SvPVX (t2)[len] = 0;
87 SvCUR_set (t2, len);
88
89 return SvPVX (t2);
90 }
91#else
92 return SvPVbyte_nolen (sv);
93#endif
94}
59 95
60static void 96static void
61debug_errcall (const DB_ENV *dbenv, const char *errpfx, const char *msg) 97debug_errcall (const DB_ENV *dbenv, const char *errpfx, const char *msg)
62{ 98{
63 printf ("err[%s]\n", msg); 99 printf ("err[%s]\n", msg);
145 NUM_PRI = PRI_MAX + PRI_BIAS + 1, 181 NUM_PRI = PRI_MAX + PRI_BIAS + 1,
146}; 182};
147 183
148#define AIO_TICKS ((1000000 + 1023) >> 10) 184#define AIO_TICKS ((1000000 + 1023) >> 10)
149 185
186static SV *on_next_submit;
187
150static unsigned int max_poll_time = 0; 188static unsigned int max_poll_time = 0;
151static unsigned int max_poll_reqs = 0; 189static unsigned int max_poll_reqs = 0;
152 190
153/* calculcate time difference in ~1/AIO_TICKS of a second */ 191/* calculcate time difference in ~1/AIO_TICKS of a second */
154static int tvdiff (struct timeval *tv1, struct timeval *tv2) 192static int tvdiff (struct timeval *tv1, struct timeval *tv2)
199static mutex_t reqlock = X_MUTEX_INIT; 237static mutex_t reqlock = X_MUTEX_INIT;
200static cond_t reqwait = X_COND_INIT; 238static cond_t reqwait = X_COND_INIT;
201 239
202#if WORDACCESS_UNSAFE 240#if WORDACCESS_UNSAFE
203 241
204static unsigned int get_nready () 242static unsigned int get_nready (void)
205{ 243{
206 unsigned int retval; 244 unsigned int retval;
207 245
208 X_LOCK (reqlock); 246 X_LOCK (reqlock);
209 retval = nready; 247 retval = nready;
210 X_UNLOCK (reqlock); 248 X_UNLOCK (reqlock);
211 249
212 return retval; 250 return retval;
213} 251}
214 252
215static unsigned int get_npending () 253static unsigned int get_npending (void)
216{ 254{
217 unsigned int retval; 255 unsigned int retval;
218 256
219 X_LOCK (reslock); 257 X_LOCK (reslock);
220 retval = npending; 258 retval = npending;
221 X_UNLOCK (reslock); 259 X_UNLOCK (reslock);
222 260
223 return retval; 261 return retval;
224} 262}
225 263
226static unsigned int get_nthreads () 264static unsigned int get_nthreads (void)
227{ 265{
228 unsigned int retval; 266 unsigned int retval;
229 267
230 X_LOCK (wrklock); 268 X_LOCK (wrklock);
231 retval = started; 269 retval = started;
294 } 332 }
295 333
296 abort (); 334 abort ();
297} 335}
298 336
299static int poll_cb (); 337static int poll_cb (void);
300static void req_free (bdb_req req); 338static void req_free (bdb_req req);
301static void req_cancel (bdb_req req); 339static void req_cancel (bdb_req req);
302 340
303static int req_invoke (bdb_req req) 341static int req_invoke (bdb_req req)
304{ 342{
385#else 423#else
386# define TO_SOCKET(x) (x) 424# define TO_SOCKET(x) (x)
387#endif 425#endif
388 426
389static void 427static void
390create_respipe () 428create_respipe (void)
391{ 429{
392#ifdef _WIN32 430#ifdef _WIN32
393 int arg; /* argg */ 431 int arg; /* argg */
394#endif 432#endif
395 int old_readfd = respipe [0]; 433 int old_readfd = respipe [0];
449 free (wrk); 487 free (wrk);
450 488
451 X_UNLOCK (wrklock); 489 X_UNLOCK (wrklock);
452} 490}
453 491
454static void maybe_start_thread () 492static void maybe_start_thread (void)
455{ 493{
456 if (get_nthreads () >= wanted) 494 if (get_nthreads () >= wanted)
457 return; 495 return;
458 496
459 /* todo: maybe use idle here, but might be less exact */ 497 /* todo: maybe use idle here, but might be less exact */
464} 502}
465 503
466static void req_send (bdb_req req) 504static void req_send (bdb_req req)
467{ 505{
468 SV *wait_callback = 0; 506 SV *wait_callback = 0;
507
508 if (on_next_submit)
509 {
510 dSP;
511 SV *cb = sv_2mortal (on_next_submit);
512
513 on_next_submit = 0;
514
515 PUSHMARK (SP);
516 PUTBACK;
517 call_sv (cb, G_DISCARD | G_EVAL);
518 }
469 519
470 // synthesize callback if none given 520 // synthesize callback if none given
471 if (!SvOK (req->callback)) 521 if (!SvOK (req->callback))
472 { 522 {
473 int count; 523 int count;
544 594
545 while (started > wanted) 595 while (started > wanted)
546 end_thread (); 596 end_thread ();
547} 597}
548 598
549static void poll_wait () 599static void poll_wait (void)
550{ 600{
551 fd_set rfd; 601 fd_set rfd;
552 602
553 while (nreqs) 603 while (nreqs)
554 { 604 {
567 617
568 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0); 618 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0);
569 } 619 }
570} 620}
571 621
572static int poll_cb () 622static int poll_cb (void)
573{ 623{
574 dSP; 624 dSP;
575 int count = 0; 625 int count = 0;
576 int maxreqs = max_poll_reqs; 626 int maxreqs = max_poll_reqs;
577 int do_croak = 0; 627 int do_croak = 0;
922 req->pri = req_pri 972 req->pri = req_pri
923 973
924#define REQ_SEND \ 974#define REQ_SEND \
925 req_send (req) 975 req_send (req)
926 976
927#define SvPTR(var, arg, type, class, nullok) \ 977#define SvPTR(var, arg, type, class, nullok) \
928 if (!SvOK (arg)) \ 978 if (!SvOK (arg)) \
929 { \ 979 { \
930 if (!nullok) \ 980 if (nullok != 1) \
931 croak (# var " must be a " # class " object, not undef"); \ 981 croak (# var " must be a " # class " object, not undef"); \
932 \ 982 \
933 (var) = 0; \ 983 (var) = 0; \
934 } \ 984 } \
935 else if (sv_derived_from ((arg), # class)) \ 985 else if (sv_derived_from ((arg), # class)) \
936 { \ 986 { \
937 IV tmp = SvIV ((SV*) SvRV (arg)); \ 987 IV tmp = SvIV ((SV*) SvRV (arg)); \
938 (var) = INT2PTR (type, tmp); \ 988 (var) = INT2PTR (type, tmp); \
939 if (!var) \ 989 if (!var && nullok != 2) \
940 croak (# var " is not a valid " # class " object anymore"); \ 990 croak (# var " is not a valid " # class " object anymore"); \
941 } \ 991 } \
942 else \ 992 else \
943 croak (# var " is not of type " # class); \ 993 croak (# var " is not of type " # class); \
944 \ 994 \
946static void 996static void
947ptr_nuke (SV *sv) 997ptr_nuke (SV *sv)
948{ 998{
949 assert (SvROK (sv)); 999 assert (SvROK (sv));
950 sv_setiv (SvRV (sv), 0); 1000 sv_setiv (SvRV (sv), 0);
1001}
1002
1003static int
1004errno_get (pTHX_ SV *sv, MAGIC *mg)
1005{
1006 if (*mg->mg_ptr == '!') // should always be the case
1007 if (-30999 <= errno && errno <= -30800)
1008 {
1009 sv_setnv (sv, (NV)errno);
1010 sv_setpv (sv, db_strerror (errno));
1011 SvNOK_on (sv); /* what a wonderful hack! */
1012 // ^^^ copied from perl sources
1013 return 0;
1014 }
1015
1016 return PL_vtbl_sv.svt_get (aTHX_ sv, mg);
1017}
1018
1019static MGVTBL vtbl_errno;
1020
1021// this wonderful hack :( patches perl's $! variable to support our errno values
1022static void
1023patch_errno (void)
1024{
1025 SV *sv;
1026 MAGIC *mg;
1027
1028 if (!(sv = get_sv ("!", 1)))
1029 return;
1030
1031 if (!(mg = mg_find (sv, PERL_MAGIC_sv)))
1032 return;
1033
1034 if (mg->mg_virtual != &PL_vtbl_sv)
1035 return;
1036
1037 vtbl_errno = PL_vtbl_sv;
1038 vtbl_errno.svt_get = errno_get;
1039 mg->mg_virtual = &vtbl_errno;
951} 1040}
952 1041
953MODULE = BDB PACKAGE = BDB 1042MODULE = BDB PACKAGE = BDB
954 1043
955PROTOTYPES: ENABLE 1044PROTOTYPES: ENABLE
1146 newCONSTSUB (stash, "VERSION_STRING", newSVpv (DB_VERSION_STRING, 0)); 1235 newCONSTSUB (stash, "VERSION_STRING", newSVpv (DB_VERSION_STRING, 0));
1147 1236
1148 create_respipe (); 1237 create_respipe ();
1149 1238
1150 X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child); 1239 X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child);
1151#ifdef _WIN32 1240 patch_errno ();
1152 X_MUTEX_CHECK (wrklock);
1153 X_MUTEX_CHECK (reslock);
1154 X_MUTEX_CHECK (reqlock);
1155
1156 X_COND_CHECK (reqwait);
1157#endif
1158} 1241}
1159 1242
1160void 1243void
1161max_poll_reqs (int nreqs) 1244max_poll_reqs (int nreqs)
1162 PROTOTYPE: $ 1245 PROTOTYPE: $
1302 CODE: 1385 CODE:
1303 RETVAL = db_strerror (errorno); 1386 RETVAL = db_strerror (errorno);
1304 OUTPUT: 1387 OUTPUT:
1305 RETVAL 1388 RETVAL
1306 1389
1390void _on_next_submit (SV *cb)
1391 CODE:
1392 SvREFCNT_dec (on_next_submit);
1393 on_next_submit = SvOK (cb) ? newSVsv (cb) : 0;
1394
1307DB_ENV * 1395DB_ENV *
1308db_env_create (U32 env_flags = 0) 1396db_env_create (U32 env_flags = 0)
1309 CODE: 1397 CODE:
1310{ 1398{
1311 errno = db_env_create (&RETVAL, env_flags); 1399 errno = db_env_create (&RETVAL, env_flags);
1320} 1408}
1321 OUTPUT: 1409 OUTPUT:
1322 RETVAL 1410 RETVAL
1323 1411
1324void 1412void
1325db_env_open (DB_ENV *env, octetstring db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef) 1413db_env_open (DB_ENV *env, bdb_filename db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef)
1326 CODE: 1414 CODE:
1327{ 1415{
1328 dREQ (REQ_ENV_OPEN); 1416 dREQ (REQ_ENV_OPEN);
1329 1417
1330 req->env = env; 1418 req->env = env;
1401} 1489}
1402 OUTPUT: 1490 OUTPUT:
1403 RETVAL 1491 RETVAL
1404 1492
1405void 1493void
1406db_open (DB *db, DB_TXN_ornull *txnid, octetstring file, octetstring database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef) 1494db_open (DB *db, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef)
1407 CODE: 1495 CODE:
1408{ 1496{
1409 dREQ (REQ_DB_OPEN); 1497 dREQ (REQ_DB_OPEN);
1410 req->db = db; 1498 req->db = db;
1411 req->txn = txnid; 1499 req->txn = txnid;
1451 req->uint1 = flags; 1539 req->uint1 = flags;
1452 REQ_SEND; 1540 REQ_SEND;
1453} 1541}
1454 1542
1455void 1543void
1456db_upgrade (DB *db, octetstring file, U32 flags = 0, SV *callback = &PL_sv_undef) 1544db_upgrade (DB *db, bdb_filename file, U32 flags = 0, SV *callback = &PL_sv_undef)
1457 CODE: 1545 CODE:
1458{ 1546{
1459 dREQ (REQ_DB_SYNC); 1547 dREQ (REQ_DB_SYNC);
1460 req->db = db; 1548 req->db = db;
1461 req->buf1 = strdup (file); 1549 req->buf1 = strdup (file);
1711 1799
1712 1800
1713MODULE = BDB PACKAGE = BDB::Env 1801MODULE = BDB PACKAGE = BDB::Env
1714 1802
1715void 1803void
1716DESTROY (DB_ENV_ornull *env) 1804DESTROY (DB_ENV_ornuked *env)
1717 CODE: 1805 CODE:
1718 if (env) 1806 if (env)
1719 env->close (env, 0); 1807 env->close (env, 0);
1720 1808
1721int set_data_dir (DB_ENV *env, const char *dir) 1809int set_data_dir (DB_ENV *env, const char *dir)
1868 RETVAL 1956 RETVAL
1869 1957
1870MODULE = BDB PACKAGE = BDB::Db 1958MODULE = BDB PACKAGE = BDB::Db
1871 1959
1872void 1960void
1873DESTROY (DB_ornull *db) 1961DESTROY (DB_ornuked *db)
1874 CODE: 1962 CODE:
1875 if (db) 1963 if (db)
1876 { 1964 {
1877 SV *env = (SV *)db->app_private; 1965 SV *env = (SV *)db->app_private;
1878 db->close (db, 0); 1966 db->close (db, 0);
1973 2061
1974 2062
1975MODULE = BDB PACKAGE = BDB::Txn 2063MODULE = BDB PACKAGE = BDB::Txn
1976 2064
1977void 2065void
1978DESTROY (DB_TXN_ornull *txn) 2066DESTROY (DB_TXN_ornuked *txn)
1979 CODE: 2067 CODE:
1980 if (txn) 2068 if (txn)
1981 txn->abort (txn); 2069 txn->abort (txn);
1982 2070
1983int set_timeout (DB_TXN *txn, NV timeout, U32 flags = DB_SET_TXN_TIMEOUT) 2071int set_timeout (DB_TXN *txn, NV timeout, U32 flags = DB_SET_TXN_TIMEOUT)
1994 2082
1995 2083
1996MODULE = BDB PACKAGE = BDB::Cursor 2084MODULE = BDB PACKAGE = BDB::Cursor
1997 2085
1998void 2086void
1999DESTROY (DBC_ornull *dbc) 2087DESTROY (DBC_ornuked *dbc)
2000 CODE: 2088 CODE:
2001 if (dbc) 2089 if (dbc)
2002 dbc->c_close (dbc); 2090 dbc->c_close (dbc);
2003 2091
2004#if DB_VERSION_MINOR >= 6 2092#if DB_VERSION_MINOR >= 6
2010#endif 2098#endif
2011 2099
2012MODULE = BDB PACKAGE = BDB::Sequence 2100MODULE = BDB PACKAGE = BDB::Sequence
2013 2101
2014void 2102void
2015DESTROY (DB_SEQUENCE_ornull *seq) 2103DESTROY (DB_SEQUENCE_ornuked *seq)
2016 CODE: 2104 CODE:
2017 if (seq) 2105 if (seq)
2018 seq->close (seq, 0); 2106 seq->close (seq, 0);
2019 2107
2020int initial_value (DB_SEQUENCE *seq, db_seq_t value) 2108int initial_value (DB_SEQUENCE *seq, db_seq_t value)
2039 CODE: 2127 CODE:
2040 RETVAL = seq->set_range (seq, min, max); 2128 RETVAL = seq->set_range (seq, min, max);
2041 OUTPUT: 2129 OUTPUT:
2042 RETVAL 2130 RETVAL
2043 2131
2132

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines