Beispiel #1
0
char *
direct_dbg_strdup( const char* file, int line, const char *func, const char *string )
{
     void          *mem;
     unsigned long *val;
     size_t         bytes = string ? direct_strlen( string ) + 1 : 1;

     D_DEBUG_AT( Direct_Mem, "  +"_ZUn(6)" bytes [%s:%d in %s()] <- \"%30s\"\n", bytes, file, line, func, string );

     if (direct_config->debugmem) {
          MemDesc *desc;

          mem = direct_malloc( bytes + sizeof(MemDesc) );

          D_DEBUG_AT( Direct_Mem, "  '-> %p\n", mem );

          if (!mem)
               return NULL;

          desc = fill_mem_desc( mem, bytes, func, file, line, direct_trace_copy_buffer(NULL) );

          direct_mutex_lock( &alloc_lock );

          direct_hash_insert( &alloc_hash, (unsigned long) desc->mem, desc );

          direct_mutex_unlock( &alloc_lock );

          if (string)
               direct_memcpy( desc->mem, string, bytes );
          else
               *(u8*)desc->mem = 0;

          return desc->mem;
     }


     mem = direct_malloc( bytes + DISABLED_OFFSET );

     D_DEBUG_AT( Direct_Mem, "  '-> %p\n", mem );

     if (!mem)
          return NULL;

     val    = mem;
     val[0] = ~0;

     if (string)
          direct_memcpy( (char*) mem + DISABLED_OFFSET, string, bytes );
     else
          *((u8*)mem + DISABLED_OFFSET) = 0;

     return (char*) mem + DISABLED_OFFSET;
}
Beispiel #2
0
static void
call_handlers( int   num,
               void *addr )
{
     DirectLink   *l, *n;

     if (num == SIG_DUMP_STACK)
          num = DIRECT_SIGNAL_DUMP_STACK;

     /* Loop through all handlers. */
     direct_mutex_lock( &handlers_lock );

     direct_list_foreach_safe (l, n, handlers) {
          DirectSignalHandler *handler = (DirectSignalHandler*) l;

          if (handler->removed) {
               direct_list_remove( &handlers, &handler->link );
               D_MAGIC_CLEAR( handler );
               D_FREE( handler );
               continue;
          }

          D_LOG( Direct_Signals, FATAL, "    --> %d\n", handler->num );

          if (handler->num != num && handler->num != DIRECT_SIGNAL_ANY)
               continue;

          if (handler->num == DIRECT_SIGNAL_ANY && num == DIRECT_SIGNAL_DUMP_STACK)
               continue;

          switch (handler->func( num, addr, handler->ctx )) {
               case DSHR_OK:
                    break;

               case DSHR_REMOVE:
                    direct_list_remove( &handlers, &handler->link );
                    D_MAGIC_CLEAR( handler );
                    D_FREE( handler );
                    break;

               case DSHR_RESUME:
                    D_LOG( Direct_Signals, FATAL, "    '-> cured!\n" );

                    direct_mutex_unlock( &handlers_lock );

                    return;

               default:
                    D_BUG( "unknown result" );
                    break;
          }
     }
Beispiel #3
0
void *
VoodooDispatcher::DispatchLoop()
{
     D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this );

     direct_mutex_lock( &lock );

     while (!manager->is_quit) {
          VoodooPacket *packet;

          D_MAGIC_ASSERT( this, VoodooDispatcher );

          if (packets) {
               packet = (VoodooPacket*) packets;

               direct_list_remove( &packets, &packet->link );

               manager->connection->WakeUp();
          }
          else {
               direct_waitqueue_wait( &queue, &lock );

               continue;
          }


          direct_mutex_unlock( &lock );

          ProcessMessages( (VoodooMessageHeader*) packet->data_start(), packet->size() );

          D_FREE( packet );

          direct_mutex_lock( &lock );
     }

     direct_mutex_unlock( &lock );

     return NULL;
}
Beispiel #4
0
void
direct_perf_dump_all()
{
     direct_mutex_lock( &counter_lock );

     if (direct_hash_count( &counter_hash )) {
          direct_log_printf( NULL, "Performance Counters                                               Total count    rate           start        end\n" );

          direct_hash_iterate( &counter_hash, perf_iterate, NULL );
     }

     direct_mutex_unlock( &counter_lock );
}
Beispiel #5
0
static void
TestDispatch( void                  *context,
              const OnePacketHeader *header,
              void                  *data,
              OneThread             *thread )
{
//     D_INFO( "TestDispatch called\n" );

    direct_mutex_lock( &lock );

    direct_waitqueue_signal( &queue );

    direct_mutex_unlock( &lock );
}
Beispiel #6
0
VoodooPacket *
VoodooConnectionLink::GetPacket( size_t length )
{
     D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p, length "_ZU" )\n", __func__, this, length );

     D_MAGIC_ASSERT( this, VoodooConnection );
     D_ASSERT( length >= (int) sizeof(VoodooMessageHeader) );
     D_ASSUME( length <= MAX_MSG_SIZE );

     if (length > MAX_MSG_SIZE) {
          D_WARN( _ZU" exceeds maximum message size of %d", length, MAX_MSG_SIZE );
          return NULL;
     }

     size_t aligned = VOODOO_MSG_ALIGN( length );


     Packets *packets = (Packets*) direct_tls_get( output.tls );

     if (!packets) {
          packets = new Packets( this );

          direct_tls_set( output.tls, packets );
     }

     VoodooPacket *packet = packets->active;

     if (packet) {
          if (packet->append( aligned ))
               return packet;

          Flush( packet );
     }

     packet = packets->Get();
     if (packet) {
          if (packet->sending) {
               direct_mutex_lock( &output.lock );

               while (packet->sending)
                    direct_waitqueue_wait( &output.wait, &output.lock );

               direct_mutex_unlock( &output.lock );
          }
          packet->reset( aligned );
     }

     return packet;
}
Beispiel #7
0
void
direct_processor_lock( DirectProcessor *processor )
{
     direct_mutex_lock( &processor->lock_mutex );

     processor->lock++;

     while (!processor->locked) {
          direct_fifo_wakeup( &processor->commands );

          direct_waitqueue_wait( &processor->lock_cond, &processor->lock_mutex );
     }

     direct_mutex_unlock( &processor->lock_mutex );
}
Beispiel #8
0
bool
VoodooDispatcher::Ready()
{
     D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this );

     D_MAGIC_ASSERT( this, VoodooDispatcher );

     direct_mutex_lock( &lock );

     bool ready = direct_list_count_elements_EXPENSIVE( packets ) < 3;

     direct_mutex_unlock( &lock );

     return ready;
}
Beispiel #9
0
void
VoodooDispatcher::PutPacket( VoodooPacket *packet )
{
     D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p, packet %p )\n", __func__, this, packet );

     D_MAGIC_ASSERT( this, VoodooDispatcher );

     direct_mutex_lock( &lock );

     direct_list_append( &packets, &packet->link );

     direct_waitqueue_broadcast( &queue );

     direct_mutex_unlock( &lock );
}
Beispiel #10
0
DirectResult
DirectResultTypeRegister( DirectResultType *type )
{
     DirectResult ret;

     D_DEBUG_AT( Direct_Result, "%s( %p )\n", __FUNCTION__, type );

     D_ASSERT( type != NULL );

     D_DEBUG_AT( Direct_Result, "  -> refs    %d\n", type->refs );
     D_DEBUG_AT( Direct_Result, "  -> base    0x%08x\n", type->base );
     D_DEBUG_AT( Direct_Result, "  -> strings %p\n", type->result_strings );
     D_DEBUG_AT( Direct_Result, "  -> count   %u\n", type->result_count );

     D_ASSERT( type->result_count > 0 );
     D_ASSERT( type->result_count <= D_RESULT_TYPE_SPACE );

     D_DEBUG_AT( Direct_Result, "  => %s\n", type->result_strings[0] );

     ret = direct_mutex_lock( &result_mutex );
     if (ret)
          return ret;

     if (direct_hash_lookup( &result_types, type->base )) {
          D_ASSERT( direct_hash_lookup( &result_types, type->base ) == type );

          D_MAGIC_ASSERT( type, DirectResultType );

          D_ASSERT( type->refs > 0 );

          type->refs++;
     }
     else {
          D_ASSERT( type->refs == 0 );

          D_MAGIC_SET( type, DirectResultType );

          ret = direct_hash_insert( &result_types, type->base, (void*) type );
          if (ret)
               D_MAGIC_CLEAR( type );
          else
               type->refs = 1;
     }

     direct_mutex_unlock( &result_mutex );

     return ret;
}
Beispiel #11
0
static ssize_t
Read( VoodooLink *link,
      void       *buffer,
      size_t      count )
{
     Link *l = link->priv;

     while (true) {
          ssize_t        ret;
          fd_set         rfds;
          struct timeval tv;
          int            retval;

          FD_ZERO( &rfds );
          FD_SET( l->socket, &rfds );

          tv.tv_sec  = 0;
          tv.tv_usec = 0;//10000;

          direct_mutex_lock( &l->lock );

          retval = select( l->socket+1, &rfds, NULL, NULL, &tv );
          switch (retval) {
               default:
                    ret = recv( l->socket, buffer, count, 0 );
                    direct_mutex_unlock( &l->lock );
                    return ret;

               case 0:
                    D_DEBUG( "Voodoo/Link: Timeout during select()\n" );
                    break;

               case -1:
                    //if (errno && errno != EINTR)
                    D_PERROR( "Voodoo/Player: select() on socket failed!\n" );
                    direct_mutex_unlock( &l->lock );
                    return -1;
          }

          direct_mutex_unlock( &l->lock );

          direct_thread_sleep( 20000 );
     }

     return -1;
}
Beispiel #12
0
void
DirectUnregisterInterface( DirectInterfaceFuncs *funcs )
{
    DirectInterfaceImplementation *impl;

    D_DEBUG_AT( Direct_Interface, "%s( %p )\n", __FUNCTION__, funcs );

    direct_mutex_lock( &implementations_mutex );

    direct_list_foreach (impl, implementations) {
        D_MAGIC_ASSERT( impl, DirectInterfaceImplementation );

        if (impl->funcs == funcs) {
            direct_list_remove( &implementations, &impl->link );

            break;
        }
    }
Beispiel #13
0
DirectResult
direct_signal_handler_remove( DirectSignalHandler *handler )
{
     D_MAGIC_ASSERT( handler, DirectSignalHandler );

     D_DEBUG_AT( Direct_Signals, "Removing handler %p for signal %d with context %p...\n",
                 handler->func, handler->num, handler->ctx );

     direct_mutex_lock( &handlers_lock );
     direct_list_remove( &handlers, &handler->link );
     direct_mutex_unlock( &handlers_lock );

     D_MAGIC_CLEAR( handler );

     D_FREE( handler );

     return DR_OK;
}
Beispiel #14
0
void
direct_dbg_free( const char *file, int line, const char *func, const char *what, void *mem )
{
     unsigned long *val;
     MemDesc       *desc;

     if (!mem) {
          D_WARN( "%s (NULL) called", __FUNCTION__ );
          return;
     }

     val = (unsigned long*)((char*) mem - DISABLED_OFFSET);

     if (val[0] == ~0) {
          D_DEBUG_AT( Direct_Mem, "  - number of bytes of %s [%s:%d in %s()] -> %p\n", what, file, line, func, mem );

          val[0] = 0;
          direct_free( val );

          return;
     }


     /* Debug only. */
     direct_mutex_lock( &alloc_lock );

     desc = (MemDesc*)((char*) mem - sizeof(MemDesc));
     D_ASSERT( desc->mem == mem );

     if (direct_hash_remove( &alloc_hash, (unsigned long) mem )) {
          D_ERROR( "Direct/Mem: Not freeing unknown %p (%s) from [%s:%d in %s()] - corrupt/incomplete list?\n",
                   mem, what, file, line, func );
     }
     else {
          D_DEBUG_AT( Direct_Mem, "  -"_ZUn(6)" bytes [%s:%d in %s()] -> %p '%s'\n", desc->bytes, file, line, func, mem, what );

          if (desc->trace)
               direct_trace_free_buffer( desc->trace );

          direct_free( desc );
     }

     direct_mutex_unlock( &alloc_lock );
}
Beispiel #15
0
void
direct_print_memleaks( void )
{
     unsigned long total = 0;

     /* Debug only. */
     direct_mutex_lock( &alloc_lock );

     if (alloc_hash.count) {
          direct_log_printf( NULL, "Local memory allocations remaining (%d): \n", alloc_hash.count );

          direct_hash_iterate( &alloc_hash, local_alloc_hash_iterator, &total );
     }

     direct_mutex_unlock( &alloc_lock );

     if (total)
          direct_log_printf( NULL, "%7lu bytes in total\n", total );
}
Beispiel #16
0
static ssize_t
Write( VoodooLink *link,
       const void *buffer,
       size_t      count )
{
     ssize_t  ret;
     Link    *l = link->priv;

     direct_mutex_lock( &l->lock );

     ret = send( l->socket, buffer, count, 0 );
     if (ret < 0) {
          D_PERROR( "send(): WSA error %d\n", WSAGetLastError() );
     }

     direct_mutex_unlock( &l->lock );

     return ret;
}
Beispiel #17
0
void
direct_perf_count( DirectPerfCounterInstallation *installation, int diff )
{
     DirectPerfCounter *counter;

     D_ASSERT( installation != NULL );

     direct_mutex_lock( &counter_lock );

     if (installation->counter_id == 0) {
          counter = D_CALLOC( 1, sizeof(DirectPerfCounter) );
          if (!counter) {
               direct_mutex_unlock( &counter_lock );
               D_OOM();
               return;
          }

          installation->counter_id = ++counter_ids;
          D_ASSERT( installation->counter_id != 0 );
          D_ASSERT( installation->counter_id != ~0 );   // FIXME: can there be more than 4 billion counters?

          direct_snputs( counter->name, installation->name, sizeof(counter->name) );

          counter->reset_on_dump = installation->reset_on_dump;

          direct_hash_insert( &counter_hash, installation->counter_id, counter );
     }
     else {
          counter = direct_hash_lookup( &counter_hash, installation->counter_id );
          if (!counter) {
               direct_mutex_unlock( &counter_lock );
               D_BUG( "unknown performance counter installation (%lu)", installation->counter_id );
               return;
          }
     }

     counter->count += diff;

     if (!counter->start)
          counter->start = direct_clock_get_time( DIRECT_CLOCK_SESSION );

     direct_mutex_unlock( &counter_lock );
}
Beispiel #18
0
void *
direct_dbg_calloc( const char* file, int line, const char *func, size_t count, size_t bytes )
{
     void          *mem;
     unsigned long *val;

     D_DEBUG_AT( Direct_Mem, "  +"_ZUn(6)" bytes [%s:%d in %s()]\n", count * bytes, file, line, func );

     if (direct_config->debugmem) {
          MemDesc *desc;

          mem = direct_calloc( 1, count * bytes + sizeof(MemDesc) );

          D_DEBUG_AT( Direct_Mem, "  '-> %p\n", mem );

          if (!mem)
               return NULL;

          desc = fill_mem_desc( mem, count * bytes, func, file, line, direct_trace_copy_buffer(NULL) );

          direct_mutex_lock( &alloc_lock );

          direct_hash_insert( &alloc_hash, (unsigned long) desc->mem, desc );

          direct_mutex_unlock( &alloc_lock );

          return desc->mem;
     }


     mem = direct_calloc( 1, count * bytes + DISABLED_OFFSET );

     D_DEBUG_AT( Direct_Mem, "  '-> %p\n", mem );

     if (!mem)
          return NULL;

     val    = mem;
     val[0] = ~0;

     return (char*) mem + DISABLED_OFFSET;
}
Beispiel #19
0
static void
CoreInputHub_Dispatch( void                  *context,
                       const OnePacketHeader *header,
                       void                  *data,
                       OneThread             *thread )
{
     InputHubAttachRequest *request = data;
     CoreInputHub          *hub     = context;

     D_DEBUG_AT( Core_InputHub, "%s()\n", __FUNCTION__ );

     direct_mutex_lock( &hub->lock );

     // FIXME: replace by own list of devices recorded in CoreInputHub_AddDevice/RemoveDevice calls
     dfb_input_enumerate_devices( CoreInputHub_EnumDevice_Callback, request, DICAPS_ALL );

     OneQueue_Attach( hub->notify_qid, request->listen_qid );

     direct_mutex_unlock( &hub->lock );
}
Beispiel #20
0
DirectResult
fusion_ref_up (FusionRef *ref, bool global)
{
     DirectResult ret = DR_OK;

     D_ASSERT( ref != NULL );

     direct_mutex_lock (&ref->single.lock);

     if (ref->single.destroyed)
          ret = DR_DESTROYED;
     else if (ref->single.locked)
          ret = DR_LOCKED;
     else
          ref->single.refs++;

     direct_mutex_unlock (&ref->single.lock);

     return ret;
}
Beispiel #21
0
DirectResult
fusion_ref_unlock (FusionRef *ref)
{
     DirectResult ret = DR_OK;

     D_ASSERT( ref != NULL );

     direct_mutex_lock (&ref->single.lock);

     if (ref->single.locked == direct_gettid()) {
          ref->single.locked = 0;

          direct_waitqueue_broadcast (&ref->single.cond);
     }
     else
          ret = DR_ACCESSDENIED;

     direct_mutex_unlock (&ref->single.lock);

     return ret;
}
Beispiel #22
0
void
VoodooConnectionLink::Flush( VoodooPacket *packet )
{
     D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p, packet %p )\n", __func__, this, packet );

     D_MAGIC_ASSERT( this, VoodooConnection );

     direct_mutex_lock( &output.lock );

     D_ASSERT( !direct_list_contains_element_EXPENSIVE( output.packets, &packet->link ) );

     D_ASSERT( !packet->sending );

     packet->sending = true;

     direct_list_append( &output.packets, &packet->link );

     direct_mutex_unlock( &output.lock );

     link->WakeUp( link );
}
Beispiel #23
0
VoodooConnectionLink::~VoodooConnectionLink()
{
     D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this );

     D_MAGIC_ASSERT( this, VoodooConnection );

     /* Acquire locks and wake up waiters. */
     direct_mutex_lock( &output.lock );
     direct_waitqueue_broadcast( &output.wait );
     direct_mutex_unlock( &output.lock );

     /* Destroy conditions. */
     direct_waitqueue_deinit( &output.wait );

     /* Destroy locks. */
     direct_mutex_deinit( &output.lock );

     /* Deallocate buffers. */
     D_FREE( input.buffer );

     direct_tls_unregister( &output.tls );
}
Beispiel #24
0
DirectResult
fusion_ref_zero_trylock (FusionRef *ref)
{
     DirectResult ret = DR_OK;

     D_ASSERT( ref != NULL );

     direct_mutex_lock (&ref->single.lock);

     if (ref->single.destroyed)
          ret = DR_DESTROYED;
     else if (ref->single.locked)
          ret = DR_LOCKED;
     else if (ref->single.refs)
          ret = DR_BUSY;
     else
          ref->single.locked = direct_gettid();

     direct_mutex_unlock (&ref->single.lock);

     return ret;
}
Beispiel #25
0
static void
CoreInputHubClient_Dispatch( void                  *context,
                             const OnePacketHeader *header,
                             void                  *data,
                             OneThread             *thread )
{
     CoreInputHubClient         *client       = context;
     const InputHubNotification *notification = data;

     D_DEBUG_AT( Core_InputHub, "%s()\n", __FUNCTION__ );

     switch (notification->type) {
          case IHNT_ATTACHED:
               direct_mutex_lock( &client->lock );

               client->activate_stop = true;

               direct_waitqueue_broadcast( &client->wq );

               direct_mutex_unlock( &client->lock );
               break;

          case IHNT_DEVICE_ADD:
               CoreInputHubClient_Dispatch_DeviceAdd( client, notification );
               break;

          case IHNT_DEVICE_REMOVE:
               CoreInputHubClient_Dispatch_DeviceRemove( client, notification );
               break;

          case IHNT_EVENT_DISPATCH:
               CoreInputHubClient_Dispatch_EventDispatch( client, notification );
               break;

          default:
               D_BUG( "unknown notification type %d", notification->type );
     }
}
Beispiel #26
0
DirectResult
fusion_ref_down (FusionRef *ref, bool global)
{
     D_ASSERT( ref != NULL );

     direct_mutex_lock (&ref->single.lock);

     if (!ref->single.refs) {
          D_BUG( "no more references" );
          direct_mutex_unlock (&ref->single.lock);
          return DR_BUG;
     }

     if (ref->single.destroyed) {
          direct_mutex_unlock (&ref->single.lock);
          return DR_DESTROYED;
     }

     if (! --ref->single.refs) {
          if (ref->single.call) {
               FusionCall *call = ref->single.call;

               if (call->handler) {
                    fusion_call_execute( call, FCEF_NODIRECT | FCEF_ONEWAY, ref->single.call_arg, NULL, NULL );

                    direct_mutex_unlock( &ref->single.lock );

                    return DR_OK;
               }
          }
          else
               direct_waitqueue_broadcast (&ref->single.cond);
     }

     direct_mutex_unlock (&ref->single.lock);

     return DR_OK;
}
Beispiel #27
0
DirectResult
DirectResultTypeUnregister( DirectResultType *type )
{
     DirectResult ret;

     D_DEBUG_AT( Direct_Result, "%s( %p )\n", __FUNCTION__, type );

     D_MAGIC_ASSERT( type, DirectResultType );

     D_DEBUG_AT( Direct_Result, "  -> refs    %d\n", type->refs );
     D_DEBUG_AT( Direct_Result, "  -> base    0x%08x\n", type->base );
     D_DEBUG_AT( Direct_Result, "  -> strings %p\n", type->result_strings );
     D_DEBUG_AT( Direct_Result, "  -> count   %u\n", type->result_count );

     D_ASSERT( type->result_count > 0 );
     D_ASSERT( type->result_count <= D_RESULT_TYPE_SPACE );

     D_DEBUG_AT( Direct_Result, "  => %s\n", type->result_strings[0] );


     ret = direct_mutex_lock( &result_mutex );
     if (ret)
          return ret;

     D_ASSERT( type->refs > 0 );

     D_ASSERT( direct_hash_lookup( &result_types, type->base ) == type );

     if (! --(type->refs)) {
          D_MAGIC_CLEAR( type );

          ret = direct_hash_remove( &result_types, type->base );
     }

     direct_mutex_unlock( &result_mutex );

     return ret;
}
Beispiel #28
0
void
DirectRegisterInterface( DirectInterfaceFuncs *funcs )
{
    DirectInterfaceImplementation *impl;

    D_DEBUG_AT( Direct_Interface, "%s( %p )\n", __FUNCTION__, funcs );

    impl = (DirectInterfaceImplementation*) D_CALLOC( 1, sizeof(DirectInterfaceImplementation) );

    D_DEBUG_AT( Direct_Interface, "  -> %p\n", impl );

    impl->funcs          = funcs;
    impl->type           = funcs->GetType();
    impl->implementation = funcs->GetImplementation();

    D_MAGIC_SET( impl, DirectInterfaceImplementation );

    D_DEBUG_AT( Direct_Interface, "  -> %s | %s\n", impl->type, impl->implementation );

    direct_mutex_lock( &implementations_mutex );
    direct_list_prepend( &implementations, &impl->link );
    direct_mutex_unlock( &implementations_mutex );
}
Beispiel #29
0
VoodooDispatcher::~VoodooDispatcher()
{
     D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this );

     D_MAGIC_ASSERT( this, VoodooDispatcher );

     /* Acquire lock and wake up waiters. */
     direct_mutex_lock( &lock );
     direct_waitqueue_broadcast( &queue );
     direct_mutex_unlock( &lock );

     /* Wait for dispatcher loop exiting. */
     direct_thread_join( dispatch_loop );
     direct_thread_destroy( dispatch_loop );

     /* Destroy queue. */
     direct_waitqueue_deinit( &queue );

     /* Destroy lock. */
     direct_mutex_deinit( &lock );

     D_MAGIC_CLEAR( this );
}
Beispiel #30
0
static void *
CoreInputHubClient_ActivateThread( DirectThread *thread,
                                   void         *arg )
{
     CoreInputHubClient    *client = arg;
     InputHubAttachRequest  request;

     D_DEBUG_AT( Core_InputHub, "%s()\n", __FUNCTION__ );

     direct_mutex_lock( &client->lock );

     while (!client->activate_stop) {
          request.listen_qid = client->listen_qid;

          OneQueue_Dispatch( client->remote_qid, &request, sizeof(request) );

          direct_waitqueue_wait_timeout( &client->wq, &client->lock, 1000000 );
     }

     direct_mutex_unlock( &client->lock );

     return DFB_OK;
}