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