Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Examples  

shm.c

Go to the documentation of this file.
00001 /*! \file shm.c
00002     This file implements basic shared memory utilities.
00003  */
00004 
00005 #include "my_shm.h"
00006 
00007 /*! \brief System isentifier for the shared memory segment. This value is set by create_shared_memory_segment() or
00008            get_shared_memory_segment_sys_id().
00009  */
00010 static int       shm_id = -1;
00011 
00012 /*! \brief Address used by the process to access the top of the shared memory segment. This value is set by the function
00013            attache_shared_memory_segment().
00014  */
00015 static SHM_addr  attachement_address = (SHM_addr)-1;
00016 
00017 /*! \brief This variable defines the default permission for all newly created SHM. It can be modified using the function
00018            change_shm_access_permission().
00019  */
00020 static int       permissions = SHM_PERMISSION;
00021 
00022 /*! \brief Data structure that contains information about the shared memory segment (see nam shmctl).
00023  */
00024 static struct shmid_ds shm_info;
00025 
00026 
00027 /*! \brief Change the SHM's default permissions.
00028     \param new_permission New permissions to apply to the shared memory (at creation time).
00029     \warning By default the permission is 0x000001C0 (grant all rights for the process' user).
00030  */
00031 
00032 void change_shm_access_permission (int new_permission)
00033 { permissions = new_permission; }
00034 
00035 /*! \brief Create the shared memory segment.
00036     \param size Size in bytes of the segment.
00037     \param ipc_key This argument represents the IPC identifier of the shared memory segment. If you know the (well known)
00038            identifier's value, then you can specify it. Otherwise, if you want to let the system choose the first available
00039            identifier, then you should set 'ipc_key' to (key_t)-1. Please note that an IPC identifier is a value greater or
00040            equal to 0.
00041     \return On success, the function may return one of the following values:
00042             <UL>
00043               <li>CREATE_SHM_ALREADY_CREATED: The shared memory segment has already been created.
00044               <li>CREATE_SHM_ERROR: An error occured while creating the segment.
00045               <li>CREATE_SHM_OK: The shared memory segment has been successfully created.
00046             </UL>
00047             Once you called create_shared_memory_segment(), you should call get_shared_memory_segment_id() to get the
00048             system's identifier assigned to the newly created shared memory segment.
00049  */
00050 
00051 int create_shared_memory_segment (key_t ipc_key, int size)
00052 {
00053   /* ===================================================== */
00054   /* Make sure that 'shm_id' is not already associated     */
00055   /* with a shared memory segment.                         */
00056   /* ===================================================== */
00057 
00058   if (shm_id != -1) { return CREATE_SHM_ALREADY_CREATED; }
00059 
00060   /* ===================================================== */
00061   /* Create the shared memory segment                      */
00062   /* ===================================================== */
00063 
00064   if (ipc_key == (key_t)-1) { shm_id = shmget (IPC_PRIVATE, size, IPC_CREAT | permissions); }
00065   else { shm_id = shmget (ipc_key, size, IPC_CREAT | permissions); }
00066 
00067   if (shm_id == -1) { return CREATE_SHM_ERROR; }
00068 
00069   return CREATE_SHM_OK;
00070 }
00071 
00072 /*! \example test_shm.c
00073     This example shows how to use the function create_shared_memory_segment().
00074  */
00075 
00076 /*! \brief Get the system's identifier of a shared memory segment that has already been created (by another process).
00077     \param size Size in bytes of the shared memory segment.
00078     \param ipc_key <b>Well known</b> IPC key that represents the shared memory segment. This key is shared between all 
00079            processes that access the shared memory segment.
00080     \return The function may return one of the following value:
00081             <UL>
00082               <li>GET_SHM_ALREADY_GET: You've already got the SHA system's identifier.
00083               <li>GET_SHM_ERROR: An error occured while getting the SHM system's identifier.
00084               <li>GET_SHM_OK: The operation was successful.
00085             </UL>
00086             Once you've called get_shared_memory_segment_sys_id(), you should call get_shared_memory_segment_id() to get the
00087             SHM system's identifier.
00088     \warning If you need to call this function, it means that you want to get the system ID of a SHM that has already been
00089              created by another process. Then you need to specify a <b>well known</b> IPC key.
00090  */
00091 
00092 int get_shared_memory_segment_sys_id (key_t ipc_key, int size)
00093 {
00094   /* ===================================================== */
00095   /* Make sure that the shared memory segement is not      */
00096   /* already attached.                                     */
00097   /* ===================================================== */
00098 
00099   if (shm_id != -1) { return GET_SHM_ALREADY_GET; }
00100 
00101   /* ===================================================== */
00102   /* Get the shared memory segment identifier              */
00103   /* ===================================================== */
00104 
00105   shm_id = shmget (ipc_key, size, 0);
00106 
00107   if (shm_id == -1) { return GET_SHM_ERROR; }
00108 
00109   return GET_SHM_OK;
00110 }
00111 
00112 /*! \brief Tell the IPC library to destroy the SHM on the last detachement.
00113     \return Upon successful completion, the function return 0, otherwise it returns -1.
00114     \warning There are 2 very important things to know:
00115              <UL>
00116                 <li>This function should be called by the process that has created the SHM.
00117                 <li>Once you've called this function, another process can NOT get the shared memory segment (the OS
00118                     consider that the segment is ready to be destroyed ... so no more process can get it). Therefore 
00119                     you must call this function when you are sure that no more process will try to get the shared memory
00120                     segment.
00121              </UL>
00122  */
00123 
00124 int set_shm_auto_destroy()
00125 { return shmctl(shm_id, IPC_RMID, NULL); }
00126 
00127 /*! \example test_shm.c
00128     This example shows how to use the function get_shared_memory_segment_sys_id().
00129  */
00130 
00131 /*! \brief Returns the shared memory segment identifier.
00132     \return The function returns the identifier of the shared memory segment.
00133     \warning The identifier should be a value greater or equal to 0. If this function returns -1, it means that an error
00134              occured during the creation of the segment or that the segment has not been created.
00135  */
00136 
00137 int get_shared_memory_segment_id() { return shm_id; }
00138 
00139 /*! \example test_shm.c
00140     This example shows how to use the function get_shared_memory_segment_id().
00141  */
00142 
00143 /*! \brief Returns the address used by the process to access the shared memory segment.
00144     \return The function returns the address used by the process to access the shared memory segment.
00145  */
00146 
00147 SHM_addr get_shm_address() { return attachement_address; }
00148 
00149 /*! \example test_shm.c
00150     This example shows how to use the function get_shm_address().
00151  */
00152 
00153 /*! \brief Attache a previously created shared memory segment.
00154     \return Upon successful completion the function returns the process' address of the memory segment (that is, the address
00155             used by the process to access the memory segment). Otherwise, the function returns (SHM_addr)-1.
00156  */
00157 
00158 SHM_addr attache_shared_memory_segment ()
00159 {
00160   attachement_address = shmat(shm_id, (SHM_addr)0, 0);
00161   return attachement_address;
00162 }
00163 
00164 /*! \example test_shm.c
00165     This example shows how to use the function attache_shared_memory_segment().
00166  */
00167 
00168 /*! \brief Return the data structure that describes the Shared Memory Segment (as documented in man shmget).
00169     \return Upon successful completion, the function returns that address of a structure &quot;struct shmid_ds&quot; that
00170             describes the SHM (see man shmctl for details about this structure). If an error occured, then the function
00171             returns NULL.
00172  */
00173 
00174 struct shmid_ds* get_shm_info()
00175 {
00176   if (shmctl (shm_id, IPC_STAT, &shm_info) == -1)
00177   { return NULL; }
00178 
00179   return &shm_info;
00180 }
00181 
00182 /*! \example test_shm.c
00183     This example shows how to use the function get_shm_info().
00184  */
00185 
00186 /*! \brief Detache the Shared Memory Segment.
00187     \return If an error occured, the function returns -1. Otherwise, the SHM attachement address is returned.
00188  */
00189 
00190 int detache_shm()
00191 { return  shmdt(attachement_address); }
00192 

Generated on Thu Apr 3 16:23:44 2003 for Common_C_libraries by doxygen1.3-rc1