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

Comparing BDB/BDB.xs (file contents):
Revision 1.53 by root, Thu Sep 25 22:09:02 2008 UTC vs.
Revision 1.59 by root, Mon Oct 20 02:31:51 2008 UTC

1#include <sys/user.h>
2#include <sys/ptrace.h>
3
4#define X_STACKSIZE 1024 * 128 + sizeof (long) * 64 * 1024 / 4 1#define X_STACKSIZE 1024 * 128 + sizeof (long) * 64 * 1024 / 4
5 2
6#include "xthread.h" 3#include "xthread.h"
7 4
8#include <errno.h> 5#include <errno.h>
39#endif 36#endif
40 37
41/* number of seconds after which idle threads exit */ 38/* number of seconds after which idle threads exit */
42#define IDLE_TIMEOUT 10 39#define IDLE_TIMEOUT 10
43 40
41typedef SV SV_mutable;
42
44typedef DB_ENV DB_ENV_ornull; 43typedef DB_ENV DB_ENV_ornull;
45typedef DB_TXN DB_TXN_ornull; 44typedef DB_TXN DB_TXN_ornull;
46typedef DBC DBC_ornull; 45typedef DBC DBC_ornull;
47typedef DB DB_ornull; 46typedef DB DB_ornull;
48 47
54#if DB_VERSION_MINOR >= 3 53#if DB_VERSION_MINOR >= 3
55typedef DB_SEQUENCE DB_SEQUENCE_ornull; 54typedef DB_SEQUENCE DB_SEQUENCE_ornull;
56typedef DB_SEQUENCE DB_SEQUENCE_ornuked; 55typedef DB_SEQUENCE DB_SEQUENCE_ornuked;
57#endif 56#endif
58 57
59typedef SV SV8; /* byte-sv, used for argument-checking */
60typedef char *bdb_filename; 58typedef char *bdb_filename;
61 59
62static SV *prepare_cb; 60static SV *prepare_cb;
63 61
64#if DB_VERSION_MINOR >= 6 62#if DB_VERSION_MINOR >= 6
135dbt_to_sv (SV *sv, DBT *dbt) 133dbt_to_sv (SV *sv, DBT *dbt)
136{ 134{
137 if (sv) 135 if (sv)
138 { 136 {
139 SvREADONLY_off (sv); 137 SvREADONLY_off (sv);
140 sv_setsv_mg (sv, dbt->data ? newSVpvn (dbt->data, dbt->size) : &PL_sv_undef); 138
139 if (dbt->data)
140 sv_setpvn_mg (sv, dbt->data, dbt->size);
141 else
142 sv_setsv_mg (sv, &PL_sv_undef);
143
141 SvREFCNT_dec (sv); 144 SvREFCNT_dec (sv);
142 } 145 }
143 146
144 //assert (dbt->flags & DBT_MALLOC || !dbt->data);
145 free (dbt->data); 147 free (dbt->data);
146} 148}
147 149
148enum { 150enum {
149 REQ_QUIT, 151 REQ_QUIT,
347 abort (); 349 abort ();
348} 350}
349 351
350static int poll_cb (void); 352static int poll_cb (void);
351static void req_free (bdb_req req); 353static void req_free (bdb_req req);
352static void req_cancel (bdb_req req);
353 354
354static int req_invoke (bdb_req req) 355static int req_invoke (bdb_req req)
355{ 356{
356 switch (req->type) 357 switch (req->type)
357 { 358 {
359 SvREFCNT_dec (req->sv1); 360 SvREFCNT_dec (req->sv1);
360 break; 361 break;
361 362
362 case REQ_DB_GET: 363 case REQ_DB_GET:
363 case REQ_DB_PGET: 364 case REQ_DB_PGET:
364 dbt_to_sv (req->sv3, &req->dbt3);
365 break;
366
367 case REQ_C_GET: 365 case REQ_C_GET:
368 case REQ_C_PGET: 366 case REQ_C_PGET:
367 case REQ_DB_PUT:
368 case REQ_C_PUT:
369 dbt_to_sv (req->sv1, &req->dbt1); 369 dbt_to_sv (req->sv1, &req->dbt1);
370 dbt_to_sv (req->sv2, &req->dbt2); 370 dbt_to_sv (req->sv2, &req->dbt2);
371 dbt_to_sv (req->sv3, &req->dbt3); 371 dbt_to_sv (req->sv3, &req->dbt3);
372 break;
373
374 case REQ_DB_PUT:
375 case REQ_C_PUT:
376 dbt_to_sv (0, &req->dbt1);
377 dbt_to_sv (0, &req->dbt2);
378 break; 372 break;
379 373
380 case REQ_DB_KEY_RANGE: 374 case REQ_DB_KEY_RANGE:
381 { 375 {
382 AV *av = newAV (); 376 AV *av = newAV ();
555 PUTBACK; 549 PUTBACK;
556 count = call_sv (prepare_cb, G_ARRAY); 550 count = call_sv (prepare_cb, G_ARRAY);
557 SPAGAIN; 551 SPAGAIN;
558 552
559 if (count != 2) 553 if (count != 2)
560 croak ("prepare callback must return exactly two values\n"); 554 croak ("sync prepare callback must return exactly two values\n");
561 555
562 wait_callback = POPs; 556 wait_callback = POPs;
563 req->callback = SvREFCNT_inc (POPs); 557 req->callback = SvREFCNT_inc (POPs);
564 } 558 }
565 else 559 else
1050 } \ 1044 } \
1051 else if (sv_derived_from ((arg), # class)) \ 1045 else if (sv_derived_from ((arg), # class)) \
1052 { \ 1046 { \
1053 IV tmp = SvIV ((SV*) SvRV (arg)); \ 1047 IV tmp = SvIV ((SV*) SvRV (arg)); \
1054 (var) = INT2PTR (type, tmp); \ 1048 (var) = INT2PTR (type, tmp); \
1055 if (!var && nullok != 2) \ 1049 if (!var && nullok != 2) \
1056 croak (# var " is not a valid " # class " object anymore"); \ 1050 croak (# var " is not a valid " # class " object anymore"); \
1057 } \ 1051 } \
1058 else \ 1052 else \
1059 croak (# var " is not of type " # class); 1053 croak (# var " is not of type " # class);
1054
1055#define ARG_MUTABLE(name) \
1056 if (SvREADONLY (name)) \
1057 croak ("argument " #name " is read-only/constant, but the request requires it to be mutable");
1060 1058
1061static void 1059static void
1062ptr_nuke (SV *sv) 1060ptr_nuke (SV *sv)
1063{ 1061{
1064 assert (SvROK (sv)); 1062 assert (SvROK (sv));
1135 } 1133 }
1136 1134
1137 return 0; 1135 return 0;
1138} 1136}
1139 1137
1140/* stupid windoes defined CALLBACK as well */ 1138/* stupid windows defines CALLBACK as well */
1141#undef CALLBACK 1139#undef CALLBACK
1142#define CALLBACK SV *cb = pop_callback (&items, ST (items - 1)); 1140#define CALLBACK SV *cb = pop_callback (&items, ST (items - 1));
1143 1141
1144MODULE = BDB PACKAGE = BDB 1142MODULE = BDB PACKAGE = BDB
1145 1143
1550db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = 0) 1548db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = 0)
1551 PREINIT: 1549 PREINIT:
1552 CALLBACK 1550 CALLBACK
1553 CODE: 1551 CODE:
1554{ 1552{
1555 dREQ (REQ_ENV_CLOSE, 1); 1553 dREQ (REQ_ENV_CLOSE, 0);
1554 ptr_nuke (ST (0));
1556 req->env = env; 1555 req->env = env;
1557 req->uint1 = flags; 1556 req->uint1 = flags;
1558 REQ_SEND; 1557 REQ_SEND;
1559 ptr_nuke (ST (0));
1560} 1558}
1561 1559
1562void 1560void
1563db_env_txn_checkpoint (DB_ENV *env, U32 kbyte = 0, U32 min = 0, U32 flags = 0, SV *callback = 0) 1561db_env_txn_checkpoint (DB_ENV *env, U32 kbyte = 0, U32 min = 0, U32 flags = 0, SV *callback = 0)
1564 PREINIT: 1562 PREINIT:
1674db_close (DB *db, U32 flags = 0, SV *callback = 0) 1672db_close (DB *db, U32 flags = 0, SV *callback = 0)
1675 PREINIT: 1673 PREINIT:
1676 CALLBACK 1674 CALLBACK
1677 CODE: 1675 CODE:
1678{ 1676{
1679 dREQ (REQ_DB_CLOSE, 1); 1677 dREQ (REQ_DB_CLOSE, 0);
1678 ptr_nuke (ST (0));
1680 req->db = db; 1679 req->db = db;
1681 req->uint1 = flags; 1680 req->uint1 = flags;
1682 req->sv1 = (SV *)db->app_private; 1681 req->sv1 = (SV *)db->app_private;
1683 REQ_SEND; 1682 REQ_SEND;
1684 ptr_nuke (ST (0));
1685} 1683}
1686 1684
1687#if DB_VERSION_MINOR >= 4 1685#if DB_VERSION_MINOR >= 4
1688 1686
1689void 1687void
1727 req->uint1 = flags; 1725 req->uint1 = flags;
1728 REQ_SEND; 1726 REQ_SEND;
1729} 1727}
1730 1728
1731void 1729void
1732db_key_range (DB *db, DB_TXN_ornull *txn, SV *key, SV *key_range, U32 flags = 0, SV *callback = 0) 1730db_key_range (DB *db, DB_TXN_ornull *txn, SV *key, SV_mutable *key_range, U32 flags = 0, SV *callback = 0)
1733 PREINIT: 1731 PREINIT:
1734 CALLBACK 1732 CALLBACK
1735 CODE: 1733 CODE:
1736{ 1734{
1737 dREQ (REQ_DB_KEY_RANGE, 2); 1735 dREQ (REQ_DB_KEY_RANGE, 2);
1775} 1773}
1776 1774
1777#endif 1775#endif
1778 1776
1779void 1777void
1780db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = 0) 1778db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV_mutable *data, U32 flags = 0, SV *callback = 0)
1781 PREINIT: 1779 PREINIT:
1782 CALLBACK 1780 CALLBACK
1783 CODE: 1781 CODE:
1784 if (SvREADONLY (data))
1785 croak ("can't modify read-only data scalar in db_get");
1786{ 1782{
1783 //TODO: key is somtimesmutable
1787 dREQ (REQ_DB_GET, 2); 1784 dREQ (REQ_DB_GET, 2);
1788 req->db = db; 1785 req->db = db;
1789 req->txn = txn; 1786 req->txn = txn;
1790 req->uint1 = flags; 1787 req->uint1 = flags;
1791 sv_to_dbt (&req->dbt1, key); 1788 sv_to_dbt (&req->dbt1, key);
1793 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); 1790 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1794 REQ_SEND; 1791 REQ_SEND;
1795} 1792}
1796 1793
1797void 1794void
1798db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = 0) 1795db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV_mutable *pkey, SV_mutable *data, U32 flags = 0, SV *callback = 0)
1799 PREINIT: 1796 PREINIT:
1800 CALLBACK 1797 CALLBACK
1801 CODE: 1798 CODE:
1802 if (SvREADONLY (data))
1803 croak ("can't modify read-only data scalar in db_pget");
1804{ 1799{
1800 //TODO: key is somtimesmutable
1805 dREQ (REQ_DB_PGET, 2); 1801 dREQ (REQ_DB_PGET, 2);
1806 req->db = db; 1802 req->db = db;
1807 req->txn = txn; 1803 req->txn = txn;
1808 req->uint1 = flags; 1804 req->uint1 = flags;
1805
1809 sv_to_dbt (&req->dbt1, key); 1806 sv_to_dbt (&req->dbt1, key);
1810 sv_to_dbt (&req->dbt2, pkey); 1807
1808 req->dbt2.flags = DB_DBT_MALLOC;
1809 req->sv2 = SvREFCNT_inc (pkey); SvREADONLY_on (pkey);
1810
1811 req->dbt3.flags = DB_DBT_MALLOC; 1811 req->dbt3.flags = DB_DBT_MALLOC;
1812 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); 1812 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1813 REQ_SEND; 1813 REQ_SEND;
1814} 1814}
1815 1815
1831db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = 0) 1831db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = 0)
1832 PREINIT: 1832 PREINIT:
1833 CALLBACK 1833 CALLBACK
1834 CODE: 1834 CODE:
1835{ 1835{
1836 dREQ (REQ_TXN_COMMIT, 1); 1836 dREQ (REQ_TXN_COMMIT, 0);
1837 ptr_nuke (ST (0));
1837 req->txn = txn; 1838 req->txn = txn;
1838 req->uint1 = flags; 1839 req->uint1 = flags;
1839 REQ_SEND; 1840 REQ_SEND;
1841}
1842
1843void
1844db_txn_abort (DB_TXN *txn, SV *callback = 0)
1845 PREINIT:
1846 CALLBACK
1847 CODE:
1848{
1849 dREQ (REQ_TXN_ABORT, 0);
1840 ptr_nuke (ST (0)); 1850 ptr_nuke (ST (0));
1841}
1842
1843void
1844db_txn_abort (DB_TXN *txn, SV *callback = 0)
1845 PREINIT:
1846 CALLBACK
1847 CODE:
1848{
1849 dREQ (REQ_TXN_ABORT, 1);
1850 req->txn = txn; 1851 req->txn = txn;
1851 REQ_SEND; 1852 REQ_SEND;
1853}
1854
1855void
1856db_txn_finish (DB_TXN *txn, U32 flags = 0, SV *callback = 0)
1857 PREINIT:
1858 CALLBACK
1859 CODE:
1860{
1861 dREQ (REQ_TXN_FINISH, 0);
1852 ptr_nuke (ST (0)); 1862 ptr_nuke (ST (0));
1853}
1854
1855void
1856db_txn_finish (DB_TXN *txn, U32 flags = 0, SV *callback = 0)
1857 PREINIT:
1858 CALLBACK
1859 CODE:
1860{
1861 dREQ (REQ_TXN_FINISH, 1);
1862 req->txn = txn; 1863 req->txn = txn;
1863 req->uint1 = flags; 1864 req->uint1 = flags;
1864 REQ_SEND; 1865 REQ_SEND;
1866}
1867
1868void
1869db_c_close (DBC *dbc, SV *callback = 0)
1870 PREINIT:
1871 CALLBACK
1872 CODE:
1873{
1874 dREQ (REQ_C_CLOSE, 0);
1865 ptr_nuke (ST (0)); 1875 ptr_nuke (ST (0));
1866}
1867
1868void
1869db_c_close (DBC *dbc, SV *callback = 0)
1870 PREINIT:
1871 CALLBACK
1872 CODE:
1873{
1874 dREQ (REQ_C_CLOSE, 1);
1875 req->dbc = dbc; 1876 req->dbc = dbc;
1876 REQ_SEND; 1877 REQ_SEND;
1877 ptr_nuke (ST (0));
1878} 1878}
1879 1879
1880void 1880void
1881db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = 0) 1881db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = 0)
1882 PREINIT: 1882 PREINIT:
1902 req->uint1 = flags; 1902 req->uint1 = flags;
1903 REQ_SEND; 1903 REQ_SEND;
1904} 1904}
1905 1905
1906void 1906void
1907db_c_get (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = 0) 1907db_c_get (DBC *dbc, SV *key, SV_mutable *data, U32 flags = 0, SV *callback = 0)
1908 PREINIT: 1908 PREINIT:
1909 CALLBACK 1909 CALLBACK
1910 CODE: 1910 CODE:
1911{ 1911{
1912 if (flags & DB_OPFLAGS_MASK != DB_SET && SvREADONLY (key))
1913 croak ("db_c_get was passed a read-only/constant 'key' argument but operation is not DB_SET");
1914 if (SvPOKp (key) && !sv_utf8_downgrade (key, 1))
1915 croak ("argument \"%s\" must be byte/octet-encoded in %s",
1916 "key",
1917 "BDB::db_c_get");
1918
1919 {
1912 dREQ (REQ_C_GET, 1); 1920 dREQ (REQ_C_GET, 1);
1913 req->dbc = dbc; 1921 req->dbc = dbc;
1914 req->uint1 = flags; 1922 req->uint1 = flags;
1915 if ((flags & DB_SET) == DB_SET 1923 if (flags & DB_OPFLAGS_MASK == DB_SET)
1916 || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1917 sv_to_dbt (&req->dbt1, key); 1924 sv_to_dbt (&req->dbt1, key);
1918 else 1925 else
1926 {
1927 if (flags & DB_OPFLAGS_MASK == DB_SET_RANGE)
1928 sv_to_dbt (&req->dbt1, key);
1929 else
1919 req->dbt1.flags = DB_DBT_MALLOC; 1930 req->dbt1.flags = DB_DBT_MALLOC;
1920 1931
1921 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key); 1932 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1933 }
1922 1934
1923 if ((flags & DB_GET_BOTH) == DB_GET_BOTH 1935 if (flags & DB_OPFLAGS_MASK == DB_GET_BOTH
1924 || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE) 1936 || flags & DB_OPFLAGS_MASK == DB_GET_BOTH_RANGE)
1925 sv_to_dbt (&req->dbt3, data); 1937 sv_to_dbt (&req->dbt3, data);
1926 else 1938 else
1927 req->dbt3.flags = DB_DBT_MALLOC; 1939 req->dbt3.flags = DB_DBT_MALLOC;
1928 1940
1929 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); 1941 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1930 REQ_SEND; 1942 REQ_SEND;
1943 }
1931} 1944}
1932 1945
1933void 1946void
1934db_c_pget (DBC *dbc, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = 0) 1947db_c_pget (DBC *dbc, SV *key, SV_mutable *pkey, SV_mutable *data, U32 flags = 0, SV *callback = 0)
1935 PREINIT: 1948 PREINIT:
1936 CALLBACK 1949 CALLBACK
1937 CODE: 1950 CODE:
1938{ 1951{
1952 if (flags & DB_OPFLAGS_MASK != DB_SET && SvREADONLY (key))
1953 croak ("db_c_pget was passed a read-only/constant 'key' argument but operation is not DB_SET");
1954 if (SvPOKp (key) && !sv_utf8_downgrade (key, 1))
1955 croak ("argument \"%s\" must be byte/octet-encoded in %s",
1956 "key",
1957 "BDB::db_c_pget");
1958
1959 {
1939 dREQ (REQ_C_PGET, 1); 1960 dREQ (REQ_C_PGET, 1);
1940 req->dbc = dbc; 1961 req->dbc = dbc;
1941 req->uint1 = flags; 1962 req->uint1 = flags;
1942 if ((flags & DB_SET) == DB_SET 1963 if (flags & DB_OPFLAGS_MASK == DB_SET)
1943 || (flags & DB_SET_RANGE) == DB_SET_RANGE)
1944 sv_to_dbt (&req->dbt1, key); 1964 sv_to_dbt (&req->dbt1, key);
1945 else 1965 else
1966 {
1967 if (flags & DB_OPFLAGS_MASK == DB_SET_RANGE)
1968 sv_to_dbt (&req->dbt1, key);
1969 else
1970 req->dbt1.flags = DB_DBT_MALLOC;
1971
1972 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1973 }
1974
1946 req->dbt1.flags = DB_DBT_MALLOC; 1975 req->dbt2.flags = DB_DBT_MALLOC;
1947
1948 req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key);
1949
1950 req->dbt2.flags = DB_DBT_MALLOC;
1951 req->sv2 = SvREFCNT_inc (pkey); SvREADONLY_on (pkey); 1976 req->sv2 = SvREFCNT_inc (pkey); SvREADONLY_on (pkey);
1952 1977
1953 if ((flags & DB_GET_BOTH) == DB_GET_BOTH 1978 if (flags & DB_OPFLAGS_MASK == DB_GET_BOTH
1954 || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE) 1979 || flags & DB_OPFLAGS_MASK == DB_GET_BOTH_RANGE)
1955 sv_to_dbt (&req->dbt3, data); 1980 sv_to_dbt (&req->dbt3, data);
1956 else 1981 else
1957 req->dbt3.flags = DB_DBT_MALLOC; 1982 req->dbt3.flags = DB_DBT_MALLOC;
1958 1983
1959 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); 1984 req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data);
1960 REQ_SEND; 1985 REQ_SEND;
1986 }
1961} 1987}
1962 1988
1963void 1989void
1964db_c_del (DBC *dbc, U32 flags = 0, SV *callback = 0) 1990db_c_del (DBC *dbc, U32 flags = 0, SV *callback = 0)
1965 PREINIT: 1991 PREINIT:
1993db_sequence_close (DB_SEQUENCE *seq, U32 flags = 0, SV *callback = 0) 2019db_sequence_close (DB_SEQUENCE *seq, U32 flags = 0, SV *callback = 0)
1994 PREINIT: 2020 PREINIT:
1995 CALLBACK 2021 CALLBACK
1996 CODE: 2022 CODE:
1997{ 2023{
1998 dREQ (REQ_SEQ_CLOSE, 1); 2024 dREQ (REQ_SEQ_CLOSE, 0);
2025 ptr_nuke (ST (0));
1999 req->seq = seq; 2026 req->seq = seq;
2000 req->uint1 = flags; 2027 req->uint1 = flags;
2001 REQ_SEND; 2028 REQ_SEND;
2002 ptr_nuke (ST (0));
2003} 2029}
2004 2030
2005void 2031void
2006db_sequence_get (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, int delta, SV *seq_value, U32 flags = DB_TXN_NOSYNC, SV *callback = 0) 2032db_sequence_get (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, int delta, SV_mutable *seq_value, U32 flags = DB_TXN_NOSYNC, SV *callback = 0)
2007 PREINIT: 2033 PREINIT:
2008 CALLBACK 2034 CALLBACK
2009 CODE: 2035 CODE:
2010{ 2036{
2011 dREQ (REQ_SEQ_GET, 2); 2037 dREQ (REQ_SEQ_GET, 2);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines