From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/FusionDale/src/core/dale_core.c | 578 +++++++++++++++++++++++++++++++++ 1 file changed, 578 insertions(+) create mode 100755 Source/FusionDale/src/core/dale_core.c (limited to 'Source/FusionDale/src/core/dale_core.c') diff --git a/Source/FusionDale/src/core/dale_core.c b/Source/FusionDale/src/core/dale_core.c new file mode 100755 index 0000000..792faac --- /dev/null +++ b/Source/FusionDale/src/core/dale_core.c @@ -0,0 +1,578 @@ +/* + (c) Copyright 2006-2007 directfb.org + + All rights reserved. + + Written by Denis Oliver Kropp . + + 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 +#include +#include +#include + +#include +#include +#include + +#include + + +#define FUSIONDALE_CORE_ABI 1 + +D_DEBUG_DOMAIN( Dale_Core, "FusionDale/Core", "FusionDale Core" ); + +/**********************************************************************************************************************/ + +struct __FD_CoreDaleShared { + int magic; + + FusionObjectPool *messenger_pool; + FusionObjectPool *messenger_port_pool; + + FusionSHMPoolShared *shmpool; +}; + +struct __FD_CoreDale { + int magic; + + int refs; + + int fusion_id; + + FusionWorld *world; + FusionArena *arena; + + CoreDaleShared *shared; + + bool master; + + DirectSignalHandler *signal_handler; +}; + +/**********************************************************************************************************************/ + +static DirectSignalHandlerResult fd_core_signal_handler( int num, + void *addr, + void *ctx ); + +/**********************************************************************************************************************/ + +static int fd_core_arena_initialize( FusionArena *arena, + void *ctx ); +static int fd_core_arena_join ( FusionArena *arena, + void *ctx ); +static int fd_core_arena_leave ( FusionArena *arena, + void *ctx, + bool emergency); +static int fd_core_arena_shutdown ( FusionArena *arena, + void *ctx, + bool emergency); + +/**********************************************************************************************************************/ + +static CoreDale *core_dale = NULL; +static pthread_mutex_t core_dale_lock = PTHREAD_MUTEX_INITIALIZER; + +DirectResult +fd_core_create( CoreDale **ret_core ) +{ + int ret; + CoreDale *core = NULL; + + D_ASSERT( ret_core != NULL ); + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + /* Lock the core singleton mutex. */ + pthread_mutex_lock( &core_dale_lock ); + + /* Core already created? */ + if (core_dale) { + /* Increase its references. */ + core_dale->refs++; + + /* Return the core. */ + *ret_core = core_dale; + + /* Unlock the core singleton mutex. */ + pthread_mutex_unlock( &core_dale_lock ); + + return DR_OK; + } + + /* Allocate local core structure. */ + core = D_CALLOC( 1, sizeof(CoreDale) ); + if (!core) { + ret = D_OOM(); + goto error; + } + + ret = fusion_enter( fusiondale_config->session, FUSIONDALE_CORE_ABI, + fusiondale_config->force_slave ? FER_SLAVE : FER_ANY, &core->world ); + if (ret) + goto error; + + core->fusion_id = fusion_id( core->world ); + + fusiondale_config->session = fusion_world_index( core->world ); + +#if FUSION_BUILD_MULTI + D_DEBUG_AT( Dale_Core, " -> world %d, fusion id %d\n", fusiondale_config->session, core->fusion_id ); +#endif + + /* Initialize the references. */ + core->refs = 1; + + direct_signal_handler_add( -1, fd_core_signal_handler, core, &core->signal_handler ); + + D_MAGIC_SET( core, CoreDale ); + + /* Enter the FusionDale core arena. */ + if (fusion_arena_enter( core->world, "FusionDale/Core", + fd_core_arena_initialize, fd_core_arena_join, + core, &core->arena, &ret ) || ret) + { + D_MAGIC_CLEAR( core ); + ret = ret ? : DR_FUSION; + goto error; + } + + /* Return the core and store the singleton. */ + *ret_core = core_dale = core; + + /* Unlock the core singleton mutex. */ + pthread_mutex_unlock( &core_dale_lock ); + + return DR_OK; + + +error: + if (core) { + if (core->world) { + direct_signal_handler_remove( core->signal_handler ); + fusion_exit( core->world, false ); + } + + D_FREE( core ); + } + + pthread_mutex_unlock( &core_dale_lock ); + + return ret; +} + +DirectResult +fd_core_destroy( CoreDale *core, bool emergency ) +{ + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core == core_dale ); + + D_DEBUG_AT( Dale_Core, "%s( %p, %semergency )\n", __FUNCTION__, core, emergency ? "" : "no " ); + + /* Lock the core singleton mutex. */ + if (!emergency) + pthread_mutex_lock( &core_dale_lock ); + + /* Decrement and check references. */ + if (!emergency && --core->refs) { + /* Unlock the core singleton mutex. */ + pthread_mutex_unlock( &core_dale_lock ); + + return DR_OK; + } + + direct_signal_handler_remove( core->signal_handler ); + + /* Exit the FusionDale core arena. */ + if (fusion_arena_exit( core->arena, fd_core_arena_shutdown, + core->master ? NULL : fd_core_arena_leave, + core, emergency, NULL ) == DR_BUSY) + { + if (core->master) { + if (emergency) { + fusion_kill( core->world, 0, SIGKILL, 1000 ); + } + else { + fusion_kill( core->world, 0, SIGTERM, 5000 ); + fusion_kill( core->world, 0, SIGKILL, 2000 ); + } + } + + while (fusion_arena_exit( core->arena, fd_core_arena_shutdown, + core->master ? NULL : fd_core_arena_leave, + core, emergency, NULL ) == DR_BUSY) + { + D_ONCE( "waiting for FusionDale slaves to terminate" ); + usleep( 100000 ); + } + } + + fusion_exit( core->world, emergency ); + + D_MAGIC_CLEAR( core ); + + /* Deallocate local core structure. */ + D_FREE( core ); + + /* Clear the singleton. */ + core_dale = NULL; + + /* Unlock the core singleton mutex. */ + if (!emergency) + pthread_mutex_unlock( &core_dale_lock ); + + return DR_OK; +} + +/**********************************************************************************************************************/ + +CoreMessenger * +fd_core_create_messenger( CoreDale *core ) +{ + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + D_ASSERT( core->shared->messenger_pool != NULL ); + + /* Create a new object in the messenger pool. */ + return (CoreMessenger*) fusion_object_create( core->shared->messenger_pool, core->world ); +} + +CoreMessengerPort * +fd_core_create_messenger_port( CoreDale *core ) +{ + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + D_ASSERT( core->shared->messenger_port_pool != NULL ); + + /* Create a new object in the messenger port pool. */ + return (CoreMessengerPort*) fusion_object_create( core->shared->messenger_port_pool, core->world ); +} + +/**********************************************************************************************************************/ + +DirectResult +fd_core_enum_messengers( CoreDale *core, + FusionObjectCallback callback, + void *ctx ) +{ + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + D_ASSERT( core->shared->messenger_pool != NULL ); + + /* Enumerate objects in the messenger pool. */ + return fusion_object_pool_enum( core->shared->messenger_pool, callback, ctx ); +} + +DirectResult +fd_core_enum_messenger_ports( CoreDale *core, + FusionObjectCallback callback, + void *ctx ) +{ + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + D_ASSERT( core->shared->messenger_port_pool != NULL ); + + /* Enumerate objects in the messenger port pool. */ + return fusion_object_pool_enum( core->shared->messenger_port_pool, callback, ctx ); +} + +DirectResult +fd_core_get_messenger( CoreDale *core, + FusionObjectID object_id, + CoreMessenger **ret_messenger ) +{ + DirectResult ret; + FusionObject *object; + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + D_ASSERT( core->shared->messenger_port_pool != NULL ); + + D_ASSERT( ret_messenger != NULL ); + + /* Enumerate objects in the messenger port pool. */ + ret = fusion_object_get( core->shared->messenger_pool, object_id, &object ); + if (ret) + return ret; + + D_MAGIC_ASSERT( (CoreMessenger*) object, CoreMessenger ); + + *ret_messenger = (CoreMessenger*) object; + + return DR_OK; +} + +/**********************************************************************************************************************/ + +FusionWorld * +fd_core_world( CoreDale *core ) +{ + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->world != NULL ); + + return core->world; +} + +FusionSHMPoolShared * +fd_core_shmpool( CoreDale *core ) +{ + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + D_ASSERT( core->shared->shmpool != NULL ); + + return core->shared->shmpool; +} + +/**********************************************************************************************************************/ + +static DirectSignalHandlerResult +fd_core_signal_handler( int num, void *addr, void *ctx ) +{ + CoreDale *core = (CoreDale*) ctx; + + D_DEBUG_AT( Dale_Core, "%s( %d, %p, %p )\n", __FUNCTION__, num, addr, ctx ); + + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + D_ASSERT( core == core_dale ); + + fd_core_destroy( core, true ); + + return DR_OK; +} + +/**********************************************************************************************************************/ + +static DirectResult +fd_core_initialize( CoreDale *core ) +{ + CoreDaleShared *shared = core->shared; + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + + /* create a pool for messenger (port) objects */ + shared->messenger_pool = fd_messenger_pool_create( core->world ); + shared->messenger_port_pool = fd_messenger_port_pool_create( core->world ); + + return DR_OK; +} + +static DirectResult +fd_core_join( CoreDale *core ) +{ + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + + /* really nothing to be done here, yet ;) */ + + return DR_OK; +} + +static DirectResult +fd_core_leave( CoreDale *core ) +{ + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + + /* really nothing to be done here, yet ;) */ + + return DR_OK; +} + +static DirectResult +fd_core_shutdown( CoreDale *core ) +{ + CoreDaleShared *shared; + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + D_ASSERT( core->shared != NULL ); + + shared = core->shared; + + D_ASSERT( shared->messenger_pool != NULL ); + + /* destroy messenger port object pool */ + fusion_object_pool_destroy( shared->messenger_port_pool, core->world ); + + /* destroy messenger object pool */ + fusion_object_pool_destroy( shared->messenger_pool, core->world ); + + return DR_OK; +} + +/**********************************************************************************************************************/ + +static int +fd_core_arena_initialize( FusionArena *arena, + void *ctx ) +{ + DirectResult ret; + CoreDale *core = ctx; + CoreDaleShared *shared; + FusionSHMPoolShared *pool; + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + + /* Create the shared memory pool first! */ + ret = fusion_shm_pool_create( core->world, "FusionDale Main Pool", 0x1000000, + fusion_config->debugshm, &pool ); + if (ret) + return ret; + + /* Allocate shared structure in the new pool. */ + shared = SHCALLOC( pool, 1, sizeof(CoreDaleShared) ); + if (!shared) { + fusion_shm_pool_destroy( core->world, pool ); + return D_OOSHM(); + } + + core->shared = shared; + core->master = true; + + shared->shmpool = pool; + + /* Initialize. */ + ret = fd_core_initialize( core ); + if (ret) { + SHFREE( pool, shared ); + fusion_shm_pool_destroy( core->world, pool ); + return ret; + } + + /* Register shared data. */ + fusion_arena_add_shared_field( arena, "Core/Shared", shared ); + + return DR_OK; +} + +static int +fd_core_arena_shutdown( FusionArena *arena, + void *ctx, + bool emergency) +{ + DirectResult ret; + CoreDale *core = ctx; + CoreDaleShared *shared; + FusionSHMPoolShared *pool; + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + + shared = core->shared; + + pool = shared->shmpool; + + if (!core->master) { + D_DEBUG( "FusionDale/Core: Refusing shutdown in slave.\n" ); + return fd_core_leave( core ); + } + + /* Shutdown. */ + ret = fd_core_shutdown( core ); + if (ret) + return ret; + + SHFREE( pool, shared ); + + fusion_dbg_print_memleaks( pool ); + + fusion_shm_pool_destroy( core->world, pool ); + + return DR_OK; +} + +static int +fd_core_arena_join( FusionArena *arena, + void *ctx ) +{ + DirectResult ret; + CoreDale *core = ctx; + CoreDaleShared *shared; + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + + /* Get shared data. */ + if (fusion_arena_get_shared_field( arena, "Core/Shared", (void*)&shared )) + return DR_FUSION; + + core->shared = shared; + + /* Join. */ + ret = fd_core_join( core ); + if (ret) + return ret; + + return DR_OK; +} + +static int +fd_core_arena_leave( FusionArena *arena, + void *ctx, + bool emergency) +{ + DirectResult ret; + CoreDale *core = ctx; + + D_DEBUG_AT( Dale_Core, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( core, CoreDale ); + + /* Leave. */ + ret = fd_core_leave( core ); + if (ret) + return ret; + + return DR_OK; +} + -- cgit