gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-merchant] branch master updated: fix FIXME on proper


From: gnunet
Subject: [GNUnet-SVN] [taler-merchant] branch master updated: fix FIXME on properly terminating MHD, resuming suspended connections before stopping the HTTPD
Date: Sun, 14 May 2017 14:13:45 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 6004b80  fix FIXME on properly terminating MHD, resuming suspended 
connections before stopping the HTTPD
6004b80 is described below

commit 6004b808cd65c2e7bc99423d3c58d23d58995eb6
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun May 14 14:13:43 2017 +0200

    fix FIXME on properly terminating MHD, resuming suspended connections 
before stopping the HTTPD
---
 src/backend/taler-merchant-httpd.c     |   5 +-
 src/backend/taler-merchant-httpd_pay.c | 156 ++++++++++++++++++++++-----------
 src/backend/taler-merchant-httpd_pay.h |  11 ++-
 3 files changed, 115 insertions(+), 57 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index 1abee1e..0efa7eb 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -286,10 +286,7 @@ do_shutdown (void *cls)
     GNUNET_SCHEDULER_cancel (mhd_task);
     mhd_task = NULL;
   }
-  /* FIXME: MHD API requires us to resume all suspended
-     connections before we do this, but /pay currently
-     suspends connections without giving us a way to
-     enumerate / resume them... */
+  MH_force_pc_resume ();
   if (NULL != mhd)
   {
     MHD_stop_daemon (mhd);
diff --git a/src/backend/taler-merchant-httpd_pay.c 
b/src/backend/taler-merchant-httpd_pay.c
index 5649894..307690e 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -119,6 +119,16 @@ struct PayContext
   struct TM_HandlerContext hc;
 
   /**
+   * Stored in a DLL.
+   */
+  struct PayContext *next;
+
+  /**
+   * Stored in a DLL.
+   */
+  struct PayContext *prev;
+
+  /**
    * Array with @e coins_cnt coins we are despositing.
    */
   struct DepositConfirmation *dc;
@@ -129,6 +139,29 @@ struct PayContext
   struct MHD_Connection *connection;
 
   /**
+   * Instance of the payment's instance (in JSON format)
+   */
+  struct MerchantInstance *mi;
+
+  /**
+   * Proposal data for the proposal that is being
+   * payed for in this context.
+   */
+  json_t *proposal_data;
+
+  /**
+   * Task called when the (suspended) processing for
+   * the /pay request times out.
+   * Happens when we don't get a response from the exchange.
+   */
+  struct GNUNET_SCHEDULER_Task *timeout_task;
+
+  /**
+   * Response to return, NULL if we don't have one yet.
+   */
+  struct MHD_Response *response;
+
+  /**
    * Handle to the exchange that we are doing the payment with.
    * (initially NULL while @e fo is trying to find a exchange).
    */
@@ -157,6 +190,17 @@ struct PayContext
   const char *order_id;
 
   /**
+   * Hashed proposal.
+   */
+  struct GNUNET_HashCode h_proposal_data;
+
+  /**
+   * "H_wire" from @e proposal_data.  Used to identify the instance's
+   * wire transfer method.
+   */
+  struct GNUNET_HashCode h_wire;
+
+  /**
    * Maximum fee the merchant is willing to pay, from @e root.
    * Note that IF the total fee of the exchange is higher, that is
    * acceptable to the merchant if the customer is willing to
@@ -184,21 +228,19 @@ struct PayContext
   struct TALER_Amount max_wire_fee;
 
   /**
-   * Number of transactions that the wire fees are expected to be
-   * amortized over.  Never zero, defaults (conservateively) to 1.
-   * May be higher if merchants expect many small transactions to
-   * be aggregated and thus wire fees to be reasonably amortized
-   * due to aggregation.
-   */
-  uint32_t wire_fee_amortization;
-
-  /**
    * Amount from @e root.  This is the amount the merchant expects
    * to make, minus @e max_fee.
    */
   struct TALER_Amount amount;
 
   /**
+   * Wire transfer deadline. How soon would the merchant like the
+   * wire transfer to be executed? (Can be given by the frontend
+   * or be determined by our configuration via #wire_transfer_delay.)
+   */
+  struct GNUNET_TIME_Absolute wire_transfer_deadline;
+
+  /**
    * Timestamp from @e proposal_data.
    */
   struct GNUNET_TIME_Absolute timestamp;
@@ -214,27 +256,13 @@ struct PayContext
   struct GNUNET_TIME_Absolute pay_deadline;
 
   /**
-   * Hashed proposal.
-   */
-  struct GNUNET_HashCode h_proposal_data;
-
-  /**
-   * "H_wire" from @e proposal_data.  Used to identify the instance's
-   * wire transfer method.
-   */
-  struct GNUNET_HashCode h_wire;
-
-  /**
-   * Wire transfer deadline. How soon would the merchant like the
-   * wire transfer to be executed? (Can be given by the frontend
-   * or be determined by our configuration via #wire_transfer_delay.)
-   */
-  struct GNUNET_TIME_Absolute wire_transfer_deadline;
-
-  /**
-   * Response to return, NULL if we don't have one yet.
+   * Number of transactions that the wire fees are expected to be
+   * amortized over.  Never zero, defaults (conservateively) to 1.
+   * May be higher if merchants expect many small transactions to
+   * be aggregated and thus wire fees to be reasonably amortized
+   * due to aggregation.
    */
-  struct MHD_Response *response;
+  uint32_t wire_fee_amortization;
 
   /**
    * Number of coins this payment is made of.  Length
@@ -257,13 +285,6 @@ struct PayContext
   unsigned int response_code;
 
   /**
-   * Task called when the (suspended) processing for
-   * the /pay request times out.
-   * Happens when we don't get a response from the exchange.
-   */
-  struct GNUNET_SCHEDULER_Task *timeout_task;
-
-  /**
    * #GNUNET_NO if the transaction is not in our database,
    * #GNUNET_YES if the transaction is known to our database,
    * #GNUNET_SYSERR if the transaction ID is used for a different
@@ -272,17 +293,42 @@ struct PayContext
   int transaction_exists;
 
   /**
-   * Instance of the payment's instance (in JSON format)
+   * #GNUNET_NO if the @e connection was not suspended,
+   * #GNUNET_YES if the @e connection was suspended,
+   * #GNUNET_SYSERR if @e connection was resumed to as
+   * part of #MH_force_pc_resume during shutdown.
    */
-  struct MerchantInstance *mi;
+  int suspended;
+};
 
