static DFBResult
system_initialize( CoreDFB *core, void **ret_data )
{
     DFBResult            ret;
     AndroidData         *android;
     AndroidDataShared   *shared;
     FusionSHMPoolShared *pool;

     D_ASSERT( m_data == NULL );

     android = D_CALLOC( 1, sizeof(AndroidData) );
     if (!android)
          return D_OOM();

     android->core = core;

     pool = dfb_core_shmpool( core );

     shared = SHCALLOC( pool, 1, sizeof(AndroidDataShared) );
     if (!shared) {
          D_FREE( android );
          return D_OOSHM();
     }

     shared->shmpool = pool;

     android->shared = shared;

     m_data = android;

     ret = InitLocal( android );
     if (ret)
          return ret;

     *ret_data = m_data;

     dfb_surface_pool_initialize( core, &androidSurfacePoolFuncs, &shared->pool );

     android->screen   = dfb_screens_register( NULL, android, androidScreenFuncs );
     android->layer    = dfb_layers_register( android->screen, android, androidLayerFuncs );
     android->java_vm  = native_data.app->activity->vm;
     android->app_path = D_STRDUP( native_data.app->activity->internalDataPath) ;

     core_arena_add_shared_field( core, "android", shared );

     return DFB_OK;
}
Example #2
0
void
direct_thread_set_name( const char *name )
{
     char         *copy;
     DirectThread *thread;

     D_DEBUG_AT( Direct_Thread, "%s( '%s' )\n", __FUNCTION__, name );

     direct_once( &thread_init_once, init_once );


     thread = pthread_getspecific( thread_key );

     /* Support this function for non-direct threads. */
     if (!thread) {
          D_DEBUG_AT( Direct_Thread, "  -> attaching unknown thread %d\n", direct_gettid() );

          thread = D_CALLOC( 1, sizeof(DirectThread) );
          if (!thread) {
               D_OOM();
               return;
          }

          thread->handle.thread = pthread_self();
          thread->tid    = direct_gettid();

          D_MAGIC_SET( thread, DirectThread );

          pthread_setspecific( thread_key, thread );
     }
     else
          D_DEBUG_AT( Direct_Thread, "  -> was '%s' (%d)\n", thread->name, direct_gettid() );

     /* Duplicate string. */
     copy = D_STRDUP( name );
     if (!copy) {
          D_OOM();
          return;
     }

     /* Free old string. */
     if (thread->name)
          D_FREE( thread->name );

     /* Keep the copy. */
     thread->name = copy;
}
Example #3
0
static DirectResult
join_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared )
{
     DirectResult  ret;
     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 );
     if (ret)
          return ret;

     /* Initialize local data. */
     pool->attached = true;
     pool->shm      = shm;
     pool->shared   = shared;
     pool->pool_id  = shared->pool_id;
     pool->filename = D_STRDUP( buf );


     D_MAGIC_SET( pool, FusionSHMPool );

     return DR_OK;
}
Example #4
0
static void 
config_allocate( void )
{
     if (fusiondale_config)
          return;
          
     fusiondale_config = D_CALLOC( 1, sizeof(FusionDaleConfig) );
     
     fusiondale_config->session           = 5;  // FIXME!!!

     fusiondale_config->banner            = true;
     fusiondale_config->coma_shmpool_size = 16 * 1024 * 1024;

#if FUSIONDALE_USE_ONE
     fusiondale_config->remote.host       = D_STRDUP( "%" );
#endif
}
Example #5
0
DirectResult 
fs_config_set( const char *name, const char *value )
{
     if (!strcmp( name, "driver" )) {
          if (value) {
               if (fs_config->driver)
                    D_FREE( fs_config->driver );
               fs_config->driver = D_STRDUP( value );
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          } 
     }
     else if (!strcmp( name, "device" )) {
          if (value) {
               if (fs_config->device)
                    D_FREE( fs_config->device );
               fs_config->device = D_STRDUP( value );
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "channels" )) {
          if (value) {
               int channels;

               if (sscanf( value, "%d", &channels ) < 1) {
                    D_ERROR( "FusionSound/Config '%s': Could not parse value!\n", name );
                    return DR_INVARG;
               }
               else if (channels < 1 || channels > FS_MAX_CHANNELS) {
                    D_ERROR( "FusionSound/Config '%s': Unsupported value '%d'!\n", name, channels );
                    return DR_INVARG;
               }      

               fs_config->channelmode = fs_mode_for_channels( channels );
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "channelmode" )) {
          if (value) {
               FSChannelMode mode;

               mode = parse_modestring( value );
               if (mode == FSCM_UNKNOWN) {
                    D_ERROR( "FusionSound/Config '%s': Could not parse value!\n", name );
                    return DR_INVARG;
               }      

               fs_config->channelmode = mode;
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "sampleformat" )) {
          if (value) {
               FSSampleFormat format;

               format = parse_sampleformat( value );
               if (format == FSSF_UNKNOWN) {
                    D_ERROR( "FusionSound/Config '%s': Could not parse value!\n", name );
                    return DR_INVARG;
               }

               fs_config->sampleformat = format;
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No format specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "samplerate" )) {
          if (value) {
               int rate;

               if (sscanf( value, "%d", &rate ) < 1) {
                    D_ERROR( "FusionSound/Config 'samplerate': "
                             "Could not parse value!\n" );
                    return DR_INVARG;
               }
               else if (rate < 1) {
                    D_ERROR( "FusionSound/Config '%s': Unsupported value '%d'!\n", name, rate );
                    return DR_INVARG;
               }      

               fs_config->samplerate = rate;
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "buffertime" )) {
          if (value) {
               int time;

               if (sscanf( value, "%d", &time ) < 1) {
                    D_ERROR( "FusionSound/Config 'buffertime': "
                             "Could not parse value!\n" );
                    return DR_INVARG;
               }
               else if (time < 1 || time > 5000) {
                    D_ERROR( "FusionSound/Config '%s': Unsupported value '%d'!\n", name, time );
                    return DR_INVARG;
               }      

               fs_config->buffertime = time;
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "session" )) {
          if (value) {
               int session;

               if (sscanf( value, "%d", &session ) < 1) {
                    D_ERROR( "FusionSound/Config '%s': Could not parse value!\n", name );
                    return DR_INVARG;
               }

               fs_config->session = session;
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp (name, "remote" )) {
          if (value) {
               char host[128];
               int  session = 0;

               if (sscanf( value, "%127s:%d", host, &session ) < 1) {
                    D_ERROR( "FusionSound/Config '%s': "
                             "Could not parse value (format is <host>[:<session>])!\n", name );
                    return DR_INVARG;
               }

               if (fs_config->remote.host)
                    D_FREE( fs_config->remote.host );

               fs_config->remote.host    = D_STRDUP( host );
               fs_config->remote.session = session;
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "remote-compression" )) {
          if (value) {
               if (!strcasecmp( value, "none" )) {
                    fs_config->remote_compression = FSRM_NONE;
               }
               else if (!strcasecmp( value, "dpack" )) {
                    fs_config->remote_compression = FSRM_DPACK;
               }
               else {
                    D_ERROR( "FusionSound/Config '%s': Unsupported value '%s'!\n", name, value );
                    return DR_INVARG;
               }
          }
          else {
               D_ERROR( "FusionSound/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } 
     else if (!strcmp( name, "banner" )) {
          fs_config->banner = true;
     }
     else if (!strcmp( name, "no-banner" )) {
          fs_config->banner = false;
     }
     else if (!strcmp( name, "wait" )) {
          fs_config->wait = true;
     }
     else if (!strcmp( name, "no-wait" )) {
          fs_config->wait = false;
     }
     else if (!strcmp( name, "deinit-check" )) {
          fs_config->deinit_check = true;
     }
     else if (!strcmp( name, "no-deinit-check" )) {
          fs_config->deinit_check = false;
     }
     else if (!strcmp( name, "dither" )) {
          fs_config->dither = true;
     }
     else if (!strcmp( name, "no-dither" )) {
          fs_config->dither = false;
     }
     else if (!strcmp( name, "dma" )) {
          fs_config->dma = true;
     }
     else if (!strcmp( name, "no-dma" )) {
          fs_config->dma = false;
     }
     else if (fusion_config_set( name, value ) && direct_config_set( name, value ))
          return DR_UNSUPPORTED;

     return DR_OK;
}
Example #6
0
static DirectResult
init_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared,
           const char          *name,
           unsigned int         max_size,
           bool                 debug )
{
     DirectResult   ret;
     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, &size );
     if (ret)
          return ret;

     /* initialize local data. */
     pool->attached = true;
     pool->shm      = shm;
     pool->shared   = shared;
     pool->pool_id  = pool_id;
     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;
}
Example #7
0
static DirectResult
init_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared,
           const char          *name,
           unsigned int         max_size,
           bool                 debug )
{
     DirectResult         ret;
     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 );

     fusion_entry_add_permissions( world, FT_SHMPOOL, pool_new.pool_id, 0,
                                   FUSION_SHMPOOL_ATTACH,
                                   FUSION_SHMPOOL_DETACH,
                                   0 );

     /* 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, &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->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_init2( &shared->lock, name, world, fusion_config->secure_fusion );


     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;
     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,
                                 !fusion_config->secure_fusion );
     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->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 );

     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 (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 );
}
Example #8
0
DirectThread *
direct_thread_create( DirectThreadType      thread_type,
                      DirectThreadMainFunc  thread_main,
                      void                 *arg,
                      const char           *name )
{
     DirectThread       *thread;
     pthread_attr_t      attr;
     struct sched_param  param;
     int                 policy;
     int                 priority;
     size_t              stack_size;

     D_ASSERT( thread_main != NULL );
     D_ASSERT( name != NULL );

     D_DEBUG_AT( Direct_Thread, "%s( %s, %p(%p), '%s' )\n", __FUNCTION__,
                 direct_thread_type_name(thread_type), thread_main, arg, name );

     /* Create the key for the TSD (thread specific data). */
     pthread_mutex_lock( &key_lock );

     if (thread_key == -1)
          pthread_key_create( &thread_key, NULL );

     pthread_mutex_unlock( &key_lock );

     /* Allocate thread structure. */
     thread = D_CALLOC( 1, sizeof(DirectThread) );
     if (!thread) {
          D_OOM();
          return NULL;
     }

     /* Write thread information to structure. */
     thread->name = D_STRDUP( name );
     thread->type = thread_type;
     thread->main = thread_main;
     thread->arg  = arg;

     /* Initialize to -1 for synchronization. */
     thread->thread = (pthread_t) -1;
     thread->tid    = (pid_t) -1;

     /* Initialize mutex and condition. */
     direct_util_recursive_pthread_mutex_init( &thread->lock );
     pthread_cond_init( &thread->cond, NULL );

     D_MAGIC_SET( thread, DirectThread );

     /* Initialize scheduling and other parameters. */
     pthread_attr_init( &attr );

     pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );

     /* Select scheduler. */
     switch (direct_config->thread_scheduler) {
          case DCTS_FIFO:
               policy = SCHED_FIFO;
               break;

          case DCTS_RR:
               policy = SCHED_RR;
               break;

          default:
               policy = SCHED_OTHER;
               break;
     }

     if (pthread_attr_setschedpolicy( &attr, policy ))
          D_PERROR( "Direct/Thread: Could not set scheduling policy to %s!\n", direct_thread_policy_name(policy) );

     /* Read (back) value. */
     pthread_attr_getschedpolicy( &attr, &policy );

     /* Select priority. */
     switch (thread->type) {
          case DTT_CLEANUP:
          case DTT_INPUT:
          case DTT_OUTPUT:
          case DTT_MESSAGING:
          case DTT_CRITICAL:
               priority = thread->type * direct_config->thread_priority_scale / 100;
               break;

          default:
               priority = direct_config->thread_priority;
               break;
     }

     D_DEBUG_AT( Direct_ThreadInit, "  -> %s (%d) [%d;%d]\n", direct_thread_policy_name(policy), priority,
                 sched_get_priority_min( policy ), sched_get_priority_max( policy ) );

     if (priority < sched_get_priority_min( policy ))
          priority = sched_get_priority_min( policy );

     if (priority > sched_get_priority_max( policy ))
          priority = sched_get_priority_max( policy );

     param.sched_priority = priority;

     if (pthread_attr_setschedparam( &attr, &param ))
          D_PERROR( "Direct/Thread: Could not set scheduling priority to %d!\n", priority );

     /* Select stack size? */
     if (direct_config->thread_stack_size > 0) {
          if (pthread_attr_setstacksize( &attr, direct_config->thread_stack_size ))
               D_PERROR( "Direct/Thread: Could not set stack size to %d!\n", direct_config->thread_stack_size );
     }

     /* Read (back) value. */
     pthread_attr_getstacksize( &attr, &stack_size );

     /* Lock the thread mutex. */
     D_DEBUG_AT( Direct_ThreadInit, "  -> locking...\n" );
     pthread_mutex_lock( &thread->lock );

     /* Create and run the thread. */
     D_DEBUG_AT( Direct_ThreadInit, "  -> creating...\n" );
     pthread_create( &thread->thread, &attr, direct_thread_main, thread );

     pthread_attr_destroy( &attr );

     pthread_getschedparam( thread->thread, &policy, &param );

     D_INFO( "Direct/Thread: Started '%s' (%d) [%s %s/%s %d/%d] <%zu>...\n",
             name, thread->tid, direct_thread_type_name(thread_type),
             direct_thread_policy_name(policy), direct_thread_scheduler_name(direct_config->thread_scheduler),
             param.sched_priority, priority, stack_size );

