# HG changeset patch # User Paul Boddie # Date 1594161754 -7200 # Node ID 6d2b694fcea20f7e232fad1fab25ba5c8bedfc9a # Parent a5d3cfa323877b677103ad579ef79e10fa22f1eb Introduced interface members for ahead-of-time reply/completion functions. diff -r a5d3cfa32387 -r 6d2b694fcea2 common.c --- a/common.c Tue Jul 07 23:07:30 2020 +0200 +++ b/common.c Wed Jul 08 00:42:34 2020 +0200 @@ -171,6 +171,21 @@ : GENERAL_FUNCTION_ROLE; } +enum specifier get_server_function_direction(enum function_role function) +{ + switch (function) + { + case COMPLETION_ROLE: + return IN_PARAMETER; + + case COMPLETION_REPLY_ROLE: + return OUT_PARAMETER; + + default: + return ANY_PARAMETER; + } +} + /* Obtain a suitable interface class name depending on the component role. */ char *get_interface_class_name(struct interface *iface, @@ -276,7 +291,8 @@ enum parameter_role role, enum function_role function) { - if ((param->specifier & OUT_PARAMETER) && (function != COMPLETION_ROLE)) + if ((param->specifier & OUT_PARAMETER) && (function != COMPLETION_ROLE) && + (function != COMPLETION_REPLY_ROLE)) { switch (role) { diff -r a5d3cfa32387 -r 6d2b694fcea2 common.h --- a/common.h Tue Jul 07 23:07:30 2020 +0200 +++ b/common.h Wed Jul 08 00:42:34 2020 +0200 @@ -51,6 +51,8 @@ enum function_role get_server_function_role(struct signature *sig); +enum specifier get_server_function_direction(enum function_role function); + /* Dispatcher object conversion (from compound to individual interfaces). */ char *get_object_conversion(struct interface *iface, int compound); diff -r a5d3cfa32387 -r 6d2b694fcea2 declaration.c --- a/declaration.c Tue Jul 07 23:07:30 2020 +0200 +++ b/declaration.c Wed Jul 08 00:42:34 2020 +0200 @@ -39,11 +39,7 @@ int declaration = (role & DECLARATION_ROLE); int member = (role & MEMBER_ROLE); int server = (component == SERVER_ROLE); - - /* Explicit completion functions only employ input/inout parameters. */ - - int completion = (function == COMPLETION_ROLE); - enum specifier direction = completion ? IN_PARAMETER : ANY_PARAMETER; + enum specifier direction = get_server_function_direction(function); /* Indent and provide a qualifier for C++ class declarations. */ @@ -54,12 +50,18 @@ char *opname = get_signature_operation_name(iface, sig, component, role, conf.language); + /* Prefix any function name appropriately. */ + + char *prefix = (function == COMPLETION_REPLY_ROLE) ? "complete_" : ""; + /* Introduce an initial parameter for the component state. */ if (!cpp && member) - fprintf(fp, interface_struct_member_function_signature_prologue, opname); + fprintf(fp, interface_struct_member_function_signature_prologue, prefix, + opname); else - fprintf(fp, interface_function_signature_prologue, qualifier, opname); + fprintf(fp, interface_function_signature_prologue, qualifier, prefix, + opname); if (have_init_param) write_initial_parameter(iface->name, fp); @@ -72,17 +74,44 @@ fputs(")", fp); /* Add a body for the function, this being used to define unimplemented - methods in C++. The client has method definitions and therefore normal - virtual methods. */ + methods or ahead-of-time reply completion functions in C++. The client + has method definitions and therefore normal virtual methods. */ if (cpp && declaration && server) - write_interface_unimplemented_method(sig, direction, fp); + { + if (function == COMPLETION_REPLY_ROLE) + write_interface_completion_reply_method(sig, fp, iface); + else + write_interface_unimplemented_method(sig, direction, fp); + } else fputs(get_signature_terminator(role), fp); free(opname); } +/* Write a completion reply member function body for a C++ interface. */ + +void write_interface_completion_reply_method(struct signature *sig, + FILE *fp, struct interface *iface) +{ + int have_init_param = (conf.language == C_LANGUAGE); + char *opname = get_operation_name(iface, sig); + + fprintf(fp, interface_completion_reply_method_prologue_cpp, opname); + + if (have_init_param) + write_initial_parameter(iface->name, fp); + + /* Write the parameters for an invocation of the server function completing an + operation by sending a reply. */ + + write_parameters(sig->parameters, fp, INVOCATION_ROLE, COMPLETION_ROLE, + OUT_PARAMETER, have_init_param); + + fputs(interface_completion_reply_method_epilogue_cpp, fp); +} + /* Write an unimplemented member function body for a C++ interface. */ void write_interface_unimplemented_method(struct signature *sig, diff -r a5d3cfa32387 -r 6d2b694fcea2 declaration.h --- a/declaration.h Tue Jul 07 23:07:30 2020 +0200 +++ b/declaration.h Wed Jul 08 00:42:34 2020 +0200 @@ -31,6 +31,9 @@ enum function_role function, FILE *fp, struct interface *iface); +void write_interface_completion_reply_method(struct signature *sig, + FILE *fp, struct interface *iface); + void write_interface_unimplemented_method(struct signature *sig, enum specifier direction, FILE *fp); diff -r a5d3cfa32387 -r 6d2b694fcea2 server.c --- a/server.c Tue Jul 07 23:07:30 2020 +0200 +++ b/server.c Wed Jul 08 00:42:34 2020 +0200 @@ -37,6 +37,11 @@ { write_interface_signature(sig, role, SERVER_ROLE, get_server_function_role(sig), fp, iface); + + /* Generate a signature for an ahead-of-time reply completion function. */ + + write_interface_signature(sig, role, SERVER_ROLE, COMPLETION_REPLY_ROLE, fp, + iface); } /* Generate signature declarations for each operation. */ @@ -98,7 +103,7 @@ char *prologue = completion ? server_completion_function_signature_prologue : - server_completion_optional_function_signature_prologue; + server_completion_reply_function_signature_prologue; fprintf(fp, prologue, opname, iface->name); @@ -270,10 +275,10 @@ if (have_attribute(sig->attributes, "completion")) fprintf(fp, server_completion_function_body_epilogue, "0", "_endp"); - /* Send a plain reply for optional/coupled completions. */ + /* Send a plain reply for reply/coupled completions. */ else - fputs(server_completion_optional_function_body_epilogue, fp); + fputs(server_completion_reply_function_body_epilogue, fp); /* Free allocated strings. */ diff -r a5d3cfa32387 -r 6d2b694fcea2 templates.h --- a/templates.h Tue Jul 07 23:07:30 2020 +0200 +++ b/templates.h Wed Jul 08 00:42:34 2020 +0200 @@ -195,7 +195,7 @@ #define server_completion_function_signature_prologue \ "\nlong complete_%s(l4_cap_idx_t _endp" -#define server_completion_optional_function_signature_prologue \ +#define server_completion_reply_function_signature_prologue \ "\nlong complete_%s(" #define server_completion_function_body_prologue \ @@ -205,7 +205,7 @@ "\n ipc_message_send(&msg, %s, %s);\n\n" \ " return l4_error(msg.tag);\n" -#define server_completion_optional_function_body_epilogue \ +#define server_completion_reply_function_body_epilogue \ "\n ipc_message_reply(&msg);\n\n" \ " return l4_error(msg.tag);\n" @@ -245,10 +245,10 @@ "\n} iface_%s;\n" #define interface_function_signature_prologue \ -"\n%slong %s(" +"\n%slong %s%s(" #define interface_struct_member_function_signature_prologue \ -"\n long (*%s)(" +"\n long (*%s%s)(" #define interface_unimplemented_method_prologue_cpp \ "\n {" @@ -259,6 +259,15 @@ #define interface_unused_parameter \ " (void) %s;" +#define interface_completion_reply_method_prologue_cpp \ +"\n" \ +" {\n" \ +" return complete_%s(" + +#define interface_completion_reply_method_epilogue_cpp \ + ");\n" \ +" }\n" + /* Reference and object type definitions for interfaces. */ #define ref_type_definition_c \ diff -r a5d3cfa32387 -r 6d2b694fcea2 types.h --- a/types.h Tue Jul 07 23:07:30 2020 +0200 +++ b/types.h Wed Jul 08 00:42:34 2020 +0200 @@ -66,8 +66,9 @@ enum function_role { - COMPLETION_ROLE, + COMPLETION_ROLE, /* decoupled input and output functions */ GENERAL_FUNCTION_ROLE, + COMPLETION_REPLY_ROLE, /* completion for ahead-of-time reply */ }; /* Role of a parameter in output. */