gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-twister] branch master updated: port state engine fi


From: gnunet
Subject: [GNUnet-SVN] [taler-twister] branch master updated: port state engine fixes from GNS proxy to twister service
Date: Thu, 20 Sep 2018 17:46:45 +0200

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

grothoff pushed a commit to branch master
in repository twister.

The following commit(s) were added to refs/heads/master by this push:
     new d4f3a2e  port state engine fixes from GNS proxy to twister service
d4f3a2e is described below

commit d4f3a2eed509d1719b58031a9fa74cd2e669327f
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Sep 20 17:46:42 2018 +0200

    port state engine fixes from GNS proxy to twister service
---
 m4/libtool.m4                       |  12 +--
 src/twister/taler-twister-service.c | 200 ++++++++++++++++++++++++++++--------
 2 files changed, 166 insertions(+), 46 deletions(-)

diff --git a/m4/libtool.m4 b/m4/libtool.m4
index ee80844..e67ed69 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -6438,7 +6438,7 @@ if test yes != "$_lt_caught_CXX_error"; then
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | 
$GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | 
$GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -6813,7 +6813,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v 
conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z 
in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; 
done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v 
conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z 
in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; 
done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -6878,7 +6878,7 @@ if test yes != "$_lt_caught_CXX_error"; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v 
conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z 
in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; 
done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v 
conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z 
in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; 
done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -7217,7 +7217,7 @@ if test yes != "$_lt_caught_CXX_error"; then
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 
2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 
2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -7301,7 +7301,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v 
conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v 
conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -7312,7 +7312,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 
2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 
2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              fi
 
              _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
diff --git a/src/twister/taler-twister-service.c 
b/src/twister/taler-twister-service.c
index d12bc67..071241d 100644
--- a/src/twister/taler-twister-service.c
+++ b/src/twister/taler-twister-service.c
@@ -40,12 +40,13 @@
 #include <microhttpd.h>
 #include <taler/taler_util.h>
 
-
-/** 
- * We allow X runs of the progress callback before
- * declaring the upload callback dead.
+/**
+ * Keep logic of Marcello's fix for #5337? Unclear how it works, and
+ * may be superceeded by subsequent revisions, but kept for now to
+ * easily identify what might fix the issue (until CG can actually
+ * reproduce it nicely).
  */
-#define DOWNLOAD_PAUSED_TIMES_MAX 10
+#define MARCELLO_FIX 1
 
 /**
  * Log curl error.
@@ -76,6 +77,11 @@ enum RequestState
   REQUEST_STATE_UPLOAD_STARTED,
 
   /**
+   * We're done with the upload from MHD.
+   */
+  REQUEST_STATE_UPLOAD_DONE,
+
+  /**
    * We've finished uploading data via CURL and can now download.
    */
   REQUEST_STATE_DOWNLOAD_STARTED,
@@ -122,6 +128,21 @@ struct HttpRequest
 {
 
   /**
+   * Kept in DLL.
+   */
+  struct HttpRequest *prev;
+
+  /**
+   * Kept in DLL.
+   */
+  struct HttpRequest *next;
+
+  /**
+   * MHD request that triggered us.
+   */
+  struct MHD_Connection *con;
+
+  /**
    * Client socket read task
    */
   struct GNUNET_SCHEDULER_Task *rtask;
@@ -153,7 +174,7 @@ struct HttpRequest
   char *url;
 
   /**
-   * JSON we use to parse payloads (in both directions). 
+   * JSON we use to parse payloads (in both directions).
    */
   json_t *json;
 
@@ -198,15 +219,22 @@ struct HttpRequest
   enum RequestState state;
 
   /**
-   * Indicates that the download callback is sleeping.
+   * Did we suspend MHD processing?
    */
-  int download_paused;
+  int suspended;
 
   /**
+   * Did we pause CURL processing?
+   */
+  int curl_paused;
+
+#if MARCELLO_FIX
+  /**
    * Indicates that the Web server returned a "Connection: close"
    * header line.
    */
   int connection_closed;
+#endif
 };
 
 
@@ -216,7 +244,17 @@ struct HttpRequest
 /**
  * The cURL download task (curl multi API).
  */
