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

Comparing BDB/BDB.xs (file contents):
Revision 1.2 by root, Mon Feb 5 20:21:38 2007 UTC vs.
Revision 1.3 by root, Mon Feb 5 22:19:07 2007 UTC

41# define WORDACCESS_UNSAFE 1 41# define WORDACCESS_UNSAFE 1
42# endif 42# endif
43#endif 43#endif
44 44
45typedef SV SV8; /* byte-sv, used for argument-checking */ 45typedef SV SV8; /* byte-sv, used for argument-checking */
46typedef char *octetstring;
46 47
48static SV *prepare_cb;
49
50static inline char *
51strdup_ornull (const char *s)
52{
53 return s ? strdup (s) : 0;
54}
55
47enum 56enum {
48{
49 REQ_QUIT, 57 REQ_QUIT,
50 REQ_ENV_OPEN, REQ_ENV_CLOSE, 58 REQ_ENV_OPEN, REQ_ENV_CLOSE,
51 REQ_DB_OPEN, REQ_DB_CLOSE, 59 REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC, REQ_DB_PUT,
52}; 60};
53 61
54typedef struct aio_cb 62typedef struct aio_cb
55{ 63{
56 struct aio_cb *volatile next; 64 struct aio_cb *volatile next;
57 SV *callback; 65 SV *callback;
58 int type, pri, errorno; 66 int type, pri, result;
59 67
60 DB_ENV *env; 68 DB_ENV *env;
61 DB *db; 69 DB *db;
62 DB_TXN *txn; 70 DB_TXN *txn;
63 DBC *cursor; 71 DBC *cursor;
64 int int1, int2; 72 int int1, int2;
65 U32 uint1, uint2; 73 U32 uint1, uint2;
66 char *buf1, *buf2; 74 char *buf1, *buf2;
75
76 DBT dbt1, dbt2, dbt3;
67} aio_cb; 77} aio_cb;
68 78
69typedef aio_cb *aio_req; 79typedef aio_cb *aio_req;
70 80
71enum { 81enum {
254 264
255 switch (req->type) 265 switch (req->type)
256 { 266 {
257 } 267 }
258 268
269 errno = req->result;
270
259 PUTBACK; 271 PUTBACK;
260 call_sv (req->callback, G_VOID | G_EVAL); 272 call_sv (req->callback, G_VOID | G_EVAL);
261 SPAGAIN; 273 SPAGAIN;
262 274
263 FREETMPS; 275 FREETMPS;
272 free (req->buf1); 284 free (req->buf1);
273 free (req->buf2); 285 free (req->buf2);
274 Safefree (req); 286 Safefree (req);
275} 287}
276 288
277static void *aio_proc(void *arg); 289static void *aio_proc (void *arg);
278 290
279static void start_thread (void) 291static void start_thread (void)
280{ 292{
281 sigset_t fullsigset, oldsigset; 293 sigset_t fullsigset, oldsigset;
282 pthread_attr_t attr; 294 pthread_attr_t attr;
324 start_thread (); 336 start_thread ();
325} 337}
326 338
327static void req_send (aio_req req) 339static void req_send (aio_req req)
328{ 340{
341 SV *wait_callback = 0;
342
343 // synthesize callback if none given
344 if (!SvOK (req->callback))
345 {
346 dSP;
347 PUSHMARK (SP);
348 PUTBACK;
349 int count = call_sv (prepare_cb, G_ARRAY);
350 SPAGAIN;
351
352 if (count != 2)
353 croak ("prepare callback must return exactly two values\n");
354
355 wait_callback = SvREFCNT_inc (POPs);
356 SvREFCNT_dec (req->callback);
357 req->callback = SvREFCNT_inc (POPs);
358 }
359
329 ++nreqs; 360 ++nreqs;
330 361
331 LOCK (reqlock); 362 LOCK (reqlock);
332 ++nready; 363 ++nready;
333 reqq_push (&req_queue, req); 364 reqq_push (&req_queue, req);
334 pthread_cond_signal (&reqwait); 365 pthread_cond_signal (&reqwait);
335 UNLOCK (reqlock); 366 UNLOCK (reqlock);
336 367
337 maybe_start_thread (); 368 maybe_start_thread ();
369
370 if (wait_callback)
371 {
372 dSP;
373 PUSHMARK (SP);
374 PUTBACK;
375 call_sv (wait_callback, G_DISCARD);
376 SvREFCNT_dec (wait_callback);
377 }
338} 378}
339 379
340static void end_thread (void) 380static void end_thread (void)
341{ 381{
342 aio_req req; 382 aio_req req;
537 577
538 --nready; 578 --nready;
539 579
540 UNLOCK (reqlock); 580 UNLOCK (reqlock);
541 581
542 errno = 0; /* strictly unnecessary */
543
544 switch (req->type) 582 switch (req->type)
545 { 583 {
546 case REQ_QUIT: 584 case REQ_QUIT:
547 goto quit; 585 goto quit;
548 586
587 case REQ_ENV_OPEN:
588 req->result = req->env->open (req->env, req->buf1, req->uint1, req->int1);
589 break;
590
591 case REQ_ENV_CLOSE:
592 req->result = req->env->close (req->env, req->uint1);
593 break;
594
595 case REQ_DB_OPEN:
596 req->result = req->db->open (req->db, req->txn, req->buf1, req->buf2, req->int1, req->uint1, req->int2);
597 break;
598
599 case REQ_DB_CLOSE:
600 req->result = req->db->close (req->db, req->uint1);
601 break;
602
603 case REQ_DB_COMPACT:
604 req->result = req->db->compact (req->db, req->txn, &req->dbt1, &req->dbt2, 0, req->uint1, 0);
605 break;
606
607 case REQ_DB_SYNC:
608 req->result = req->db->sync (req->db, req->uint1);
609 break;
610
611 case REQ_DB_PUT:
612 req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1);
613 break;
614
549 default: 615 default:
550 //req->result = ENOSYS; 616 req->result = ENOSYS;
551 break; 617 break;
552 } 618 }
553
554 //req->errorno = errno;
555 619
556 LOCK (reslock); 620 LOCK (reslock);
557 621
558 ++npending; 622 ++npending;
559 623
651 { \ 715 { \
652 IV tmp = SvIV ((SV*) SvRV (arg)); \ 716 IV tmp = SvIV ((SV*) SvRV (arg)); \
653 (var) = INT2PTR (type, tmp); \ 717 (var) = INT2PTR (type, tmp); \
654 } \ 718 } \
655 else \ 719 else \
656 Perl_croak (# var " is not of type " # type) 720 Perl_croak (# var " is not of type " # class)
721
722inline void
723set_dbt (DBT *dbt, SV *sv)
724{
725 STRLEN len;
726 char *data = SvPVbyte (sv, len);
727
728 dbt->data = malloc (len);
729 memcpy (dbt->data, data, len);
730 dbt->size = len;
731}
657 732
658MODULE = BDB PACKAGE = BDB 733MODULE = BDB PACKAGE = BDB
659 734
660PROTOTYPES: ENABLE 735PROTOTYPES: ENABLE
661 736
734 const_iv (NOTFOUND) 809 const_iv (NOTFOUND)
735 const_iv (KEYEMPTY) 810 const_iv (KEYEMPTY)
736 const_iv (LOCK_DEADLOCK) 811 const_iv (LOCK_DEADLOCK)
737 const_iv (LOCK_NOTGRANTED) 812 const_iv (LOCK_NOTGRANTED)
738 const_iv (RUNRECOVERY) 813 const_iv (RUNRECOVERY)
814 const_iv (OLD_VERSION)
815 const_iv (REP_HANDLE_DEAD)
816 const_iv (REP_LOCKOUT)
817
818 const_iv (FREE_SPACE)
819 const_iv (FREELIST_ONLY)
820
821 const_iv (APPEND)
822 const_iv (NODUPDATA)
823 const_iv (NOOVERWRITE)
824
825 const_iv (SET_LOCK_TIMEOUT)
826 const_iv (SET_TXN_TIMEOUT)
739 }; 827 };
740 828
741 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 829 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
742 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 830 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
743 831
779 max_outstanding = maxreqs; 867 max_outstanding = maxreqs;
780 OUTPUT: 868 OUTPUT:
781 RETVAL 869 RETVAL
782 870
783int 871int
784bdbreq_pri (int pri = 0) 872dbreq_pri (int pri = 0)
785 PROTOTYPE: ;$ 873 PROTOTYPE: ;$
786 CODE: 874 CODE:
787 RETVAL = next_pri - PRI_BIAS; 875 RETVAL = next_pri - PRI_BIAS;
788 if (items > 0) 876 if (items > 0)
789 { 877 {
793 } 881 }
794 OUTPUT: 882 OUTPUT:
795 RETVAL 883 RETVAL
796 884
797void 885void
798bdbreq_nice (int nice = 0) 886dbreq_nice (int nice = 0)
799 CODE: 887 CODE:
800 nice = next_pri - nice; 888 nice = next_pri - nice;
801 if (nice < PRI_MIN) nice = PRI_MIN; 889 if (nice < PRI_MIN) nice = PRI_MIN;
802 if (nice > PRI_MAX) nice = PRI_MAX; 890 if (nice > PRI_MAX) nice = PRI_MAX;
803 next_pri = nice + PRI_BIAS; 891 next_pri = nice + PRI_BIAS;
811 poll_wait (); 899 poll_wait ();
812 poll_cb (); 900 poll_cb ();
813 } 901 }
814 902
815int 903int
816poll() 904poll ()
817 PROTOTYPE: 905 PROTOTYPE:
818 CODE: 906 CODE:
819 poll_wait (); 907 poll_wait ();
820 RETVAL = poll_cb (); 908 RETVAL = poll_cb ();
821 OUTPUT: 909 OUTPUT:
822 RETVAL 910 RETVAL
823 911
824int 912int
825poll_fileno() 913poll_fileno ()
826 PROTOTYPE: 914 PROTOTYPE:
827 CODE: 915 CODE:
828 RETVAL = respipe [0]; 916 RETVAL = respipe [0];
829 OUTPUT: 917 OUTPUT:
830 RETVAL 918 RETVAL
831 919
832int 920int
833poll_cb(...) 921poll_cb (...)
834 PROTOTYPE: 922 PROTOTYPE:
835 CODE: 923 CODE:
836 RETVAL = poll_cb (); 924 RETVAL = poll_cb ();
837 OUTPUT: 925 OUTPUT:
838 RETVAL 926 RETVAL
839 927
840void 928void
841poll_wait() 929poll_wait ()
842 PROTOTYPE: 930 PROTOTYPE:
843 CODE: 931 CODE:
844 poll_wait (); 932 poll_wait ();
845 933
846int 934int
847nreqs() 935nreqs ()
848 PROTOTYPE: 936 PROTOTYPE:
849 CODE: 937 CODE:
850 RETVAL = nreqs; 938 RETVAL = nreqs;
851 OUTPUT: 939 OUTPUT:
852 RETVAL 940 RETVAL
853 941
854int 942int
855nready() 943nready ()
856 PROTOTYPE: 944 PROTOTYPE:
857 CODE: 945 CODE:
858 RETVAL = get_nready (); 946 RETVAL = get_nready ();
859 OUTPUT: 947 OUTPUT:
860 RETVAL 948 RETVAL
861 949
862int 950int
863npending() 951npending ()
864 PROTOTYPE: 952 PROTOTYPE:
865 CODE: 953 CODE:
866 RETVAL = get_npending (); 954 RETVAL = get_npending ();
867 OUTPUT: 955 OUTPUT:
868 RETVAL 956 RETVAL
869 957
870int 958int
871nthreads() 959nthreads ()
872 PROTOTYPE: 960 PROTOTYPE:
873 CODE: 961 CODE:
874 if (WORDACCESS_UNSAFE) LOCK (wrklock); 962 if (WORDACCESS_UNSAFE) LOCK (wrklock);
875 RETVAL = started; 963 RETVAL = started;
876 if (WORDACCESS_UNSAFE) UNLOCK (wrklock); 964 if (WORDACCESS_UNSAFE) UNLOCK (wrklock);
877 OUTPUT: 965 OUTPUT:
878 RETVAL 966 RETVAL
879 967
968void
969set_sync_prepare (SV *cb)
970 PROTOTYPE: &
971 CODE:
972 SvREFCNT_dec (prepare_cb);
973 prepare_cb = newSVsv (cb);
974
880DB_ENV * 975DB_ENV *
881bdb_env_create (U32 env_flags = 0) 976db_env_create (U32 env_flags = 0)
882 CODE: 977 CODE:
883{ 978{
884 int err = db_env_create (&RETVAL, env_flags); 979 errno = db_env_create (&RETVAL, env_flags);
885 if (err) 980 if (errno)
886 croak ("db_env_create: %s", db_strerror (err)); 981 croak ("db_env_create: %s", db_strerror (errno));
887} 982}
983 OUTPUT:
984 RETVAL
888 985
889void 986void
890bdb_env_open (DB_ENV *env, char *db_home, U32 open_flags, int mode, SV *callback = 0) 987db_env_open (DB_ENV *env, octetstring db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef)
891 CODE: 988 CODE:
892{ 989{
893 dREQ (REQ_ENV_OPEN); 990 dREQ (REQ_ENV_OPEN);
894 req->env = env; 991 req->env = env;
895 req->uint1 = open_flags; 992 req->uint1 = open_flags | DB_THREAD;
896 req->int1 = mode; 993 req->int1 = mode;
897 req->buf1 = strdup (db_home); 994 req->buf1 = strdup_ornull (db_home);
898 REQ_SEND; 995 REQ_SEND;
899} 996}
900 997
901void 998void
902bdb_env_close (DB_ENV *env, U32 flags = 0, SV *callback = 0) 999db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = &PL_sv_undef)
903 CODE: 1000 CODE:
904{ 1001{
905 dREQ (REQ_ENV_CLOSE); 1002 dREQ (REQ_ENV_CLOSE);
906 req->env = env; 1003 req->env = env;
907 req->uint1 = flags; 1004 req->uint1 = flags;
908 REQ_SEND; 1005 REQ_SEND;
909} 1006}
910 1007
911DB * 1008DB *
912bdb_db_create (DB_ENV *env = 0, U32 flags = 0) 1009db_create (DB_ENV *env = 0, U32 flags = 0)
913 CODE: 1010 CODE:
914{ 1011{
915 int err = db_create (&RETVAL, env, flags); 1012 errno = db_create (&RETVAL, env, flags);
916 if (err) 1013 if (errno)
917 croak ("db_env_create: %s", db_strerror (err)); 1014 croak ("db_env_create: %s", db_strerror (errno));
918} 1015}
1016 OUTPUT:
1017 RETVAL
919 1018
920void 1019void
921bdb_db_open (DB *db, DB_TXN *txnid, const char *file, const char *database, int type, U32 flags, int mode, SV *callback = 0) 1020db_open (DB *db, DB_TXN *txnid, octetstring file, octetstring database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef)
922 CODE: 1021 CODE:
923{ 1022{
924 dREQ (REQ_DB_OPEN); 1023 dREQ (REQ_DB_OPEN);
925 req->db = db; 1024 req->db = db;
926 req->txn = txnid; 1025 req->txn = txnid;
927 req->buf1 = strdup (file); 1026 req->buf1 = strdup_ornull (file);
928 req->buf2 = strdup (database); 1027 req->buf2 = strdup_ornull (database);
929 req->int1 = type; 1028 req->int1 = type;
930 req->uint1 = flags; 1029 req->uint1 = flags | DB_THREAD;
931 req->int2 = mode; 1030 req->int2 = mode;
932 REQ_SEND; 1031 REQ_SEND;
933} 1032}
934 1033
935void 1034void
936bdb_db_close (DB *db, U32 flags = 0, SV *callback = 0) 1035db_close (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
937 CODE: 1036 CODE:
938{ 1037{
939 dREQ (REQ_DB_CLOSE); 1038 dREQ (REQ_DB_CLOSE);
940 req->db = db; 1039 req->db = db;
941 req->uint1 = flags; 1040 req->uint1 = flags;
942 REQ_SEND; 1041 REQ_SEND;
943} 1042}
944 1043
1044void
1045db_compact (DB *db, DB_TXN *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = &PL_sv_undef)
1046 CODE:
1047{
1048 dREQ (REQ_DB_COMPACT);
1049 req->db = db;
1050 req->txn = txn;
1051 set_dbt (&req->dbt1, start);
1052 set_dbt (&req->dbt2, stop);
1053 req->uint1 = flags;
1054 REQ_SEND;
1055}
1056
1057void
1058db_sync (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef)
1059 CODE:
1060{
1061 dREQ (REQ_DB_SYNC);
1062 req->db = db;
1063 req->uint1 = flags;
1064 REQ_SEND;
1065}
1066
1067void
1068db_put (DB *db, DB_TXN *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef)
1069 CODE:
1070{
1071 dREQ (REQ_DB_PUT);
1072 req->db = db;
1073 req->txn = 0;
1074 set_dbt (&req->dbt1, key);
1075 set_dbt (&req->dbt2, data);
1076 req->uint1 = flags;
1077 REQ_SEND;
1078}
1079
945 1080
946MODULE = BDB PACKAGE = BDB::Env 1081MODULE = BDB PACKAGE = BDB::Env
947 1082
948int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0) 1083int set_cachesize (DB_ENV *env, U32 gbytes, U32 bytes, int ncache = 0)
1084 CODE:
1085 RETVAL = env->set_cachesize (env, gbytes, bytes, ncache);
1086 OUTPUT:
1087 RETVAL
949 1088
950int set_flags (DB_ENV *env, U32 flags, int onoff) 1089int set_flags (DB_ENV *env, U32 flags, int onoff)
1090 CODE:
1091 RETVAL = env->set_flags (env, flags, onoff);
1092 OUTPUT:
1093 RETVAL
951 1094
952int set_encrypt (DB_ENV *env, const char *password, U32 flags) 1095int set_encrypt (DB_ENV *env, const char *password, U32 flags = 0)
1096 CODE:
1097 RETVAL = env->set_encrypt (env, password, flags);
1098 OUTPUT:
1099 RETVAL
1100
1101int set_timeout (DB_ENV *env, NV timeout, U32 flags)
1102 CODE:
1103 RETVAL = env->set_timeout (env, timeout * 1000000, flags);
1104 OUTPUT:
1105 RETVAL
1106
953 1107
954MODULE = BDB PACKAGE = BDB::Db 1108MODULE = BDB PACKAGE = BDB::Db
955 1109
956int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0) 1110int set_cachesize (DB *db, U32 gbytes, U32 bytes, int ncache = 0)
1111 CODE:
1112 RETVAL = db->set_cachesize (db, gbytes, bytes, ncache);
1113 OUTPUT:
1114 RETVAL
957 1115
958int set_flags (DB *env, U32 flags, int onoff) 1116int set_flags (DB *db, U32 flags);
1117 CODE:
1118 RETVAL = db->set_flags (db, flags);
1119 OUTPUT:
1120 RETVAL
959 1121
960int set_encrypt (DB *db, const char *password, U32 flags) 1122int set_encrypt (DB *db, const char *password, U32 flags)
1123 CODE:
1124 RETVAL = db->set_encrypt (db, password, flags);
1125 OUTPUT:
1126 RETVAL
961 1127
962int set_lorder (DB *db, int lorder) 1128int set_lorder (DB *db, int lorder)
1129 CODE:
1130 RETVAL = db->set_lorder (db, lorder);
1131 OUTPUT:
1132 RETVAL
963 1133
964 1134
965int set_bt_minkey (DB *db, U32 minkey) 1135int set_bt_minkey (DB *db, U32 minkey)
1136 CODE:
1137 RETVAL = db->set_bt_minkey (db, minkey);
1138 OUTPUT:
1139 RETVAL
966 1140
967int set_re_delim(DB *db, int delim); 1141int set_re_delim(DB *db, int delim);
1142 CODE:
1143 RETVAL = db->set_re_delim (db, delim);
1144 OUTPUT:
1145 RETVAL
968 1146
969int set_re_pad (DB *db, int re_pad) 1147int set_re_pad (DB *db, int re_pad)
1148 CODE:
1149 RETVAL = db->set_re_pad (db, re_pad);
1150 OUTPUT:
1151 RETVAL
970 1152
971int set_re_source (DB *db, char *source) 1153int set_re_source (DB *db, char *source)
1154 CODE:
1155 RETVAL = db->set_re_source (db, source);
1156 OUTPUT:
1157 RETVAL
972 1158
973int set_re_len (DB *db, U32 re_len) 1159int set_re_len (DB *db, U32 re_len)
1160 CODE:
1161 RETVAL = db->set_re_len (db, re_len);
1162 OUTPUT:
1163 RETVAL
974 1164
975int set_h_ffactor (DB *db, U32 h_ffactor) 1165int set_h_ffactor (DB *db, U32 h_ffactor)
1166 CODE:
1167 RETVAL = db->set_h_ffactor (db, h_ffactor);
1168 OUTPUT:
1169 RETVAL
976 1170
977int set_h_nelem (DB *db, U32 h_nelem) 1171int set_h_nelem (DB *db, U32 h_nelem)
1172 CODE:
1173 RETVAL = db->set_h_nelem (db, h_nelem);
1174 OUTPUT:
1175 RETVAL
978 1176
979int set_q_extentsize (DB *db, U32 extentsize) 1177int set_q_extentsize (DB *db, U32 extentsize)
1178 CODE:
1179 RETVAL = db->set_q_extentsize (db, extentsize);
1180 OUTPUT:
1181 RETVAL
980 1182
981 1183

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines