2 * See the file LICENSE for redistribution information.
5 * Sleepycat Software. All rights reserved.
8 #pragma ident "%Z%%M% %I% %E% SMI"
13 static const char sccsid
[] = "@(#)xa_db.c 10.6 (Sleepycat) 12/19/98";
16 #ifndef NO_SYSTEM_INCLUDES
17 #include <sys/types.h>
30 #include "common_ext.h"
32 static int __xa_c_close
__P((DBC
*));
33 static int __xa_c_del
__P((DBC
*, u_int32_t
));
34 static int __xa_c_get
__P((DBC
*, DBT
*, DBT
*, u_int32_t
));
35 static int __xa_c_put
__P((DBC
*, DBT
*, DBT
*, u_int32_t
));
36 static int __xa_close
__P((DB
*, u_int32_t
));
37 static int __xa_cursor
__P((DB
*, DB_TXN
*, DBC
**, u_int32_t
));
38 static int __xa_del
__P((DB
*, DB_TXN
*, DBT
*, u_int32_t
));
39 static int __xa_fd
__P((DB
*, int *));
40 static int __xa_get
__P((DB
*, DB_TXN
*, DBT
*, DBT
*, u_int32_t
));
41 static int __xa_put
__P((DB
*, DB_TXN
*, DBT
*, DBT
*, u_int32_t
));
42 static int __xa_stat
__P((DB
*, void *, void *(*)(size_t), u_int32_t
));
43 static int __xa_sync
__P((DB
*, u_int32_t
));
46 db_xa_open(fname
, type
, flags
, mode
, dbinfo
, dbpp
)
60 * First try to open up the underlying DB.
63 * The dbenv argument is taken from the global list of environments.
64 * When the transaction manager called xa_start() (__db_xa_start()),
65 * the "current" DB environment was moved to the start of the list.
66 * However, if we were called in a tpsvrinit function (which is
67 * entirely plausible), then it's possible that xa_open was called
68 * (which simply recorded the name of the environment to open) and
69 * this is the next call into DB. In that case, we still have to
70 * open the environment.
72 * The way that we know that xa_open and nothing else was called
73 * is because the nameq is not NULL.
75 if ((rp
= TAILQ_FIRST(&DB_GLOBAL(db_nameq
))) != NULL
&&
76 (ret
= __db_rmid_to_env(rp
->rmid
, &dbenv
, 1)) != 0)
79 dbenv
= TAILQ_FIRST(&DB_GLOBAL(db_envq
));
80 if ((ret
= db_open(fname
,
81 type
, flags
, mode
, dbenv
, dbinfo
, &real_dbp
)) != 0)
85 * Allocate our own DB handle, and copy the exported fields and
86 * function pointers into it. The internal pointer references
87 * the real underlying DB handle.
89 if ((ret
= __os_calloc(1, sizeof(DB
), &dbp
)) != 0) {
90 (void)real_dbp
->close(real_dbp
, 0);
93 dbp
->type
= real_dbp
->type
;
94 dbp
->byteswapped
= real_dbp
->byteswapped
;
96 dbp
->internal
= real_dbp
;
97 TAILQ_INIT(&dbp
->active_queue
);
98 TAILQ_INIT(&dbp
->free_queue
);
99 dbp
->close
= __xa_close
;
100 dbp
->cursor
= __xa_cursor
;
104 dbp
->join
= real_dbp
->join
;
106 dbp
->stat
= __xa_stat
;
107 dbp
->sync
= __xa_sync
;
114 __xa_close(dbp
, flags
)
122 /* Close any associated cursors. */
123 while ((dbc
= TAILQ_FIRST(&dbp
->active_queue
)) != NULL
)
124 (void)dbc
->c_close(dbc
);
126 /* Close the DB handle. */
127 real_dbp
= (DB
*)dbp
->internal
;
128 ret
= real_dbp
->close(real_dbp
, flags
);
130 __os_free(dbp
, sizeof(DB
));
135 __xa_cursor(dbp
, txn
, dbcp
, flags
)
145 real_dbp
= (DB
*)dbp
->internal
;
146 txn
= dbp
->dbenv
->xa_txn
;
148 if ((ret
= real_dbp
->cursor(real_dbp
, txn
, &real_dbc
, flags
)) != 0)
152 * Allocate our own DBC handle, and copy the exported fields and
153 * function pointers into it. The internal pointer references
154 * the real underlying DBC handle.
156 if ((ret
= __os_calloc(1, sizeof(DBC
), &dbc
)) != 0) {
157 (void)real_dbc
->c_close(real_dbc
);
161 dbc
->c_close
= __xa_c_close
;
162 dbc
->c_del
= __xa_c_del
;
163 dbc
->c_get
= __xa_c_get
;
164 dbc
->c_put
= __xa_c_put
;
165 dbc
->internal
= real_dbc
;
166 TAILQ_INSERT_TAIL(&dbp
->active_queue
, dbc
, links
);
179 COMPQUIET(fdp
, NULL
);
181 real_dbp
= (DB
*)dbp
->internal
;
182 return (__db_eopnotsup(real_dbp
->dbenv
));
186 __xa_del(dbp
, txn
, key
, flags
)
194 real_dbp
= (DB
*)dbp
->internal
;
195 txn
= dbp
->dbenv
->xa_txn
;
197 return (real_dbp
->del(real_dbp
, txn
, key
, flags
));
201 __xa_get(dbp
, txn
, key
, data
, flags
)
210 real_dbp
= (DB
*)dbp
->internal
;
211 txn
= dbp
->dbenv
->xa_txn
;
213 return (real_dbp
->get(real_dbp
, txn
, key
, data
, flags
));
217 __xa_put(dbp
, txn
, key
, data
, flags
)
226 real_dbp
= (DB
*)dbp
->internal
;
227 txn
= dbp
->dbenv
->xa_txn
;
229 return (real_dbp
->put(real_dbp
, txn
, key
, data
, flags
));
233 __xa_stat(dbp
, spp
, db_malloc
, flags
)
236 void *(*db_malloc
) __P((size_t));
241 real_dbp
= (DB
*)dbp
->internal
;
242 return (real_dbp
->stat(real_dbp
, spp
, db_malloc
, flags
));
246 __xa_sync(dbp
, flags
)
252 real_dbp
= (DB
*)dbp
->internal
;
253 return (real_dbp
->sync(real_dbp
, flags
));
263 real_dbc
= (DBC
*)dbc
->internal
;
265 ret
= real_dbc
->c_close(real_dbc
);
267 TAILQ_REMOVE(&dbc
->dbp
->active_queue
, dbc
, links
);
268 __os_free(dbc
, sizeof(DBC
));
274 __xa_c_del(dbc
, flags
)
280 real_dbc
= (DBC
*)dbc
->internal
;
281 return (real_dbc
->c_del(real_dbc
, flags
));
285 __xa_c_get(dbc
, key
, data
, flags
)
293 real_dbc
= (DBC
*)dbc
->internal
;
294 return (real_dbc
->c_get(real_dbc
, key
, data
, flags
));
298 __xa_c_put(dbc
, key
, data
, flags
)
306 real_dbc
= (DBC
*)dbc
->internal
;
307 return (real_dbc
->c_put(real_dbc
, key
, data
, flags
));