#ifdef DIRECT_THREAD_WAIT_INIT
     /* Wait for completion of the thread's initialization. */
     while (!thread->init) {
          D_DEBUG_AT( Direct_ThreadInit, "  -> waiting...\n" );
          pthread_cond_wait( &thread->cond, &thread->lock );
     }

     D_DEBUG_AT( Direct_ThreadInit, "  -> ...thread is running.\n" );
#endif

     /* Unlock the thread mutex. */
     D_DEBUG_AT( Direct_ThreadInit, "  -> unlocking...\n" );
     pthread_mutex_unlock( &thread->lock );

     D_DEBUG_AT( Direct_ThreadInit, "  -> returning %p\n", thread );

     return thread;
}
Example #9
0
DirectResult
voodoo_client_create( const char     *host,
                      int             port,
                      VoodooClient  **ret_client )
{
     DirectResult    ret;
     VoodooPlayInfo  info;
     VoodooClient   *client;
     VoodooPlayer   *player;
     char            buf[100] = { 0 };
     const char     *hostname = host;
     bool            raw = true;

     D_ASSERT( ret_client != NULL );

     if (!host)
          host = "";

     if (!port)
          port = 2323;

     D_DEBUG_AT( Voodoo_Client, "%s( '%s', %d )\n", __FUNCTION__, host, port );

     if (port != 2323) {
          D_DEBUG_AT( Voodoo_Client, "  -> port != 2323, using PACKET mode right away\n" );

          raw = false;
     }

     direct_list_foreach (client, m_clients) {
          if (!strcmp( client->host, host ) && client->port == port) {
               D_INFO( "Voodoo/Client: Reconnecting to '%s', increasing ref count of existing connection!\n", host );

               client->refs++;

               *ret_client = client;

               return DR_OK;
          }
     }

     /*
      * Get the player singleton
      */
     ret = voodoo_player_create( NULL, &player );
     if (ret) {
          D_DERROR( ret, "Voodoo/Client: Could not create the player!\n" );
          return ret;
     }

     /*
      * If we got a hostname or address try to lookup the player info
      */
     // FIXME: resolve first, not late in voodoo_link_init_connect
     if (hostname && hostname[0]) {
          ret = voodoo_player_lookup_by_address( player, hostname, &info );
          if (ret == DR_OK) {
               if (info.flags & VPIF_PACKET)
                    raw = false;
          }
     }
     else {
          /*
           * Start discovery and use first host visible
           */
          ret = discover_host( player, NULL, &info, buf, sizeof(buf) );
          if (ret == DR_OK) {
               if (info.flags & VPIF_PACKET)
                    raw = false;

               hostname = buf;
          }
     }

     if (!hostname || !hostname[0]) {
          D_ERROR( "Voodoo/Client: Did not find any other player!\n" );
          return DR_ITEMNOTFOUND;
     }


     /* Allocate client structure. */
     client = D_CALLOC( 1, sizeof(VoodooClient) );
     if (!client)
          return D_OOM();


     raw = !voodoo_config->link_packet && (voodoo_config->link_raw || raw);

     /* Create a link to the other player. */
     ret = voodoo_link_init_connect( &client->vl, hostname, port, raw );
     if (ret) {
          D_DERROR( ret, "Voodoo/Client: Failed to initialize Voodoo Link!\n" );
          D_FREE( client );
          return ret;
     }

     D_INFO( "Voodoo/Client: Fetching player information...\n" );

     if (raw) {     // FIXME: send_discover_and_receive_info() only does RAW, but we don't need it for packet connection, yet
          VoodooPlayVersion version;
          VoodooPlayInfo    info;

          ret = send_discover_and_receive_info( &client->vl, &version, &info );
          if (ret) {
               D_DEBUG_AT( Voodoo_Client, "  -> Failed to receive player info via TCP!\n" );

               D_INFO( "Voodoo/Client: No player information from '%s', trying to discover via UDP!\n", host );

               /*
                * Fallback to UDP discovery
                */
               ret = discover_host( player, hostname, &info, buf, sizeof(buf) );
               if (ret == DR_OK) {
                    if (info.flags & VPIF_PACKET)
                         raw = false;
               }
          }
          else {
               D_INFO( "Voodoo/Client: Connected to '%s' (%-15s) %s "
                       "=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x= "
                       "(vendor: %s, model: %s)\n",
                       info.name, host,
                       (info.flags & VPIF_LEVEL2) ? "*" : " ",
                       info.uuid[0], info.uuid[1], info.uuid[2], info.uuid[3], info.uuid[4],
                       info.uuid[5], info.uuid[6], info.uuid[7], info.uuid[8], info.uuid[9],
                       info.uuid[10], info.uuid[11], info.uuid[12], info.uuid[13], info.uuid[14],
                       info.uuid[15],
                       info.vendor, info.model );

               if (raw && !voodoo_config->link_raw) {
                    /*
                     * Switch to packet mode?
                     */
                    if (info.flags & VPIF_PACKET)
                         raw = false;
               }
          }

          /*
           * Switch to packet mode?
           */
          if (!raw) {
               D_INFO( "Voodoo/Client: Switching to packet mode!\n" );

               client->vl.Close( &client->vl );

               /* Create another link to the other player. */
               ret = voodoo_link_init_connect( &client->vl, hostname, port, false );
               if (ret) {
                    D_DERROR( ret, "Voodoo/Client: Failed to initialize second Voodoo Link!\n" );
                    D_FREE( client );
                    return ret;
               }
          }
     }


     /* Create the manager. */
     ret = voodoo_manager_create( &client->vl, client, NULL, &client->manager );
     if (ret) {
          client->vl.Close( &client->vl );
          D_FREE( client );
          return ret;
     }

     client->refs = 1;
     client->host = D_STRDUP( host );
     client->port = port;

     direct_list_prepend( &m_clients, &client->link );

     /* Return the new client. */
     *ret_client = client;

     D_DEBUG_AT( Voodoo_Client, "  => client %p\n", client );

     return DR_OK;
}
Example #10
0
DirectResult 
fd_config_set( const char *name, const char *value )
{
     if (!strcmp( name, "session" )) {
          if (value) {
               int session;

               if (sscanf( value, "%d", &session ) < 1) {
                    D_ERROR( "FusionDale/Config 'session': "
                             "Could not parse value!\n");
                    return DR_INVARG;
               }

               fusiondale_config->session = session;

               if (fusiondale_config->remote.host) {
                    D_FREE( fusiondale_config->remote.host );
                    fusiondale_config->remote.host = NULL;
               }
          }
          else {
               D_ERROR( "FusionDale/Config 'session': "
                        "No value specified!\n" );
               return DR_INVARG;
          }
     }
     else if (strcmp (name, "remote" ) == 0) {
          if (value) {
               char host[128];
               int  session = 0;

               if (sscanf( value, "%127s:%d", host, &session ) < 1) {
                    D_ERROR("FusionDale/Config 'remote': "
                            "Could not parse value (format is <host>[:<session>])!\n");
                    return DR_INVARG;
               }

               if (fusiondale_config->remote.host)
                    D_FREE( fusiondale_config->remote.host );

               fusiondale_config->remote.host    = D_STRDUP( host );
               fusiondale_config->remote.session = session;
          }
          else {
               fusiondale_config->remote.host    = D_STRDUP( "" );
               fusiondale_config->remote.session = 0;
          }
     }
     else if (!strcmp( name, "coma-shmpool-size" )) {
          if (value) {
               int size_kb;

               if (sscanf( value, "%d", &size_kb ) < 1) {
                    D_ERROR( "FusionDale/Config '%s': Could not parse value!\n", name);
                    return DR_INVARG;
               }

               fusiondale_config->coma_shmpool_size = size_kb * 1024;
          }
          else {
               D_ERROR( "FusionDale/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else if (!strcmp( name, "banner" )) {
          fusiondale_config->banner = true;
     }
     else if (!strcmp( name, "no-banner" )) {
          fusiondale_config->banner = false;
     }
     else if (strcmp ( name, "force-slave" ) == 0) {
          fusiondale_config->force_slave = true;
     }
     else if (strcmp ( name, "no-force-slave" ) == 0) {
          fusiondale_config->force_slave = false;
     }
#if !DIRECTFB_BUILD_PURE_VOODOO
     else if (strcmp ( name, "coma-allow" ) == 0) {
          if (value) {
               coma_policy_config( value, true );
          }
          else {
               fusiondale_config->coma_policy = true;
          }
     }
     else if (strcmp ( name, "coma-deny" ) == 0) {
          if (value) {
               coma_policy_config( value, false );
          }
          else {
               fusiondale_config->coma_policy = false;
          }
     } else
#endif
     if (fusion_config_set( name, value ) && direct_config_set( name, value ))
          return DR_UNSUPPORTED;

     return DR_OK;
}
Example #11
0
DirectResult
fusion_config_set( const char *name, const char *value )
{
     if (strcmp (name, "tmpfs" ) == 0) {
          if (value) {
               if (fusion_config->tmpfs)
                    D_FREE( fusion_config->tmpfs );
               fusion_config->tmpfs = D_STRDUP( value );
          }
          else {
               D_ERROR("Fusion/Config 'tmpfs': No directory specified!\n");
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "shmfile-group" ) == 0) {
          if (value) {
               struct group *group_info;
               
               group_info = getgrnam( value );
               if (group_info)
                    fusion_config->shmfile_gid = group_info->gr_gid;
               else
                    D_PERROR("Fusion/Config 'shmfile-group': Group '%s' not found!\n", value);
          }
          else {
               D_ERROR("Fusion/Config 'shmfile-group': No file group name specified!\n");
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "force-slave" ) == 0) {
          fusion_config->force_slave = true;
     } else
     if (strcmp (name, "no-force-slave" ) == 0) {
          fusion_config->force_slave = false;
     } else
     if (strcmp (name, "debugshm" ) == 0) {
          fusion_config->debugshm = true;
     } else
     if (strcmp (name, "no-debugshm" ) == 0) {
          fusion_config->debugshm = false;
     } else
     if (strcmp (name, "madv-remove" ) == 0) {
          fusion_config->madv_remove       = true;
          fusion_config->madv_remove_force = true;
     } else
     if (strcmp (name, "no-madv-remove" ) == 0) {
          fusion_config->madv_remove       = false;
          fusion_config->madv_remove_force = true;
     } else
     if (strcmp (name, "secure-fusion" ) == 0) {
          fusion_config->secure_fusion = true;
     } else
     if (strcmp (name, "no-secure-fusion" ) == 0) {
          fusion_config->secure_fusion = false;
     } else
     if (strcmp (name, "trace-ref" ) == 0) {
          if (value) {
               if (sscanf( value, "%x", &fusion_config->trace_ref ) != 1) {
                    D_ERROR( "Fusion/Config '%s': Invalid value!\n", name );
                    return DR_INVARG;
               }
          }
          else {
               D_ERROR( "Fusion/Config '%s': No ID specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (direct_config_set( name, value ))
          return DR_UNSUPPORTED;

     return DR_OK;
}
Example #12
0
DirectResult
voodoo_config_set( const char *name, const char *value )
{
     if (strcmp (name, "player-name" ) == 0) {
          if (value) {
               direct_snputs( voodoo_config->play_info.name, value, VOODOO_PLAYER_NAME_LENGTH );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "player-vendor" ) == 0) {
          if (value) {
               direct_snputs( voodoo_config->play_info.vendor, value, VOODOO_PLAYER_VENDOR_LENGTH );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "player-model" ) == 0) {
          if (value) {
               direct_snputs( voodoo_config->play_info.model, value, VOODOO_PLAYER_MODEL_LENGTH );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "player-uuid" ) == 0) {
          if (value) {
               sscanf( value, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                       (unsigned int*)&voodoo_config->play_info.uuid[0], (unsigned int*)&voodoo_config->play_info.uuid[1], (unsigned int*)&voodoo_config->play_info.uuid[2], (unsigned int*)&voodoo_config->play_info.uuid[3], (unsigned int*)&voodoo_config->play_info.uuid[4],
                       (unsigned int*)&voodoo_config->play_info.uuid[5], (unsigned int*)&voodoo_config->play_info.uuid[6], (unsigned int*)&voodoo_config->play_info.uuid[7], (unsigned int*)&voodoo_config->play_info.uuid[8], (unsigned int*)&voodoo_config->play_info.uuid[9],
                       (unsigned int*)&voodoo_config->play_info.uuid[10], (unsigned int*)&voodoo_config->play_info.uuid[11], (unsigned int*)&voodoo_config->play_info.uuid[12], (unsigned int*)&voodoo_config->play_info.uuid[13], (unsigned int*)&voodoo_config->play_info.uuid[14],
                       (unsigned int*)&voodoo_config->play_info.uuid[15] );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-memory-max" ) == 0) {
          if (value) {
               unsigned int max;

               if (direct_sscanf( value, "%u", &max ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->memory_max = max * 1024;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-surface-max" ) == 0) {
          if (value) {
               unsigned int max;

               if (direct_sscanf( value, "%u", &max ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->surface_max = max * 1024;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-layer-mask" ) == 0) {
          if (value) {
               unsigned int mask;

               if (direct_sscanf( value, "%u", &mask ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->layer_mask = mask;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-stacking-mask" ) == 0) {
          if (value) {
               unsigned int mask;

               if (direct_sscanf( value, "%u", &mask ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->stacking_mask = mask;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-resource-id" ) == 0) {
          if (value) {
               unsigned int resource_id;

               if (direct_sscanf( value, "%u", &resource_id ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->resource_id = resource_id;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "server-fork" ) == 0) {
          voodoo_config->server_fork = true;
     } else
     if (strcmp (name, "no-server-fork" ) == 0) {
          voodoo_config->server_fork = false;
     } else
     if (strcmp (name, "server-single" ) == 0) {
          if (value) {
               if (voodoo_config->server_single)
                    D_FREE( voodoo_config->server_single );

               voodoo_config->server_single = D_STRDUP( value );
               if (!voodoo_config->server_single)
                    D_OOM();
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "play-broadcast" ) == 0) {
          if (value) {
               if (voodoo_config->play_broadcast)
                    D_FREE( voodoo_config->play_broadcast );

               voodoo_config->play_broadcast = D_STRDUP( value );
               if (!voodoo_config->play_broadcast)
                    D_OOM();
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "compression-min" ) == 0) {
          if (value) {
               unsigned int min;

               if (direct_sscanf( value, "%u", &min ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->compression_min = min;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "link-raw" ) == 0) {
          voodoo_config->link_raw = true;
     } else
     if (strcmp (name, "no-link-raw" ) == 0) {
          voodoo_config->link_raw = false;
     } else
     if (strcmp (name, "link-packet" ) == 0) {
          voodoo_config->link_packet = true;
     } else
     if (strcmp (name, "no-link-packet" ) == 0) {
          voodoo_config->link_packet = false;
     } else
          return DR_UNSUPPORTED;

     return DR_OK;
}
Example #13
0
File: conf.c Project: kuii/dfbNEON
DirectResult
direct_config_set( const char *name, const char *value )
{
     if (direct_strcmp (name, "disable-module" ) == 0) {
          if (value) {
               int n = 0;

               while (direct_config->disable_module &&
                      direct_config->disable_module[n])
                    n++;

               direct_config->disable_module = (char**) D_REALLOC( direct_config->disable_module,
                                                                   sizeof(char*) * (n + 2) );

               direct_config->disable_module[n] = D_STRDUP( value );
               direct_config->disable_module[n+1] = NULL;
          }
          else {
               D_ERROR("Direct/Config '%s': No module name specified!\n", name);
               return DR_INVARG;
          }
     } else
     if (direct_strcmp (name, "module-dir" ) == 0) {
          if (value) {
               if (direct_config->module_dir)
                    D_FREE( direct_config->module_dir );
               direct_config->module_dir = D_STRDUP( value );
          }
          else {
               D_ERROR("Direct/Config 'module-dir': No directory name specified!\n");
               return DR_INVARG;
          }
     } else
     if (direct_strcmp (name, "memcpy" ) == 0) {
          if (value) {
               if (direct_config->memcpy)
                    D_FREE( direct_config->memcpy );
               direct_config->memcpy = D_STRDUP( value );
          }
          else {
               D_ERROR("Direct/Config '%s': No method specified!\n", name);
               return DR_INVARG;
          }
     }
     else
          if (direct_strcmp (name, "quiet" ) == 0 || strcmp (name, "no-quiet" ) == 0) {
          /* Enable/disable all at once by default. */
          DirectMessageType type = DMT_ALL;

          /* Find out the specific message type being configured. */
          if (value) {
               if (!strcmp( value, "info" ))           type = DMT_INFO;              else
               if (!strcmp( value, "warning" ))        type = DMT_WARNING;           else
               if (!strcmp( value, "error" ))          type = DMT_ERROR;             else
               if (!strcmp( value, "once" ))           type = DMT_ONCE;              else
               if (!strcmp( value, "untested" ))       type = DMT_UNTESTED;          else
               if (!strcmp( value, "unimplemented" ))  type = DMT_UNIMPLEMENTED; 
               else {
                    D_ERROR( "DirectFB/Config '%s': Unknown message type '%s'!\n", name, value );
                    return DR_INVARG;
               }
          }

          /* Set/clear the corresponding flag in the configuration. */
          if (name[0] == 'q')
               D_FLAGS_SET( direct_config->quiet, type );
          else
               D_FLAGS_CLEAR( direct_config->quiet, type );
     }
     else
          if (direct_strcmp (name, "no-quiet" ) == 0) {
          direct_config->quiet = DMT_NONE;
     }
     else
          if (direct_strcmp (name, "debug" ) == 0) {
          if (value) {
               DirectLogDomainConfig config = {0};

               if (value[0] && value[1] == ':') {
                    config.level = value[0] - '0' + DIRECT_LOG_DEBUG_0;

                    value += 2;
               }
               else
                    config.level = DIRECT_LOG_DEBUG;

               direct_log_domain_configure( value, &config );
          }
          else if (direct_config->log_level < DIRECT_LOG_DEBUG)
               direct_config->log_level = DIRECT_LOG_DEBUG;
     }
     else
          if (direct_strcmp (name, "no-debug" ) == 0) {
          if (value) {
               DirectLogDomainConfig config = {0};

               config.level = DIRECT_LOG_DEBUG_0;
                    
               direct_log_domain_configure( value, &config );
          }
          else if (direct_config->log_level > DIRECT_LOG_DEBUG_0)
               direct_config->log_level = DIRECT_LOG_DEBUG_0;
     }
     else
          if (direct_strcmp (name, "log-all" ) == 0) {
          direct_config->log_all = true;
     }
     else
          if (direct_strcmp (name, "log-none" ) == 0) {
          direct_config->log_none = true;
     }
     else
          if (direct_strcmp (name, "debugmem" ) == 0) {
          direct_config->debugmem = true;
     }
     else
          if (direct_strcmp (name, "no-debugmem" ) == 0) {
          direct_config->debugmem = false;
     }
     else
          if (direct_strcmp (name, "trace" ) == 0) {
          direct_config->trace = true;
     }
     else
          if (direct_strcmp (name, "no-trace" ) == 0) {
          direct_config->trace = false;
     }
     else
          if (direct_strcmp (name, "log-file" ) == 0 || strcmp (name, "log-udp" ) == 0) {
          if (value) {
               DirectResult  ret;
               DirectLog    *log;

               ret = direct_log_create( strcmp(name,"log-udp") ? DLT_FILE : DLT_UDP, value, &log );
               if (ret)
                    return ret;

               if (direct_config->log)
                    direct_log_destroy( direct_config->log );

               direct_config->log = log;

               direct_log_set_default( log );
          }
          else {
               if (direct_strcmp(name,"log-udp"))
                    D_ERROR("Direct/Config '%s': No file name specified!\n", name);
               else
                    D_ERROR("Direct/Config '%s': No host and port specified!\n", name);
               return DR_INVARG;
          }
     }
     else
          if (direct_strcmp (name, "fatal-level" ) == 0) {
          if (direct_strcasecmp (value, "none" ) == 0) {
               direct_config->fatal = DCFL_NONE;
          }
          else
               if (direct_strcasecmp (value, "assert" ) == 0) {
               direct_config->fatal = DCFL_ASSERT;
          }
          else
               if (direct_strcasecmp (value, "assume" ) == 0) {
               direct_config->fatal = DCFL_ASSUME;
          }
          else {
               D_ERROR("Direct/Config '%s': Unknown level specified (use 'none', 'assert', 'assume')!\n", name);
               return DR_INVARG;
          }
     }
     else
          if (direct_strcmp (name, "fatal-break" ) == 0) {
          direct_config->fatal_break = true;
     }
     else
          if (direct_strcmp (name, "no-fatal-break" ) == 0) {
          direct_config->fatal_break = false;
     }
     else
          if (direct_strcmp (name, "sighandler" ) == 0) {
          direct_config->sighandler = true;
     }
     else
          if (direct_strcmp (name, "no-sighandler" ) == 0) {
          direct_config->sighandler = false;
     }
     else
          if (direct_strcmp (name, "dont-catch" ) == 0) {
          if (value) {
               char *signals   = D_STRDUP( value );
               char *p = NULL, *r, *s = signals;

               while ((r = direct_strtok_r( s, ",", &p ))) {
                    char          *error;
                    unsigned long  signum;

                    direct_trim( &r );

                    signum = direct_strtoul( r, &error, 10 );

                    if (*error) {
                         D_ERROR( "Direct/Config '%s': Error in number at '%s'!\n", name, error );
                         D_FREE( signals );
                         return DR_INVARG;
                    }

                    sigaddset( &direct_config->dont_catch, signum );

                    s = NULL;
               }

               D_FREE( signals );
          }
          else {
               D_ERROR("Direct/Config '%s': No signals specified!\n", name);
               return DR_INVARG;
          }
     }
     else
          if (direct_strcmp (name, "thread_block_signals") == 0) {
          direct_config->thread_block_signals = true;
     }
     else
          if (direct_strcmp (name, "no-thread_block_signals") == 0) {
          direct_config->thread_block_signals = false;
     } else
     if (direct_strcmp (name, "thread-priority-scale" ) == 0) {
          if (value) {
               int scale;

               if (direct_sscanf( value, "%d", &scale ) < 1) {
                    D_ERROR("Direct/Config '%s': Could not parse value!\n", name);
                    return DR_INVARG;
               }

               direct_config->thread_priority_scale = scale;
          }
          else {
               D_ERROR("Direct/Config '%s': No value specified!\n", name);
               return DR_INVARG;
          }
     } else
     if (direct_strcmp (name, "thread-priority" ) == 0) {  /* Must be moved to lib/direct/conf.c in trunk! */
          if (value) {
               int priority;

               if (direct_sscanf( value, "%d", &priority ) < 1) {
                    D_ERROR("Direct/Config '%s': Could not parse value!\n", name);
                    return DR_INVARG;
               }

               direct_config->thread_priority = priority;
          }
          else {
               D_ERROR("Direct/Config '%s': No value specified!\n", name);
               return DR_INVARG;
          }
     } else
     if (direct_strcmp (name, "thread-scheduler" ) == 0) {  /* Must be moved to lib/direct/conf.c in trunk! */
          if (value) {
               if (direct_strcmp( value, "other" ) == 0) {
                    direct_config->thread_scheduler = DCTS_OTHER;
               } else
               if (direct_strcmp( value, "fifo" ) == 0) {
                    direct_config->thread_scheduler = DCTS_FIFO;
               } else
               if (direct_strcmp( value, "rr" ) == 0) {
                    direct_config->thread_scheduler = DCTS_RR;
               } else {
                    D_ERROR( "Direct/Config '%s': Unknown scheduler '%s'!\n", name, value );
                    return DR_INVARG;
               }
          }
          else {
               D_ERROR( "Direct/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (direct_strcmp (name, "thread-stacksize" ) == 0) {  /* Must be moved to lib/direct/conf.c in trunk! */
          if (value) {
               int size;

               if (direct_sscanf( value, "%d", &size ) < 1) {
                    D_ERROR( "Direct/Config '%s': Could not parse value!\n", name );
                    return DR_INVARG;
               }

               direct_config->thread_stack_size = size;
          }
          else {
               D_ERROR( "Direct/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     }
     else
          return DR_UNSUPPORTED;

     return DR_OK;
}