static DirectResult Dispatch_Sync( void *dispatcher, void *real, VoodooManager *manager, VoodooRequestMessage *msg ) { return voodoo_manager_respond( manager, true, msg->header.serial, DR_OK, VOODOO_INSTANCE_NONE, VMBT_NONE ); }
static void handle_super( VoodooManager *manager, VoodooSuperMessage *super ) { DirectResult ret; const char *name; D_MAGIC_ASSERT( manager, VoodooManager ); D_ASSERT( super != NULL ); D_ASSERT( super->header.size >= sizeof(VoodooSuperMessage) ); D_ASSERT( super->header.type == VMSG_SUPER ); name = (const char *) (super + 1); D_DEBUG( "Voodoo/Dispatch: Handling SUPER message %llu for '%s' (%d bytes).\n", (unsigned long long)super->header.serial, name, super->header.size ); if (manager->server) { VoodooInstanceID instance; ret = voodoo_server_construct( manager->server, manager, name, &instance ); if (ret) { voodoo_manager_respond( manager, super->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); return; } voodoo_manager_respond( manager, super->header.serial, DR_OK, instance, VMBT_NONE ); } else { D_WARN( "can't handle this as a client" ); voodoo_manager_respond( manager, super->header.serial, DR_UNSUPPORTED, VOODOO_INSTANCE_NONE, VMBT_NONE ); } }
static void * dispatch_async_thread( void *arg ) { DirectResult ret; DispatchAsyncContext *context = arg; VoodooManager *manager = context->manager; VoodooInstance *instance = context->instance; VoodooRequestMessage *request = context->request; ret = instance->dispatch( instance->proxy, instance->real, manager, request ); if (ret && (request->flags & VREQ_RESPOND)) voodoo_manager_respond( manager, request->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); D_FREE( context ); return NULL; }
/* * Callback for handling incoming requests */ static DirectResult VoodooTestDispatch( void *dispatcher, /* context 1 */ void *real, /* context 2 */ VoodooManager *manager, VoodooRequestMessage *msg ) { VoodooTestConnection *connection = dispatcher; VoodooTestServer *server = connection->server; switch (msg->method) { case VOODOO_TEST_INCREASE: server->count++; break; case VOODOO_TEST_QUERY: voodoo_manager_respond( manager, true, msg->header.serial, DR_OK, VOODOO_INSTANCE_NONE, VMBT_UINT, server->count, VMBT_NONE ); break; } return DR_OK; }
static void handle_request( VoodooManager *manager, VoodooRequestMessage *request ) { DirectResult ret; VoodooInstance *instance; D_MAGIC_ASSERT( manager, VoodooManager ); D_ASSERT( request != NULL ); D_ASSERT( request->header.size >= sizeof(VoodooRequestMessage) ); D_ASSERT( request->header.type == VMSG_REQUEST ); D_DEBUG( "Voodoo/Dispatch: Handling REQUEST message %llu to %u::%u %s%s(%d bytes).\n", (unsigned long long)request->header.serial, request->instance, request->method, (request->flags & VREQ_RESPOND) ? "[RESPONDING] " : "", (request->flags & VREQ_ASYNC) ? "[ASYNC] " : "", request->header.size ); pthread_mutex_lock( &manager->instances.lock ); instance = direct_hash_lookup( manager->instances.local, request->instance ); if (!instance) { pthread_mutex_unlock( &manager->instances.lock ); D_ERROR( "Voodoo/Dispatch: " "Requested instance %u doesn't exist (anymore)!\n", request->instance ); if (request->flags & VREQ_RESPOND) voodoo_manager_respond( manager, request->header.serial, DR_NOSUCHINSTANCE, VOODOO_INSTANCE_NONE, VMBT_NONE ); return; } if (request->flags & VREQ_ASYNC) { pthread_t thread; DispatchAsyncContext *context; context = D_MALLOC( sizeof(DispatchAsyncContext) + request->header.size ); if (!context) { D_WARN( "out of memory" ); pthread_mutex_unlock( &manager->instances.lock ); return; } context->manager = manager; context->instance = instance; context->request = (VoodooRequestMessage*) (context + 1); direct_memcpy( context->request, request, request->header.size ); pthread_create( &thread, NULL, dispatch_async_thread, context ); pthread_detach( thread ); } else { ret = instance->dispatch( instance->proxy, instance->real, manager, request ); if (ret && (request->flags & VREQ_RESPOND)) voodoo_manager_respond( manager, request->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } pthread_mutex_unlock( &manager->instances.lock ); }