summaryrefslogtreecommitdiff
path: root/subversion/include/private/svn_object_pool.h
blob: 7a9383e5f625301c7309992be623bce162ab635b (plain)
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
 * @copyright
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 * @endcopyright
 *
 * @file svn_object_pool.h
 * @brief multithreaded object pool API
 *
 * This is the core data structure behind various object pools.  It
 * provides a thread-safe associative container for object instances of
 * the same type.
 *
 * Memory and lifetime management for the objects are handled by the pool.
 * Reference counting takes care that neither objects nor the object pool
 * get actually destroyed while other parts depend on them.  All objects
 * are thought to be recycle-able and live in their own root memory pools
 * making them (potentially) safe to be used from different threads.
 * Currently unused objects may be kept around for a while and returned
 * by the next lookup.
 *
 * Two modes are supported: shared use and exclusive use.  In shared mode,
 * any object can be handed out to multiple users and in potentially
 * different threads at the same time.  In exclusive mode, the same object
 * will only be referenced at most once.
 *
 * Object creation and access must be provided outside this structure.
 * In particular, the using container will usually wrap the actual object
 * in a meta-data struct containing key information etc and must provide
 * getters and setters for those wrapper structs.
 */



#ifndef SVN_OBJECT_POOL_H
#define SVN_OBJECT_POOL_H

#include <apr.h>        /* for apr_int64_t */
#include <apr_pools.h>  /* for apr_pool_t */
#include <apr_hash.h>   /* for apr_hash_t */

#include "svn_types.h"

#include "private/svn_mutex.h"
#include "private/svn_string_private.h"



/* The opaque object container type. */
typedef struct svn_object_pool__t svn_object_pool__t;

/* Extract the actual object from the WRAPPER using optional information
 * from BATON (provided through #svn_object_pool__lookup) and return it.
 * The result will be used with POOL and must remain valid throughout
 * POOL's lifetime.
 *
 * It is legal to return a copy, allocated in POOL, of the wrapped object.
 */
typedef void * (* svn_object_pool__getter_t)(void *wrapper,
                                             void *baton,
                                             apr_pool_t *pool);

/* Copy the information from the SOURCE object wrapper into the already
 * existing *TARGET object wrapper using POOL for allocations and BATON
 * for optional context (provided through #svn_object_pool__insert).
 */
typedef svn_error_t * (* svn_object_pool__setter_t)(void **target,
                                                    void *source,
                                                    void *baton,
                                                    apr_pool_t *pool);

/* Create a new object pool in POOL and return it in *OBJECT_POOL.
 * Objects will be extracted using GETTER and updated using SETTER.  Either
 * one (or both) may be NULL and the default implementation assumes that
 * wrapper == object and updating is a no-op.
 *
 * If THREAD_SAFE is not set, neither the object pool nor the object
 * references returned from it may be accessed from multiple threads.
 *
 * It is not legal to call any API on the object pool after POOL got
 * cleared or destroyed.  However, existing object references handed out
 * from the object pool remain valid and will keep the internal pool data
 * structures alive for as long as such object references exist.
 */
svn_error_t *
svn_object_pool__create(svn_object_pool__t **object_pool,
                        svn_object_pool__getter_t getter,
                        svn_object_pool__setter_t setter,
                        svn_boolean_t thread_safe,
                        apr_pool_t *pool);

/* Return the root pool containing the OBJECT_POOL and all sub-structures.
 */
apr_pool_t *
svn_object_pool__new_wrapper_pool(svn_object_pool__t *object_pool);

/* Return the mutex used to serialize all OBJECT_POOL access.
 */
svn_mutex__t *
svn_object_pool__mutex(svn_object_pool__t *object_pool);

/* Return the number of object instances (used or unused) in OBJECT_POOL.
 */
unsigned
svn_object_pool__count(svn_object_pool__t *object_pool);

/* In OBJECT_POOL, look for an available object by KEY and return a
 * reference to it in *OBJECT.  If none can be found, *OBJECT will be NULL.
 * BATON will be passed to OBJECT_POOL's getter function.  The reference
 * will be returned when *RESULT_POOL gets cleaned up or destroyed.
 */
svn_error_t *
svn_object_pool__lookup(void **object,
                        svn_object_pool__t *object_pool,
                        svn_membuf_t *key,
                        void *baton,
                        apr_pool_t *result_pool);

/* Store the wrapped object WRAPPER under KEY in OBJECT_POOL and return
 * a reference to the object in *OBJECT (just like lookup).
 *
 * The object must have been created in WRAPPER_POOL and the latter must
 * be a sub-pool of OBJECT_POOL's root POOL (see #svn_object_pool__pool).
 *
 * BATON will be passed to OBJECT_POOL's setter and getter functions.
 * The reference will be returned when *RESULT_POOL gets cleaned up or
 * destroyed.
 */
svn_error_t *
svn_object_pool__insert(void **object,
                        svn_object_pool__t *object_pool,
                        const svn_membuf_t *key,
                        void *wrapper,
                        void *baton,
                        apr_pool_t *wrapper_pool,
                        apr_pool_t *result_pool);

#endif /* SVN_OBJECT_POOL_H */