176 lines
4.1 KiB
C
176 lines
4.1 KiB
C
/*
|
|
This file is part of TALER
|
|
Copyright (C) 2019-2021 Taler Systems SA
|
|
|
|
TALER is free software; you can redistribute it and/or modify it under the
|
|
terms of the GNU Affero General Public License as published by the Free Software
|
|
Foundation; either version 3, or (at your option) any later version.
|
|
|
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License along with
|
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
/**
|
|
* @file mhd_run.c
|
|
* @brief API for running an MHD daemon with the
|
|
* GNUnet scheduler
|
|
* @author Christian Grothoff
|
|
*/
|
|
#include "platform.h"
|
|
#include <gnunet/gnunet_util_lib.h>
|
|
#include <gnunet/gnunet_json_lib.h>
|
|
#include <jansson.h>
|
|
#include <microhttpd.h>
|
|
#include "taler_util.h"
|
|
#include "taler_mhd_lib.h"
|
|
|
|
|
|
/**
|
|
* Set to true if we should immediately MHD_run() again.
|
|
*/
|
|
static bool triggered;
|
|
|
|
/**
|
|
* Task running the HTTP server.
|
|
*/
|
|
static struct GNUNET_SCHEDULER_Task *mhd_task;
|
|
|
|
/**
|
|
* The MHD daemon we are running.
|
|
*/
|
|
static struct MHD_Daemon *mhd;
|
|
|
|
|
|
/**
|
|
* Function that queries MHD's select sets and
|
|
* starts the task waiting for them.
|
|
*/
|
|
static struct GNUNET_SCHEDULER_Task *
|
|
prepare_daemon (void);
|
|
|
|
|
|
/**
|
|
* Call MHD to process pending requests and then go back
|
|
* and schedule the next run.
|
|
*
|
|
* @param cls NULL
|
|
*/
|
|
static void
|
|
run_daemon (void *cls)
|
|
{
|
|
(void) cls;
|
|
mhd_task = NULL;
|
|
do {
|
|
triggered = false;
|
|
GNUNET_assert (MHD_YES ==
|
|
MHD_run (mhd));
|
|
} while (triggered);
|
|
mhd_task = prepare_daemon ();
|
|
}
|
|
|
|
|
|
/**
|
|
* Function that queries MHD's select sets and starts the task waiting for
|
|
* them.
|
|
*
|
|
* @return task handle for the MHD task.
|
|
*/
|
|
static struct GNUNET_SCHEDULER_Task *
|
|
prepare_daemon (void)
|
|
{
|
|
struct GNUNET_SCHEDULER_Task *ret;
|
|
fd_set rs;
|
|
fd_set ws;
|
|
fd_set es;
|
|
struct GNUNET_NETWORK_FDSet *wrs;
|
|
struct GNUNET_NETWORK_FDSet *wws;
|
|
int max;
|
|
MHD_UNSIGNED_LONG_LONG timeout;
|
|
int haveto;
|
|
struct GNUNET_TIME_Relative tv;
|
|
|
|
FD_ZERO (&rs);
|
|
FD_ZERO (&ws);
|
|
FD_ZERO (&es);
|
|
wrs = GNUNET_NETWORK_fdset_create ();
|
|
wws = GNUNET_NETWORK_fdset_create ();
|
|
max = -1;
|
|
GNUNET_assert (MHD_YES ==
|
|
MHD_get_fdset (mhd,
|
|
&rs,
|
|
&ws,
|
|
&es,
|
|
&max));
|
|
haveto = MHD_get_timeout (mhd,
|
|
&timeout);
|
|
if (haveto == MHD_YES)
|
|
tv = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
|
|
timeout);
|
|
else
|
|
tv = GNUNET_TIME_UNIT_FOREVER_REL;
|
|
GNUNET_NETWORK_fdset_copy_native (wrs,
|
|
&rs,
|
|
max + 1);
|
|
GNUNET_NETWORK_fdset_copy_native (wws,
|
|
&ws,
|
|
max + 1);
|
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
"Adding run_daemon select task\n");
|
|
ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
|
|
tv,
|
|
wrs,
|
|
wws,
|
|
&run_daemon,
|
|
NULL);
|
|
GNUNET_NETWORK_fdset_destroy (wrs);
|
|
GNUNET_NETWORK_fdset_destroy (wws);
|
|
return ret;
|
|
}
|
|
|
|
|
|
void
|
|
TALER_MHD_daemon_start (struct MHD_Daemon *daemon)
|
|
{
|
|
GNUNET_assert (NULL == mhd);
|
|
mhd = daemon;
|
|
mhd_task = prepare_daemon ();
|
|
}
|
|
|
|
|
|
struct MHD_Daemon *
|
|
TALER_MHD_daemon_stop (void)
|
|
{
|
|
struct MHD_Daemon *ret;
|
|
|
|
if (NULL != mhd_task)
|
|
{
|
|
GNUNET_SCHEDULER_cancel (mhd_task);
|
|
mhd_task = NULL;
|
|
}
|
|
ret = mhd;
|
|
mhd = NULL;
|
|
return ret;
|
|
}
|
|
|
|
|
|
void
|
|
TALER_MHD_daemon_trigger (void)
|
|
{
|
|
if (NULL != mhd_task)
|
|
{
|
|
GNUNET_SCHEDULER_cancel (mhd_task);
|
|
mhd_task = NULL;
|
|
run_daemon (NULL);
|
|
}
|
|
else
|
|
{
|
|
triggered = true;
|
|
}
|
|
}
|
|
|
|
|
|
/* end of mhd_run.c */
|