-static struct GNUNET_SCHEDULER_Task * curl_download_task;
+static struct GNUNET_SCHEDULER_Task *curl_download_task;
+
+/**
+ * DLL of active HTTP requests.
+ */
+static struct HttpRequest *hr_head;
+
+/**
+ * DLL of active HTTP requests.
+ */
+static struct HttpRequest *hr_tail;
 
 /**
  * The cURL multi handle
@@ -395,17 +433,17 @@ curl_check_hdr (void *buffer,
     *tok = '\0';
   if (NULL != (tok = strchr (hdr_val, '\t')))
     *tok = '\0';
-
-  if (0 == strcasecmp (hdr_type,
-                      MHD_HTTP_HEADER_CONNECTION)
-    && (0 == strcasecmp (hdr_val,
-                         "close")))
+#if MARCELLO_FIX
+  if ( (0 == strcasecmp (hdr_type,
+                         MHD_HTTP_HEADER_CONNECTION) &&
+        (0 == strcasecmp (hdr_val,
+                          "close")) ) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Server wants to close the TCP connection\n");
     hr->connection_closed = GNUNET_YES;
   }
-
+#endif
 
   if (0 != strlen (hdr_val)) /* Rely in MHD to set those */
   {
@@ -463,6 +501,9 @@ create_mhd_response_from_hr (struct HttpRequest *hr)
                          hr->io_len,
                          JSON_DECODE_ANY,
                          &error);
+  GNUNET_assert (GNUNET_YES == hr->suspended);
+  MHD_resume_connection (hr->con);
+  hr->suspended = GNUNET_NO;
   return GNUNET_OK;
 }
 
@@ -489,11 +530,23 @@ curl_download_cb (void *ptr,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Curl download proceeding\n");
 
-  if (REQUEST_STATE_DOWNLOAD_STARTED != hr->state) 
+  if ( (REQUEST_STATE_UPLOAD_STARTED == hr->state) ||
+       (REQUEST_STATE_UPLOAD_DONE == hr->state) )
+  {
+    /* we're still not done with the upload, do not yet
+       start the download, the IO buffer is still full
+       with upload data. */
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Pausing CURL download, waiting for UPLOAD to finish\n");
+    hr->curl_paused = GNUNET_YES;
+    return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */
+  }
+
+ if (REQUEST_STATE_DOWNLOAD_STARTED != hr->state)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Download callback goes to sleep\n");
-    hr->download_paused = GNUNET_YES;
+    hr->curl_paused = GNUNET_YES;
     return CURL_WRITEFUNC_PAUSE;
   }
 
@@ -509,7 +562,6 @@ curl_download_cb (void *ptr,
                       GNUNET_MAX (total + hr->io_len,
                                   hr->io_size * 2 + 1024));
   }
-
   GNUNET_memcpy (&hr->io_buf[hr->io_len],
                  ptr,
                  total);
@@ -541,18 +593,33 @@ curl_upload_cb (void *buf,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Upload cb is working...\n");
 
-  if (REQUEST_STATE_UPLOAD_STARTED != hr->state)
+  if ( (0 == hr->io_len) &&
+       (REQUEST_STATE_UPLOAD_DONE != hr->state) )
   {
-    GNUNET_break (0);
-    return CURL_READFUNC_ABORT;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Pausing CURL UPLOAD, need more data\n");
+    return CURL_READFUNC_PAUSE;
   }
-  if (0 == hr->io_len)
+  if ( (0 == hr->io_len) &&
+       (REQUEST_STATE_UPLOAD_DONE == hr->state) )
   {
     hr->state = REQUEST_STATE_DOWNLOAD_STARTED;
+    if (GNUNET_YES == hr->curl_paused)
+    {
+      hr->curl_paused = GNUNET_NO;
+      curl_easy_pause (hr->curl,
+                      CURLPAUSE_CONT);
+    }
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Completed CURL UPLOAD\n");
     return 0; /* upload finished, can now download */
   }
+  if ( (REQUEST_STATE_UPLOAD_STARTED != hr->state) &&
+       (REQUEST_STATE_UPLOAD_DONE != hr->state) )
+  {
+    GNUNET_break (0);
+    return CURL_READFUNC_ABORT;
+  }
   to_copy = GNUNET_MIN (hr->io_len,
                         len);
   GNUNET_memcpy (buf,
@@ -697,7 +764,7 @@ curl_task_download (void *cls)
            CURLINFO_PRIVATE,
            (char **) &hr ));
 
