示例#1
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;
          }
     }
示例#2
0
void
VoodooConnectionLink::Stop()
{
     D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this );

     D_MAGIC_ASSERT( this, VoodooConnection );

     direct_mutex_lock( &output.lock );

     while (output.packets) {
          VoodooPacket *packet = (VoodooPacket*) output.packets;

          D_DEBUG_AT( Voodoo_Connection, "  -> discarding output packet %p\n", packet );

          D_ASSUME( packet->sending );

          packet->sending = false;

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

     direct_mutex_unlock( &output.lock );

     direct_waitqueue_broadcast( &output.wait );
}
示例#3
0
void
dfb_core_cleanup_remove( CoreDFB     *core,
                         CoreCleanup *cleanup )
{
     D_ASSUME( core != NULL );

     if (!core)
          core = core_dfb;

     D_MAGIC_ASSERT( core, CoreDFB );

     direct_list_remove( &core->cleanups, &cleanup->link );

     D_FREE( cleanup );
}
示例#4
0
void
direct_thread_remove_init_handler( DirectThreadInitHandler *handler )
{
     D_MAGIC_ASSERT( handler, DirectThreadInitHandler );

     pthread_mutex_lock( &handler_lock );

     direct_list_remove( &handlers, &handler->link );

     pthread_mutex_unlock( &handler_lock );

     D_MAGIC_CLEAR( handler );

     D_FREE( handler );
}
示例#5
0
void
DirectUnregisterInterface( DirectInterfaceFuncs *funcs )
{
     DirectInterfaceImplementation *impl;

     pthread_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;
          }
     }
示例#6
0
文件: signals.c 项目: kuii/dfbNEON
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;
}
示例#7
0
文件: interface.c 项目: kuii/dfbNEON
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;
        }
    }
示例#8
0
static void
stack_containers_remove(CoreWindowStack *p)
{
     Stack_Container    *stack_cntr = NULL;

     D_DEBUG_AT( Core_WindowStack, "Enter:%s()\n", __FUNCTION__);

     pthread_mutex_lock( &stack_containers_lock );

     direct_list_foreach(stack_cntr, stack_containers) {
          if((void *)p == stack_cntr->ctx) {
               direct_list_remove(&stack_containers, &stack_cntr->link);
               D_FREE(stack_cntr);
          }
     }

     pthread_mutex_unlock( &stack_containers_lock );
}
示例#9
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;
}
示例#10
0
文件: client.c 项目: kuii/dfbNEON
DirectResult
voodoo_client_destroy( VoodooClient *client )
{
     D_ASSERT( client != NULL );

     D_DEBUG_AT( Voodoo_Client, "%s( %p )\n", __FUNCTION__, client );

     D_INFO( "Voodoo/Client: Decreasing ref count of connection...\n" );

     if (! --(client->refs)) {
          voodoo_manager_destroy( client->manager );

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

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

          D_FREE( client->host );
          D_FREE( client );
     }

     return DR_OK;
}
示例#11
0
static void *
DecoupledCall_thread_main( DirectThread *thread,
                           void         *ctx )
{
    while (true) {
        DecoupledCall *call;

        direct_mutex_lock( &decoupled_calls_lock );

        while (!decoupled_calls)
            direct_waitqueue_wait( &decoupled_calls_wq, &decoupled_calls_lock );

        call = (DecoupledCall*) decoupled_calls;

        direct_list_remove( &decoupled_calls, &call->link );

        direct_mutex_unlock( &decoupled_calls_lock );


        ComaTestInstance *instance  = call->instance;
        IComaComponent   *component = instance->component;

        switch (call->method) {
        case COMA_TEST_CALL1:
            DispatchCall1( instance, call->data, call->serial );
            break;

        default:
            component->Return( component, DR_NOIMPL, call->serial );
            break;
        }

        D_FREE( call );
    }

    return NULL;
}
示例#12
0
文件: signals.c 项目: kuii/dfbNEON
static void
signal_handler( int num, siginfo_t *info, void *foo )
{
     ucontext_t   *uctx = foo;
#else
static void
signal_handler( int num )
{
#endif
     DirectResult  ret;
     int           i;
     DirectLink   *l, *n;
     SigHandled   *sig  = NULL;
     void         *addr = NULL;

//     fflush(stdout);
//     fflush(stderr);

     for (i=0; i<NUM_SIGS_TO_HANDLE; i++) {
          if (sigs_handled[i].signum == num) {
               sig = &sigs_handled[i];

               /* Using SA_RESETHAND, so... */
               sig->signum = -1;
               break;
          }
     }

/*     ret = direct_sigaction( num, &sig->old_action, NULL );
     if (ret) {
          D_DERROR( ret, "Direct/Signals: Unable to restore previous handler for signal %d!\n", num );
          sig = NULL;
     }
*/

#ifndef SA_SIGINFO
     D_LOG( Direct_Signals, FATAL, "    --> Caught signal %d <--\n", num );
#else
     if (info && info > (siginfo_t*) 0x100) {
          bool shown = false;

          /* Kernel genrated signal? */
          if (info->si_code > 0 && info->si_code < 0x80) {
               addr = info->si_addr;

               switch (num) {
                    case SIGSEGV:
                         shown = show_segv( info, uctx );
                         break;

                    case SIGBUS:
                         shown = show_bus( info, uctx );
                         break;

                    case SIGILL:
                         shown = show_ill( info, uctx );
                         break;

                    case SIGFPE:
                         shown = show_fpe( info, uctx );
                         break;

                    default:
                         D_LOG( Direct_Signals, FATAL, "    --> Caught signal %d <--\n", info->si_signo );
                         addr  = NULL;
                         shown = true;
                         break;
               }
          }
          else
               shown = show_any( info, uctx );

          if (!shown)
               D_LOG( Direct_Signals, FATAL, "    --> Caught signal %d (unknown origin) <--\n", info->si_signo );
     }
     else
          D_LOG( Direct_Signals, FATAL, "    --> Caught signal %d, no siginfo available <--\n", num );
#endif

     direct_log_lock( NULL );
     direct_trace_print_stacks();
     direct_log_unlock( NULL );


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

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

          if (handler->num != num && handler->num != DIRECT_SIGNAL_ANY)
               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 );

                    if (sig) {
                         ret = direct_sigaction( num, &sig->new_action, NULL );
                         if (ret)
                              D_DERROR( ret, "Direct/Signals: Unable to reinstall handler for signal %d!\n", num );
                         else
                              sig->signum = num;
                    }
                    return;

               default:
                    D_BUG( "unknown result" );
                    break;
          }
     }
