size_name.c
1 /*
2  shm-arena shared memory arena
3  Copyright (C) 2006-2008 Lance Arsenault (LGPL v3)
4 
5 
6  This file is part of shm-arena.
7 
8  shm-arena is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as
10  published by the Free Software Foundation; either version 3 of the
11  License, or (at your option) any later version.
12 
13  shm-arena is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this program. If not, see
20  <http://www.gnu.org/licenses/>.
21 */
22 
27 #include "config.h"
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <sys/mman.h>
37 #include <pthread.h>
38 #include <stdint.h>
39 
40 #include <pthread.h>
41 #include "spew.h"
42 #include "assert.h"
43 #include "debug_lock.h"
44 #include "shm_arena.h"
45 #include "arena.h"
46 #include "arena_lock.h"
47 #include "avl.h"
48 
63 ssize_t shm_size(shm_arena_t arena, const void *ptr)
64 {
65  ssize_t ret = -1;
66  int err;
67  struct seg_header *seg;
68 
69  SPEW(_INFO, "%s(arena=%p, ptr=%p)", __func__, arena, ptr);
70 
71  if(!ptr)
72  /* ptr is not set */
73  return SPEW_SYS_ERR_RET(ret, _WARN, EINVAL,
74  "%s(arena=%p, ptr=%p) failed: ptr=%p",
75  __func__, arena, ptr, ptr);
76 
77  arena = get_arena_and_autolock(arena, 1, &err IF_SPEW(, __func__));
78  if(!arena)
79  {
80  errno = err;
81  return -1;
82  }
83 
84  ASSERT(arena->header);
85 
86  /* Make sure that we have the current number of memory mappings for
87  * this arena file, by comparing the local and arena file
88  * change_count. */
89  pthread_mutex_lock(&arena->mapping_mutex);
90  if(arena->change_count != arena->header->change_count)
91  if(_shm_arena_sync_mappings(IF_SPEW(__func__,) arena))
92  {
93  pthread_mutex_unlock(&arena->mapping_mutex);
94  goto finish;
95  }
96  pthread_mutex_unlock(&arena->mapping_mutex);
97 
98  /*****************************************************************
99  * shm_size()
100  *****************************************************************/
101 
102 #ifdef SHM_DEBUG
103 
106 #endif
107 
108  /* Here we assume that the ptr is in one of the shared memory
109  * regions. */
110 
111  seg = (struct seg_header *)(((uint8_t *) ptr) - CHUNKS(sizeof(struct seg_header)));
112  ret = (ssize_t) (seg->user_length);
113 
114 
115  /*****************************************************************/
116 
117  finish:
118 
119  err = arena_autounlock(arena IF_SPEW(, __func__));
120 
121  ASSERT(err == 0);
122  if(err)
123  {
124  errno = err;
125  ret = -1;
126  }
127 
128  return ret;
129 }
130 
131 
145 ssize_t shm_size_name(shm_arena_t arena, const char *name)
146 {
147  ssize_t ret = -1;
148  size_t size;
149  int err;
150 
151  SPEW(_INFO, "%s(arena=%p, name=\"%s\")",
152  __func__, arena, name);
153 
154  if(!name || !name[0])
155  /* name is not set */
156  return SPEW_SYS_ERR_RET(ret, _WARN, EINVAL,
157  "%s() failed: name is invalid", __func__);
158 
159  arena = get_arena_and_autolock(arena, 1, &err IF_SPEW(, __func__));
160  if(!arena)
161  {
162  errno = err;
163  return -1;
164  }
165 
166  ASSERT(arena->header);
167 
168  /* Make sure that we have the current number of memory mappings for
169  * this arena file, by comparing the local and arena file
170  * change_count. */
171  pthread_mutex_lock(&arena->mapping_mutex);
172  if(arena->change_count != arena->header->change_count)
173  if(_shm_arena_sync_mappings(IF_SPEW(__func__,) arena))
174  {
175  pthread_mutex_unlock(&arena->mapping_mutex);
176  goto finish;
177  }
178  pthread_mutex_unlock(&arena->mapping_mutex);
179 
180  /*****************************************************************
181  * shm_size_name()
182  *****************************************************************/
183 
184  if(find_segment_name(arena, name, &size))
185  ret = (ssize_t) size;
186 
187  /*****************************************************************/
188 
189  finish:
190 
191  err = arena_autounlock(arena IF_SPEW(, __func__));
192 
193  ASSERT(err == 0);
194  if(err)
195  {
196  errno = err;
197  ret = -1;
198  }
199 
200  return ret;
201 }
202 
227 char *shm_name(shm_arena_t arena, const void *ptr,
228  char *name, size_t name_size)
229 {
230  char *ret = NULL;
231  struct seg_header *seg;
232  int err;
233 
234  SPEW(_INFO, "%s(arena=%p, ptr=%p, name=%p, name_size=%zu)",
235  __func__, arena, ptr, name, name_size);
236 
237  if(!ptr)
238  /* ptr is not set */
239  return SPEW_SYS_ERR_RET(ret, _WARN, EINVAL,
240  "%s() failed: ptr=%p",
241  __func__, ptr);
242 
243  arena = get_arena_and_autolock(arena, 1, &err IF_SPEW(, __func__));
244  if(!arena)
245  {
246  errno = err;
247  return NULL;
248  }
249 
250  ASSERT(arena->header);
251 
252  /* Make sure that we have the current number of memory mappings for
253  * this arena file, by comparing the local and arena file
254  * change_count. */
255  pthread_mutex_lock(&arena->mapping_mutex);
256  if(arena->change_count != arena->header->change_count)
257  if(_shm_arena_sync_mappings(IF_SPEW(__func__,) arena))
258  {
259  pthread_mutex_unlock(&arena->mapping_mutex);
260  /* errno should be set */
261  goto finish;
262  }
263  pthread_mutex_unlock(&arena->mapping_mutex);
264 
265  /*****************************************************************
266  * shm_size()
267  *****************************************************************/
268 
269 #ifdef SHM_DEBUG
270 
273 #endif
274 
275  /* Here we assume that the ptr is in one of the shared memory
276  * regions. */
277 
278  seg = (struct seg_header *)(((uint8_t *) ptr) - CHUNKS(sizeof(struct seg_header)));
279  ret = get_seg_name(seg);
280 
281  /* We should have a null terminated string here. */
282  ASSERT(CHUNKS(sizeof(struct seg_header)) + CHUNKS(sizeof(struct seg_footer)) +
283  CHUNKS(strlen(ret)) +
284  ((get_seg_footer(seg)->flags & WITH_RWLOCK)?CHUNKS(sizeof(pthread_rwlock_t)):0)
285  < seg->length*CHUNK);
286 
287  if(name_size > 0 && name)
288  {
289  size_t len;
290  len = strlen(ret);
291  if(len < name_size)
292  {
293  strcpy(name, ret);
294  ret = name;
295  }
296  else
297  {
298  ret = NULL;
299  SPEW(_WARN, "%s() failed: name_size=%zu is smaller than the"
300  " segment name size=%zu with null terminator",
301  __func__, name_size, len+1);
302  }
303  }
304  else
305  {
306  name = strdup(ret);
307 #ifdef WITH_SPEW
308  if(!name)
309  SPEW(_WARN, "%s() failed: malloc() failed", __func__);
310 #endif
311  ret = name;
312  }
313 
314  /*****************************************************************/
315 
316  finish:
317 
318  err = arena_autounlock(arena IF_SPEW(, __func__));
319 
320  if(err)
321  {
322  errno = err;
323  ret = NULL;
324  }
325 
326  return ret;
327 }
struct arena_header * header
Definition: arena.h:446
pthread_mutex_t mapping_mutex
Definition: arena.h:468
ssize_t shm_size(shm_arena_t arena, const void *ptr)
get the size of a shared memory segment
Definition: size_name.c:63
uint32_t change_count
Definition: arena.h:464
offset_t length
Definition: arena.h:153
char * shm_name(shm_arena_t arena, const void *ptr, char *name, size_t name_size)
get the name of a shared memory segment for a pointer
Definition: size_name.c:227
uint32_t change_count
Definition: arena.h:383
size_t user_length
Definition: arena.h:156
ssize_t shm_size_name(shm_arena_t arena, const char *name)
get the size of a shared memory segment
Definition: size_name.c:145

Shared Memory Arena version RC-0.0.25