LCOV - code coverage report
Current view: top level - source/ipc - sharedMemSegment.cpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 0.0 % 63 0
Test Date: 2026-08-30 22:23:37 Functions: 0.0 % 5 0

            Line data    Source code
       1              : /** \file sharedMemSegment.cpp
       2              :  * \author Jared R. Males (jaredmales@gmail.com)
       3              :  * \brief Definitions for the mxlib shared memory facility
       4              :  * \ingroup IPC_sharedmem
       5              :  * \ingroup IPC
       6              :  *
       7              :  */
       8              : 
       9              : //***********************************************************************//
      10              : // Copyright 2021 Jared R. Males (jaredmales@gmail.com)
      11              : //
      12              : // This file is part of mxlib.
      13              : //
      14              : // mxlib is free software: you can redistribute it and/or modify
      15              : // it under the terms of the GNU General Public License as published by
      16              : // the Free Software Foundation, either version 3 of the License, or
      17              : // (at your option) any later version.
      18              : //
      19              : // mxlib is distributed in the hope that it will be useful,
      20              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      21              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      22              : // GNU General Public License for more details.
      23              : //
      24              : // You should have received a copy of the GNU General Public License
      25              : // along with mxlib.  If not, see <http://www.gnu.org/licenses/>.
      26              : //***********************************************************************//
      27              : 
      28              : #include "ipc/sharedMemSegment.hpp"
      29              : 
      30              : namespace mx
      31              : {
      32              : namespace ipc
      33              : {
      34              : 
      35            0 : void sharedMemSegment::initialize()
      36              : {
      37            0 :     key_id = 0;
      38            0 :     key = 0;
      39            0 :     shmemid = 0;
      40            0 :     addr = 0;
      41            0 :     size = 0;
      42              : 
      43            0 :     attached = 0;
      44            0 : }
      45              : 
      46            0 : key_t sharedMemSegment::setKey( const char *path, const int id )
      47              : {
      48            0 :     if( path != 0 )
      49              :     {
      50            0 :         strncpy( key_path, path, MX_IPC_KEYLEN );
      51            0 :         key_id = id;
      52              : 
      53            0 :         key = ftok( key_path, key_id );
      54              :     }
      55              :     else
      56              :     {
      57            0 :         key_path[0] = 0;
      58            0 :         key_id = id;
      59              : 
      60            0 :         key = id;
      61              :     }
      62              : 
      63            0 :     return key;
      64              : }
      65              : 
      66            0 : int sharedMemSegment::create( size_t sz )
      67              : {
      68            0 :     if( ( shmemid = shmget( key, sz + 1 * sizeof( uintptr_t ), IPC_CREAT | 0666 ) ) < 0 )
      69              :     {
      70              :         // If it failed, try to remove the shmem block and recreate it.
      71            0 :         shmemid = shmget( key, 1, 0666 );
      72            0 :         if( shmctl( shmemid, IPC_RMID, 0 ) < 0 )
      73              :         {
      74            0 :             fprintf( stderr, "Could not remove shared memory with key %i\n", key );
      75            0 :             return -1;
      76              :         }
      77              : 
      78              :         // removal successful, now try to create again
      79            0 :         if( ( shmemid = shmget( key, sz + 1 * sizeof( uintptr_t ), IPC_CREAT | 0666 ) ) < 0 )
      80              :         {
      81            0 :             fprintf( stderr, "Could not create shared memory with key %i\n", key );
      82            0 :             return -1;
      83              :         }
      84              :     }
      85              : 
      86            0 :     attach( true );
      87              : 
      88              :     // Since we created this segment, we set the address field.
      89            0 :     *( (uintptr_t *)addr ) = (uintptr_t)addr;
      90              : 
      91            0 :     return 0;
      92              : }
      93              : 
      94            0 : int sharedMemSegment::attach( bool donot_set_addr )
      95              : {
      96              :     struct shmid_ds shmstats;
      97              :     void *new_addr;
      98              : 
      99            0 :     if( shmemid == 0 )
     100              :     {
     101            0 :         if( ( shmemid = shmget( key, 0, 0666 ) ) < 0 )
     102              :         {
     103            0 :             fprintf( stderr, "Could not remove shared memory with key %i\n", key );
     104            0 :             return -1;
     105              :         }
     106              :     }
     107              : 
     108            0 :     if( ( new_addr = shmat( shmemid, 0, 0 ) ) == (char *)-1 )
     109              :     {
     110            0 :         fprintf( stderr, "Could not attach to shared memory with key %i\n", key );
     111            0 :         return -1;
     112              :     }
     113              : 
     114            0 :     attached = 1;
     115              : 
     116            0 :     if( shmctl( shmemid, IPC_STAT, &shmstats ) < 0 )
     117              :     {
     118            0 :         fprintf( stderr, "Could not get shared memory stats with key %i\n", key );
     119            0 :         return -1;
     120              :     }
     121              : 
     122            0 :     size = shmstats.shm_segsz;
     123              : 
     124              :     // Here we first read in the address from the first unitptr_t size block
     125              :     // then detach, then re-attach specifying the address.
     126            0 :     if( !donot_set_addr )
     127              :     {
     128            0 :         addr = (void *)*( (uintptr_t *)new_addr ); // read the address from the segment itself
     129              : 
     130              :         // now detach
     131            0 :         if( shmdt( new_addr ) != 0 )
     132              :         {
     133            0 :             fprintf( stderr, "Unable to detach from shared memory\n" );
     134            0 :             return -1;
     135              :         }
     136              : 
     137            0 :         attached = 0;
     138              : 
     139              :         // and then re-attach, but now specifying an address
     140            0 :         if( ( new_addr = shmat( shmemid, addr, 0 ) ) == (char *)-1 )
     141              :         {
     142            0 :             fprintf( stderr, "Could not re-attach shared memory with key %i\n", key );
     143            0 :             return -1;
     144              :         }
     145              :     }
     146              :     else
     147              :     {
     148            0 :         addr = new_addr;
     149              :     }
     150              : 
     151            0 :     attached = 1;
     152              : 
     153            0 :     return 0;
     154              : }
     155              : 
     156            0 : int sharedMemSegment::detach()
     157              : {
     158              : 
     159            0 :     if( attached )
     160            0 :         return 0;
     161              : 
     162            0 :     if( addr == 0 )
     163            0 :         return 0;
     164              : 
     165              :     // now detach
     166            0 :     if( shmdt( addr ) != 0 )
     167              :     {
     168            0 :         fprintf( stderr, "Unable to detach from shared memory\n" );
     169            0 :         return -1;
     170              :     }
     171              : 
     172            0 :     return 0;
     173              : }
     174              : 
     175              : } // namespace ipc
     176              : } // namespace mx
        

Generated by: LCOV version 2.0-1