diff options
Diffstat (limited to 'bdb/rep/rep_region.c')
-rw-r--r-- | bdb/rep/rep_region.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/bdb/rep/rep_region.c b/bdb/rep/rep_region.c new file mode 100644 index 00000000000..1ac3fb8a20c --- /dev/null +++ b/bdb/rep/rep_region.c @@ -0,0 +1,187 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001-2002 + * Sleepycat Software. All rights reserved. + */ +#include "db_config.h" + +#ifndef lint +static const char revid[] = "$Id: rep_region.c,v 1.29 2002/08/06 04:50:36 bostic Exp $"; +#endif /* not lint */ + +#ifndef NO_SYSTEM_INCLUDES +#endif + +#include <string.h> + +#include "db_int.h" +#include "dbinc/rep.h" +#include "dbinc/log.h" + +/* + * __rep_region_init -- + * Initialize the shared memory state for the replication system. + * + * PUBLIC: int __rep_region_init __P((DB_ENV *)); + */ +int +__rep_region_init(dbenv) + DB_ENV *dbenv; +{ + REGENV *renv; + REGINFO *infop; + DB_MUTEX *db_mutexp; + DB_REP *db_rep; + REP *rep; + int ret; + + db_rep = dbenv->rep_handle; + infop = dbenv->reginfo; + renv = infop->primary; + ret = 0; + + MUTEX_LOCK(dbenv, &renv->mutex); + if (renv->rep_off == INVALID_ROFF) { + /* Must create the region. */ + if ((ret = __db_shalloc(infop->addr, + sizeof(REP), MUTEX_ALIGN, &rep)) != 0) + goto err; + memset(rep, 0, sizeof(*rep)); + rep->tally_off = INVALID_ROFF; + renv->rep_off = R_OFFSET(infop, rep); + + if ((ret = __db_mutex_setup(dbenv, infop, &rep->mutex, + MUTEX_NO_RECORD)) != 0) + goto err; + + /* + * We must create a place for the db_mutex separately; + * mutexes have to be aligned to MUTEX_ALIGN, and the only way + * to guarantee that is to make sure they're at the beginning + * of a shalloc'ed chunk. + */ + if ((ret = __db_shalloc(infop->addr, sizeof(DB_MUTEX), + MUTEX_ALIGN, &db_mutexp)) != 0) + goto err; + rep->db_mutex_off = R_OFFSET(infop, db_mutexp); + + /* + * Because we have no way to prevent deadlocks and cannot log + * changes made to it, we single-thread access to the client + * bookkeeping database. This is suboptimal, but it only gets + * accessed when messages arrive out-of-order, so it should + * stay small and not be used in a high-performance app. + */ + if ((ret = __db_mutex_setup(dbenv, infop, db_mutexp, + MUTEX_NO_RECORD)) != 0) + goto err; + + /* We have the region; fill in the values. */ + rep->eid = DB_EID_INVALID; + rep->master_id = DB_EID_INVALID; + rep->gen = 0; + + /* + * Set default values for the min and max log records that we + * wait before requesting a missing log record. + */ + rep->request_gap = DB_REP_REQUEST_GAP; + rep->max_gap = DB_REP_MAX_GAP; + } else + rep = R_ADDR(infop, renv->rep_off); + MUTEX_UNLOCK(dbenv, &renv->mutex); + + db_rep->mutexp = &rep->mutex; + db_rep->db_mutexp = R_ADDR(infop, rep->db_mutex_off); + db_rep->region = rep; + + return (0); + +err: MUTEX_UNLOCK(dbenv, &renv->mutex); + return (ret); +} + +/* + * __rep_region_destroy -- + * Destroy any system resources allocated in the replication region. + * + * PUBLIC: int __rep_region_destroy __P((DB_ENV *)); + */ +int +__rep_region_destroy(dbenv) + DB_ENV *dbenv; +{ + DB_REP *db_rep; + int ret, t_ret; + + ret = t_ret = 0; + db_rep = (DB_REP *)dbenv->rep_handle; + + if (db_rep != NULL) { + if (db_rep->mutexp != NULL) + ret = __db_mutex_destroy(db_rep->mutexp); + if (db_rep->db_mutexp != NULL) + t_ret = __db_mutex_destroy(db_rep->db_mutexp); + } + + return (ret == 0 ? t_ret : ret); +} + +/* + * __rep_dbenv_close -- + * Replication-specific destruction of the DB_ENV structure. + * + * PUBLIC: int __rep_dbenv_close __P((DB_ENV *)); + */ +int +__rep_dbenv_close(dbenv) + DB_ENV *dbenv; +{ + DB_REP *db_rep; + + db_rep = (DB_REP *)dbenv->rep_handle; + + if (db_rep != NULL) { + __os_free(dbenv, db_rep); + dbenv->rep_handle = NULL; + } + + return (0); +} + +/* + * __rep_preclose -- + * If we are a client, shut down our client database and, if we're + * actually closing the environment, close all databases we've opened + * while applying messages. + * + * PUBLIC: int __rep_preclose __P((DB_ENV *, int)); + */ +int +__rep_preclose(dbenv, do_closefiles) + DB_ENV *dbenv; + int do_closefiles; +{ + DB *dbp; + DB_REP *db_rep; + int ret, t_ret; + + ret = t_ret = 0; + + /* If replication is not initialized, we have nothing to do. */ + if ((db_rep = (DB_REP *)dbenv->rep_handle) == NULL) + return (0); + + if ((dbp = db_rep->rep_db) != NULL) { + MUTEX_LOCK(dbenv, db_rep->db_mutexp); + ret = dbp->close(dbp, 0); + db_rep->rep_db = NULL; + MUTEX_UNLOCK(dbenv, db_rep->db_mutexp); + } + + if (do_closefiles) + t_ret = __dbreg_close_files(dbenv); + + return (ret == 0 ? t_ret : ret); +} |