Sat, 22 Jan 2022 11:06:11 +0100
add ResourcePool initialization
260 | 1 | /* |
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. | |
3 | * | |
269
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
4 | * Copyright 2022 Olaf Wintermann. All rights reserved. |
260 | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions are met: | |
8 | * | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | |
28 | ||
29 | #include "resourcepool.h" | |
30 | #include "request.h" | |
31 | #include "session.h" | |
269
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
32 | #include "../public/nsapi.h" |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
33 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
34 | #define RESOURCE_POOL_MAX_DEFAULT 32 |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
35 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
36 | #define RESOURCE_POOL_MAX_ALLOC 268435455 |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
37 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
38 | static UcxMap *resource_pool_types; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
39 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
40 | int init_resource_pools(void) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
41 | resource_pool_types = ucx_map_new(4); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
42 | return resource_pool_types ? 0 : 1; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
43 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
44 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
45 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
46 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
47 | int resourcepool_new(ServerConfiguration *cfg, scstr_t type, scstr_t name, ConfigNode *node) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
48 | ResourceType *restype = ucx_map_sstr_get(resource_pool_types, type); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
49 | if(!restype) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
50 | log_ereport(LOG_MISCONFIG, "Unknown resource pool type: %s", type.ptr); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
51 | return 1; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
52 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
53 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
54 | // convert ConfigNode to pblock |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
55 | // no sub-objects allowed for this specific ConfigNode, therefore |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
56 | // it can be represented as key-value-pairs |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
57 | pblock *param = config_obj2pblock(cfg->pool, node); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
58 | if(!param) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
59 | log_ereport(LOG_FAILURE, "resourcepool_new: OOM"); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
60 | return 1; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
61 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
62 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
63 | ResourcePool *respool = pool_malloc(cfg->pool, sizeof(ResourcePool)); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
64 | if(!respool) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
65 | log_ereport(LOG_FAILURE, "resourcepool_new: OOM"); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
66 | return 1; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
67 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
68 | respool->pool = cfg->pool; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
69 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
70 | void *respool_data = restype->init(cfg->pool, param); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
71 | if(!respool_data) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
72 | log_ereport(LOG_FAILURE, "Cannot create resource pool data: pool: %s type: %s", name.ptr, type.ptr); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
73 | return 1; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
74 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
75 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
76 | respool->type = restype; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
77 | respool->data = respool_data; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
78 | respool->min = 0; // TODO: get from node |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
79 | respool->max = RESOURCE_POOL_MAX_DEFAULT; // TODO: get from node |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
80 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
81 | // don't allow too large resource pools |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
82 | // this prevents the need to check malloc integer overflows |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
83 | if(respool->max > RESOURCE_POOL_MAX_ALLOC) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
84 | respool->max = RESOURCE_POOL_MAX_ALLOC; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
85 | log_ereport(LOG_WARN, "Resource pool %s: limit max to %d", name.ptr, respool->max); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
86 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
87 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
88 | respool->resalloc = respool->max; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
89 | respool->resources = pool_malloc(cfg->pool, respool->resalloc * sizeof(void*)); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
90 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
91 | if(!respool->resources || ucx_map_sstr_put(cfg->resources, name, respool)) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
92 | log_ereport(LOG_FAILURE, "Cannot add resource pool: OOM"); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
93 | // the only cleanup we have to do |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
94 | restype->destroy(respool_data); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
95 | return 1; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
96 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
97 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
98 | pthread_mutex_init(&respool->lock, NULL); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
99 | pthread_cond_init(&respool->available, NULL); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
100 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
101 | if(resourcepool_create_resources(respool, respool->max)) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
102 | log_ereport(LOG_FAILURE, "Resource pool %s: Cannot create resources", name.ptr); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
103 | resourcepool_destroy(respool); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
104 | return 1; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
105 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
106 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
107 | return 0; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
108 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
109 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
110 | int resourcepool_create_resources(ResourcePool *pool, int num_res) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
111 | if(num_res > pool->resalloc) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
112 | num_res = pool->resalloc; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
113 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
114 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
115 | for(int i=pool->numresources;i<num_res;i++) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
116 | void *resource = pool->type->createresource(pool->data); |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
117 | if(resource) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
118 | pool->resources[pool->numresources++] = resource; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
119 | } else { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
120 | return 1; // error |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
121 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
122 | } |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
123 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
124 | return 0; |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
125 | } |
260 | 126 | |
127 | ResourceData* resourcepool_lookup(Session *sn, Request *rq, const char *name, int flags) { | |
128 | NSAPIRequest *request = (NSAPIRequest*)rq; | |
129 | NSAPISession *session = (NSAPISession*)sn; | |
130 | ServerConfiguration *cfg = session->config; | |
131 | ||
132 | ResourceDataPrivate *res = NULL; | |
133 | ||
134 | // was this resource already used by this request? | |
135 | if(request->resources) { | |
136 | res = ucx_map_cstr_get(request->resources, name); | |
137 | if(res) { | |
138 | return (ResourceData*)res; | |
139 | } | |
140 | } | |
141 | ||
142 | // TODO: get cached resource | |
143 | ||
269
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
144 | /* |
260 | 145 | ResourceType *type = ucx_map_cstr_get(cfg->resources, name); |
146 | if(!type) { | |
147 | return NULL; | |
148 | } | |
269
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
149 | */ |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
150 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
151 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
152 | return NULL; |
260 | 153 | } |
154 | ||
155 | void resourcepool_free(ResourceData *data) { | |
156 | ||
157 | } | |
269
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
158 | |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
159 | void resourcepool_destroy(ResourcePool *respool) { |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
160 | // TODO |
3dfbd0b91950
add ResourcePool initialization
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
260
diff
changeset
|
161 | } |