-      if   (NULL == hr)
+      if (NULL == hr)
       {
         GNUNET_break (0);
         continue;
@@ -719,6 +786,12 @@ curl_task_download (void *cls)
                 GNUNET_assert (GNUNET_OK ==
                               create_mhd_response_from_hr (hr));
               hr->state = REQUEST_STATE_DOWNLOAD_DONE;
+             if (GNUNET_YES == hr->suspended)
+             {
+               MHD_resume_connection (hr->con);
+               hr->suspended = GNUNET_NO;
+             }
+              run_mhd_now ();
               break;
             default:
               GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -727,13 +800,18 @@ curl_task_download (void *cls)
               /* FIXME: indicate error somehow?
                * close MHD connection badly as well? */
               hr->state = REQUEST_STATE_DOWNLOAD_DONE;
+             if (GNUNET_YES == hr->suspended)
+             {
+               MHD_resume_connection (hr->con);
+               hr->suspended = GNUNET_NO;
+             }
+              run_mhd_now ();
               break;
           }
           if (NULL == hr->response)
             hr->response = curl_failure_response;
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Curl request for `%s' finished,"
-                      " response generated\n",
+                     "Curl request for `%s' finished, response generated\n",
                      hr->url);
          run_mhd_now ();
           break;
@@ -765,6 +843,7 @@ curl_task_download (void *cls)
   curl_download_prepare ();
 }
 
