Line data Source code
1 : /* 2 : This file is part of TALER 3 : Copyright (C) 2019-2021 Taler Systems SA 4 : 5 : TALER is free software; you can redistribute it and/or modify it under the 6 : terms of the GNU Affero General Public License as published by the Free Software 7 : Foundation; either version 3, or (at your option) any later version. 8 : 9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 : A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 : 13 : You should have received a copy of the GNU Affero General Public License along with 14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 : */ 16 : /** 17 : * @file mhd_run.c 18 : * @brief API for running an MHD daemon with the 19 : * GNUnet scheduler 20 : * @author Christian Grothoff 21 : */ 22 : #include "platform.h" 23 : #include <gnunet/gnunet_util_lib.h> 24 : #include <gnunet/gnunet_json_lib.h> 25 : #include <jansson.h> 26 : #include <microhttpd.h> 27 : #include "taler_util.h" 28 : #include "taler_mhd_lib.h" 29 : 30 : 31 : /** 32 : * Set to true if we should immediately MHD_run() again. 33 : */ 34 : static bool triggered; 35 : 36 : /** 37 : * Task running the HTTP server. 38 : */ 39 : static struct GNUNET_SCHEDULER_Task *mhd_task; 40 : 41 : /** 42 : * The MHD daemon we are running. 43 : */ 44 : static struct MHD_Daemon *mhd; 45 : 46 : 47 : /** 48 : * Function that queries MHD's select sets and 49 : * starts the task waiting for them. 50 : */ 51 : static struct GNUNET_SCHEDULER_Task * 52 : prepare_daemon (void); 53 : 54 : 55 : /** 56 : * Call MHD to process pending requests and then go back 57 : * and schedule the next run. 58 : * 59 : * @param cls NULL 60 : */ 61 : static void 62 0 : run_daemon (void *cls) 63 : { 64 : (void) cls; 65 0 : mhd_task = NULL; 66 : do { 67 0 : triggered = false; 68 0 : GNUNET_assert (MHD_YES == 69 : MHD_run (mhd)); 70 0 : } while (triggered); 71 0 : mhd_task = prepare_daemon (); 72 0 : } 73 : 74 : 75 : /** 76 : * Function that queries MHD's select sets and starts the task waiting for 77 : * them. 78 : * 79 : * @return task handle for the MHD task. 80 : */ 81 : static struct GNUNET_SCHEDULER_Task * 82 0 : prepare_daemon (void) 83 : { 84 : struct GNUNET_SCHEDULER_Task *ret; 85 : fd_set rs; 86 : fd_set ws; 87 : fd_set es; 88 : struct GNUNET_NETWORK_FDSet *wrs; 89 : struct GNUNET_NETWORK_FDSet *wws; 90 : int max; 91 : MHD_UNSIGNED_LONG_LONG timeout; 92 : int haveto; 93 : struct GNUNET_TIME_Relative tv; 94 : 95 0 : FD_ZERO (&rs); 96 0 : FD_ZERO (&ws); 97 0 : FD_ZERO (&es); 98 0 : wrs = GNUNET_NETWORK_fdset_create (); 99 0 : wws = GNUNET_NETWORK_fdset_create (); 100 0 : max = -1; 101 0 : GNUNET_assert (MHD_YES == 102 : MHD_get_fdset (mhd, 103 : &rs, 104 : &ws, 105 : &es, 106 : &max)); 107 0 : haveto = MHD_get_timeout (mhd, 108 : &timeout); 109 0 : if (haveto == MHD_YES) 110 0 : tv = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 111 : timeout); 112 : else 113 0 : tv = GNUNET_TIME_UNIT_FOREVER_REL; 114 0 : GNUNET_NETWORK_fdset_copy_native (wrs, 115 : &rs, 116 : max + 1); 117 0 : GNUNET_NETWORK_fdset_copy_native (wws, 118 : &ws, 119 : max + 1); 120 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 121 : "Adding run_daemon select task\n"); 122 0 : ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, 123 : tv, 124 : wrs, 125 : wws, 126 : &run_daemon, 127 : NULL); 128 0 : GNUNET_NETWORK_fdset_destroy (wrs); 129 0 : GNUNET_NETWORK_fdset_destroy (wws); 130 0 : return ret; 131 : } 132 : 133 : 134 : void 135 0 : TALER_MHD_daemon_start (struct MHD_Daemon *daemon) 136 : { 137 0 : GNUNET_assert (NULL == mhd); 138 0 : mhd = daemon; 139 0 : mhd_task = prepare_daemon (); 140 0 : } 141 : 142 : 143 : struct MHD_Daemon * 144 0 : TALER_MHD_daemon_stop (void) 145 : { 146 : struct MHD_Daemon *ret; 147 : 148 0 : if (NULL != mhd_task) 149 : { 150 0 : GNUNET_SCHEDULER_cancel (mhd_task); 151 0 : mhd_task = NULL; 152 : } 153 0 : ret = mhd; 154 0 : mhd = NULL; 155 0 : return ret; 156 : } 157 : 158 : 159 : void 160 0 : TALER_MHD_daemon_trigger (void) 161 : { 162 0 : if (NULL != mhd_task) 163 : { 164 0 : GNUNET_SCHEDULER_cancel (mhd_task); 165 0 : mhd_task = NULL; 166 0 : run_daemon (NULL); 167 : } 168 : else 169 : { 170 0 : triggered = true; 171 : } 172 0 : } 173 : 174 : 175 : /* end of mhd_run.c */