2.1 --- a/server.c Sun Apr 26 22:59:15 2020 +0200
2.2 +++ b/server.c Sun Jul 05 00:34:30 2020 +0200
2.3 @@ -1,7 +1,7 @@
2.4 /*
2.5 * Server code generation.
2.6 *
2.7 - * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
2.8 + * Copyright (C) 2019, 2020 Paul Boddie <paul@boddie.org.uk>
2.9 *
2.10 * This program is free software; you can redistribute it and/or
2.11 * modify it under the terms of the GNU General Public License as
2.12 @@ -44,12 +44,14 @@
2.13 FILE *fp, struct interface *iface)
2.14 {
2.15 if (have_attribute(sig->attributes, "completion"))
2.16 - {
2.17 write_server_initiation_signature(sig, role, fp, iface);
2.18 - write_server_completion_signature(sig, role, fp, iface);
2.19 - }
2.20 else
2.21 write_server_wrapper_signature(sig, role, fp, iface);
2.22 +
2.23 + /* Write the appropriate completion signature even for use by conventional
2.24 + operations. */
2.25 +
2.26 + write_server_completion_signature(sig, role, fp, iface);
2.27 }
2.28
2.29 /* Generic signature generation. */
2.30 @@ -88,13 +90,21 @@
2.31 {
2.32 char *opname = get_operation_name(iface, sig);
2.33
2.34 - /* Generate a signature featuring an initiator reference and only "out" and
2.35 - "inout" parameters. */
2.36 + /* Generate a signature featuring an initiator reference (for genuine
2.37 + decoupled completions) and only "out" and "inout" parameters. */
2.38 +
2.39 + int completion = have_attribute(sig->attributes, "completion");
2.40
2.41 - fprintf(fp, server_completion_function_signature_prologue, opname, iface->name);
2.42 + char *prologue = completion ?
2.43 + server_completion_function_signature_prologue :
2.44 + server_completion_optional_function_signature_prologue;
2.45 +
2.46 + fprintf(fp, prologue, opname, iface->name);
2.47 +
2.48 + /* Continue from the initial endpoint parameter if a genuine completion. */
2.49
2.50 write_parameters(sig->parameters, fp, SIGNATURE_ROLE, COMPLETION_ROLE,
2.51 - OUT_PARAMETER, 1);
2.52 + OUT_PARAMETER, completion);
2.53
2.54 fputs(")", fp);
2.55 fputs(get_signature_terminator(role), fp);
2.56 @@ -113,10 +123,6 @@
2.57 write_server_initiation_signature(sig, DEFINITION_ROLE, fp, iface);
2.58 write_server_initiation_function_body(sig->parameters, fp, iface, sig);
2.59 fputs(END_FUNCTION, fp);
2.60 -
2.61 - write_server_completion_signature(sig, DEFINITION_ROLE, fp, iface);
2.62 - write_server_completion_function_body(sig->parameters, fp, iface, sig);
2.63 - fputs(END_FUNCTION, fp);
2.64 }
2.65 else
2.66 {
2.67 @@ -124,6 +130,13 @@
2.68 write_server_wrapper_function_body(sig->parameters, fp, iface, sig);
2.69 fputs(END_FUNCTION, fp);
2.70 }
2.71 +
2.72 + /* Write the appropriate completion function even for use by conventional
2.73 + operations. */
2.74 +
2.75 + write_server_completion_signature(sig, DEFINITION_ROLE, fp, iface);
2.76 + write_server_completion_function_body(sig->parameters, fp, iface, sig);
2.77 + fputs(END_FUNCTION, fp);
2.78 }
2.79
2.80 /* Generate a function body corresponding to an operation for server use. */
2.81 @@ -250,10 +263,16 @@
2.82
2.83 write_output_initialisation(param, fp, opname, output_words, output_items, COMPLETION_ROLE);
2.84
2.85 - /* Send the response.
2.86 + /* Send a response as a new message to the given endpoint.
2.87 NOTE: The label 0 is employed but an error condition could be communicated. */
2.88
2.89 - fprintf(fp, server_completion_function_body_epilogue, "0", "_endp");
2.90 + if (have_attribute(sig->attributes, "completion"))
2.91 + fprintf(fp, server_completion_function_body_epilogue, "0", "_endp");
2.92 +
2.93 + /* Send a plain reply for optional/coupled completions. */
2.94 +
2.95 + else
2.96 + fputs(server_completion_optional_function_body_epilogue, fp);
2.97
2.98 /* Free allocated strings. */
2.99
3.1 --- a/templates.h Sun Apr 26 22:59:15 2020 +0200
3.2 +++ b/templates.h Sun Jul 05 00:34:30 2020 +0200
3.3 @@ -195,6 +195,9 @@
3.4 #define server_completion_function_signature_prologue \
3.5 "\nlong complete_%s(l4_cap_idx_t _endp"
3.6
3.7 +#define server_completion_optional_function_signature_prologue \
3.8 +"\nlong complete_%s("
3.9 +
3.10 #define server_completion_function_body_prologue \
3.11 " ipc_message_t msg;\n"
3.12
3.13 @@ -202,6 +205,10 @@
3.14 "\n ipc_message_send(&msg, %s, %s);\n\n" \
3.15 " return l4_error(msg.tag);\n"
3.16
3.17 +#define server_completion_optional_function_body_epilogue \
3.18 +"\n ipc_message_reply(&msg);\n\n" \
3.19 + " return l4_error(msg.tag);\n"
3.20 +
3.21 #define server_initiation_function_body_epilogue \
3.22 "\n ipc_message_prepare(msg);\n\n" \
3.23 " return L4_EOK;\n"
3.24 @@ -317,8 +324,10 @@
3.25
3.26 #define dispatch_function_reply_wrapper_case \
3.27 " case %s:\n" \
3.28 -" ipc_message_send_error(msg, %s_%s(msg, %s));\n" \
3.29 -" ipc_message_reply(msg);\n" \
3.30 +" err = %s_%s(msg, %s);\n" \
3.31 +" ipc_message_send_error(msg, err != IPC_MESSAGE_SENT ? err : L4_EOK);\n" \
3.32 +" if (err != IPC_MESSAGE_SENT)\n" \
3.33 +" ipc_message_reply(msg);\n" \
3.34 " break;\n\n"
3.35
3.36 /* Tokens. */