do propper delaying of notification past return
authorChristian Grothoff <christian@grothoff.org>
Sat, 24 Oct 2009 22:17:58 +0000 (22:17 +0000)
committerChristian Grothoff <christian@grothoff.org>
Sat, 24 Oct 2009 22:17:58 +0000 (22:17 +0000)
src/util/client.c
src/util/connection.c

index 75d90b074c482991b3bd42b9e632928f196e34e2..d5358cab4677db059d5290b978df784c0e481d4a 100644 (file)
@@ -674,6 +674,7 @@ client_notify (void *cls,
   size_t ret;
   struct GNUNET_TIME_Relative delay;
   
+  th->th = NULL;
   if (buf == NULL)
     {
       delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
@@ -691,7 +692,6 @@ client_notify (void *cls,
       /* auto-retry */
       GNUNET_CONNECTION_destroy (th->sock->sock);
       th->sock->sock = NULL;
-      th->th = NULL;
       delay = GNUNET_TIME_relative_min (delay, GNUNET_TIME_UNIT_SECONDS);
       th->task = GNUNET_SCHEDULER_add_delayed (th->sock->sched,
                                               GNUNET_NO,
@@ -771,8 +771,11 @@ void
 GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle *th)
 {
   if (th->task != GNUNET_SCHEDULER_NO_TASK)
-    GNUNET_SCHEDULER_cancel (th->sock->sched,
-                            th->task);
+    {
+      GNUNET_break (NULL == th->th);
+      GNUNET_SCHEDULER_cancel (th->sock->sched,
+                              th->task);      
+    }
   else
     {
       GNUNET_break (NULL != th->th);
index 980f8c07248bd983d8ad176ca9decf95428fb940..2999831a3526a423d2183a4e5ade35409f3be8c6 100644 (file)
@@ -1293,6 +1293,32 @@ transmit_timeout (void *cls,
 }
 
 
+/**
+ * Task invoked by the scheduler when we failed to connect
+ * at the time of being asked to transmit.
+ *
+ * This task notifies the client about the error.
+ */
+static void
+connect_error (void *cls,
+              const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_CONNECTION_Handle *sock = cls;
+  GNUNET_CONNECTION_TransmitReadyNotify notify;
+
+#if DEBUG_CONNECTION
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Transmission request of size %u fails, connection failed (%p).\n",
+             sock->nth.notify_size,
+             sock);
+#endif
+  sock->write_task = GNUNET_SCHEDULER_NO_TASK;
+  notify = sock->nth.notify_ready;
+  sock->nth.notify_ready = NULL;
+  notify (sock->nth.notify_ready_cls, 0, NULL);
+}
+
+
 static void
 transmit_error (struct GNUNET_CONNECTION_Handle *sock)
 {
@@ -1455,20 +1481,6 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle
     return NULL;
   GNUNET_assert (notify != NULL);
   GNUNET_assert (sock->write_buffer_size >= size);
-
-  if ( (sock->sock == NULL) &&
-       (sock->ap_head == NULL) &&
-       (sock->dns_active != GNUNET_YES) )
-    {
-#if DEBUG_CONNECTION
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "Transmission request of size %u fails, connection failed (%p).\n",
-                 size,
-                 sock);
-#endif
-      notify (notify_cls, 0, NULL);
-      return &sock->nth;
-    }
   GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size);
   GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size);
   GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_off);
@@ -1478,6 +1490,19 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle
   sock->nth.notify_size = size;
   sock->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->nth.timeout_task);
+  if ( (sock->sock == NULL) &&
+       (sock->ap_head == NULL) &&
+       (sock->dns_active != GNUNET_YES) )
+    {     
+      sock->write_task = GNUNET_SCHEDULER_add_delayed (sock->sched,
+                                                      GNUNET_NO,
+                                                      GNUNET_SCHEDULER_PRIORITY_KEEP,
+                                                      GNUNET_SCHEDULER_NO_TASK,
+                                                      GNUNET_TIME_UNIT_ZERO,
+                                                      &connect_error,
+                                                      sock);
+      return &sock->nth;
+    }
   if (GNUNET_SCHEDULER_NO_TASK != sock->write_task)
     return &sock->nth;
   if (sock->sock != NULL)