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 27struct 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 36APR_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 74APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m) 75{ 76 delete_area(m->aid); 77 m->avail = 0; 78 m->memblock = NULL; 79 return APR_SUCCESS; 80} 81 82APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename, 83 apr_pool_t *pool) 84{ 85 area_id deleteme = find_area(filename); 86 87 if (deleteme == B_NAME_NOT_FOUND) 88 return APR_EINVAL; 89 90 delete_area(deleteme); 91 return APR_SUCCESS; 92} 93 94APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, 95 const char *filename, 96 apr_pool_t *pool) 97{ 98 area_info ai; 99 thread_info ti; 100 apr_shm_t *new_m; 101 area_id deleteme = find_area(filename); 102 103 if (deleteme == B_NAME_NOT_FOUND) 104 return APR_EINVAL; 105 106 new_m = (apr_shm_t*)apr_palloc(pool, sizeof(apr_shm_t*)); 107 if (new_m == NULL) 108 return APR_ENOMEM; 109 new_m->pool = pool; 110 111 get_area_info(deleteme, &ai); 112 get_thread_info(find_thread(NULL), &ti); 113 114 if (ti.team != ai.team) { 115 area_id narea; 116 117 narea = clone_area(ai.name, &(ai.address), B_CLONE_ADDRESS, 118 B_READ_AREA|B_WRITE_AREA, ai.area); 119 120 if (narea < B_OK) 121 return narea; 122 123 get_area_info(narea, &ai); 124 new_m->aid = narea; 125 new_m->memblock = ai.address; 126 new_m->ptr = (void*)ai.address; 127 new_m->avail = ai.size; 128 new_m->reqsize = ai.size; 129 } 130 131 (*m) = new_m; 132 133 return APR_SUCCESS; 134} 135 136APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m) 137{ 138 delete_area(m->aid); 139 return APR_SUCCESS; 140} 141 142APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m) 143{ 144 return m->memblock; 145} 146 147APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m) 148{ 149 return m->reqsize; 150} 151 152APR_POOL_IMPLEMENT_ACCESSOR(shm) 153 154APR_DECLARE(apr_status_t) apr_os_shm_get(apr_os_shm_t *osshm, 155 apr_shm_t *shm) 156{ 157 return APR_ENOTIMPL; 158} 159 160APR_DECLARE(apr_status_t) apr_os_shm_put(apr_shm_t **m, 161 apr_os_shm_t *osshm, 162 apr_pool_t *pool) 163{ 164 return APR_ENOTIMPL; 165} 166 167