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; } }
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 ); }
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 ); }
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 ); }
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; } }
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; }
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; } }
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 ); }
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; }
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; }
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; }
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; } }
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; }