fix #7049: immediate restart of MHD when already running

This commit is contained in:
Christian Grothoff 2021-10-20 16:01:11 +02:00
parent c75a3a1921
commit c13810ba2c
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 94 additions and 46 deletions

View File

@ -29,6 +29,13 @@
#include "taler_signatures.h" #include "taler_signatures.h"
/**
* How much longer than the application-specified timeout
* do we wait (giving the server a chance to respond)?
*/
#define GRACE_PERIOD_MS 1000
/** /**
* @brief A /history/incoming Handle * @brief A /history/incoming Handle
*/ */
@ -66,7 +73,7 @@ struct TALER_BANK_CreditHistoryHandle
* were set, * were set,
* #GNUNET_SYSERR if there was a protocol violation in @a history * #GNUNET_SYSERR if there was a protocol violation in @a history
*/ */
static int static enum GNUNET_GenericReturnValue
parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh, parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh,
const json_t *history) const json_t *history)
{ {
@ -305,7 +312,7 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
GNUNET_break (CURLE_OK == GNUNET_break (CURLE_OK ==
curl_easy_setopt (eh, curl_easy_setopt (eh,
CURLOPT_TIMEOUT_MS, CURLOPT_TIMEOUT_MS,
(long) tms)); (long) tms + GRACE_PERIOD_MS));
} }
hh->job = GNUNET_CURL_job_add2 (ctx, hh->job = GNUNET_CURL_job_add2 (ctx,
eh, eh,

View File

@ -29,6 +29,13 @@
#include "taler_signatures.h" #include "taler_signatures.h"
/**
* How much longer than the application-specified timeout
* do we wait (giving the server a chance to respond)?
*/
#define GRACE_PERIOD_MS 1000
/** /**
* @brief A /history/outgoing Handle * @brief A /history/outgoing Handle
*/ */
@ -307,7 +314,7 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
GNUNET_break (CURLE_OK == GNUNET_break (CURLE_OK ==
curl_easy_setopt (eh, curl_easy_setopt (eh,
CURLOPT_TIMEOUT_MS, CURLOPT_TIMEOUT_MS,
(long) tms)); (long) tms + GRACE_PERIOD_MS));
} }
hh->job = GNUNET_CURL_job_add2 (ctx, hh->job = GNUNET_CURL_job_add2 (ctx,
eh, eh,

View File

@ -425,6 +425,11 @@ struct TALER_FAKEBANK_Handle
*/ */
bool in_shutdown; bool in_shutdown;
/**
* Should we run MHD immediately again?
*/
bool mhd_again;
#if EPOLL_SUPPORT #if EPOLL_SUPPORT
/** /**
* Boxed @e mhd_fd. * Boxed @e mhd_fd.
@ -474,6 +479,7 @@ lp_trigger (struct LongPoller *lp,
lp); lp);
MHD_resume_connection (lp->conn); MHD_resume_connection (lp->conn);
GNUNET_free (lp); GNUNET_free (lp);
h->mhd_again = true;
if (NULL != h->mhd_task) if (NULL != h->mhd_task)
GNUNET_SCHEDULER_cancel (h->mhd_task); GNUNET_SCHEDULER_cancel (h->mhd_task);
h->mhd_task = h->mhd_task =
@ -508,12 +514,8 @@ lp_expiration_thread (void *cls)
{ {
GNUNET_assert (lp == GNUNET_assert (lp ==
GNUNET_CONTAINER_heap_remove_root (h->lp_heap)); GNUNET_CONTAINER_heap_remove_root (h->lp_heap));
GNUNET_assert (0 ==
pthread_mutex_lock (&h->big_lock));
lp_trigger (lp, lp_trigger (lp,
h); h);
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
lp = GNUNET_CONTAINER_heap_peek (h->lp_heap); lp = GNUNET_CONTAINER_heap_peek (h->lp_heap);
} }
if (NULL != lp) if (NULL != lp)
@ -674,7 +676,7 @@ check_log (struct TALER_FAKEBANK_Handle *h)
} }
int enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h, TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h,
const struct TALER_Amount *want_amount, const struct TALER_Amount *want_amount,
const char *want_debit, const char *want_debit,
@ -722,7 +724,7 @@ TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h,
} }
int enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h, TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h,
const struct TALER_Amount *want_amount, const struct TALER_Amount *want_amount,
const char *want_debit, const char *want_debit,
@ -866,36 +868,6 @@ post_transaction (struct TALER_FAKEBANK_Handle *h,
ca->in_tail, ca->in_tail,
old); old);
} }
{
struct LongPoller *nxt;
for (struct LongPoller *lp = debit_acc->lp_head;
NULL != lp;
lp = nxt)
{
nxt = lp->next;
if (LP_DEBIT == lp->type)
{
GNUNET_assert (lp ==
GNUNET_CONTAINER_heap_remove_node (lp->hn));
lp_trigger (lp,
h);
}
}
for (struct LongPoller *lp = credit_acc->lp_head;
NULL != lp;
lp = nxt)
{
nxt = lp->next;
if (LP_CREDIT == lp->type)
{
GNUNET_assert (lp ==
GNUNET_CONTAINER_heap_remove_node (lp->hn));
lp_trigger (lp,
h);
}
}
}
GNUNET_assert (0 == GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock)); pthread_mutex_unlock (&h->big_lock));
if ( (NULL != old) && if ( (NULL != old) &&
@ -914,6 +886,54 @@ post_transaction (struct TALER_FAKEBANK_Handle *h,
} }
/**
* Trigger long pollers that might have been waiting
* for @a t.
*
* @param h fakebank handle
* @param t transaction to notify on
*/
static void
notify_transaction (struct TALER_FAKEBANK_Handle *h,
struct Transaction *t)
{
struct Account *debit_acc = t->debit_account;
struct Account *credit_acc = t->credit_account;
struct LongPoller *nxt;
GNUNET_assert (0 ==
pthread_mutex_lock (&h->big_lock));
for (struct LongPoller *lp = debit_acc->lp_head;
NULL != lp;
lp = nxt)
{
nxt = lp->next;
if (LP_DEBIT == lp->type)
{
GNUNET_assert (lp ==
GNUNET_CONTAINER_heap_remove_node (lp->hn));
lp_trigger (lp,
h);
}
}
for (struct LongPoller *lp = credit_acc->lp_head;
NULL != lp;
lp = nxt)
{
nxt = lp->next;
if (LP_CREDIT == lp->type)
{
GNUNET_assert (lp ==
GNUNET_CONTAINER_heap_remove_node (lp->hn));
lp_trigger (lp,
h);
}
}
GNUNET_assert (0 ==
pthread_mutex_unlock (&h->big_lock));
}
/** /**
* Tell the fakebank to create another wire transfer *from* an exchange. * Tell the fakebank to create another wire transfer *from* an exchange.
* *
@ -1030,6 +1050,8 @@ make_transfer (
TALER_B2S (subject), TALER_B2S (subject),
exchange_base_url); exchange_base_url);
*ret_row_id = t->row_id; *ret_row_id = t->row_id;
notify_transaction (h,
t);
return GNUNET_OK; return GNUNET_OK;
} }
@ -1124,11 +1146,13 @@ make_admin_transfer (
TALER_amount2s (amount), TALER_amount2s (amount),
TALER_B2S (reserve_pub), TALER_B2S (reserve_pub),
(unsigned long long) t->row_id); (unsigned long long) t->row_id);
notify_transaction (h,
t);
return GNUNET_OK; return GNUNET_OK;
} }
int enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h) TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h)
{ {
for (uint64_t i = 0; i<h->ram_limit; i++) for (uint64_t i = 0; i<h->ram_limit; i++)
@ -1852,6 +1876,7 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h,
connection, connection,
&ha))) &ha)))
{ {
GNUNET_break_op (0);
return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES;
} }
if (&special_ptr == *con_cls) if (&special_ptr == *con_cls)
@ -2056,13 +2081,15 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h,
enum GNUNET_GenericReturnValue ret; enum GNUNET_GenericReturnValue ret;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Handling /history/incoming connection %p\n", "Handling /history/incoming connection %p (%d)\n",
connection); connection,
(*con_cls == &special_ptr));
if (GNUNET_OK != if (GNUNET_OK !=
(ret = parse_history_common_args (h, (ret = parse_history_common_args (h,
connection, connection,
&ha))) &ha)))
{ {
GNUNET_break_op (0);
return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES;
} }
if (&special_ptr == *con_cls) if (&special_ptr == *con_cls)
@ -2107,6 +2134,8 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h,
if ( (NULL == t) || if ( (NULL == t) ||
overflow) overflow)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"No transactions available, suspending request\n");
GNUNET_free (credit_payto); GNUNET_free (credit_payto);
if (GNUNET_TIME_relative_is_zero (ha.lp_timeout) && if (GNUNET_TIME_relative_is_zero (ha.lp_timeout) &&
(0 < ha.delta)) (0 < ha.delta))
@ -2478,7 +2507,12 @@ run_mhd (void *cls)
struct TALER_FAKEBANK_Handle *h = cls; struct TALER_FAKEBANK_Handle *h = cls;
h->mhd_task = NULL; h->mhd_task = NULL;
MHD_run (h->mhd_bank); h->mhd_again = true;
while (h->mhd_again)
{
h->mhd_again = false;
MHD_run (h->mhd_bank);
}
schedule_httpd (h); schedule_httpd (h);
} }

View File

@ -87,7 +87,7 @@ TALER_FAKEBANK_start2 (uint16_t port,
* @param h bank instance * @param h bank instance
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
int enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h); TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h);
@ -109,7 +109,7 @@ TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h);
* @param[out] wtid set to the wire transfer identifier * @param[out] wtid set to the wire transfer identifier
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
int enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h, TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h,
const struct TALER_Amount *want_amount, const struct TALER_Amount *want_amount,
const char *want_debit, const char *want_debit,
@ -133,7 +133,7 @@ TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h,
* @param reserve_pub reserve public key expected in wire subject * @param reserve_pub reserve public key expected in wire subject
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
int enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h, TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h,
const struct TALER_Amount *want_amount, const struct TALER_Amount *want_amount,
const char *want_debit, const char *want_debit,