Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

shm.hh File Reference

#include "rcs_defs.hh"
#include <sys/types.h>
#include <stddef.h>
#include "_shm.h"

Include dependency graph for shm.hh:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  shm_t
class  RCS_SHAREDMEM

Defines

#define RCS_SHAREDMEM_NOCREATE   0x00
#define RCS_SHAREDMEM_CREATE   0x01

Functions

shm_trcs_shm_open (key_t key, size_t size, int oflag,...)
int rcs_shm_close (shm_t *shm)
int rcs_shm_delete (shm_t *shm)
int rcs_shm_nattch (shm_t *shm)


Define Documentation

#define RCS_SHAREDMEM_NOCREATE   0x00
 

Definition at line 112 of file shm.hh.

#define RCS_SHAREDMEM_CREATE   0x01
 

Definition at line 113 of file shm.hh.


Function Documentation

shm_t* rcs_shm_open key_t    key,
size_t    size,
int    oflag,
...   
 

Definition at line 568 of file _shm.c.

Referenced by RCS_SHAREDMEM::RCS_SHAREDMEM(), and shm_t::addr().

00569 {
00570   va_list ap;
00571   int mode;
00572   int shmflg = 0;
00573   shm_t *shm;
00574 #ifdef USE_POSIX_SHAREDMEM
00575   int existed_before = 0;
00576   rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00577                    "rcs_shm_open(key=%d(0x%X),size=%d(0x%X),oflag=%d)\n",
00578                    key, key, size, size, oflag);
00579 
00580   if (key == 0)
00581     {
00582       rcs_print_error ("rcs_shm_open(%d(0x%X), %d(0x%X), %d(0x%X)): error\n",
00583                        key, key, size, size, oflag, oflag);
00584       rcs_print_error ("RCS Shared Memory key may not be zero.\n");
00585       return NULL;
00586     }
00587 
00588   shm = (shm_t *) DEBUG_CALLOC (sizeof (shm_t), 1);
00589   if (NULL == shm)
00590     {
00591       rcs_print_error ("rcs_shm_open: calloc failed\n");
00592       return NULL;
00593     }
00594   shm->create_errno = 0;
00595   shm->addr = NULL;
00596   shm->key = key;
00597   shm->size = size;
00598   sprintf (shm->name, "/rcs_shm%d", key);
00599   shm->id = 0;
00600   errno = 0;
00601 
00602 
00603 #if defined(IPC_CREAT)
00604 #if O_CREAT != IPC_CREAT
00605   if ((oflag & IPC_CREAT) && !(oflag & O_CREAT))
00606     {
00607       oflag &= ~(IPC_CREAT);
00608       oflag |= O_CREAT;
00609     }
00610 #endif
00611 #endif
00612 
00613   if ((oflag & O_CREAT))
00614     {
00615       shm->id = shm_open (shm->name, O_RDWR, mode);
00616       if (shm->id > 0)
00617         {
00618           shm->created = 0;
00619           existed_before = 1;
00620         }
00621     }
00622 
00623   /* Create a new memory object */
00624   if (shm->id <= 0)
00625     {
00626       shm->id = shm_open (shm->name, oflag | O_RDWR, mode);
00627       if (shm->id == -1)
00628         {
00629           rcs_print_error ("shm_open(%s,%d(0x%X),%d(0x%X)) failed:%s %d\n",
00630                            shm->name, oflag | O_RDWR, oflag | O_RDWR,
00631                            mode, mode, strerror (errno), errno);
00632           shm->create_errno = errno;
00633           return shm;
00634         }
00635       shm->created = 1;
00636       existed_before = 0;
00637     }
00638 
00639   /* Set the memory object's size */
00640   if (ftruncate (shm->id, size + 16) == -1)
00641     {
00642       rcs_print_error ("ftruncate(%d,%d): %s %d\n",
00643                        shm->id, size, strerror (errno), errno);
00644       shm->create_errno = errno;
00645       return shm;
00646     }
00647 
00648   /* Map the memory object */
00649   shm->addr = mmap (0, size + 16,
00650                     PROT_READ | PROT_WRITE, MAP_SHARED, shm->id, 0);
00651   if (shm->addr == MAP_FAILED)
00652     {
00653       rcs_print_error
00654         ("mmap(0,%d,PROT_READ | PROT_WRITE, MAP_SHARED,%d,0) failed: %s %d\n",
00655          shm->id, size, strerror (errno), errno);
00656       shm->create_errno = errno;
00657     }
00658   if (oflag & O_CREAT && !existed_before)
00659     {
00660       *((int *) ((char *) shm->addr + size)) = 0;
00661     }
00662   else
00663     {
00664       (*((int *) ((char *) shm->addr + size)))++;
00665     }
00666 
00667   return (shm);
00668 #else
00669 
00670   struct shmid_ds shared_mem_info;
00671   int pid;
00672   int i;
00673 
00674   rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00675                    "rcs_shm_open(key=%d(0x%X),size=%d(0x%X),oflag=%d)\n",
00676                    key, key, size, size, oflag);
00677 
00678   if (key == 0)
00679     {
00680       rcs_print_error ("rcs_shm_open(%d(0x%X), %d(0x%X), %d(0x%X)): error\n",
00681                        key, key, size, size, oflag, oflag);
00682       rcs_print_error ("RCS Shared Memory key may not be zero.\n");
00683       return NULL;
00684     }
00685 
00686 #if defined(O_CREAT)
00687 #if O_CREAT != IPC_CREAT
00688   if ((oflag & O_CREAT) && !(oflag & IPC_CREAT))
00689     {
00690       oflag &= ~(O_CREAT);
00691       oflag |= IPC_CREAT;
00692     }
00693 #endif
00694 #endif
00695 
00696   if (oflag)
00697     {
00698       shmflg |= IPC_CREAT;
00699     }
00700   if (shmflg & IPC_CREAT)
00701     {
00702 #ifdef USING_VARARGS
00703       va_start (ap);
00704 #else
00705       va_start (ap, oflag);
00706 #endif
00707       mode = va_arg (ap, int);
00708       shmflg |= mode;
00709     }
00710 
00711   shm = (shm_t *) DEBUG_CALLOC (sizeof (shm_t), 1);
00712   if (NULL == shm)
00713     {
00714       rcs_print_error ("rcs_shm_open: calloc failed\n");
00715       return NULL;
00716     }
00717   shm->create_errno = 0;
00718   shm->addr = NULL;
00719   shm->key = key;
00720   errno = 0;
00721 
00722   if ((shm->id = shmget (key, (int) size, shmflg)) == -1)
00723     {
00724       shm->create_errno = errno;
00725       rcs_print_error ("shmget(%d(0x%X),%d,%d) failed: (errno = %d): %s\n",
00726                        key, key, size, shmflg, errno, strerror (errno));
00727       switch (errno)
00728         {
00729         case EEXIST:
00730           rcs_print_error
00731             ("A shared memory buffer for this key already exists.\n");
00732           break;
00733 
00734         case EINVAL:
00735           rcs_print_error
00736             ("Either the size is too big or the shared memory buffer already exists but is of the wrong size.\n");
00737           break;
00738 
00739         case ENOSPC:
00740           rcs_print_error
00741             ("The system imposed limit on the maximum number of shared memory segments has been exceeded.\n");
00742           break;
00743         }
00744       return (shm);
00745     }
00746 
00747   /* map shmem area into local address space */
00748   shmflg = 0;
00749   shmflg &= ~SHM_RDONLY;
00750   if ((shm->addr = (void *) shmat (shm->id, 0, shmflg)) == (void *) -1)
00751     {
00752       shm->create_errno = errno;
00753       rcs_print_error ("shmat(%d,0,%d) failed:(errno = %d): %s\n", shm->id,
00754                        shmflg, errno, strerror (errno));
00755       rcs_print_error ("key = %d (0x%X)\n", key, key);
00756       shm->addr = NULL;
00757       return (shm);
00758     }
00759 
00760   /* Check to see if I am the creator of this shared memory buffer. */
00761   if (shmctl (shm->id, IPC_STAT, &shared_mem_info) < 0)
00762     {
00763       rcs_print_error ("shmctl error: %d %s\n", errno, strerror (errno));
00764       return shm;
00765     }
00766 
00767   /* If oflag was not set this process couldn't be the creator. */
00768   if (!oflag)
00769     {
00770       return shm;
00771     }
00772 
00773   if (!shmems_created_list_initialized)
00774     {
00775       memset (shmems_created_list, 0, 100 * sizeof (int));
00776       shmems_created_list_initialized = 1;
00777     }
00778   else
00779     {
00780       for (i = 0; i < 100; i++)
00781         {
00782           if (shmems_created_list[i] == key)
00783             {
00784               return shm;
00785             }
00786         }
00787     }
00788 
00789   pid = (int) getpid ();
00790   if (pid <= 0)
00791     {
00792       rcs_print_error ("getpid error: %d %s\n", errno, strerror (errno));
00793       return shm;
00794     }
00795   shm->created = (shared_mem_info.shm_cpid == pid);
00796 #if defined(darwin) || defined(linux_2_4_0)
00797   shm->created = 1;
00798 #endif
00799 
00800   if (shm->created)
00801     {
00802       for (i = 0; i < 100; i++)
00803         {
00804           if (shmems_created_list[i] <= 0)
00805             {
00806               shmems_created_list[i] = shm->key;
00807               break;
00808             }
00809         }
00810     }
00811   return shm;
00812 #endif
00813 }

