… | |
… | |
58 | #endif |
58 | #endif |
59 | |
59 | |
60 | typedef char *bdb_filename; |
60 | typedef char *bdb_filename; |
61 | |
61 | |
62 | static SV *prepare_cb; |
62 | static SV *prepare_cb; |
|
|
63 | |
|
|
64 | static HV |
|
|
65 | *bdb_stash, |
|
|
66 | *bdb_env_stash, |
|
|
67 | *bdb_txn_stash, |
|
|
68 | *bdb_cursor_stash, |
|
|
69 | *bdb_db_stash, |
|
|
70 | *bdb_sequence_stash; |
63 | |
71 | |
64 | #if DB_VERSION_MINOR >= 6 |
72 | #if DB_VERSION_MINOR >= 6 |
65 | # define c_close close |
73 | # define c_close close |
66 | # define c_count count |
74 | # define c_count count |
67 | # define c_del del |
75 | # define c_del del |
… | |
… | |
216 | static int next_pri = DEFAULT_PRI + PRI_BIAS; |
224 | static int next_pri = DEFAULT_PRI + PRI_BIAS; |
217 | |
225 | |
218 | static unsigned int started, idle, wanted; |
226 | static unsigned int started, idle, wanted; |
219 | |
227 | |
220 | /* worker threads management */ |
228 | /* worker threads management */ |
221 | static mutex_t wrklock = X_MUTEX_INIT; |
229 | static xmutex_t wrklock = X_MUTEX_INIT; |
222 | |
230 | |
223 | typedef struct worker { |
231 | typedef struct worker { |
224 | /* locked by wrklock */ |
232 | /* locked by wrklock */ |
225 | struct worker *prev, *next; |
233 | struct worker *prev, *next; |
226 | |
234 | |
227 | thread_t tid; |
235 | xthread_t tid; |
228 | |
236 | |
229 | /* locked by reslock, reqlock or wrklock */ |
237 | /* locked by reslock, reqlock or wrklock */ |
230 | bdb_req req; /* currently processed request */ |
238 | bdb_req req; /* currently processed request */ |
231 | void *dbuf; |
239 | void *dbuf; |
232 | DIR *dirp; |
240 | DIR *dirp; |
… | |
… | |
249 | static volatile unsigned int nreqs, nready, npending; |
257 | static volatile unsigned int nreqs, nready, npending; |
250 | static volatile unsigned int max_idle = 4; |
258 | static volatile unsigned int max_idle = 4; |
251 | static volatile unsigned int max_outstanding = 0xffffffff; |
259 | static volatile unsigned int max_outstanding = 0xffffffff; |
252 | static s_epipe respipe; |
260 | static s_epipe respipe; |
253 | |
261 | |
254 | static mutex_t reslock = X_MUTEX_INIT; |
262 | static xmutex_t reslock = X_MUTEX_INIT; |
255 | static mutex_t reqlock = X_MUTEX_INIT; |
263 | static xmutex_t reqlock = X_MUTEX_INIT; |
256 | static cond_t reqwait = X_COND_INIT; |
264 | static xcond_t reqwait = X_COND_INIT; |
257 | |
265 | |
258 | #if WORDACCESS_UNSAFE |
266 | #if WORDACCESS_UNSAFE |
259 | |
267 | |
260 | static unsigned int get_nready (void) |
268 | static unsigned int get_nready (void) |
261 | { |
269 | { |
… | |
… | |
608 | end_thread (); |
616 | end_thread (); |
609 | } |
617 | } |
610 | |
618 | |
611 | static void poll_wait (void) |
619 | static void poll_wait (void) |
612 | { |
620 | { |
613 | fd_set rfd; |
|
|
614 | |
|
|
615 | while (nreqs) |
621 | while (nreqs) |
616 | { |
622 | { |
617 | int size; |
623 | int size; |
618 | if (WORDACCESS_UNSAFE) X_LOCK (reslock); |
624 | if (WORDACCESS_UNSAFE) X_LOCK (reslock); |
619 | size = res_queue.size; |
625 | size = res_queue.size; |
… | |
… | |
1020 | (void)0; |
1026 | (void)0; |
1021 | |
1027 | |
1022 | #define REQ_SEND \ |
1028 | #define REQ_SEND \ |
1023 | req_send (req) |
1029 | req_send (req) |
1024 | |
1030 | |
1025 | #define SvPTR(var, arg, type, class, nullok) \ |
1031 | #define SvPTR(var, arg, type, stash, class, nullok) \ |
1026 | if (!SvOK (arg)) \ |
1032 | if (!SvOK (arg)) \ |
1027 | { \ |
1033 | { \ |
1028 | if (nullok != 1) \ |
1034 | if (nullok != 1) \ |
1029 | croak (# var " must be a " # class " object, not undef"); \ |
1035 | croak (# var " must be a " # class " object, not undef"); \ |
1030 | \ |
1036 | \ |
1031 | (var) = 0; \ |
1037 | (var) = 0; \ |
1032 | } \ |
1038 | } \ |
1033 | else if (sv_derived_from ((arg), # class)) \ |
1039 | else if (SvSTASH (SvRV (arg)) == stash || sv_derived_from ((arg), # class)) \ |
1034 | { \ |
1040 | { \ |
1035 | IV tmp = SvIV ((SV*) SvRV (arg)); \ |
1041 | IV tmp = SvIV ((SV*) SvRV (arg)); \ |
1036 | (var) = INT2PTR (type, tmp); \ |
1042 | (var) = INT2PTR (type, tmp); \ |
1037 | if (!var && nullok != 2) \ |
1043 | if (!var && nullok != 2) \ |
1038 | croak (# var " is not a valid " # class " object anymore"); \ |
1044 | croak (# var " is not a valid " # class " object anymore"); \ |
… | |
… | |
1041 | croak (# var " is not of type " # class); |
1047 | croak (# var " is not of type " # class); |
1042 | |
1048 | |
1043 | #define ARG_MUTABLE(name) \ |
1049 | #define ARG_MUTABLE(name) \ |
1044 | if (SvREADONLY (name)) \ |
1050 | if (SvREADONLY (name)) \ |
1045 | croak ("argument " #name " is read-only/constant, but the request requires it to be mutable"); |
1051 | croak ("argument " #name " is read-only/constant, but the request requires it to be mutable"); |
|
|
1052 | |
|
|
1053 | static SV * |
|
|
1054 | newSVptr (void *ptr, HV *stash) |
|
|
1055 | { |
|
|
1056 | SV *rv = NEWSV (0, 0); |
|
|
1057 | sv_upgrade (rv, SVt_PVMG); |
|
|
1058 | sv_setiv (rv, PTR2IV (ptr)); |
|
|
1059 | |
|
|
1060 | return sv_bless (newRV_noinc (rv), stash); |
|
|
1061 | } |
1046 | |
1062 | |
1047 | static void |
1063 | static void |
1048 | ptr_nuke (SV *sv) |
1064 | ptr_nuke (SV *sv) |
1049 | { |
1065 | { |
1050 | assert (SvROK (sv)); |
1066 | assert (SvROK (sv)); |
… | |
… | |
1172 | |
1188 | |
1173 | PROTOTYPES: ENABLE |
1189 | PROTOTYPES: ENABLE |
1174 | |
1190 | |
1175 | BOOT: |
1191 | BOOT: |
1176 | { |
1192 | { |
1177 | HV *stash = gv_stashpv ("BDB", 1); |
|
|
1178 | |
|
|
1179 | static const struct { |
1193 | static const struct { |
1180 | const char *name; |
1194 | const char *name; |
1181 | IV iv; |
1195 | IV iv; |
1182 | } *civ, const_iv[] = { |
1196 | } *civ, const_iv[] = { |
1183 | #define const_iv(name) { # name, (IV)DB_ ## name }, |
1197 | #define const_iv(name) { # name, (IV)DB_ ## name }, |
… | |
… | |
1212 | const_iv (TXN_NOT_DURABLE) |
1226 | const_iv (TXN_NOT_DURABLE) |
1213 | const_iv (TXN_WRITE_NOSYNC) |
1227 | const_iv (TXN_WRITE_NOSYNC) |
1214 | const_iv (WRITECURSOR) |
1228 | const_iv (WRITECURSOR) |
1215 | const_iv (YIELDCPU) |
1229 | const_iv (YIELDCPU) |
1216 | const_iv (ENCRYPT_AES) |
1230 | const_iv (ENCRYPT_AES) |
|
|
1231 | #if DB_VERSION_MINOR < 8 |
1217 | const_iv (XA_CREATE) |
1232 | const_iv (XA_CREATE) |
|
|
1233 | #endif |
1218 | const_iv (BTREE) |
1234 | const_iv (BTREE) |
1219 | const_iv (HASH) |
1235 | const_iv (HASH) |
1220 | const_iv (QUEUE) |
1236 | const_iv (QUEUE) |
1221 | const_iv (RECNO) |
1237 | const_iv (RECNO) |
1222 | const_iv (UNKNOWN) |
1238 | const_iv (UNKNOWN) |
… | |
… | |
1286 | const_iv (LOCK_OLDEST) |
1302 | const_iv (LOCK_OLDEST) |
1287 | const_iv (LOCK_RANDOM) |
1303 | const_iv (LOCK_RANDOM) |
1288 | const_iv (LOCK_YOUNGEST) |
1304 | const_iv (LOCK_YOUNGEST) |
1289 | |
1305 | |
1290 | const_iv (DONOTINDEX) |
1306 | const_iv (DONOTINDEX) |
1291 | const_iv (KEYEMPTY ) |
1307 | const_iv (KEYEMPTY) |
1292 | const_iv (KEYEXIST ) |
1308 | const_iv (KEYEXIST) |
1293 | const_iv (LOCK_DEADLOCK) |
1309 | const_iv (LOCK_DEADLOCK) |
1294 | const_iv (LOCK_NOTGRANTED) |
1310 | const_iv (LOCK_NOTGRANTED) |
1295 | const_iv (NOSERVER) |
1311 | const_iv (NOSERVER) |
1296 | const_iv (NOSERVER_HOME) |
1312 | const_iv (NOSERVER_HOME) |
1297 | const_iv (NOSERVER_ID) |
1313 | const_iv (NOSERVER_ID) |
… | |
… | |
1326 | const_iv (VERB_WAITSFOR) |
1342 | const_iv (VERB_WAITSFOR) |
1327 | |
1343 | |
1328 | const_iv (VERSION_MAJOR) |
1344 | const_iv (VERSION_MAJOR) |
1329 | const_iv (VERSION_MINOR) |
1345 | const_iv (VERSION_MINOR) |
1330 | const_iv (VERSION_PATCH) |
1346 | const_iv (VERSION_PATCH) |
|
|
1347 | const_iv (LOGVERSION) |
|
|
1348 | const_iv (LOGOLDVER) |
1331 | #if DB_VERSION_MINOR >= 3 |
1349 | #if DB_VERSION_MINOR >= 3 |
1332 | const_iv (INORDER) |
1350 | const_iv (INORDER) |
1333 | const_iv (LOCK_MAXWRITE) |
1351 | const_iv (LOCK_MAXWRITE) |
1334 | const_iv (SEQ_DEC) |
1352 | const_iv (SEQ_DEC) |
1335 | const_iv (SEQ_INC) |
1353 | const_iv (SEQ_INC) |
… | |
… | |
1376 | const_iv (LOG_AUTOREMOVE) |
1394 | const_iv (LOG_AUTOREMOVE) |
1377 | # if DB_VERSION_MINOR >= 3 |
1395 | # if DB_VERSION_MINOR >= 3 |
1378 | const_iv (DSYNC_LOG) |
1396 | const_iv (DSYNC_LOG) |
1379 | const_iv (LOG_INMEMORY) |
1397 | const_iv (LOG_INMEMORY) |
1380 | # endif |
1398 | # endif |
|
|
1399 | #if DB_VERSION_MINOR >= 8 |
|
|
1400 | const_iv (LOGVERSION_LATCHING) |
|
|
1401 | #endif |
1381 | #endif |
1402 | #endif |
1382 | }; |
1403 | }; |
1383 | |
1404 | |
|
|
1405 | bdb_stash = gv_stashpv ("BDB" , 1); |
|
|
1406 | bdb_env_stash = gv_stashpv ("BDB::Env" , 1); |
|
|
1407 | bdb_txn_stash = gv_stashpv ("BDB::Txn" , 1); |
|
|
1408 | bdb_cursor_stash = gv_stashpv ("BDB::Cursor" , 1); |
|
|
1409 | bdb_db_stash = gv_stashpv ("BDB::Db" , 1); |
|
|
1410 | bdb_sequence_stash = gv_stashpv ("BDB::Sequence", 1); |
|
|
1411 | |
1384 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) |
1412 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--) |
1385 | newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); |
1413 | newCONSTSUB (bdb_stash, (char *)civ[-1].name, newSViv (civ[-1].iv)); |
1386 | |
1414 | |
1387 | prepare_cb = &PL_sv_undef; |
1415 | prepare_cb = &PL_sv_undef; |
1388 | |
1416 | |
1389 | { |
1417 | { |
1390 | /* we currently only allow version, minor-version and patchlevel to go up to 255 */ |
1418 | /* we currently only allow version, minor-version and patchlevel to go up to 255 */ |
1391 | char vstring[3] = { DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH }; |
1419 | char vstring[3] = { DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH }; |
1392 | |
1420 | |
1393 | newCONSTSUB (stash, "VERSION_v", newSVpvn (vstring, 3)); |
1421 | newCONSTSUB (bdb_stash, "VERSION_v", newSVpvn (vstring, 3)); |
1394 | } |
1422 | } |
1395 | |
1423 | |
1396 | newCONSTSUB (stash, "VERSION_STRING", newSVpv (DB_VERSION_STRING, 0)); |
1424 | newCONSTSUB (bdb_stash, "VERSION_STRING", newSVpv (DB_VERSION_STRING, 0)); |
1397 | |
1425 | |
1398 | create_respipe (); |
1426 | create_respipe (); |
1399 | |
1427 | |
1400 | X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child); |
1428 | X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child); |
1401 | patch_errno (); |
1429 | patch_errno (); |