-  /**
-   * Proposal data for the proposal that is being
-   * payed for in this context.
-   */
-  json_t *proposal_data;
 
-};
+/**
+ * Head of active pay context DLL.
+ */
+static struct PayContext *pc_head;
+
+/**
+ * Tail of active pay context DLL.
+ */
+static struct PayContext *pc_tail;
+
+
+/**
+ * Force all pay contexts to be resumed as we are about
+ * to shut down MHD.
+ */
+void
+MH_force_pc_resume ()
+{
+  for (struct PayContext *pc = pc_head; NULL != pc; pc = pc->next)
+  {
+    if (GNUNET_YES == pc->suspended)
+    {
+      pc->suspended = GNUNET_SYSERR;
+      MHD_resume_connection (pc->connection);
+    }
+  }
+}
 
 
 /**
@@ -309,6 +355,8 @@ resume_pay_with_response (struct PayContext *pc,
     GNUNET_SCHEDULER_cancel (pc->timeout_task);
     pc->timeout_task = NULL;
   }
+  GNUNET_assert (GNUNET_YES == pc->suspended);
+  pc->suspended = GNUNET_NO;
   MHD_resume_connection (pc->connection);
   TMH_trigger_daemon (); /* we resumed, kick MHD */
 }
@@ -479,16 +527,14 @@ static void
 pay_context_cleanup (struct TM_HandlerContext *hc)
 {
   struct PayContext *pc = (struct PayContext *) hc;
-  unsigned int i;
 
   if (NULL != pc->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (pc->timeout_task);
     pc->timeout_task = NULL;
   }
-
   TMH_PARSE_post_cleanup_callback (pc->json_parse_context);
-  for (i=0;i<pc->coins_cnt;i++)
+  for (unsigned int i=0;i<pc->coins_cnt;i++)
   {
     struct DepositConfirmation *dc = &pc->dc[i];
 
@@ -529,6 +575,9 @@ pay_context_cleanup (struct TM_HandlerContext *hc)
     json_decref (pc->proposal_data);
     pc->proposal_data = NULL;
   }
+  GNUNET_CONTAINER_DLL_remove (pc_head,
+                               pc_tail,
+                               pc);
   GNUNET_free (pc);
 }
 
@@ -1262,12 +1311,11 @@ handler_pay_json (struct MHD_Connection *connection,
   {
     struct MHD_Response *resp;
     int ret;
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Payment succeeded in the past; take short cut"
-                " and accept immediately.\n");
 
     /* Payment succeeded in the past; take short cut
        and accept immediately */
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Payment succeeded in the past; taking short cut");
     resp = MHD_create_response_from_buffer (0,
                                            NULL,
                                            MHD_RESPMEM_PERSISTENT);
@@ -1300,6 +1348,7 @@ handler_pay_json (struct MHD_Connection *connection,
   if (GNUNET_NO == pc->transaction_exists)
   {
     struct GNUNET_TIME_Absolute now;
+
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Dealing with new transaction '%s'\n",
                 GNUNET_h2s (&pc->h_proposal_data));
@@ -1309,12 +1358,11 @@ handler_pay_json (struct MHD_Connection *connection,
     {
       /* Time expired, we don't accept this payment now! */
       const char *pd_str;
-      pd_str = GNUNET_STRINGS_absolute_time_to_string (pc->pay_deadline);
 
+      pd_str = GNUNET_STRINGS_absolute_time_to_string (pc->pay_deadline);
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "Attempt to get coins for expired contract. Deadline: 
'%s'\n",
                  pd_str);
-
       return TMH_RESPONSE_reply_bad_request (connection,
                                             TALER_EC_PAY_OFFER_EXPIRED,
                                              "The time to pay for this 
contract has expired.");
@@ -1341,6 +1389,7 @@ handler_pay_json (struct MHD_Connection *connection,
   }
 
   MHD_suspend_connection (connection);
+  pc->suspended = GNUNET_YES;
 
   /* Find the responsible exchange, this may take a while... */
   pc->fo = TMH_EXCHANGES_find_exchange (pc->chosen_exchange,
@@ -1390,6 +1439,9 @@ MH_handler_pay (struct TMH_RequestHandler *rh,
   if (NULL == *connection_cls)
   {
     pc = GNUNET_new (struct PayContext);
+    GNUNET_CONTAINER_DLL_insert (pc_head,
+                                 pc_tail,
+                                 pc);
     pc->hc.cc = &pay_context_cleanup;
     pc->connection = connection;
     *connection_cls = pc;
diff --git a/src/backend/taler-merchant-httpd_pay.h 
b/src/backend/taler-merchant-httpd_pay.h
index 124a9d9..d4f4958 100644
--- a/src/backend/taler-merchant-httpd_pay.h
+++ b/src/backend/taler-merchant-httpd_pay.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2014, 2015 GNUnet e.V.
+  (C) 2014-2017 GNUnet e.V.
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -23,6 +23,15 @@
 #include <microhttpd.h>
 #include "taler-merchant-httpd.h"
 
+
+/**
+ * Force all pay contexts to be resumed as we are about
+ * to shut down MHD.
+ */
+void
+MH_force_pc_resume (void);
+
+
 /**
  * Manage a payment
  *

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]