From c13810ba2c43a63504269c646b438c2fd157d4ff Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 20 Oct 2021 16:01:11 +0200 Subject: fix #7049: immediate restart of MHD when already running --- src/bank-lib/bank_api_credit.c | 11 +++- src/bank-lib/bank_api_debit.c | 9 +++- src/bank-lib/fakebank.c | 114 +++++++++++++++++++++++++-------------- src/include/taler_fakebank_lib.h | 6 +-- 4 files changed, 94 insertions(+), 46 deletions(-) diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c index 91fbe506d..eff2ad971 100644 --- a/src/bank-lib/bank_api_credit.c +++ b/src/bank-lib/bank_api_credit.c @@ -29,6 +29,13 @@ #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 */ @@ -66,7 +73,7 @@ struct TALER_BANK_CreditHistoryHandle * were set, * #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, const json_t *history) { @@ -305,7 +312,7 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx, GNUNET_break (CURLE_OK == curl_easy_setopt (eh, CURLOPT_TIMEOUT_MS, - (long) tms)); + (long) tms + GRACE_PERIOD_MS)); } hh->job = GNUNET_CURL_job_add2 (ctx, eh, diff --git a/src/bank-lib/bank_api_debit.c b/src/bank-lib/bank_api_debit.c index 8cca0cc50..339dfef40 100644 --- a/src/bank-lib/bank_api_debit.c +++ b/src/bank-lib/bank_api_debit.c @@ -29,6 +29,13 @@ #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 */ @@ -307,7 +314,7 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx, GNUNET_break (CURLE_OK == curl_easy_setopt (eh, CURLOPT_TIMEOUT_MS, - (long) tms)); + (long) tms + GRACE_PERIOD_MS)); } hh->job = GNUNET_CURL_job_add2 (ctx, eh, diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c index 2a53419b6..24878bdd6 100644 --- a/src/bank-lib/fakebank.c +++ b/src/bank-lib/fakebank.c @@ -425,6 +425,11 @@ struct TALER_FAKEBANK_Handle */ bool in_shutdown; + /** + * Should we run MHD immediately again? + */ + bool mhd_again; + #if EPOLL_SUPPORT /** * Boxed @e mhd_fd. @@ -474,6 +479,7 @@ lp_trigger (struct LongPoller *lp, lp); MHD_resume_connection (lp->conn); GNUNET_free (lp); + h->mhd_again = true; if (NULL != h->mhd_task) GNUNET_SCHEDULER_cancel (h->mhd_task); h->mhd_task = @@ -508,12 +514,8 @@ lp_expiration_thread (void *cls) { GNUNET_assert (lp == GNUNET_CONTAINER_heap_remove_root (h->lp_heap)); - GNUNET_assert (0 == - pthread_mutex_lock (&h->big_lock)); lp_trigger (lp, h); - GNUNET_assert (0 == - pthread_mutex_unlock (&h->big_lock)); lp = GNUNET_CONTAINER_heap_peek (h->lp_heap); } 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, const struct TALER_Amount *want_amount, 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, const struct TALER_Amount *want_amount, const char *want_debit, @@ -866,36 +868,6 @@ post_transaction (struct TALER_FAKEBANK_Handle *h, ca->in_tail, 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 == pthread_mutex_unlock (&h->big_lock)); 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. * @@ -1030,6 +1050,8 @@ make_transfer ( TALER_B2S (subject), exchange_base_url); *ret_row_id = t->row_id; + notify_transaction (h, + t); return GNUNET_OK; } @@ -1124,11 +1146,13 @@ make_admin_transfer ( TALER_amount2s (amount), TALER_B2S (reserve_pub), (unsigned long long) t->row_id); + notify_transaction (h, + t); return GNUNET_OK; } -int +enum GNUNET_GenericReturnValue TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h) { for (uint64_t i = 0; iram_limit; i++) @@ -1852,6 +1876,7 @@ handle_debit_history (struct TALER_FAKEBANK_Handle *h, connection, &ha))) { + GNUNET_break_op (0); return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES; } if (&special_ptr == *con_cls) @@ -2056,13 +2081,15 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h, enum GNUNET_GenericReturnValue ret; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Handling /history/incoming connection %p\n", - connection); + "Handling /history/incoming connection %p (%d)\n", + connection, + (*con_cls == &special_ptr)); if (GNUNET_OK != (ret = parse_history_common_args (h, connection, &ha))) { + GNUNET_break_op (0); return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES; } if (&special_ptr == *con_cls) @@ -2107,6 +2134,8 @@ handle_credit_history (struct TALER_FAKEBANK_Handle *h, if ( (NULL == t) || overflow) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "No transactions available, suspending request\n"); GNUNET_free (credit_payto); if (GNUNET_TIME_relative_is_zero (ha.lp_timeout) && (0 < ha.delta)) @@ -2478,7 +2507,12 @@ run_mhd (void *cls) struct TALER_FAKEBANK_Handle *h = cls; 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); } diff --git a/src/include/taler_fakebank_lib.h b/src/include/taler_fakebank_lib.h index dc6ba1dac..16135a4d7 100644 --- a/src/include/taler_fakebank_lib.h +++ b/src/include/taler_fakebank_lib.h @@ -87,7 +87,7 @@ TALER_FAKEBANK_start2 (uint16_t port, * @param h bank instance * @return #GNUNET_OK on success */ -int +enum GNUNET_GenericReturnValue 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 * @return #GNUNET_OK on success */ -int +enum GNUNET_GenericReturnValue TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h, const struct TALER_Amount *want_amount, 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 * @return #GNUNET_OK on success */ -int +enum GNUNET_GenericReturnValue TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h, const struct TALER_Amount *want_amount, const char *want_debit, -- cgit v1.2.3