#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 } |