2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997
5 * Sleepycat Software. All rights reserved.
10 static const char sccsid
[] = "@(#)mp_open.c 10.15 (Sleepycat) 10/25/97";
13 #ifndef NO_SYSTEM_INCLUDES
14 #include <sys/types.h>
27 #include "common_ext.h"
31 * Initialize and/or join a memory pool.
34 memp_open(path
, flags
, mode
, dbenv
, retp
)
44 /* Validate arguments. */
46 #define OKFLAGS (DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP | DB_THREAD)
48 #define OKFLAGS (DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP)
50 if ((ret
= __db_fchk(dbenv
, "memp_open", flags
, OKFLAGS
)) != 0)
53 /* Extract fields from DB_ENV structure. */
54 cachesize
= dbenv
== NULL
? 0 : dbenv
->mp_size
;
56 /* Create and initialize the DB_MPOOL structure. */
57 if ((dbmp
= (DB_MPOOL
*)__db_calloc(1, sizeof(DB_MPOOL
))) == NULL
)
59 LIST_INIT(&dbmp
->dbregq
);
60 TAILQ_INIT(&dbmp
->dbmfq
);
64 /* Decide if it's possible for anyone else to access the pool. */
65 if ((dbenv
== NULL
&& path
== NULL
) || LF_ISSET(DB_MPOOL_PRIVATE
))
66 F_SET(dbmp
, MP_ISPRIVATE
);
70 * HP-UX won't permit mutexes to live in anything but shared memory.
71 * So, we have to instantiate the shared mpool region file on that
72 * architecture, regardless. If this turns out to be a performance
73 * problem, we could probably use anonymous memory instead.
76 F_CLR(dbmp
, MP_ISPRIVATE
);
80 * Map in the region. We do locking regardless, as portions of it are
81 * implemented in common code (if we put the region in a file, that is).
83 F_SET(dbmp
, MP_LOCKREGION
);
84 if ((ret
= __memp_ropen(dbmp
, path
, cachesize
, mode
, flags
)) != 0)
86 F_CLR(dbmp
, MP_LOCKREGION
);
89 * If there's concurrent access, then we have to lock the region.
90 * If it's threaded, then we have to lock both the handles and the
91 * region, and we need to allocate a mutex for that purpose.
93 if (!F_ISSET(dbmp
, MP_ISPRIVATE
))
94 F_SET(dbmp
, MP_LOCKREGION
);
95 if (LF_ISSET(DB_THREAD
)) {
96 F_SET(dbmp
, MP_LOCKHANDLE
| MP_LOCKREGION
);
98 ret
= __memp_ralloc(dbmp
,
99 sizeof(db_mutex_t
), NULL
, &dbmp
->mutexp
);
102 (void)memp_close(dbmp
);
105 LOCKINIT(dbmp
, dbmp
->mutexp
);
111 err
: if (dbmp
!= NULL
)
112 FREE(dbmp
, sizeof(DB_MPOOL
));
118 * Close a memory pool.
130 /* Discard DB_MPREGs. */
131 while ((mpreg
= LIST_FIRST(&dbmp
->dbregq
)) != NULL
) {
132 LIST_REMOVE(mpreg
, q
);
133 FREE(mpreg
, sizeof(DB_MPREG
));
136 /* Discard DB_MPOOLFILEs. */
137 while ((dbmfp
= TAILQ_FIRST(&dbmp
->dbmfq
)) != NULL
)
138 if ((t_ret
= memp_fclose(dbmfp
)) != 0 && ret
== 0)
141 /* Discard thread mutex. */
142 if (F_ISSET(dbmp
, MP_LOCKHANDLE
)) {
144 __db_shalloc_free(dbmp
->addr
, dbmp
->mutexp
);
148 /* Close the region. */
149 if ((t_ret
= __memp_rclose(dbmp
)) && ret
== 0)
152 /* Discard the structure. */
153 FREE(dbmp
, sizeof(DB_MPOOL
));
160 * Exit a memory pool.
163 memp_unlink(path
, force
, dbenv
)
168 return (__db_runlink(dbenv
,
169 DB_APP_NONE
, path
, DB_DEFAULT_MPOOL_FILE
, force
));
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
);