int rcs_shm_close shm_t   shm
 

Definition at line 816 of file _shm.c.

Referenced by shm_t::addr(), and RCS_SHAREDMEM::~RCS_SHAREDMEM().

00817 {
00818 #ifdef USE_POSIX_SHAREDMEM
00819   if (shm == 0)
00820     {
00821       return -1;
00822     }
00823   if (shm->addr > 0)
00824     {
00825       (*((int *) ((char *) shm->addr + shm->size)))--;
00826       if (munmap (shm->addr, shm->size + 16) == -1)
00827         {
00828           rcs_print_error ("munmap(%p,%d) failed. %s %d\n",
00829                            shm->addr, shm->size, strerror (errno), errno);
00830           return -1;
00831         }
00832       shm->addr = NULL;
00833       if (shm->id > 0)
00834         {
00835           if (close (shm->id) == -1)
00836             {
00837               rcs_print_error ("close(%d) failed. %s %d\n",
00838                                shm->id, strerror (errno), errno);
00839             }
00840         }
00841       shm->id = 0;
00842     }
00843 #else
00844   struct shmid_ds shm_ds;       /* dummy */
00845   int i;
00846 
00847   /* check for invalid ptr */
00848   if (shm == NULL)
00849     return -1;
00850 
00851   rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00852                    "rcs_shm_close(shm->key=%d(0x%X),shm->size=%d(0x%X),shm->addr=0x%X)\n",
00853                    shm->key, shm->key, shm->size, shm->size, shm->addr);
00854 
00855   /* detach from shmem */
00856   shmdt ((char *) shm->addr);
00857 
00858   /* remove OS shmem if there are no attached processes */
00859   if (rcs_shm_nattch (shm) == 0)
00860     {
00861       shmctl (shm->id, IPC_RMID, &shm_ds);
00862     }
00863 
00864   if (shm->created && shmems_created_list_initialized)
00865     {
00866       for (i = 0; i < 100; i++)
00867         {
00868           if (shmems_created_list[i] == shm->key)
00869             {
00870               shmems_created_list[i] = 0;
00871               break;
00872             }
00873         }
00874     }
00875 
00876 #endif
00877 
00878   /* DEBUG_FREE the shm_t data struct */
00879 #ifdef sparcworks_sun4          /* free is defined as int free(char *) for this platform
00880                                    it should be void free(void *); */
00881   DEBUG_FREE ((char *) shm);
00882 #else
00883   DEBUG_FREE (shm);
00884 #endif
00885 
00886   return 0;
00887 }

