#include "rcs_defs.hh"#include <sys/types.h>#include <stddef.h>#include "_shm.h"Include dependency graph for shm.hh:

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

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_t * | rcs_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) |
|
|
|
|
|
|
|
||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
1.2.11.1 written by Dimitri van Heesch,
© 1997-2001