+
 static int
 curl_progress_cb (void *clientp,
                   double dltotal,
@@ -776,21 +855,22 @@ curl_progress_cb (void *clientp,
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Progress callback..\n");
-
-  if ((GNUNET_YES == hr->download_paused)
-    && (GNUNET_YES == hr->connection_closed))
+#if MARCELLO_FIX
+  if ( (GNUNET_YES == hr->curl_paused) &&
+       (GNUNET_YES == hr->connection_closed) )
   {
     hr->state = REQUEST_STATE_DOWNLOAD_STARTED;
-    hr->download_paused = GNUNET_NO;
+    hr->curl_paused = GNUNET_NO;
     hr->connection_closed = GNUNET_NO;
     curl_easy_pause (hr->curl, CURLPAUSE_CONT);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Unpausing the download callback\n");
   }
-
+#endif
   return CURLE_OK;
 }
 
+
 /* *************** MHD response generation ******************* */
 
 
@@ -1173,8 +1253,8 @@ delete_object (struct MHD_Connection *con,
  *        value to the number of bytes NOT processed;
  * @param con_cls pointer to location where we store the
  *        'struct Request'
- * @return MHD_YES if the connection was handled successfully,
- *         MHD_NO if the socket must be closed due to a serious
+ * @return #MHD_YES if the connection was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serious
  *         error while handling the request
  */
 static int
@@ -1238,11 +1318,24 @@ create_response (void *cls,
 
     hr->io_len += *upload_data_size;
     *upload_data_size = 0;
+    if (GNUNET_YES == hr->curl_paused)
+    {
+      hr->curl_paused = GNUNET_NO;
+      curl_easy_pause (hr->curl,
+                       CURLPAUSE_CONT);
+    }
     return MHD_YES;
   }
 
-  /* Upload (*from the client*) finished,
-   * generate curl request to the proxied service.  */
+  /* Upload (*from the client*) finished */
+  if (REQUEST_STATE_UPLOAD_STARTED == hr->state)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Finished processing UPLOAD\n");
+    hr->state = REQUEST_STATE_UPLOAD_DONE;
+  }
+
+  /* generate curl request to the proxied service. */
   if (NULL == hr->curl)
   {
     /* Malform request body.  Note, this flag will be
@@ -1273,7 +1366,7 @@ create_response (void *cls,
       json_dumpb (hr->json,
                   hr->io_buf,
 /* Existing io_len is enough to accomodate this encoding.  */
-                  hr->io_len, 
+                  hr->io_len,
                   JSON_COMPACT);
 
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1298,7 +1391,7 @@ create_response (void *cls,
       json_dumpb (hr->json,
                   hr->io_buf,
 /* Existing io_len is enough to accomodate this encoding.  */
-                  hr->io_len, 
+                  hr->io_len,
                   JSON_COMPACT);
 
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1549,7 +1642,11 @@ create_response (void *cls,
   }
 
   if (REQUEST_STATE_DOWNLOAD_DONE != hr->state)
+  {
+    MHD_suspend_connection (con);
+    hr->suspended = GNUNET_YES;
     return MHD_YES; /* wait for curl */
+  }
 
   if (0 != hack_response_code)
   {
@@ -1570,7 +1667,8 @@ create_response (void *cls,
   {
     TALER_LOG_DEBUG ("Will delete path: %s\n",
                      delete_path);
-    delete_object (con, hr);
+    delete_object (con,
+                   hr);
   }
 
   if ('\0' != modify_path_dl[0])
@@ -1583,7 +1681,6 @@ create_response (void *cls,
                    modify_path_dl);
   }
 
-
   if (NULL != hr->json)
   {
     TALER_LOG_DEBUG ("Parsing final JSON.\n");
@@ -1623,6 +1720,7 @@ create_response (void *cls,
                                            header->type,
                                            header->value));
   }
+  run_mhd_now ();
   return MHD_queue_response (con,
                              hr->response_code,
                              hr->response);
@@ -1700,6 +1798,9 @@ mhd_completed_cb (void *cls,
 
   GNUNET_free (hr->url);
   GNUNET_free_non_null (hr->io_buf);
+  GNUNET_CONTAINER_DLL_remove (hr_head,
+                               hr_tail,
+                               hr);
   GNUNET_free (hr);
   *con_cls = NULL;
 }
@@ -1739,7 +1840,11 @@ mhd_log_callback (void *cls,
   }
 
   hr = GNUNET_new (struct HttpRequest);
+  hr->con = connection;
   hr->url = GNUNET_strdup (url);
+  GNUNET_CONTAINER_DLL_insert (hr_head,
+                               hr_tail,
+                               hr);
   return hr;
 }
 
@@ -1886,6 +1991,17 @@ do_shutdown (void *cls)
   (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Shutting down...\n");
+  /* MHD requires resuming before destroying the daemons */
+  for (struct HttpRequest *hr = hr_head;
+       NULL != hr;
+       hr = hr->next)
+  {
+    if (hr->suspended)
+    {
+      hr->suspended = GNUNET_NO;
+      MHD_resume_connection (hr->con);
+    }
+  }
   kill_httpd ();
   if (NULL != curl_multi)
   {
@@ -2046,6 +2162,7 @@ send_acknowledgement (struct GNUNET_SERVICE_Client *c)
   GNUNET_SERVICE_client_continue (c);
 }
 
+
 /**
  * Control handler for malforming responses.
  *
@@ -2063,6 +2180,7 @@ handle_malform (void *cls,
   send_acknowledgement (c);
 }
 
+
 /**
  * Control handler for malforming requests.
  *
@@ -2080,6 +2198,7 @@ handle_malform_upload (void *cls,
   send_acknowledgement (c);
 }
 
+
 /**
  * Control handler for deleting JSON response objects
  *
@@ -2094,7 +2213,6 @@ handle_modify_path_dl (void *cls,
 
   strcpy (modify_path_dl, src->path);
   strcpy (modify_value, src->value);
-
   send_acknowledgement (c);
 }
 
@@ -2114,10 +2232,10 @@ handle_modify_path_ul (void *cls,
 
   strcpy (modify_path_ul, src->path);
   strcpy (modify_value, src->value);
-
   send_acknowledgement (c);
 }
 
+
 /**
  * Control handler for flipping JSON strings into response objects
  *
@@ -2151,6 +2269,7 @@ handle_flip_path_ul (void *cls,
   send_acknowledgement (c);
 }
 
+
 /**
  * Control handler for deleting JSON fields from response objects
  *
@@ -2167,6 +2286,7 @@ handle_delete_path (void *cls,
   send_acknowledgement (c);
 }
 
+
 /**
  * Control handler for changing the response code
  *

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



reply via email to

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