Fawkes API
Fawkes Development Version
|
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;
311 e.
append(
"SharedMemory public copy constructor");
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;
468 e.
append(
"SharedMemory public copy constructor");
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) {
551 if (
_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);
608 if (errno == EEXIST) {
613 }
else if (errno == EINVAL) {
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;
1119 const char * registry_name)
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());
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) {
1347 std::list<SharedMemoryRegistry::SharedMemID> ids,
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) {
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);
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);
1548 if (shm_buf_ != (
void *)-1) {
1550 shm_buf_ = (
void *)-1;
1554 header_ = shmit.header_->
clone();
1556 cur_shmid_ = shmit.cur_shmid_;
1559 if (shmit.id_it_ != shmit.ids_.end()) {
1560 for (id_it_ = ids_.begin(); id_it_ != ids_.end(); ++id_it_) {
1561 if (id_it_->shmid == shmit.id_it_->shmid)
1566 if (shmit.shm_buf_ != (
void *)-1) {
1580 if (id_it_ == ids_.end()) {
1583 return id_it_->magic_token;
char * _shm_magic_token
Magic token as stored in the shared memory segment.
char * _magic_token
Magic token.
bool _is_read_only
Read-only.
bool is_creator() const
Determine if the shared memory segment has been created by this instance.
void set_swapable(bool swapable)
Set shared memory swapable.
int shmid() const
Get shared memory ID.
Memory size does not match.
The pointer does not point inside the shared memory.
int shmem_id() const
Get shared memory ID.
void set(void *memptr)
Copies data from the memptr to shared memory.
bool _destroy_on_delete
destroy on delete.
static void list(const char *magic_token, SharedMemoryHeader *header, SharedMemoryLister *lister, const char *registry_name=0)
List shared memory segments of a given type.
Format list output for shared memory segments.
~SharedMemoryIterator()
Destructor.
void attach()
Attach to the shared memory segment.
static const unsigned int MagicTokenSize
The magic token size.
bool is_read_only() const
Check for read-only mode.
void free()
Detach from and maybe destroy the shared memory segment.
SharedMemoryIterator & operator+(unsigned int i)
Advance by i steps.
const char * magic_token() const
Get magic token.
long unsigned int _shm_offset
Offset to the master's base addr.
SharedMemoryIterator & operator+=(unsigned int i)
Advance by i steps.
unsigned int num_attached() const
Get number of attached processes.
void set_destroy_on_delete(bool destroy)
Set if semaphore set should be destroyed on delete.
static void erase_orphaned(const char *magic_token, SharedMemoryHeader *header, SharedMemoryLister *lister=0, const char *registry_name=0)
Erase orphaned (attach count = 0) shared memory segments of a given type.
void unlock()
Unlock memory.
void * memptr() const
Get a pointer to the shared memory This method returns a pointer to the data-segment of the shared me...
virtual void print_no_segments()=0
Print this if no matching segment was found.
virtual ~SharedMemory()
Destructor.
virtual void print_info(const SharedMemoryHeader *header, int shm_id, int semaphore, unsigned int mem_size, const void *memptr)=0
Print info about segment.
void append(const char *format,...)
Append messages to the message list.
const SharedMemoryHeader * operator*() const
Get SharedMemoryHeader.
virtual void print_no_orphaned_segments()=0
Print this if no matching orphaned segment was found.
SharedMemoryHeader * _header
Data-specific header.
size_t data_size() const
Get the size of the data-segment.
int semaphore() const
Get semaphore.
SharedMemoryIterator & operator=(const SharedMemoryIterator &shmit)
Make this instance point to the same segment as shmit.
SharedMemory(const char *magic_token, SharedMemoryHeader *header, bool is_read_only, bool create, bool destroy_on_delete, const char *registry_name=0)
Create a new shared memory segment.
void set_value(int sem_num, int val)
Set the semaphore value.
bool operator==(const SharedMemoryIterator &s) const
Check iterators for equality.
bool try_lock(unsigned short sem_num=0, short num=1)
Try to lock resources on the semaphore set.
bool _should_create
Create shared memory segment.
size_t _mem_size
Total size of the segment, including headers.
void lock_for_write()
Lock shared memory segment for writing.
bool is_swapable() const
Check if memory can be swapped out.
bool operator!=(const SharedMemoryIterator &s) const
Check iterators for inequality.
void * _shm_upper_bound
Upper bound of memory.
Fawkes library namespace.
virtual void print_footer()=0
Print footer of the table.
size_t segmsize() const
Get segment size.
size_t _data_size
Size of the data segment only.
void * addr(void *ptr) const
Get an address from a real pointer.
bool is_valid() const
Check validity of shared memory segment.
virtual void print_header()=0
Print header of the table.
The address points out of the shared memory.
static void erase(const char *magic_token, SharedMemoryHeader *header, SharedMemoryLister *lister=0, const char *registry_name=0)
Erase shared memory segments of a given type.
bool try_lock_for_read()
Try to aquire lock on shared memory segment for reading.
size_t segmnattch() const
Get number of attached parties.
bool is_destroyed() const
Check if segment has been destroyed This can be used if the segment has been destroyed.
int key()
Get key of semaphore.
bool is_protected() const
Check if memory segment is protected.
static SharedMemoryIterator end()
Get invalid iterator.
SharedMemory & operator=(const SharedMemory &s)
Assignment operator.
void lock(unsigned short sem_num=0, short num=1)
Lock resources on the semaphore set.
void * ptr(void *addr) const
Get the real pointer to the data based on an address.
SharedMemoryIterator()
Constructor.
SharedMemoryIterator & operator++()
Prefix increment.
static bool exists(const char *magic_token, SharedMemoryHeader *header, const char *registry_name=0)
Check if a specific shared memory segment exists.
SharedMemory_header_t * _shm_header
general header as stored in the shared memory segment
void * _memptr
Pointer to the data segment.
void remove_segment(int shmid)
Remove segment.
Could not attach to shared memory segment.
void add_semaphore()
Add semaphore to shared memory segment.
bool try_lock_for_write()
Try to aquire lock on shared memory segment for writing.
void lock_for_read()
Lock shared memory segment for reading.
void unlock(unsigned short sem_num=0, short num=-1)
Unlock resources on the semaphore set.
static SharedMemoryIterator find(const char *magic_token, SharedMemoryHeader *header, const char *registry_name=0)
Find SharedMemory segments.
std::list< SharedMemoryRegistry::SharedMemID > find_segments(const char *magic_token) const
Find segments with particular magic token.
void add_segment(int shmid, const char *magic_token)
Register a segment.
void set_destroy_on_delete(bool destroy)
Set deletion behaviour.
static void destroy(int key)
Destroy a semaphore set.
void * databuf() const
Get pointer to data buffer.
static const short MaxNumConcurrentReaders
Maximum number of concurrent readers.
Base class for exceptions in Fawkes.