示例#13
0
void *
VoodooConnectionPacket::io_loop()
{
     D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );

     while (!stop) {
          D_MAGIC_ASSERT( this, VoodooConnection );

          if (input.start == input.max) {
               input.start = 0;
               input.end   = 0;
               input.last  = 0;
               input.max   = VOODOO_CONNECTION_LINK_INPUT_BUF_MAX;
          }

          if (!stop) {
               DirectResult  ret;
               VoodooChunk   chunks[2];
               VoodooChunk  *chunk_read  = NULL;
               VoodooChunk  *chunk_write = NULL;
               size_t        last        = input.last;
               VoodooPacket *packet      = NULL;

               std::vector<VoodooChunk> chunks_write;
               std::vector<VoodooChunk> chunks_read;

               if (!output.sending) {
                    direct_mutex_lock( &output.lock );

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

                         D_ASSERT( packet->sending );

                         if (voodoo_config->compression_min && packet->size() >= voodoo_config->compression_min) {
                              output.sending = VoodooPacket::Compressed( packet );

                              if (output.sending->flags() & VPHF_COMPRESSED) {
                                   D_DEBUG_AT( Voodoo_Output, "  -> Compressed %u to %u bytes... (packet %p)\n",
                                               output.sending->uncompressed(), output.sending->size(), packet );

                                   output.sending->sending = true;

                                   packet->sending = false;

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

                                   direct_waitqueue_broadcast( &output.wait );
                              }
                         }
                         else
                              output.sending = packet;

                         output.sent = 0;
                    }

                    direct_mutex_unlock( &output.lock );
               }

               if (output.sending) {
                    packet = output.sending;

                    D_ASSERT( packet->sending );

                    chunk_write = &chunks[1];

                    chunk_write->ptr    = (char*) packet->data_header() + output.sent;
                    chunk_write->length = VOODOO_MSG_ALIGN(packet->size() + sizeof(VoodooPacketHeader)) - output.sent;
                    chunk_write->done   = 0;

                    chunks_write.push_back( chunks[1] );

                    chunk_write = chunks_write.data();
               }

               if (input.end < input.max && manager->DispatchReady()) {
                    chunk_read = &chunks[0];

                    chunk_read->ptr    = input.buffer + input.end;
                    chunk_read->length = input.max - input.end;
                    chunk_read->done   = 0;

                    chunks_read.push_back( chunks[0] );

                    chunk_read = chunks_read.data();
               }


               ret = link->SendReceive( link,
                                        chunks_write.data(), chunks_write.size(),
                                        chunks_read.data(), chunks_read.size() );
               switch (ret) {
                    case DR_OK:
                         if (chunk_write && chunk_write->done) {
                              D_DEBUG_AT( Voodoo_Output, "  -> Sent "_ZD"/"_ZD" bytes... (packet %p)\n", chunk_write->done, chunk_write->length, packet );

                              output.sent += chunk_write->done;

                              if (output.sent == VOODOO_MSG_ALIGN(packet->size() + sizeof(VoodooPacketHeader))) {
                                   output.sending = NULL;

                                   if (packet->flags() & VPHF_COMPRESSED) {
                                        packet->sending = false;

                                        D_FREE( packet );
                                   }
                                   else {
                                        direct_mutex_lock( &output.lock );

                                        packet->sending = false;

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

                                        direct_mutex_unlock( &output.lock );

                                        direct_waitqueue_broadcast( &output.wait );
                                   }
                              }
                         }
                         break;

                    case DR_TIMEOUT:
                         //D_DEBUG_AT( Voodoo_Connection, "  -> timeout\n" );
                         break;

                    case DR_INTERRUPTED:
                         D_DEBUG_AT( Voodoo_Connection, "  -> interrupted\n" );
                         break;

                    default:
                         if (ret == DR_IO)
                              D_DEBUG_AT( Voodoo_Connection, "  -> Connection closed!\n" );
                         else
                              D_DERROR( ret, "Voodoo/ConnectionPacket: Could not receive data!\n" );

                         goto disconnect;
               }


               if (chunk_read && chunk_read->done) {
                    D_DEBUG_AT( Voodoo_Input, "  -> Received "_ZD" bytes...\n", chunk_read->done );

                    input.end += (size_t) chunk_read->done;

                    do {
                         VoodooPacketHeader *header;
                         size_t              aligned;

                         D_DEBUG_AT( Voodoo_Input, "  -> last = %zu\n", last );

                         /* Get the packet header. */
                         header  = (VoodooPacketHeader *)(input.buffer + last);
                         D_DEBUG_AT( Voodoo_Input, "  -> header = %p\n", header );
                         D_DEBUG_AT( Voodoo_Input, "  -> header->size = %u\n", header->size );
                         aligned = VOODOO_MSG_ALIGN( header->size );

                         D_DEBUG_AT( Voodoo_Input, "  -> Next packet has %u ("_ZU") -> %u bytes (flags 0x%04x)...\n",
                                     header->size, aligned, header->uncompressed, header->flags );

                         if (input.end - last >= sizeof(VoodooPacketHeader)) {
                              if (header->uncompressed < (int) sizeof(VoodooMessageHeader)) {
                                   D_DERROR( ret, "Voodoo/ConnectionPacket: Data error, uncompressed %d < min %zu!\n", header->uncompressed, sizeof(VoodooPacketHeader) );

                                   goto disconnect;
                              }

                              if (header->uncompressed > VOODOO_PACKET_MAX) {
                                   D_DERROR( ret, "Voodoo/ConnectionPacket: Data error, uncompressed %d > max %d!\n", header->uncompressed, VOODOO_PACKET_MAX );

                                   goto disconnect;
                              }
                         }

                         if (sizeof(VoodooPacketHeader) + aligned > input.end - last) {
                              D_DEBUG_AT( Voodoo_Input, "  -> ...fetching tail of message.\n" );

                              /* Extend the buffer if the message doesn't fit into the default boundary. */
                              if (sizeof(VoodooPacketHeader) + aligned > input.max - last)
                                   input.max = last + sizeof(VoodooPacketHeader) + aligned;

                              break;
                         }

                         last += sizeof(VoodooPacketHeader) + aligned;
                    } while (last < input.end);

                    if (last != input.last) {
                         input.last = last;

                         D_DEBUG_AT( Voodoo_Input, "  { START "_ZD", LAST "_ZD", END "_ZD", MAX "_ZD" }\n",
                                     input.start, input.last, input.end, input.max );

                         while (input.start < input.last) {
                              /* Get the packet header. */
                              VoodooPacketHeader *header = (VoodooPacketHeader *)(input.buffer + input.start);

                              VoodooPacket *p;

                              D_ASSERT( header->uncompressed <= VOODOO_PACKET_MAX );

                              if (header->flags & VPHF_COMPRESSED) {
                                   size_t uncompressed = direct_fastlz_decompress( header + 1, header->size, tmp, header->uncompressed );

                                   D_DEBUG_AT( Voodoo_Input, "  -> Uncompressed "_ZU" bytes (%u compressed)\n", uncompressed, header->size );

                                   (void) uncompressed;

                                   D_ASSERT( uncompressed == header->uncompressed );

                                   // FIXME: don't copy, but read into packet directly, maybe call manager->GetPacket() at the top of this loop
                                   p = VoodooPacket::Copy( header->uncompressed, VPHF_NONE,
                                                           header->uncompressed, tmp );
                              }
                              else {
                                   // FIXME: don't copy, but read into packet directly, maybe call manager->GetPacket() at the top of this loop
                                   p = VoodooPacket::Copy( header->uncompressed, VPHF_NONE,
                                                           header->uncompressed, header + 1 );
                              }

                              manager->DispatchPacket( p );

                              input.start += VOODOO_MSG_ALIGN(header->size) + sizeof(VoodooPacketHeader);
                         }
                    }
               }
          }
     }

     return NULL;


disconnect:
     closed = true;

     manager->handle_disconnect();

     return NULL;
}