aboutsummaryrefslogtreecommitdiff
path: root/src/mhd/mhd_run.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mhd/mhd_run.c')
-rw-r--r--src/mhd/mhd_run.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/mhd/mhd_run.c b/src/mhd/mhd_run.c
new file mode 100644
index 000000000..8a3c369b9
--- /dev/null
+++ b/src/mhd/mhd_run.c
@@ -0,0 +1,174 @@
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 if we should immediately #MHD_run again.
33 */
34static int triggered;
35
36/**
37 * Task running the HTTP server.
38 */
39static struct GNUNET_SCHEDULER_Task *mhd_task;
40
41/**
42 * The MHD daemon we are running.
43 */
44static struct MHD_Daemon *mhd;
45
46
47/**
48 * Function that queries MHD's select sets and
49 * starts the task waiting for them.
50 */
51static struct GNUNET_SCHEDULER_Task *
52prepare_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 */
61static void
62run_daemon (void *cls)
63{
64 mhd_task = NULL;
65 do {
66 triggered = 0;
67 GNUNET_assert (MHD_YES ==
68 MHD_run (mhd));
69 } while (0 != triggered);
70 mhd_task = prepare_daemon ();
71}
72
73
74/**
75 * Function that queries MHD's select sets and starts the task waiting for
76 * them.
77 *
78 * @return task handle for the MHD task.
79 */
80static struct GNUNET_SCHEDULER_Task *
81prepare_daemon (void)
82{
83 struct GNUNET_SCHEDULER_Task *ret;
84 fd_set rs;
85 fd_set ws;
86 fd_set es;
87 struct GNUNET_NETWORK_FDSet *wrs;
88 struct GNUNET_NETWORK_FDSet *wws;
89 int max;
90 MHD_UNSIGNED_LONG_LONG timeout;
91 int haveto;
92 struct GNUNET_TIME_Relative tv;
93
94 FD_ZERO (&rs);
95 FD_ZERO (&ws);
96 FD_ZERO (&es);
97 wrs = GNUNET_NETWORK_fdset_create ();
98 wws = GNUNET_NETWORK_fdset_create ();
99 max = -1;
100 GNUNET_assert (MHD_YES ==
101 MHD_get_fdset (mhd,
102 &rs,
103 &ws,
104 &es,
105 &max));
106 haveto = MHD_get_timeout (mhd,
107 &timeout);
108 if (haveto == MHD_YES)
109 tv = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
110 timeout);
111 else
112 tv = GNUNET_TIME_UNIT_FOREVER_REL;
113 GNUNET_NETWORK_fdset_copy_native (wrs,
114 &rs,
115 max + 1);
116 GNUNET_NETWORK_fdset_copy_native (wws,
117 &ws,
118 max + 1);
119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
120 "Adding run_daemon select task\n");
121 ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
122 tv,
123 wrs,
124 wws,
125 &run_daemon,
126 NULL);
127 GNUNET_NETWORK_fdset_destroy (wrs);
128 GNUNET_NETWORK_fdset_destroy (wws);
129 return ret;
130}
131
132
133void
134TALER_MHD_daemon_start (struct MHD_Daemon *daemon)
135{
136 GNUNET_assert (NULL == mhd);
137 mhd = daemon;
138 mhd_task = prepare_daemon ();
139}
140
141
142struct MHD_Daemon *
143TALER_MHD_daemon_stop (void)
144{
145 struct MHD_Daemon *ret;
146
147 if (NULL != mhd_task)
148 {
149 GNUNET_SCHEDULER_cancel (mhd_task);
150 mhd_task = NULL;
151 }
152 ret = mhd;
153 mhd = NULL;
154 return ret;
155}
156
157
158void
159TALER_MHD_daemon_trigger (void)
160{
161 if (NULL != mhd_task)
162 {
163 GNUNET_SCHEDULER_cancel (mhd_task);
164 mhd_task = NULL;
165 run_daemon (NULL);
166 }
167 else
168 {
169 triggered = 1;
170 }
171}
172
173
174/* end of mhd_run.c */