- fix
[oweals/gnunet.git] / src / util / connection.c
index ba129661b604be48fe213e16448c6540bd2e008e..ea35b04e1da009501ca49835bfe001195c48f106 100644 (file)
@@ -247,7 +247,14 @@ struct GNUNET_CONNECTION_Handle
    * termination as a signal (because only then will the leaked
    * socket be freed!)
    */
-  int16_t persist;
+  int8_t persist;
+
+  /**
+   * Usually 0.  Set to 1 if this handle is in used and should
+   * 'GNUNET_CONNECTION_destroy' be called right now, the action needs
+   * to be deferred by setting it to -1.
+   */
+  int8_t destroy_later;
 
 };
 
@@ -556,6 +563,7 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task);
 
   /* signal errors for jobs that used to wait on the connection */
+  connection->destroy_later = 1;
   if (NULL != connection->receiver)
     signal_receive_error (connection, ECONNREFUSED);
   if (NULL != connection->nth.notify_ready)
@@ -565,6 +573,14 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
     connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
     signal_transmit_error (connection, ECONNREFUSED);
   }
+  if (-1 == connection->destroy_later)
+  {
+    /* do it now */
+    connection->destroy_later = 0;
+    GNUNET_CONNECTION_destroy (connection);
+    return;
+  }
+  connection->destroy_later = 0;
 }
 
 
@@ -744,10 +760,6 @@ try_connect_using_address (void *cls, const struct sockaddr *addr,
   {
     /* maybe refused / unsupported address, try next */
     LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
-#if 0
-    LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to connect to `%s' (%p)\n"),
-         GNUNET_a2s (ap->addr, ap->addrlen), connection);
-#endif
     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
     GNUNET_free (ap);
     return;
@@ -852,8 +864,9 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
     GNUNET_free (connection);
     return NULL;
   }
-  if (GNUNET_OK !=
-      GNUNET_NETWORK_socket_connect (connection->sock, connection->addr, connection->addrlen))
+  if ( (GNUNET_OK !=
+       GNUNET_NETWORK_socket_connect (connection->sock, connection->addr, connection->addrlen)) &&
+       (EINPROGRESS != errno) )
   {
     /* Just return; we expect everything to work eventually so don't fail HARD */
     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
@@ -941,6 +954,11 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
 {
   struct AddressProbe *pos;
 
+  if (0 != connection->destroy_later)
+  {
+    connection->destroy_later = -1;
+    return;
+  }
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
   GNUNET_assert (NULL == connection->nth.notify_ready);
   GNUNET_assert (NULL == connection->receiver);
@@ -1110,7 +1128,7 @@ GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t m
 void *
 GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
 {
-  if (GNUNET_SCHEDULER_NO_TASK == connection->read_task)
+  if (GNUNET_SCHEDULER_NO_TASK != connection->read_task)
   {
     GNUNET_assert (connection == GNUNET_SCHEDULER_cancel (connection->read_task));
     connection->read_task = GNUNET_SCHEDULER_NO_TASK;
@@ -1135,14 +1153,22 @@ process_notify (struct GNUNET_CONNECTION_Handle *connection)
   size_t size;
   GNUNET_CONNECTION_TransmitReadyNotify notify;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "process_notify is running\n");
+
   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task);
   if (NULL == (notify = connection->nth.notify_ready))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Noone to notify\n");
     return GNUNET_NO;
+  }
   used = connection->write_buffer_off - connection->write_buffer_pos;
   avail = connection->write_buffer_size - used;
   size = connection->nth.notify_size;
   if (size > avail)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Not enough buffer\n");
     return GNUNET_NO;
+  }
   connection->nth.notify_ready = NULL;
   if (connection->write_buffer_size - connection->write_buffer_off < size)
   {