From 66339d10c0702db7d008d1249c6fb57a1992b65d Mon Sep 17 00:00:00 2001 From: Antoine Villeret Date: Tue, 3 Sep 2013 07:53:52 +0000 Subject: fix allocate fn on linux fix size issue on windows svn path=/trunk/externals/share_mem/; revision=17201 --- shmem.c | 140 ++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 79 insertions(+), 61 deletions(-) (limited to 'shmem.c') diff --git a/shmem.c b/shmem.c index d609360..f84cb60 100644 --- a/shmem.c +++ b/shmem.c @@ -203,68 +203,83 @@ void shmem_read(t_shmem *x, t_float index) void shmem_allocate(t_shmem *x, t_float fId, t_float fSize) { - int id = (int) fId; - x->segment_size = (int) fSize; + int id = (int) fId; + if ( id < 1 ){ + error("id should be > 0"); // shmid 0 doesn't seem to work + return; + } + + x->segment_size = (int) fSize; #ifdef _WIN32 - if ( x->share_memory ) UnmapViewOfFile( x->share_memory ); - if ( x->m_MapFile ) CloseHandle( x->m_MapFile ); + if ( x->share_memory ) UnmapViewOfFile( x->share_memory ); + if ( x->m_MapFile ) CloseHandle( x->m_MapFile ); - sprintf(x->m_fileMappingName, "puredata-FileMappingObject_%d", id); + sprintf(x->m_fileMappingName, "puredata-FileMappingObject_%d", id); - x->m_MapFile = CreateFileMapping( - INVALID_HANDLE_VALUE, // use paging file - NULL, // default security - PAGE_READWRITE, // read/write access - (x->segment_size & 0xFFFFFFFF00000000) >> 32, // maximum object size (high-order DWORD) - x->segment_size & 0xFFFFFFFF, // maximum object size (low-order DWORD) - x->m_fileMappingName); // name of mapping object + x->m_MapFile = CreateFileMapping( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + (x->segment_size & 0xFFFFFFFF00000000) >> 32, // maximum object size (high-order DWORD) + x->segment_size & 0xFFFFFFFF, // maximum object size (low-order DWORD) + x->m_fileMappingName); // name of mapping object - if (x->m_MapFile == NULL) - { - error("Could not create file mapping object %s - error %ld.",x->m_fileMappingName, GetLastError()); - outlet_float(x->m_info_out, -1); - return; - } + if (x->m_MapFile == NULL) + { + error("Could not create file mapping object %s - error %ld.",x->m_fileMappingName, GetLastError()); + outlet_float(x->m_info_out, -1); + return; + } - x->share_memory = (t_float*) MapViewOfFile(x->m_MapFile, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write permission - 0, - 0, - x->segment_size); + x->share_memory = (t_float*) MapViewOfFile(x->m_MapFile, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + sizeof(t_float)*x->segment_size); - if ( !x->share_memory ){ - error("Could not get a view of file %s - error %ld",x->m_fileMappingName, GetLastError()); - outlet_float(x->m_info_out, -1); - return; - } else { - verbose(0,"File mapping object %s successfully created.",x->m_fileMappingName); - } + if ( !x->share_memory ){ + error("Could not get a view of file %s - error %ld",x->m_fileMappingName, GetLastError()); + outlet_float(x->m_info_out, -1); + return; + } else { + verbose(0,"File mapping object %s successfully created.",x->m_fileMappingName); + } -#else +#else // for LINUX / UNIX - struct shmid_ds shmbuffer; + struct shmid_ds shmbuffer; + if (x->share_memory) { + shmdt (x->share_memory); + x->share_memory=NULL; + } + if (x->segment_id != -1) { + shmctl (x->segment_id, IPC_RMID, 0); + x->segment_id = -1; + } - x->segment_id = shmget (id, sizeof(t_float)*x->segment_size, - IPC_CREAT | S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH); - if(x->segment_id>0) { - x->share_memory = (t_float*) shmat (x->segment_id, 0, 0); - // post("shmem memory attached at address %p\n", x->share_memory); + x->segment_id = shmget (id, sizeof(t_float)*x->segment_size, + IPC_CREAT | S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH); // AV it should safer to use ftok() to generate an id + + if(x->segment_id != -1) { // 0 could be a valid value, -1 means error + x->share_memory = (t_float*) shmat (x->segment_id, 0, 0); + // post("shmem memory attached at address %p\n", x->share_memory); - shmctl (x->segment_id, IPC_STAT, &shmbuffer); - // post ("segment size: %d\n", shmbuffer.shm_segsz); + shmctl (x->segment_id, IPC_STAT, &shmbuffer); + // post ("segment size: %d\n", shmbuffer.shm_segsz); - if ((int)shmbuffer.shm_segsz < (int)sizeof(t_float)*x->segment_size) { - // there was a problem, set object meme size to 0 - error("could not allocate shmem memory Id : %d, size %d", (int)id, x->segment_size ); - x->segment_size = 0; - outlet_float(x->m_info_out, -1); - } - } - else { - error("could not allocate shmem memory Id : %d, size %d", (int)id, x->segment_size ); - x->segment_size = 0; - outlet_float(x->m_info_out, -1); - } + if ((int)shmbuffer.shm_segsz < (int)sizeof(t_float)*x->segment_size) { + // there was a problem, set object meme size to 0 + error("could not allocate shmem memory Id : %d, size %d", (int)id, x->segment_size ); + x->segment_size = 0; + x->share_memory=NULL; + outlet_float(x->m_info_out, -1); + } + } + else { + error("could not allocate shmem memory Id : %d, size %d", (int)id, x->segment_size ); + x->segment_size = 0; + outlet_float(x->m_info_out, -1); + } #endif // _WIN32 outlet_float(x->m_info_out, id); } @@ -281,22 +296,25 @@ t_class *shmem_class; */ void *shmem_new( t_floatarg id, t_floatarg size) { - // post ("id, size: %f, %f", id, size); - t_shmem *x = (t_shmem *)pd_new(shmem_class); - - x->share_memory = NULL; + // post ("id, size: %f, %f", id, size); + t_shmem *x = (t_shmem *)pd_new(shmem_class); + +#ifndef _WIN32 + x->segment_id=-1; +#endif + x->share_memory = NULL; - outlet_new(&x->x_obj, 0); - x->m_info_out = outlet_new(&x->x_obj, 0); - shmem_allocate(x, id, size); - return (void *)x; + outlet_new(&x->x_obj, 0); + x->m_info_out = outlet_new(&x->x_obj, 0); + shmem_allocate(x, id, size); + return (void *)x; } void shmem_free(t_shmem *x) { #ifdef _WIN32 - if ( x->share_memory ) UnmapViewOfFile( x->share_memory ); - if ( x->m_MapFile ) CloseHandle( x->m_MapFile ); + if ( x->share_memory ) UnmapViewOfFile( x->share_memory ); + if ( x->m_MapFile ) CloseHandle( x->m_MapFile ); #else shmdt (x->share_memory); shmctl (x->segment_id, IPC_RMID, 0); -- cgit v1.2.1