1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "apr_general.h"
18 #include "apr_shm.h"
19 #include "apr_errno.h"
20 #include "apr_lib.h"
21 #include "apr_strings.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <kernel/OS.h>
25 #include "apr_portable.h"
26
27 struct apr_shm_t {
28 apr_pool_t *pool;
29 void *memblock;
30 void *ptr;
31 apr_size_t reqsize;
32 apr_size_t avail;
33 area_id aid;
34 };
35
apr_shm_create(apr_shm_t ** m,apr_size_t reqsize,const char * filename,apr_pool_t * p)36 APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m,
37 apr_size_t reqsize,
38 const char *filename,
39 apr_pool_t *p)
40 {
41 apr_size_t pagesize;
42 area_id newid;
43 char *addr;
44 char shname[B_OS_NAME_LENGTH];
45
46 (*m) = (apr_shm_t *)apr_pcalloc(p, sizeof(apr_shm_t));
47 /* we MUST allocate in pages, so calculate how big an area we need... */
48 pagesize = ((reqsize + B_PAGE_SIZE - 1) / B_PAGE_SIZE) * B_PAGE_SIZE;
49
50 if (!filename) {
51 int num = 0;
52 snprintf(shname, B_OS_NAME_LENGTH, "apr_shmem_%ld", find_thread(NULL));
53 while (find_area(shname) >= 0)
54 snprintf(shname, B_OS_NAME_LENGTH, "apr_shmem_%ld_%d",
55 find_thread(NULL), num++);
56 }
57 newid = create_area(filename ? filename : shname,
58 (void*)&addr, B_ANY_ADDRESS,
59 pagesize, B_LAZY_LOCK, B_READ_AREA|B_WRITE_AREA);
60
61 if (newid < 0)
62 return errno;
63
64 (*m)->pool = p;
65 (*m)->aid = newid;
66 (*m)->memblock = addr;
67 (*m)->ptr = (void*)addr;
68 (*m)->avail = pagesize; /* record how big an area we actually created... */
69 (*m)->reqsize = reqsize;
70
71 return APR_SUCCESS;
72 }
73
apr_shm_create_ex(apr_shm_t ** m,apr_size_t reqsize,const char * filename,apr_pool_t * p,apr_int32_t flags)74 APR_DECLARE(apr_status_t) apr_shm_create_ex(apr_shm_t **m,
75 apr_size_t reqsize,
76 const char *filename,
77 apr_pool_t *p,
78 apr_int32_t flags)
79 {
80 return apr_shm_create(m, reqsize, filename, p);
81 }
82
apr_shm_destroy(apr_shm_t * m)83 APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m)
84 {
85 delete_area(m->aid);
86 m->avail = 0;
87 m->memblock = NULL;
88 return APR_SUCCESS;
89 }
90
apr_shm_remove(const char * filename,apr_pool_t * pool)91 APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
92 apr_pool_t *pool)
93 {
94 area_id deleteme = find_area(filename);
95
96 if (deleteme == B_NAME_NOT_FOUND)
97 return APR_EINVAL;
98
99 delete_area(deleteme);
100 return APR_SUCCESS;
101 }
102
apr_shm_attach(apr_shm_t ** m,const char * filename,apr_pool_t * pool)103 APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
104 const char *filename,
105 apr_pool_t *pool)
106 {
107 area_info ai;
108 thread_info ti;
109 apr_shm_t *new_m;
110 area_id deleteme = find_area(filename);
111
112 if (deleteme == B_NAME_NOT_FOUND)
113 return APR_EINVAL;
114
115 new_m = (apr_shm_t*)apr_palloc(pool, sizeof(apr_shm_t*));
116 if (new_m == NULL)
117 return APR_ENOMEM;
118 new_m->pool = pool;
119
120 get_area_info(deleteme, &ai);
121 get_thread_info(find_thread(NULL), &ti);
122
123 if (ti.team != ai.team) {
124 area_id narea;
125
126 narea = clone_area(ai.name, &(ai.address), B_CLONE_ADDRESS,
127 B_READ_AREA|B_WRITE_AREA, ai.area);
128
129 if (narea < B_OK)
130 return narea;
131
132 get_area_info(narea, &ai);
133 new_m->aid = narea;
134 new_m->memblock = ai.address;
135 new_m->ptr = (void*)ai.address;
136 new_m->avail = ai.size;
137 new_m->reqsize = ai.size;
138 }
139
140 (*m) = new_m;
141
142 return APR_SUCCESS;
143 }
144
apr_shm_attach_ex(apr_shm_t ** m,const char * filename,apr_pool_t * pool,apr_int32_t flags)145 APR_DECLARE(apr_status_t) apr_shm_attach_ex(apr_shm_t **m,
146 const char *filename,
147 apr_pool_t *pool,
148 apr_int32_t flags)
149 {
150 return apr_shm_attach(m, filename, pool);
151 }
152
apr_shm_detach(apr_shm_t * m)153 APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m)
154 {
155 delete_area(m->aid);
156 return APR_SUCCESS;
157 }
158
apr_shm_baseaddr_get(const apr_shm_t * m)159 APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m)
160 {
161 return m->memblock;
162 }
163
apr_shm_size_get(const apr_shm_t * m)164 APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m)
165 {
166 return m->reqsize;
167 }
168
169 APR_POOL_IMPLEMENT_ACCESSOR(shm)
170
APR_DECLARE(apr_status_t)171 APR_DECLARE(apr_status_t) apr_os_shm_get(apr_os_shm_t *osshm,
172 apr_shm_t *shm)
173 {
174 return APR_ENOTIMPL;
175 }
176
apr_os_shm_put(apr_shm_t ** m,apr_os_shm_t * osshm,apr_pool_t * pool)177 APR_DECLARE(apr_status_t) apr_os_shm_put(apr_shm_t **m,
178 apr_os_shm_t *osshm,
179 apr_pool_t *pool)
180 {
181 return APR_ENOTIMPL;
182 }
183
184