2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
10 static const char sccsid
[] = "@(#)mp_open.c 10.23 (Sleepycat) 5/3/98";
13 #ifndef NO_SYSTEM_INCLUDES
14 #include <sys/types.h>
24 #include "common_ext.h"
28 * Initialize and/or join a memory pool.
31 memp_open(path
, flags
, mode
, dbenv
, retp
)
42 /* Validate arguments. */
44 #define OKFLAGS (DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP | DB_THREAD)
46 #define OKFLAGS (DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP)
48 if ((ret
= __db_fchk(dbenv
, "memp_open", flags
, OKFLAGS
)) != 0)
51 /* Extract fields from DB_ENV structure. */
52 cachesize
= dbenv
== NULL
? 0 : dbenv
->mp_size
;
54 /* Create and initialize the DB_MPOOL structure. */
55 if ((dbmp
= (DB_MPOOL
*)__db_calloc(1, sizeof(DB_MPOOL
))) == NULL
)
57 LIST_INIT(&dbmp
->dbregq
);
58 TAILQ_INIT(&dbmp
->dbmfq
);
62 /* Decide if it's possible for anyone else to access the pool. */
64 (dbenv
== NULL
&& path
== NULL
) || LF_ISSET(DB_MPOOL_PRIVATE
);
67 * Map in the region. We do locking regardless, as portions of it are
68 * implemented in common code (if we put the region in a file, that is).
70 F_SET(dbmp
, MP_LOCKREGION
);
71 if ((ret
= __memp_ropen(dbmp
,
72 path
, cachesize
, mode
, is_private
, LF_ISSET(DB_CREATE
))) != 0)
74 F_CLR(dbmp
, MP_LOCKREGION
);
77 * If there's concurrent access, then we have to lock the region.
78 * If it's threaded, then we have to lock both the handles and the
79 * region, and we need to allocate a mutex for that purpose.
82 F_SET(dbmp
, MP_LOCKREGION
);
83 if (LF_ISSET(DB_THREAD
)) {
84 F_SET(dbmp
, MP_LOCKHANDLE
| MP_LOCKREGION
);
86 ret
= __memp_ralloc(dbmp
,
87 sizeof(db_mutex_t
), NULL
, &dbmp
->mutexp
);
90 (void)memp_close(dbmp
);
93 LOCKINIT(dbmp
, dbmp
->mutexp
);
99 err
: if (dbmp
!= NULL
)
100 FREE(dbmp
, sizeof(DB_MPOOL
));
106 * Close a memory pool.
118 /* Discard DB_MPREGs. */
119 while ((mpreg
= LIST_FIRST(&dbmp
->dbregq
)) != NULL
) {
120 LIST_REMOVE(mpreg
, q
);
121 FREE(mpreg
, sizeof(DB_MPREG
));
124 /* Discard DB_MPOOLFILEs. */
125 while ((dbmfp
= TAILQ_FIRST(&dbmp
->dbmfq
)) != NULL
)
126 if ((t_ret
= memp_fclose(dbmfp
)) != 0 && ret
== 0)
129 /* Discard thread mutex. */
130 if (F_ISSET(dbmp
, MP_LOCKHANDLE
)) {
132 __db_shalloc_free(dbmp
->addr
, dbmp
->mutexp
);
136 /* Close the region. */
137 if ((t_ret
= __db_rdetach(&dbmp
->reginfo
)) != 0 && ret
== 0)
140 if (dbmp
->reginfo
.path
!= NULL
)
141 FREES(dbmp
->reginfo
.path
);
142 FREE(dbmp
, sizeof(DB_MPOOL
));
149 * Exit a memory pool.
152 memp_unlink(path
, force
, dbenv
)
160 memset(®info
, 0, sizeof(reginfo
));
161 reginfo
.dbenv
= dbenv
;
162 reginfo
.appname
= DB_APP_NONE
;
163 if (path
!= NULL
&& (reginfo
.path
= __db_strdup(path
)) == NULL
)
165 reginfo
.file
= DB_DEFAULT_MPOOL_FILE
;
166 ret
= __db_runlink(®info
, force
);
167 if (reginfo
.path
!= NULL
)
174 * Register a file type's pgin, pgout routines.
177 memp_register(dbmp
, ftype
, pgin
, pgout
)
180 int (*pgin
) __P((db_pgno_t
, void *, DBT
*));
181 int (*pgout
) __P((db_pgno_t
, void *, DBT
*));
185 if ((mpr
= (DB_MPREG
*)__db_malloc(sizeof(DB_MPREG
))) == NULL
)
193 * Insert at the head. Because we do a linear walk, we'll find
194 * the most recent registry in the case of multiple entries, so
195 * we don't have to check for multiple registries.
197 LOCKHANDLE(dbmp
, dbmp
->mutexp
);
198 LIST_INSERT_HEAD(&dbmp
->dbregq
, mpr
, q
);
199 UNLOCKHANDLE(dbmp
, dbmp
->mutexp
);