# HG changeset patch # User Paul Boddie # Date 1647032949 -3600 # Node ID eb691992a8f478d411c17a3afc528854c0f924e4 # Parent c146c6d1802fe8f7395bd0ed1effe720be483836 Changed server initialisation and IPC receive label interpretation to permit the invocation of other endpoints bound to the IPC thread. diff -r c146c6d1802f -r eb691992a8f4 libfsserver/lib/generic/resource_server.cc --- a/libfsserver/lib/generic/resource_server.cc Thu Mar 10 23:23:07 2022 +0100 +++ b/libfsserver/lib/generic/resource_server.cc Fri Mar 11 22:09:09 2022 +0100 @@ -34,7 +34,7 @@ long ResourceServer::bind(const char *name) { - return ipc_server_bind(name, (l4_umword_t) _resource, &_config->server); + return ipc_server_bind(name, (l4_umword_t) _config, &_config->server); } /* Start in the same thread with no deletion notifications or finalisation. */ diff -r c146c6d1802f -r eb691992a8f4 libipc/include/ipc/server.h --- a/libipc/include/ipc/server.h Thu Mar 10 23:23:07 2022 +0100 +++ b/libipc/include/ipc/server.h Fri Mar 11 22:09:09 2022 +0100 @@ -1,7 +1,7 @@ /* * Server binding/registration. * - * Copyright (C) 2018, 2019, 2020, 2021 Paul Boddie + * Copyright (C) 2018, 2019, 2020, 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -27,12 +27,6 @@ EXTERN_C_BEGIN -/* A convenience macro for invoking the server mainloop. */ - -#define ipc_server_loop_for(TYPE, POINTER) \ - ipc_server_loop(TYPE##_expected_items, (TYPE *) POINTER, \ - (ipc_server_handler_type) handle_##TYPE) - /* A handler function type. */ typedef void (*ipc_server_handler_type)(ipc_message_t *, void *); @@ -113,13 +107,12 @@ /* Handle incoming messages for a server. */ -long ipc_server_loop(int expected_items, void *obj, - ipc_server_handler_type handler); +long ipc_server_loop(int expected_items, ipc_server_config_type *config); /* Handle incoming messages and IRQ notifications for a server. */ -long ipc_server_managed_loop(int expected_items, void *obj, l4_cap_idx_t irq, - ipc_server_handler_type handler); +long ipc_server_managed_loop(int expected_items, ipc_server_config_type *config, + l4_cap_idx_t irq); /* A pthread-compatible mainloop initiation function. */ diff -r c146c6d1802f -r eb691992a8f4 libipc/lib/src/server.c --- a/libipc/lib/src/server.c Thu Mar 10 23:23:07 2022 +0100 +++ b/libipc/lib/src/server.c Fri Mar 11 22:09:09 2022 +0100 @@ -153,21 +153,24 @@ /* A server main loop with no endpoint deletion detection. */ -long ipc_server_loop(int expected_items, void *obj, - ipc_server_handler_type handler) +long ipc_server_loop(int expected_items, ipc_server_config_type *config) { - return ipc_server_managed_loop(expected_items, obj, L4_INVALID_CAP, handler); + return ipc_server_managed_loop(expected_items, config, L4_INVALID_CAP); } /* A server main loop handling endpoint deletion for an IPC gate dedicated to a particular object within its own thread. */ -long ipc_server_managed_loop(int expected_items, void *obj, l4_cap_idx_t irq, - ipc_server_handler_type handler) +long ipc_server_managed_loop(int expected_items, ipc_server_config_type *config, + l4_cap_idx_t irq) { ipc_message_t msg; l4_umword_t label, irq_label = (l4_umword_t) irq; + /* Permit other endpoints by dynamically interpreting the label. */ + + ipc_server_config_type *config_from_label; + /* Declare the extent to which capabilities are expected in messages. */ long err = ipc_message_expect(&msg, expected_items); @@ -198,7 +201,10 @@ /* Message involves the IPC gate itself. */ if (label != irq_label) - handler(&msg, obj); + { + config_from_label = (ipc_server_config_type *) label; + config_from_label->handler(&msg, config_from_label->handler_obj); + } /* Message involves the IRQ or a termination condition occurred. */ @@ -219,8 +225,8 @@ { ipc_server_config_type *config = (ipc_server_config_type *) data; - long err = ipc_server_managed_loop(config->expected_items, config->handler_obj, - config->irq, config->handler); + long err = ipc_server_managed_loop(config->expected_items, config, + config->irq); if (config->finaliser != NULL) config->finaliser(config); @@ -317,7 +323,7 @@ if (l4_is_invalid_cap(config->server)) { - err = ipc_server_new_for_thread(&config->server, config->handler_obj, config->thread); + err = ipc_server_new_for_thread(&config->server, config, config->thread); if (err) return err;