24 #include <utils/ipc/shm.h>
25 #include <utils/ipc/shm_exceptions.h>
26 #include <utils/ipc/shm_lister.h>
27 #include <utils/ipc/semset.h>
28 #include <utils/ipc/shm_registry.h>
224 #define WRITE_MUTEX_SEM 0
244 bool destroy_on_delete,
245 const char *registry_name)
265 __shared_mem_upper_bound = NULL;
267 __write_lock_aquired =
false;
269 __registry_name = NULL;
272 __registry_name = strdup(registry_name);
302 __shared_mem_upper_bound = NULL;
304 __write_lock_aquired =
false;
305 if (s.__registry_name) {
306 __registry_name = strdup(s.__registry_name);
308 __registry_name = NULL;
314 e.
append(
"SharedMemory public copy constructor");
354 bool is_read_only,
bool create,
bool destroy_on_delete,
355 const char *registry_name)
375 __shared_mem_upper_bound = NULL;
377 __write_lock_aquired =
false;
379 __registry_name = NULL;
381 __registry_name = strdup(__registry_name);
387 e.
append(
"SharedMemory public constructor");
402 if ( __semset != NULL ) {
413 delete __shm_registry;
414 if (__registry_name)
::free(__registry_name);
430 shmctl(__shared_mem_id, IPC_RMID, NULL);
432 __shared_mem_id = -1;
434 if (__shared_mem != NULL) {
458 if ((
_memptr != NULL) && (__shared_mem_id != -1)) {
463 std::list<SharedMemoryRegistry::SharedMemID> segments =
467 std::list<SharedMemoryRegistry::SharedMemID>::iterator s;
471 struct shmid_ds shm_segment;
473 for (s = segments.begin(); (
_memptr == NULL) && (s != segments.end()); ++s) {
475 if (shmctl(s->shmid, IPC_STAT, &shm_segment) < 0)
continue;
478 shm_buf = shmat(s->shmid, NULL,
_is_read_only ? SHM_RDONLY : 0);
479 if (shm_buf != (
void *)-1) {
494 if (
_mem_size != (
unsigned int) shm_segment.shm_segsz) {
496 (
unsigned int)shm_segment.shm_segsz);
499 __shared_mem_id = s->shmid;
500 __shared_mem = shm_buf;
501 __shared_mem_upper_bound = (
void *)((
size_t)__shared_mem +
_mem_size);
525 while ((
_memptr == NULL) && (key < INT_MAX)) {
527 __shared_mem_id = shmget(key,
_mem_size, IPC_CREAT | IPC_EXCL | 0666);
528 if (__shared_mem_id != -1) {
529 __shared_mem = shmat(__shared_mem_id, NULL, 0);
530 if (__shared_mem != (
void *)-1) {
550 shmctl(__shared_mem_id, IPC_RMID, NULL);
554 if (errno == EEXIST) {
559 }
else if (errno == EINVAL) {
609 if ( addr == NULL)
return NULL;
610 if ( (addr < _shm_header->shm_addr) ||
640 if ( ptr == NULL)
return NULL;
641 if ( (ptr < __shared_mem) ||
642 (ptr >= __shared_mem_upper_bound) ) {
706 return __shared_mem_id;
785 return (__semset != NULL);
812 if (__semset != NULL)
return;
813 if (
_memptr == NULL)
throw Exception(
"Cannot add semaphore if not attached");
828 __semset->
unlock(WRITE_MUTEX_SEM);
833 throw Exception(
"Cannot create semaphore for read-only shmem segment");
851 shmctl(__shared_mem_id, SHM_UNLOCK, NULL);
853 shmctl(__shared_mem_id, SHM_LOCK, NULL);
869 if ( __semset == NULL ) {
873 __semset->
lock(READ_SEM);
874 __lock_aquired =
true;
899 if ( __semset == NULL )
return false;
901 if ( __semset->
try_lock(READ_SEM) ) {
902 __lock_aquired =
true;
920 if ( __semset == NULL ) {
924 __semset->
lock(WRITE_MUTEX_SEM);
926 __semset->
lock(READ_SEM);
928 __write_lock_aquired =
true;
929 __lock_aquired =
true;
930 __semset->
unlock(WRITE_MUTEX_SEM);
955 if ( __semset == NULL )
return false;
957 if ( __semset->
try_lock(WRITE_MUTEX_SEM) ) {
959 if ( ! __semset->
try_lock(READ_SEM) ) {
961 for (
short j = 0; j < i - 1; ++j) {
962 __semset->
unlock(READ_SEM);
964 __semset->
unlock(WRITE_MUTEX_SEM);
968 __lock_aquired =
true;
969 __write_lock_aquired =
true;
970 __semset->
unlock(WRITE_MUTEX_SEM);
987 if ( __semset == NULL || ! __lock_aquired )
return;
989 if ( __write_lock_aquired ) {
991 __semset->
unlock(READ_SEM);
993 __write_lock_aquired =
false;
995 __semset->
unlock(READ_SEM);
1013 struct shmid_ds shm_segment;
1015 if (shmctl(shm_id, IPC_STAT, &shm_segment ) == -1) {
1019 struct ipc_perm *perm = &shm_segment.shm_perm;
1020 return (perm->mode & SHM_DEST);
1037 struct shmid_ds shm_segment;
1038 struct ipc_perm *perm = &shm_segment.shm_perm;
1040 if (shmctl(shm_id, IPC_STAT, &shm_segment ) < 0) {
1043 return ! (perm->mode & SHM_LOCKED);
1058 struct shmid_ds shm_segment;
1060 if (shmctl(shm_id, IPC_STAT, &shm_segment ) < 0) {
1063 return shm_segment.shm_nattch;
1081 const char *registry_name)
1083 printf(
"Looking for '%s' @ registry '%s'\n", magic_token,
1084 registry_name ? registry_name :
"default");
1093 while ( i != endi ) {
1117 const char *registry_name)
1125 if ( (i == endi) && (lister != NULL)) {
1129 while ( i != endi ) {
1136 shmctl(i.
shmid(), IPC_RMID, NULL);
1138 if ( lister != NULL) {
1166 const char *registry_name)
1174 if ( (i == endi) && (lister != NULL)) {
1178 unsigned int num_segments = 0;
1180 while ( i != endi ) {
1190 shmctl(i.
shmid(), IPC_RMID, NULL);
1192 if ( lister != NULL) {
1202 if ( (num_segments == 0) && (lister != NULL) ) {
1223 const char *registry_name)
1225 return (
find(magic_token, header, registry_name) !=
end());
1238 const char *registry_name)
1272 __id_it = __ids.end();
1278 __initialized =
true;
1287 __header = shmit.__header->
clone();
1288 __cur_shmid = shmit.__cur_shmid;
1292 __ids = shmit.__ids;
1293 __initialized =
true;
1295 if (shmit.__id_it == shmit.__ids.end()) {
1296 __id_it = __ids.end();
1298 std::list<SharedMemoryRegistry::SharedMemID>::iterator s;
1299 for (s = __ids.begin(); s != __ids.end(); ++s) {
1300 if (s->shmid == shmit.__id_it->shmid)
break;
1304 if ( shmit.__shm_buf != (
void *)-1 ) {
1320 std::list<SharedMemoryRegistry::SharedMemID> ids,
1323 __header = header->
clone();
1325 __shm_buf = (
void *)-1;
1329 __initialized =
false;
1340 if ( __shm_buf != (
void *)-1 ) {
1342 __shm_buf = (
void *)-1;
1349 SharedMemory::SharedMemoryIterator::attach()
1351 struct shmid_ds shm_segment;
1354 __cur_shmid = __id_it->shmid;
1355 if ( __cur_shmid < 0 ) {
1367 __shm_buf = shmat(__cur_shmid, NULL, SHM_RDONLY);
1368 if (__shm_buf == (
void *)-1) {
1373 if (shmctl( __cur_shmid, IPC_STAT, &shm_segment) < 0 ) {
1375 throw ShmCouldNotAttachException(
"SharedMemoryIterator could not stat (2)");
1378 __segmsize = shm_segment.shm_segsz;
1379 __segmnattch = shm_segment.shm_nattch;
1385 SharedMemory::SharedMemoryIterator::reset()
1387 if ( __header) __header->reset();
1388 if ( __shm_buf != (
void *)-1) {
1390 __shm_buf = (
void *)-1;
1403 SharedMemory::SharedMemoryIterator &
1408 if (! __initialized) {
1409 __id_it = __ids.begin();
1412 if (__id_it == __ids.end())
return *
this;
1414 if (__initialized) ++__id_it;
1415 else __initialized =
true;
1417 for (; __id_it != __ids.end(); ++__id_it) {
1421 if (!__header || __header->matches((
char *)__shm_buf +
MagicTokenSize
1432 + (__header ? __header->size() : 0);
1472 for (
unsigned int j = 0; j < i; ++j) {
1486 for (
unsigned int j = 0; j < i; ++j) {
1500 return (__cur_shmid == s.__cur_shmid);
1511 return ! (*
this == s);
1532 if ( __shm_buf != (
void *)-1 ) {
1534 __shm_buf = (
void *)-1;
1538 __header = shmit.__header->
clone();
1539 __ids = shmit.__ids;
1540 __cur_shmid = shmit.__cur_shmid;
1543 if (shmit.__id_it != shmit.__ids.end()) {
1544 for (__id_it = __ids.begin(); __id_it != __ids.end(); ++__id_it) {
1545 if (__id_it->shmid == shmit.__id_it->shmid)
break;
1549 if ( shmit.__shm_buf != (
void *)-1 ) {
1564 if (__id_it == __ids.end()) {
1567 return __id_it->magic_token;
1608 return __segmnattch;