Line data Source code
1 : /* 2 : Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain 3 : Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany 4 : 5 : This software was partially supported by the 6 : EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). 7 : 8 : This software was partially supported by the 9 : ADA-FS project under the SPPEXA project funded by the DFG. 10 : 11 : This file is part of GekkoFS. 12 : 13 : GekkoFS is free software: you can redistribute it and/or modify 14 : it under the terms of the GNU General Public License as published by 15 : the Free Software Foundation, either version 3 of the License, or 16 : (at your option) any later version. 17 : 18 : GekkoFS is distributed in the hope that it will be useful, 19 : but WITHOUT ANY WARRANTY; without even the implied warranty of 20 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 : GNU General Public License for more details. 22 : 23 : You should have received a copy of the GNU General Public License 24 : along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. 25 : 26 : SPDX-License-Identifier: GPL-3.0-or-later 27 : */ 28 : /** 29 : * @brief Provide helper functions for Margo's RPC interfaces reduce code 30 : * verbosity of the RPC handler functions. 31 : * @internal 32 : * Note, this is a temporary solution and is planned to be refactored. 33 : * @endinternal 34 : */ 35 : 36 : #ifndef GEKKOFS_DAEMON_RPC_UTIL_HPP 37 : #define GEKKOFS_DAEMON_RPC_UTIL_HPP 38 : 39 : extern "C" { 40 : #include <mercury_types.h> 41 : #include <mercury_proc_string.h> 42 : #include <margo.h> 43 : } 44 : 45 : #include <string> 46 : 47 : namespace gkfs::rpc { 48 : 49 : /** 50 : * @brief Frees all given RPC resources allocated by Margo. 51 : * @tparam InputType Any RPC input struct from client requests 52 : * @tparam OutputType Any RPC output struct for client response 53 : * @param handle Pointer to Mercury RPC handle 54 : * @param input Pointer to input struct 55 : * @param output Pointer to output struct 56 : * @param bulk_handle Pointer to Mercury bulk handle 57 : * @return Mercury error code. HG_SUCCESS on success. 58 : */ 59 : template <typename InputType, typename OutputType> 60 : inline hg_return_t 61 100 : cleanup(hg_handle_t* handle, InputType* input, OutputType* output, 62 : hg_bulk_t* bulk_handle) { 63 100 : auto ret = HG_SUCCESS; 64 100 : if(bulk_handle) { 65 86 : ret = margo_bulk_free(*bulk_handle); 66 86 : if(ret != HG_SUCCESS) 67 : return ret; 68 : } 69 100 : if(input && handle) { 70 100 : ret = margo_free_input(*handle, input); 71 100 : if(ret != HG_SUCCESS) 72 : return ret; 73 : } 74 100 : if(output && handle) { 75 0 : ret = margo_free_output(*handle, output); 76 0 : if(ret != HG_SUCCESS) 77 : return ret; 78 : } 79 100 : if(handle) { 80 100 : ret = margo_destroy(*handle); 81 : if(ret != HG_SUCCESS) 82 : return ret; 83 : } 84 : return ret; 85 : } 86 : 87 : /** 88 : * @brief Responds to a client request. 89 : * @internal 90 : * Note, Mercury frees the output struct itself after it responded to the 91 : * client. Attempting to explicitly free the output struct can cause segfaults 92 : * because the response is non-blocking and we could free the resources before 93 : * Mercury has responded. 94 : * @endinternal 95 : * 96 : * @tparam OutputType Any RPC output struct for client response 97 : * @param handle Pointer to Mercury RPC handle 98 : * @param output Pointer to output struct 99 : * @return Mercury error code. HG_SUCCESS on success. 100 : */ 101 : template <typename OutputType> 102 : inline hg_return_t 103 102 : respond(hg_handle_t* handle, OutputType* output) { 104 102 : auto ret = HG_SUCCESS; 105 102 : if(output && handle) { 106 102 : ret = margo_respond(*handle, output); 107 : if(ret != HG_SUCCESS) 108 : return ret; 109 : } 110 : return ret; 111 : } 112 : /** 113 : * @brief Combines responding to the client and cleaning up all RPC resources 114 : * after. 115 : * @tparam InputType Any RPC input struct from client requests 116 : * @tparam OutputType Any RPC output struct for client response 117 : * @param handle Pointer to Mercury RPC handle 118 : * @param input Pointer to input struct 119 : * @param output Pointer to output struct 120 : * @param bulk_handle Pointer to Mercury bulk handle 121 : * @return Mercury error code. HG_SUCCESS on success. 122 : */ 123 : template <typename InputType, typename OutputType> 124 : inline hg_return_t 125 100 : cleanup_respond(hg_handle_t* handle, InputType* input, OutputType* output, 126 : hg_bulk_t* bulk_handle) { 127 100 : auto ret = respond(handle, output); 128 100 : if(ret != HG_SUCCESS) 129 : return ret; 130 100 : return cleanup(handle, input, static_cast<OutputType*>(nullptr), 131 100 : bulk_handle); 132 : } 133 : /** 134 : * @brief Combines responding to the client and cleaning up all RPC resources 135 : * after. 136 : * @tparam InputType Any RPC input struct from client requests 137 : * @tparam OutputType Any RPC output struct for client response 138 : * @param handle Pointer to Mercury RPC handle 139 : * @param input Pointer to input struct 140 : * @param output Pointer to output struct 141 : * @return Mercury error code. HG_SUCCESS on success. 142 : */ 143 : template <typename InputType, typename OutputType> 144 : inline hg_return_t 145 14 : cleanup_respond(hg_handle_t* handle, InputType* input, OutputType* output) { 146 14 : return cleanup_respond(handle, input, output, nullptr); 147 : } 148 : /** 149 : * @brief Combines responding to the client and cleaning up all RPC resources 150 : * after. 151 : * @tparam OutputType Any RPC output struct for client response 152 : * @param handle Pointer to Mercury RPC handle 153 : * @param output Pointer to output struct 154 : * @return Mercury error code. HG_SUCCESS on success. 155 : */ 156 : template <typename OutputType> 157 : inline hg_return_t 158 2 : cleanup_respond(hg_handle_t* handle, OutputType* output) { 159 2 : auto ret = respond(handle, output); 160 2 : if(ret != HG_SUCCESS) 161 : return ret; 162 2 : if(handle) { 163 2 : ret = margo_destroy(*handle); 164 : if(ret != HG_SUCCESS) 165 : return ret; 166 : } 167 : return ret; 168 : } 169 : 170 : } // namespace gkfs::rpc 171 : 172 : 173 : #endif // GEKKOFS_DAEMON_RPC_UTIL_HPP