1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
#include "db_config.h"
#include "db_int.h"
#include "dbinc/log.h"
#include "dbinc/mp.h"
/*
* memp_register_pp --
* ENV->memp_register pre/post processing.
*
* PUBLIC: int __memp_register_pp __P((DB_ENV *, int,
* PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *),
* PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
*/
int
__memp_register_pp(dbenv, ftype, pgin, pgout)
DB_ENV *dbenv;
int ftype;
int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *));
int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *));
{
DB_THREAD_INFO *ip;
ENV *env;
int ret;
env = dbenv->env;
ENV_REQUIRES_CONFIG(env,
env->mp_handle, "DB_ENV->memp_register", DB_INIT_MPOOL);
if (REP_ON(env)) {
__db_errx(env, DB_STR_A("3001",
"%smethod not permitted when replication is configured",
"%s"), "DB_ENV->memp_register: ");
return (EINVAL);
}
ENV_ENTER(env, ip);
ret = __memp_register(env, ftype, pgin, pgout);
ENV_LEAVE(env, ip);
return (ret);
}
/*
* memp_register --
* ENV->memp_register.
*
* PUBLIC: int __memp_register __P((ENV *, int,
* PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *),
* PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
*/
int
__memp_register(env, ftype, pgin, pgout)
ENV *env;
int ftype;
int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *));
int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *));
{
DB_MPOOL *dbmp;
DB_MPREG *mpreg;
int ret;
dbmp = env->mp_handle;
/*
* We keep the DB pgin/pgout functions outside of the linked list
* to avoid locking/unlocking the linked list on every page I/O.
*
* The Berkeley DB I/O conversion functions are registered when the
* environment is first created, so there's no need for locking here.
*/
if (ftype == DB_FTYPE_SET) {
if (dbmp->pg_inout != NULL)
return (0);
if ((ret =
__os_malloc(env, sizeof(DB_MPREG), &dbmp->pg_inout)) != 0)
return (ret);
dbmp->pg_inout->ftype = ftype;
dbmp->pg_inout->pgin = pgin;
dbmp->pg_inout->pgout = pgout;
return (0);
}
/*
* The item may already have been registered. If already registered,
* just update the entry, although it's probably unchanged.
*/
MUTEX_LOCK(env, dbmp->mutex);
LIST_FOREACH(mpreg, &dbmp->dbregq, q)
if (mpreg->ftype == ftype) {
mpreg->pgin = pgin;
mpreg->pgout = pgout;
break;
}
if (mpreg == NULL) { /* New entry. */
if ((ret = __os_malloc(env, sizeof(DB_MPREG), &mpreg)) != 0)
return (ret);
mpreg->ftype = ftype;
mpreg->pgin = pgin;
mpreg->pgout = pgout;
LIST_INSERT_HEAD(&dbmp->dbregq, mpreg, q);
}
MUTEX_UNLOCK(env, dbmp->mutex);
return (0);
}
|