# HG changeset patch # User Paul Boddie # Date 1670947482 -3600 # Node ID bb05d5c2d7364fde43ae3b1556563259cf4e55df # Parent 170967cc0f8bf1574d08120d7aff974e7ddb0e88 Fixed dispatching to multiple levels of interfaces. diff -r 170967cc0f8b -r bb05d5c2d736 dispatch.c --- a/dispatch.c Sat Dec 10 01:28:22 2022 +0100 +++ b/dispatch.c Tue Dec 13 17:04:42 2022 +0100 @@ -80,22 +80,34 @@ /* Write cases for each interface, using the protocol to select between the cases. */ - if (by_protocol && (protocol != NULL)) + if (by_protocol) { - /* Convert to any base interface. */ + if (protocol != NULL) + { + /* Convert to any base interface. */ - ref = get_object_conversion(base->iface, 1); - fprintf(fp, dispatch_function_interface_case, protocol, base->name, ref); - free(ref); + ref = get_object_conversion(base->iface, 1); + fprintf(fp, dispatch_function_interface_case, protocol, base->name, ref); + free(ref); + } + + /* Look for any base interfaces employing protocols. */ + + else + write_dispatcher_interface_cases(fp, base->iface, 1); } /* Write cases for each operation provided by the interface so that they can be selected. Note that this requires distinct opcodes to be used, so in practice requiring explicit opcodes to be indicated. */ - else if (!by_protocol && (protocol == NULL)) - write_dispatcher_cases(fp, base->iface, 1); + else if (protocol == NULL) + write_dispatcher_interface_cases(fp, base->iface, 1); } + + /* Dispatch to each operation defined at this level. */ + + write_dispatcher_cases(fp, iface, is_compound_interface(iface)); } /* Return whether any base interface specifies a protocol. */ @@ -141,34 +153,26 @@ /* Declare an error variable to support testing for already-sent messages. */ - fputs(" long err;\n\n", fp); + fputs(dispatch_function_prologue, fp); /* Without a protocol applying to the entire interface, dispatch using the protocol from the message label. */ if (protocol == NULL) - { - fputs(" switch (l4_msgtag_label(msg->tag))\n {\n", fp); + fputs(dispatch_function_label_dispatcher, fp); + + /* If a protocol applies to the entire interface, test for this protocol and + dispatch using an operation indicator in the word data. */ - /* Dispatch using the protocol to base interfaces employing protocols. */ - - if (have_interfaces_using_protocols(iface)) - write_dispatcher_interface_cases(fp, iface, 1); + else + { + fprintf(fp, dispatch_function_test_protocol, protocol); + fputs(dispatch_function_word_dispatcher, fp); } - /* If a protocol applies to the entire interface, dispatch using an operation - indicator in the word data. */ - - else - fputs(" switch (ipc_message_get_word(msg, 0))\n {\n", fp); + /* Dispatch to operations and any base interfaces. */ - /* Dispatch to operations provided by compound interfaces. */ - - write_dispatcher_interface_cases(fp, iface, 0); - - /* Dispatch to each operation defined at this level. */ - - write_dispatcher_cases(fp, iface, is_compound_interface(iface)); + write_dispatcher_interface_cases(fp, iface, (protocol == NULL)); /* Terminate the dispatcher. */ diff -r 170967cc0f8b -r bb05d5c2d736 program.c --- a/program.c Sat Dec 10 01:28:22 2022 +0100 +++ b/program.c Tue Dec 13 17:04:42 2022 +0100 @@ -198,10 +198,6 @@ if (server_fp != NULL) { - /* Write any includes for base interfaces. */ - - write_server_includes(iface, server_fp); - /* Write the dispatcher and handler functions. */ write_functions(iface->signatures, server_fp, iface, @@ -245,6 +241,10 @@ if (iface->tail == NULL) write_include(iface->output_basename, "_interface.h", server_header_fp); + /* Write any includes for base interfaces. */ + + write_server_includes(iface, server_header_fp); + /* Emit signatures. */ write_signatures(iface->signatures, DECLARATION_ROLE, server_header_fp, diff -r 170967cc0f8b -r bb05d5c2d736 templates.h --- a/templates.h Sat Dec 10 01:28:22 2022 +0100 +++ b/templates.h Tue Dec 13 17:04:42 2022 +0100 @@ -87,16 +87,6 @@ -/* Compound interface dispatcher templates. */ - -#define compound_dispatch_prologue \ -"#include \"%s_server.h\"\n" - -#define compound_dispatch_function_prologue \ -" long err;\n\n" \ -" switch (l4_msgtag_label(msg->tag))\n" \ -" {\n" - /* Compound interface definitions. */ #define compound_interface_include \ @@ -128,8 +118,32 @@ #define dispatch_function_signature \ "\nvoid dispatch_%s(ipc_message_t *msg, %s *_self)" +#define dispatch_function_prologue \ +" long err;\n\n" + +#define dispatch_function_test_protocol \ +" if (l4_msgtag_label(msg->tag) != %s)\n" \ +" {\n" \ +" ipc_message_send_error(msg, -L4_EBADPROTO);\n" \ +" return;\n" \ +" }\n" + +#define dispatch_function_label_dispatcher \ +" switch (l4_msgtag_label(msg->tag))\n" \ +" {\n" + +#define dispatch_function_word_dispatcher \ +" switch (ipc_message_get_word(msg, 0))\n" \ +" {\n" + /* Dispatch templates. */ +#define dispatch_function_case_prologue \ +" case %s:\n" + +#define dispatch_function_case_epilogue \ +" break;\n\n" + #define dispatch_function_interface_case \ " case %s:\n" \ " dispatch_%s(msg, %s);\n" \