int rcs_shm_delete shm_t   shm
 

Definition at line 890 of file _shm.c.

Referenced by shm_t::addr(), and RCS_SHAREDMEM::~RCS_SHAREDMEM().

00891 {
00892 #ifdef USE_POSIX_SHAREDMEM
00893   if (shm == 0)
00894     {
00895       return -1;
00896     }
00897   if (shm->addr > 0)
00898     {
00899       (*((int *) ((char *) shm->addr + shm->size)))--;
00900       if (munmap (shm->addr, shm->size + 16) == -1)
00901         {
00902           rcs_print_error ("munmap(%p,%d) failed. %s %d\n",
00903                            shm->addr, shm->size, strerror (errno), errno);
00904           return -1;
00905         }
00906       shm->addr = NULL;
00907       if (shm->id > 0)
00908         {
00909           if (close (shm->id) == -1)
00910             {
00911               rcs_print_error ("close(%d) failed. %s %d\n",
00912                                shm->id, strerror (errno), errno);
00913             }
00914         }
00915       shm->id = 0;
00916     }
00917   shm_unlink (shm->name);
00918 #else
00919   struct shmid_ds shm_ds;       /* dummy */
00920 
00921   /* check for invalid ptr */
00922   if (shm == NULL)
00923     return -1;
00924 
00925   /* detach from shmem */
00926   shmdt ((char *) shm->addr);
00927 
00928   /* remove OS shmem regardless of whether there are attached processes */
00929   shmctl (shm->id, IPC_RMID, &shm_ds);
00930 #endif
00931 
00932   /* DEBUG_FREE the shm_t data struct */
00933 #ifdef sparcworks_sun4          /* free is defined as int free(char *) for this platform
00934                                    it should be void free(void *); */
00935   DEBUG_FREE ((char *) shm);
00936 #else
00937   DEBUG_FREE (shm);
00938 #endif
00939 
00940   return 0;
00941 }

int rcs_shm_nattch shm_t   shm
 

Definition at line 944 of file _shm.c.

Referenced by shm_t::addr(), RCS_SHAREDMEM::nattch(), and rcs_shm_close().

00945 {
00946 #ifdef USE_POSIX_SHAREDMEM
00947   if (shm == 0)
00948     {
00949       return -1;
00950     }
00951   if (shm->addr == 0)
00952     {
00953       return -1;
00954     }
00955   return *((int *) (((char *) shm->addr) + shm->size));
00956 #else
00957   struct shmid_ds shm_ds;
00958 
00959   /* check for invalid ptr */
00960   if (shm == NULL)
00961     return -1;
00962 
00963   /* get the status of shared memory */
00964   shmctl (shm->id, IPC_STAT, &shm_ds);
00965 
00966   return shm_ds.shm_nattch;
00967 #endif
00968 
00969 }


Generated on Sun Dec 2 15:57:55 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001