* 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;
};
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)
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;
}
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Connection succeeded, starting with receiving data (%p)\n",
connection);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->read_task);
connection->read_task =
GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
(connection->receive_timeout), connection->sock,
{
/* 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;
{
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);
*
* @param connection connection handle
* @param max maximum number of bytes to read
- * @param timeout maximum amount of time to wait (use -1 for "forever")
+ * @param timeout maximum amount of time to wait
* @param receiver function to call with received data
* @param receiver_cls closure for receiver
*/
{
GNUNET_assert ((GNUNET_SCHEDULER_NO_TASK == connection->read_task) &&
(NULL == connection->receiver));
+ GNUNET_assert (NULL != receiver);
connection->receiver = receiver;
connection->receiver_cls = receiver_cls;
connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
}
if ((NULL == connection->dns_active) && (NULL == connection->ap_head))
{
+ connection->receiver = NULL;
receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT);
return;
}
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;