📄 db_server_cxxutil.cpp
字号:
new_ct_ent(int *errp){ time_t t; ct_entry *ctp, *octp; int ret; if ((ret = __os_malloc(NULL, sizeof(ct_entry), &ctp)) != 0) { *errp = ret; return (NULL); } memset(ctp, 0, sizeof(ct_entry)); /* * Get the time as ID. We may service more than one request per * second however. If we are, then increment id value until we * find an unused one. We insert entries in LRU fashion at the * head of the list. So, if the first entry doesn't match, then * we know for certain that we can use our entry. */ if ((t = time(NULL)) == -1) { *errp = __os_get_errno(); __os_free(NULL, ctp); return (NULL); } octp = LIST_FIRST(&__dbsrv_head); if (octp != NULL && octp->ct_id >= t) t = octp->ct_id + 1; ctp->ct_id = t; ctp->ct_idle = __dbsrv_idleto; ctp->ct_activep = &ctp->ct_active; ctp->ct_origp = NULL; ctp->ct_refcount = 1; LIST_INSERT_HEAD(&__dbsrv_head, ctp, entries); return (ctp);}extern "C" ct_entry *get_tableent(long id){ ct_entry *ctp; for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; ctp = LIST_NEXT(ctp, entries)) if (ctp->ct_id == id) return (ctp); return (NULL);}extern "C" ct_entry *__dbsrv_sharedb(ct_entry *db_ctp, const char *name, const char *subdb, DBTYPE type, u_int32_t flags){ ct_entry *ctp; /* * Check if we can share a db handle. Criteria for sharing are: * If any of the non-sharable flags are set, we cannot share. * Must be a db ctp, obviously. * Must share the same env parent. * Must be the same type, or current one DB_UNKNOWN. * Must be same byteorder, or current one must not care. * All flags must match. * Must be same name, but don't share in-memory databases. * Must be same subdb name. */ if (flags & DB_SERVER_DBNOSHARE) return (NULL); for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; ctp = LIST_NEXT(ctp, entries)) { /* * Skip ourselves. */ if (ctp == db_ctp) continue; if (ctp->ct_type != CT_DB) continue; if (ctp->ct_envparent != db_ctp->ct_envparent) continue; if (type != DB_UNKNOWN && ctp->ct_dbdp.type != type) continue; if (ctp->ct_dbdp.dbflags != LF_ISSET(DB_SERVER_DBFLAGS)) continue; if (db_ctp->ct_dbdp.setflags != 0 && ctp->ct_dbdp.setflags != db_ctp->ct_dbdp.setflags) continue; if (name == NULL || ctp->ct_dbdp.db == NULL || strcmp(name, ctp->ct_dbdp.db) != 0) continue; if (subdb != ctp->ct_dbdp.subdb && (subdb == NULL || ctp->ct_dbdp.subdb == NULL || strcmp(subdb, ctp->ct_dbdp.subdb) != 0)) continue; /* * If we get here, then we match. */ ctp->ct_refcount++; return (ctp); } return (NULL);}extern "C" ct_entry *__dbsrv_shareenv(ct_entry *env_ctp, home_entry *home, u_int32_t flags){ ct_entry *ctp; /* * Check if we can share an env. Criteria for sharing are: * Must be an env ctp, obviously. * Must share the same home env. * All flags must match. */ for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; ctp = LIST_NEXT(ctp, entries)) { /* * Skip ourselves. */ if (ctp == env_ctp) continue; if (ctp->ct_type != CT_ENV) continue; if (ctp->ct_envdp.home != home) continue; if (ctp->ct_envdp.envflags != flags) continue; if (ctp->ct_envdp.onflags != env_ctp->ct_envdp.onflags) continue; if (ctp->ct_envdp.offflags != env_ctp->ct_envdp.offflags) continue; /* * If we get here, then we match. The only thing left to * check is the timeout. Since the server timeout set by * the client is a hint, for sharing we'll give them the * benefit of the doubt and grant them the longer timeout. */ if (ctp->ct_timeout < env_ctp->ct_timeout) ctp->ct_timeout = env_ctp->ct_timeout; ctp->ct_refcount++; return (ctp); } return (NULL);}extern "C" void__dbsrv_active(ct_entry *ctp){ time_t t; ct_entry *envctp; if (ctp == NULL) return; if ((t = time(NULL)) == -1) return; *(ctp->ct_activep) = t; if ((envctp = ctp->ct_envparent) == NULL) return; *(envctp->ct_activep) = t; return;}extern "C" int__db_close_int(long id, u_int32_t flags){ Db *dbp; int ret; ct_entry *ctp; ret = 0; ctp = get_tableent(id); if (ctp == NULL) return (DB_NOSERVER_ID); DB_ASSERT(ctp->ct_type == CT_DB); if (__dbsrv_verbose && ctp->ct_refcount != 1) printf("Deref'ing dbp id %ld, refcount %d\n", id, ctp->ct_refcount); if (--ctp->ct_refcount != 0) return (ret); dbp = ctp->ct_dbp; if (__dbsrv_verbose) printf("Closing dbp id %ld\n", id); ret = dbp->close(flags); __dbdel_ctp(ctp); return (ret);}extern "C" int__dbc_close_int(ct_entry *dbc_ctp){ Dbc *dbc; int ret; ct_entry *ctp; dbc = (Dbc *)dbc_ctp->ct_anyp; ret = dbc->close(); /* * If this cursor is a join cursor then we need to fix up the * cursors that it was joined from so that they are independent again. */ if (dbc_ctp->ct_type & CT_JOINCUR) for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; ctp = LIST_NEXT(ctp, entries)) { /* * Test if it is a join cursor, and if it is part * of this one. */ if ((ctp->ct_type & CT_JOIN) && ctp->ct_activep == &dbc_ctp->ct_active) { ctp->ct_type &= ~CT_JOIN; ctp->ct_activep = ctp->ct_origp; __dbsrv_active(ctp); } } __dbclear_ctp(dbc_ctp); return (ret);}extern "C" int__dbenv_close_int(long id, u_int32_t flags, int force){ DbEnv *dbenv; int ret; ct_entry *ctp; ret = 0; ctp = get_tableent(id); if (ctp == NULL) return (DB_NOSERVER_ID); DB_ASSERT(ctp->ct_type == CT_ENV); if (__dbsrv_verbose && ctp->ct_refcount != 1) printf("Deref'ing env id %ld, refcount %d\n", id, ctp->ct_refcount); /* * If we are timing out, we need to force the close, no matter * what the refcount. */ if (--ctp->ct_refcount != 0 && !force) return (ret); dbenv = ctp->ct_envp; if (__dbsrv_verbose) printf("Closing env id %ld\n", id); ret = dbenv->close(flags); __dbdel_ctp(ctp); return (ret);}static intadd_home(char *home){ home_entry *hp, *homep; int ret; if ((ret = __os_malloc(NULL, sizeof(home_entry), &hp)) != 0) return (ret); if ((ret = __os_malloc(NULL, strlen(home)+1, &hp->home)) != 0) return (ret); memcpy(hp->home, home, strlen(home)+1); hp->dir = home; hp->passwd = NULL; /* * This loop is to remove any trailing path separators, * to assure hp->name points to the last component. */ hp->name = __db_rpath(home); *(hp->name) = '\0'; hp->name++; while (*(hp->name) == '\0') { hp->name = __db_rpath(home); *(hp->name) = '\0'; hp->name++; } /* * Now we have successfully added it. Make sure there are no * identical names. */ for (homep = LIST_FIRST(&__dbsrv_home); homep != NULL; homep = LIST_NEXT(homep, entries)) if (strcmp(homep->name, hp->name) == 0) { printf("Already added home name %s, at directory %s\n", hp->name, homep->dir); return (-1); } LIST_INSERT_HEAD(&__dbsrv_home, hp, entries); if (__dbsrv_verbose) printf("Added home %s in dir %s\n", hp->name, hp->dir); return (0);}static intadd_passwd(char *passwd){ home_entry *hp; /* * We add the passwd to the last given home dir. If there * isn't a home dir, or the most recent one already has a * passwd, then there is a user error. */ hp = LIST_FIRST(&__dbsrv_home); if (hp == NULL || hp->passwd != NULL) return (EINVAL); /* * We've already strdup'ed the passwd above, so we don't need * to malloc new space, just point to it. */ hp->passwd = passwd; return (0);}extern "C" home_entry *get_home(char *name){ home_entry *hp; for (hp = LIST_FIRST(&__dbsrv_home); hp != NULL; hp = LIST_NEXT(hp, entries)) if (strcmp(name, hp->name) == 0) return (hp); return (NULL);}static intenv_recover(char *progname){ DbEnv *dbenv; home_entry *hp; u_int32_t flags; int exitval, ret; for (hp = LIST_FIRST(&__dbsrv_home); hp != NULL; hp = LIST_NEXT(hp, entries)) { exitval = 0; dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS); if (__dbsrv_verbose == 1) { (void)dbenv->set_verbose(DB_VERB_RECOVERY, 1); (void)dbenv->set_verbose(DB_VERB_CHKPOINT, 1); } dbenv->set_errfile(stderr); dbenv->set_errpfx(progname); if (hp->passwd != NULL) (void)dbenv->set_encrypt(hp->passwd, DB_ENCRYPT_AES); /* * Initialize the env with DB_RECOVER. That is all we * have to do to run recovery. */ if (__dbsrv_verbose) printf("Running recovery on %s\n", hp->home); flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_USE_ENVIRON | DB_RECOVER; if ((ret = dbenv->open(hp->home, flags, 0)) != 0) { dbenv->err(ret, "DbEnv->open"); goto error; } if (0) {error: exitval = 1; } if ((ret = dbenv->close(0)) != 0) { exitval = 1; fprintf(stderr, "%s: dbenv->close: %s\n", progname, db_strerror(ret)); } if (exitval) return (exitval); } return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -