26 #include <utils/ipc/semset.h>
27 #include <utils/ipc/shm.h>
28 #include <utils/ipc/shm_exceptions.h>
29 #include <utils/ipc/shm_lister.h>
30 #include <utils/ipc/shm_registry.h>
223 #define WRITE_MUTEX_SEM 0
242 bool destroy_on_delete,
243 const char *registry_name)
263 shared_mem_upper_bound_ = NULL;
265 write_lock_aquired_ =
false;
267 registry_name_ = NULL;
270 registry_name_ = strdup(registry_name);
299 shared_mem_upper_bound_ = NULL;
301 write_lock_aquired_ =
false;
302 if (s.registry_name_) {
303 registry_name_ = strdup(s.registry_name_);
305 registry_name_ = NULL;
310 }
catch (Exception &e) {
311 e.append(
"SharedMemory public copy constructor");
316 throw ShmCouldNotAttachException(
"Could not attach to created shared memory segment");
319 shm_registry_ =
new SharedMemoryRegistry(registry_name_);
349 SharedMemoryHeader *header,
352 bool destroy_on_delete,
353 const char * registry_name)
373 shared_mem_upper_bound_ = NULL;
375 write_lock_aquired_ =
false;
377 registry_name_ = NULL;
379 registry_name_ = strdup(registry_name);
385 e.
append(
"SharedMemory public constructor");
399 if (semset_ != NULL) {
410 delete shm_registry_;
423 if (semset_ != NULL) {
434 delete shm_registry_;
456 shared_mem_upper_bound_ = NULL;
458 write_lock_aquired_ =
false;
459 if (s.registry_name_) {
460 registry_name_ = strdup(s.registry_name_);
462 registry_name_ = NULL;
467 }
catch (Exception &e) {
468 e.append(
"SharedMemory public copy constructor");
473 throw ShmCouldNotAttachException(
"Could not attach to created shared memory segment");
476 shm_registry_ =
new SharedMemoryRegistry(registry_name_);
493 shmctl(shared_mem_id_, IPC_RMID, NULL);
497 if (shared_mem_ != NULL) {
519 if ((
_memptr != NULL) && (shared_mem_id_ != -1)) {
524 std::list<SharedMemoryRegistry::SharedMemID> segments =
527 std::list<SharedMemoryRegistry::SharedMemID>::iterator s;
531 struct shmid_ds shm_segment;
533 for (s = segments.begin(); (
_memptr == NULL) && (s != segments.end()); ++s) {
534 if (shmctl(s->shmid, IPC_STAT, &shm_segment) < 0)
537 shm_buf = shmat(s->shmid, NULL,
_is_read_only ? SHM_RDONLY : 0);
538 if (shm_buf != (
void *)-1) {
542 shm_ptr = (
char *)shm_buf +
MagicTokenSize +
sizeof(SharedMemory_header_t);
551 if (
_mem_size != (
unsigned int)shm_segment.shm_segsz) {
552 throw ShmInconsistentSegmentSizeException(
_mem_size, (
unsigned int)shm_segment.shm_segsz);
555 shared_mem_id_ = s->shmid;
556 shared_mem_ = shm_buf;
557 shared_mem_upper_bound_ = (
void *)((
size_t)shared_mem_ +
_mem_size);
581 while ((
_memptr == NULL) && (key < INT_MAX)) {
583 shared_mem_id_ = shmget(key,
_mem_size, IPC_CREAT | IPC_EXCL | 0666);
584 if (shared_mem_id_ != -1) {
585 shared_mem_ = shmat(shared_mem_id_, NULL, 0);
586 if (shared_mem_ != (
void *)-1) {
604 shmctl(shared_mem_id_, IPC_RMID, NULL);
605 throw ShmCouldNotAttachException(
"Could not create shared memory segment");
608 if (errno == EEXIST) {
613 }
else if (errno == EINVAL) {
614 throw ShmCouldNotAttachException(
"Could not attach, segment too small or too big");
616 throw ShmCouldNotAttachException(
"Could not attach, shmget failed");
623 throw ShmCouldNotAttachException(
"Could not attach to shared memory segment");
628 }
catch (Exception &e) {
696 if ((
ptr < shared_mem_) || (
ptr >= shared_mem_upper_bound_)) {
756 return shared_mem_id_;
829 return (semset_ != NULL);
857 throw Exception(
"Cannot add semaphore if not attached");
872 semset_->
unlock(WRITE_MUTEX_SEM);
877 throw Exception(
"Cannot create semaphore for read-only shmem segment");
894 shmctl(shared_mem_id_, SHM_UNLOCK, NULL);
896 shmctl(shared_mem_id_, SHM_LOCK, NULL);
911 if (semset_ == NULL) {
915 semset_->
lock(READ_SEM);
916 lock_aquired_ =
true;
944 lock_aquired_ =
true;
961 if (semset_ == NULL) {
965 semset_->
lock(WRITE_MUTEX_SEM);
967 semset_->
lock(READ_SEM);
969 write_lock_aquired_ =
true;
970 lock_aquired_ =
true;
971 semset_->
unlock(WRITE_MUTEX_SEM);
998 if (semset_->
try_lock(WRITE_MUTEX_SEM)) {
1000 if (!semset_->
try_lock(READ_SEM)) {
1002 for (
short j = 0; j < i - 1; ++j) {
1003 semset_->
unlock(READ_SEM);
1005 semset_->
unlock(WRITE_MUTEX_SEM);
1009 lock_aquired_ =
true;
1010 write_lock_aquired_ =
true;
1011 semset_->
unlock(WRITE_MUTEX_SEM);
1027 if (semset_ == NULL || !lock_aquired_)
1030 if (write_lock_aquired_) {
1032 semset_->
unlock(READ_SEM);
1034 write_lock_aquired_ =
false;
1036 semset_->
unlock(READ_SEM);
1053 struct shmid_ds shm_segment;
1055 if (shmctl(shm_id, IPC_STAT, &shm_segment) == -1) {
1059 struct ipc_perm *perm = &shm_segment.shm_perm;
1060 return (perm->mode & SHM_DEST);
1076 struct shmid_ds shm_segment;
1077 struct ipc_perm *perm = &shm_segment.shm_perm;
1079 if (shmctl(shm_id, IPC_STAT, &shm_segment) < 0) {
1082 return !(perm->mode & SHM_LOCKED);
1096 struct shmid_ds shm_segment;
1098 if (shmctl(shm_id, IPC_STAT, &shm_segment) < 0) {
1101 return shm_segment.shm_nattch;
1117 SharedMemoryHeader *header,
1118 SharedMemoryLister *lister,
1119 const char * registry_name)
1123 lister->print_header();
1128 lister->print_no_segments();
1136 lister->print_footer();
1154 const char * registry_name)
1162 if ((i == endi) && (lister != NULL)) {
1173 shmctl(i.
shmid(), IPC_RMID, NULL);
1175 if (lister != NULL) {
1202 const char * registry_name)
1210 if ((i == endi) && (lister != NULL)) {
1214 unsigned int num_segments = 0;
1225 shmctl(i.
shmid(), IPC_RMID, NULL);
1227 if (lister != NULL) {
1236 if ((num_segments == 0) && (lister != NULL)) {
1257 return (
find(magic_token, header, registry_name) !=
end());
1282 SharedMemory::SharedMemoryIterator
1285 return SharedMemoryIterator();
1300 id_it_ = ids_.end();
1306 initialized_ =
true;
1314 header_ = shmit.header_->
clone();
1315 cur_shmid_ = shmit.cur_shmid_;
1320 initialized_ =
true;
1322 if (shmit.id_it_ == shmit.ids_.end()) {
1323 id_it_ = ids_.end();
1325 std::list<SharedMemoryRegistry::SharedMemID>::iterator s;
1326 for (s = ids_.begin(); s != ids_.end(); ++s) {
1327 if (s->shmid == shmit.id_it_->shmid)
1332 if (shmit.shm_buf_ != (
void *)-1) {
1336 }
catch (Exception &e) {
1347 std::list<SharedMemoryRegistry::SharedMemID> ids,
1348 SharedMemoryHeader * header)
1350 header_ = header->clone();
1352 shm_buf_ = (
void *)-1;
1356 initialized_ =
false;
1366 if (shm_buf_ != (
void *)-1) {
1368 shm_buf_ = (
void *)-1;
1374 SharedMemory::SharedMemoryIterator::attach()
1376 struct shmid_ds shm_segment;
1379 cur_shmid_ = id_it_->shmid;
1380 if (cur_shmid_ < 0) {
1392 shm_buf_ = shmat(cur_shmid_, NULL, SHM_RDONLY);
1393 if (shm_buf_ == (
void *)-1) {
1394 throw ShmCouldNotAttachException(
"SharedMemoryIterator could not attach");
1398 if (shmctl(cur_shmid_, IPC_STAT, &shm_segment) < 0) {
1400 throw ShmCouldNotAttachException(
"SharedMemoryIterator could not stat (2)");
1403 segmsize_ = shm_segment.shm_segsz;
1404 segmnattch_ = shm_segment.shm_nattch;
1409 SharedMemory::SharedMemoryIterator::reset()
1413 if (shm_buf_ != (
void *)-1) {
1415 shm_buf_ = (
void *)-1;
1427 SharedMemory::SharedMemoryIterator &
1432 if (!initialized_) {
1433 id_it_ = ids_.begin();
1436 if (id_it_ == ids_.end())
1442 initialized_ =
true;
1444 for (; id_it_ != ids_.end(); ++id_it_) {
1456 + (header_ ? header_->size() : 0);
1466 }
catch (ShmCouldNotAttachException &e) {
1478 SharedMemory::SharedMemoryIterator
1481 SharedMemoryIterator rv(*
this);
1493 for (
unsigned int j = 0; j < i; ++j) {
1506 for (
unsigned int j = 0; j < i; ++j) {
1519 return (cur_shmid_ == s.cur_shmid_);
1529 return !(*
this == s);
1547 if (shm_buf_ != (
void *)-1) {
1549 shm_buf_ = (
void *)-1;
1553 header_ = shmit.header_->
clone();
1555 cur_shmid_ = shmit.cur_shmid_;
1558 if (shmit.id_it_ != shmit.ids_.end()) {
1559 for (id_it_ = ids_.begin(); id_it_ != ids_.end(); ++id_it_) {
1560 if (id_it_->shmid == shmit.id_it_->shmid)
1565 if (shmit.shm_buf_ != (
void *)-1) {
1579 if (id_it_ == ids_.end()) {
1582 return id_it_->magic_token;