/* (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) (c) Copyright 2000-2004 Convergence (integrated media) GmbH All rights reserved. Written by Denis Oliver Kropp , Andreas Hundt , Sven Neumann , Ville Syrjälä and Claudio Ciccani . This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include D_DEBUG_DOMAIN( Fusion_SHMPool, "Fusion/SHMPool", "Fusion Shared Memory Pool" ); /**********************************************************************************************************************/ static DirectResult init_pool ( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared, const char *name, unsigned int max_size, bool debug ); static DirectResult join_pool ( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ); static void leave_pool ( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ); static void shutdown_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ); /**********************************************************************************************************************/ DirectResult fusion_shm_pool_create( FusionWorld *world, const char *name, unsigned int max_size, bool debug, FusionSHMPoolShared **ret_pool ) { int i; DirectResult ret; FusionSHM *shm; FusionSHMShared *shared; D_MAGIC_ASSERT( world, FusionWorld ); D_MAGIC_ASSERT( world->shared, FusionWorldShared ); D_ASSERT( name != NULL ); D_ASSERT( max_size > 0 ); D_ASSERT( ret_pool != NULL ); D_DEBUG_AT( Fusion_SHMPool, "%s( %p [%d], '%s', %d, %p, %sdebug )\n", __FUNCTION__, world, world->shared->world_index, name, max_size, ret_pool, debug ? "" : "non-" ); #if !DIRECT_BUILD_DEBUGS debug = false; #endif shm = &world->shm; D_MAGIC_ASSERT( shm, FusionSHM ); shared = shm->shared; D_MAGIC_ASSERT( shared, FusionSHMShared ); if (max_size < 8192) { D_ERROR( "Fusion/SHMPool: Maximum size (%d) should be 8192 at least!\n", max_size ); return DR_INVARG; } ret = fusion_skirmish_prevail( &shared->lock ); if (ret) goto error; if (shared->num_pools == FUSION_SHM_MAX_POOLS) { D_ERROR( "Fusion/SHMPool: Maximum number of pools (%d) already reached!\n", FUSION_SHM_MAX_POOLS ); ret = DR_LIMITEXCEEDED; goto error; } for (i=0; ipools[i].active) break; D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared ); D_MAGIC_ASSUME( &shm->pools[i], FusionSHMPool ); } D_ASSERT( i < FUSION_SHM_MAX_POOLS ); D_DEBUG_AT( Fusion_SHMPool, " -> index %d\n", i ); memset( &shm->pools[i], 0, sizeof(FusionSHMPool) ); memset( &shared->pools[i], 0, sizeof(FusionSHMPoolShared) ); shared->pools[i].index = i; ret = init_pool( shm, &shm->pools[i], &shared->pools[i], name, max_size, debug ); if (ret) goto error; shared->num_pools++; fusion_skirmish_dismiss( &shared->lock ); *ret_pool = &shared->pools[i]; D_DEBUG_AT( Fusion_SHMPool, " -> %p\n", *ret_pool ); return DR_OK; error: fusion_skirmish_dismiss( &shared->lock ); return ret; } DirectResult fusion_shm_pool_destroy( FusionWorld *world, FusionSHMPoolShared *pool ) { DirectResult ret; FusionSHM *shm; FusionSHMShared *shared; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, world, pool ); D_MAGIC_ASSERT( world, FusionWorld ); D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); shm = &world->shm; D_MAGIC_ASSERT( shm, FusionSHM ); shared = shm->shared; D_MAGIC_ASSERT( shared, FusionSHMShared ); D_ASSERT( shared == pool->shm ); ret = fusion_skirmish_prevail( &shared->lock ); if (ret) return ret; ret = fusion_skirmish_prevail( &pool->lock ); if (ret) { fusion_skirmish_dismiss( &shared->lock ); return ret; } D_ASSERT( pool->active ); D_ASSERT( pool->index >= 0 ); D_ASSERT( pool->index < FUSION_SHM_MAX_POOLS ); D_ASSERT( pool->pool_id == shm->pools[pool->index].pool_id ); D_ASSERT( pool == &shared->pools[pool->index] ); D_MAGIC_ASSERT( &shm->pools[pool->index], FusionSHMPool ); shutdown_pool( shm, &shm->pools[pool->index], pool ); shared->num_pools--; fusion_skirmish_dismiss( &shared->lock ); return DR_OK; } DirectResult fusion_shm_pool_attach( FusionSHM *shm, FusionSHMPoolShared *pool ) { DirectResult ret; FusionSHMShared *shared; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, shm, pool ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); shared = shm->shared; D_MAGIC_ASSERT( shared, FusionSHMShared ); D_ASSERT( shared == pool->shm ); ret = fusion_skirmish_prevail( &pool->lock ); if (ret) { return ret; } D_ASSERT( pool->active ); D_ASSERT( pool->index >= 0 ); D_ASSERT( pool->index < FUSION_SHM_MAX_POOLS ); D_ASSERT( pool == &shared->pools[pool->index] ); D_ASSERT( !shm->pools[pool->index].attached ); ret = join_pool( shm, &shm->pools[pool->index], pool ); fusion_skirmish_dismiss( &pool->lock ); return ret; } DirectResult fusion_shm_pool_detach( FusionSHM *shm, FusionSHMPoolShared *pool ) { DirectResult ret; FusionSHMShared *shared; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, shm, pool ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); shared = shm->shared; D_MAGIC_ASSERT( shared, FusionSHMShared ); D_ASSERT( shared == pool->shm ); ret = fusion_skirmish_prevail( &pool->lock ); if (ret) { fusion_skirmish_dismiss( &shared->lock ); return ret; } D_ASSERT( pool->active ); D_ASSERT( pool->index >= 0 ); D_ASSERT( pool->index < FUSION_SHM_MAX_POOLS ); D_ASSERT( pool->pool_id == shm->pools[pool->index].pool_id ); D_ASSERT( pool == &shared->pools[pool->index] ); D_ASSERT( shm->pools[pool->index].attached ); D_MAGIC_ASSERT( &shm->pools[pool->index], FusionSHMPool ); leave_pool( shm, &shm->pools[pool->index], pool ); fusion_skirmish_dismiss( &pool->lock ); return DR_OK; } DirectResult fusion_shm_pool_allocate( FusionSHMPoolShared *pool, int size, bool clear, bool lock, void **ret_data ) { DirectResult ret; void *data; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %d, %sclear, %p )\n", __FUNCTION__, pool, size, clear ? "" : "un", ret_data ); D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); D_ASSERT( size > 0 ); D_ASSERT( ret_data != NULL ); if (lock) { ret = fusion_skirmish_prevail( &pool->lock ); if (ret) return ret; } __shmalloc_brk( pool->heap, 0 ); data = _fusion_shmalloc( pool->heap, size ); if (!data) { if (lock) fusion_skirmish_dismiss( &pool->lock ); return DR_NOSHAREDMEMORY; } if (clear) memset( data, 0, size ); *ret_data = data; if (lock) fusion_skirmish_dismiss( &pool->lock ); return DR_OK; } DirectResult fusion_shm_pool_reallocate( FusionSHMPoolShared *pool, void *data, int size, bool lock, void **ret_data ) { DirectResult ret; void *new_data; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %d, %p )\n", __FUNCTION__, pool, data, size, ret_data ); D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); D_ASSERT( data != NULL ); D_ASSERT( data >= pool->addr_base ); D_ASSERT( data < pool->addr_base + pool->max_size ); D_ASSERT( size > 0 ); D_ASSERT( ret_data != NULL ); if (lock) { ret = fusion_skirmish_prevail( &pool->lock ); if (ret) return ret; } __shmalloc_brk( pool->heap, 0 ); new_data = _fusion_shrealloc( pool->heap, data, size ); if (!new_data) { if (lock) fusion_skirmish_dismiss( &pool->lock ); return DR_NOSHAREDMEMORY; } *ret_data = new_data; if (lock) fusion_skirmish_dismiss( &pool->lock ); return DR_OK; } DirectResult fusion_shm_pool_deallocate( FusionSHMPoolShared *pool, void *data, bool lock ) { DirectResult ret; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, pool, data ); D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); D_ASSERT( data != NULL ); D_ASSERT( data >= pool->addr_base ); D_ASSERT( data < pool->addr_base + pool->max_size ); if (lock) { ret = fusion_skirmish_prevail( &pool->lock ); if (ret) return ret; } __shmalloc_brk( pool->heap, 0 ); _fusion_shfree( pool->heap, data ); if (lock) fusion_skirmish_dismiss( &pool->lock ); return DR_OK; } /**********************************************************************************************************************/ #if FUSION_BUILD_KERNEL static DirectResult init_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared, const char *name, unsigned int max_size, bool debug ) { DirectResult ret; int fd; int size; FusionWorld *world; FusionSHMPoolNew pool_new = { .pool_id = 0 }; FusionSHMPoolAttach pool_attach = { .pool_id = 0 }; FusionEntryInfo info; char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32]; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n", __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( shm->shared, FusionSHMShared ); D_ASSERT( name != NULL ); D_ASSERT( max_size > sizeof(shmalloc_heap) ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); D_ASSERT( pool != NULL ); D_ASSERT( shared != NULL ); /* Fill out information for new pool. */ pool_new.max_size = max_size; pool_new.max_size += BLOCKALIGN(sizeof(shmalloc_heap)) + BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) ); /* Create the new pool. */ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_NEW, &pool_new )) { if (errno == EINTR) continue; D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_NEW failed!\n" ); return DR_FUSION; } /* Set the pool info. */ info.type = FT_SHMPOOL; info.id = pool_new.pool_id; snprintf( info.name, sizeof(info.name), "%s", name ); ioctl( world->fusion_fd, FUSION_ENTRY_SET_INFO, &info ); /* Set pool to attach to. */ pool_attach.pool_id = pool_new.pool_id; /* Attach to the pool. */ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) { if (errno == EINTR) continue; D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" ); while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" ); break; } } return DR_FUSION; } /* Generate filename. */ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs, fusion_world_index( shm->world ), pool_new.pool_id ); /* Initialize the heap. */ ret = __shmalloc_init_heap( shm, buf, pool_new.addr_base, max_size, &fd, &size ); if (ret) { while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" ); break; } } return ret; } /* Initialize local data. */ pool->attached = true; pool->shm = shm; pool->shared = shared; pool->pool_id = pool_new.pool_id; pool->fd = fd; pool->filename = D_STRDUP( buf ); /* Initialize shared data. */ shared->active = true; shared->debug = debug; shared->shm = shm->shared; shared->max_size = pool_new.max_size; shared->pool_id = pool_new.pool_id; shared->addr_base = pool_new.addr_base; shared->heap = pool_new.addr_base; shared->heap->pool = shared; fusion_skirmish_init( &shared->lock, name, world ); D_MAGIC_SET( pool, FusionSHMPool ); D_MAGIC_SET( shared, FusionSHMPoolShared ); shared->name = SHSTRDUP( shared, name ); return DR_OK; } static DirectResult join_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ) { DirectResult ret; int fd; FusionWorld *world; FusionSHMPoolAttach pool_attach = { .pool_id = 0 }; char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32]; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( shm->shared, FusionSHMShared ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); #if !DIRECT_BUILD_DEBUGS if (shared->debug) { D_ERROR( "Fusion/SHM: Can't join debug enabled pool with pure-release library!\n" ); return DR_UNSUPPORTED; } #endif world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); /* Set pool to attach to. */ pool_attach.pool_id = shared->pool_id; /* Attach to the pool. */ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) { if (errno == EINTR) continue; D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" ); return DR_FUSION; } /* Generate filename. */ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs, fusion_world_index( shm->world ), shared->pool_id ); /* Join the heap. */ ret = __shmalloc_join_heap( shm, buf, pool_attach.addr_base, shared->max_size, &fd ); if (ret) { while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" ); break; } } return ret; } /* Initialize local data. */ pool->attached = true; pool->shm = shm; pool->shared = shared; pool->pool_id = shared->pool_id; pool->fd = fd; pool->filename = D_STRDUP( buf ); D_MAGIC_SET( pool, FusionSHMPool ); return DR_OK; } static void leave_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ) { FusionWorld *world; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPool ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" ); break; } } if (munmap( shared->addr_base, shared->max_size )) D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename ); if (pool->fd != -1 && close( pool->fd )) D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename ); pool->attached = false; D_FREE( pool->filename ); D_MAGIC_CLEAR( pool ); } static void shutdown_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ) { FusionWorld *world; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPool ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); SHFREE( shared, shared->name ); fusion_dbg_print_memleaks( shared ); while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" ); break; } } if (munmap( shared->addr_base, shared->max_size )) D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename ); if (pool->fd != -1 && close( pool->fd )) D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename ); if (unlink( pool->filename )) D_PERROR( "Fusion/SHM: Could not unlink shared memory file '%s'!\n", pool->filename ); shared->active = false; pool->attached = false; D_FREE( pool->filename ); D_MAGIC_CLEAR( pool ); fusion_skirmish_destroy( &shared->lock ); D_MAGIC_CLEAR( shared ); } #else /* FUSION_BUILD_KERNEL */ static DirectResult init_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared, const char *name, unsigned int max_size, bool debug ) { DirectResult ret; int fd; int size; long page_size; int pool_id; unsigned int pool_max_size; void *pool_addr_base = NULL; FusionWorld *world; char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32]; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n", __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( shm->shared, FusionSHMShared ); D_ASSERT( name != NULL ); D_ASSERT( max_size > sizeof(shmalloc_heap) ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); D_ASSERT( pool != NULL ); D_ASSERT( shared != NULL ); page_size = direct_pagesize(); pool_id = ++world->shared->pool_ids; pool_max_size = max_size + BLOCKALIGN(sizeof(shmalloc_heap)) + BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) ); pool_addr_base = world->shared->pool_base; world->shared->pool_base += ((pool_max_size + page_size - 1) & ~(page_size - 1)) + page_size; /* Exceeded limit? */ if (world->shared->pool_base > world->shared->pool_max) return DR_NOSHAREDMEMORY; /* Generate filename. */ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs, fusion_world_index( world ), pool_id ); /* Initialize the heap. */ ret = __shmalloc_init_heap( shm, buf, pool_addr_base, max_size, &fd, &size ); if (ret) return ret; /* Initialize local data. */ pool->attached = true; pool->shm = shm; pool->shared = shared; pool->pool_id = pool_id; pool->fd = fd; pool->filename = D_STRDUP( buf ); /* Initialize shared data. */ shared->active = true; shared->debug = debug; shared->shm = shm->shared; shared->max_size = pool_max_size; shared->pool_id = pool_id; shared->addr_base = pool_addr_base; shared->heap = pool_addr_base; shared->heap->pool = shared; fusion_skirmish_init( &shared->lock, name, world ); D_MAGIC_SET( pool, FusionSHMPool ); D_MAGIC_SET( shared, FusionSHMPoolShared ); shared->name = SHSTRDUP( shared, name ); return DR_OK; } static DirectResult join_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ) { DirectResult ret; int fd; FusionWorld *world; char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32]; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( shm->shared, FusionSHMShared ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); #if !DIRECT_BUILD_DEBUGS if (shared->debug) { D_ERROR( "Fusion/SHM: Can't join debug enabled pool with pure-release library!\n" ); return DR_UNSUPPORTED; } #endif world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); /* Generate filename. */ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs, fusion_world_index( shm->world ), shared->pool_id ); /* Join the heap. */ ret = __shmalloc_join_heap( shm, buf, shared->addr_base, shared->max_size, &fd ); if (ret) return ret; /* Initialize local data. */ pool->attached = true; pool->shm = shm; pool->shared = shared; pool->pool_id = shared->pool_id; pool->fd = fd; pool->filename = D_STRDUP( buf ); D_MAGIC_SET( pool, FusionSHMPool ); return DR_OK; } static void leave_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ) { FusionWorld *world; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPool ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); if (munmap( shared->addr_base, shared->max_size )) D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename ); if (pool->fd != -1 && close( pool->fd )) D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename ); pool->attached = false; D_FREE( pool->filename ); D_MAGIC_CLEAR( pool ); } static void shutdown_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ) { FusionWorld *world; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPool ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); SHFREE( shared, shared->name ); fusion_dbg_print_memleaks( shared ); if (munmap( shared->addr_base, shared->max_size )) D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename ); if (pool->fd != -1 && close( pool->fd )) D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename ); if (unlink( pool->filename )) D_PERROR( "Fusion/SHM: Could not unlink shared memory file '%s'!\n", pool->filename ); shared->active = false; pool->attached = false; D_FREE( pool->filename ); D_MAGIC_CLEAR( pool ); fusion_skirmish_destroy( &shared->lock ); D_MAGIC_CLEAR( shared ); } #endif /* FUSION_BUILD_KERNEL */ /**********************************************************************************************************************/ #if FUSION_BUILD_KERNEL void _fusion_shmpool_process( FusionWorld *world, int pool_id, FusionSHMPoolMessage *msg ) { int i; DirectResult ret; FusionSHM *shm; FusionSHMShared *shared; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %d, %p )\n", __FUNCTION__, world, pool_id, msg ); D_MAGIC_ASSERT( world, FusionWorld ); shm = &world->shm; D_MAGIC_ASSERT( shm, FusionSHM ); shared = shm->shared; D_MAGIC_ASSERT( shared, FusionSHMShared ); ret = fusion_skirmish_prevail( &shared->lock ); if (ret) return; for (i=0; ipools[i].attached) { D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool ); if (shm->pools[i].pool_id == pool_id) { switch (msg->type) { case FSMT_REMAP: break; case FSMT_UNMAP: D_UNIMPLEMENTED(); break; } break; } } } fusion_skirmish_dismiss( &shared->lock ); } #endif /* FUSION_BUILD_KERNEL */