}
+/**
+ * Call a callback once the envelope has been sent, that is,
+ * sending it can not be canceled anymore.
+ * There can be only one notify sent callback per envelope.
+ *
+ * @param ev message to call the notify callback for
+ * @param cb the notify callback
+ * @param cb_cls closure for the callback
+ */
void
GNUNET_MQ_notify_sent (struct GNUNET_MQ_Envelope *mqm,
GNUNET_MQ_NotifyCallback cb,
- void *cls)
+ void *cb_cls)
{
mqm->sent_cb = cb;
- mqm->sent_cls = cls;
+ mqm->sent_cls = cb_cls;
}
+/**
+ * Handle we return for callbacks registered to be
+ * notified when #GNUNET_MQ_destroy() is called on a queue.
+ */
+struct GNUNET_MQ_DestroyNotificationHandle
+{
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_MQ_DestroyNotificationHandle *prev;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_MQ_DestroyNotificationHandle *next;
+
+ /**
+ * Queue to notify about.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Function to call.
+ */
+ GNUNET_SCHEDULER_TaskCallback cb;
+
+ /**
+ * Closure for @e cb.
+ */
+ void *cb_cls;
+};
+
+
+/**
+ * Destroy the message queue.
+ *
+ * @param mq message queue to destroy
+ */
void
GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq)
{
+ struct GNUNET_MQ_DestroyNotificationHandle *dnh;
+
if (NULL != mq->destroy_impl)
{
mq->destroy_impl (mq, mq->impl_state);
GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
mq->envelope_tail,
ev);
+ GNUNET_assert (0 < mq->queue_length);
mq->queue_length--;
GNUNET_MQ_discard (ev);
}
mq->current_envelope->parent_queue = NULL;
GNUNET_MQ_discard (mq->current_envelope);
mq->current_envelope = NULL;
+ GNUNET_assert (0 < mq->queue_length);
mq->queue_length--;
}
GNUNET_assert (0 == mq->queue_length);
+ while (NULL != (dnh = mq->dnh_head))
+ {
+ dnh->cb (dnh->cb_cls);
+ GNUNET_MQ_destroy_notify_cancel (dnh);
+ }
if (NULL != mq->assoc_map)
{
GNUNET_CONTAINER_multihashmap32_destroy (mq->assoc_map);
{
// complex case, we already started with transmitting
// the message
+ GNUNET_assert (0 < mq->queue_length);
mq->queue_length--;
mq->cancel_impl (mq,
mq->impl_state);
GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
mq->envelope_tail,
mq->current_envelope);
- mq->queue_length--;
mq->send_impl (mq,
mq->current_envelope->mh,
mq->impl_state);
GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
mq->envelope_tail,
ev);
+ GNUNET_assert (0 < mq->queue_length);
mq->queue_length--;
}
}
-/**
- * Handle we return for callbacks registered to be
- * notified when #GNUNET_MQ_destroy() is called on a queue.
- */
-struct GNUNET_MQ_DestroyNotificationHandle
-{
- /**
- * Kept in a DLL.
- */
- struct GNUNET_MQ_DestroyNotificationHandle *prev;
-
- /**
- * Kept in a DLL.
- */
- struct GNUNET_MQ_DestroyNotificationHandle *next;
-
- /**
- * Queue to notify about.
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Function to call.
- */
- GNUNET_SCHEDULER_TaskCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-};
-
-
/**
* Register function to be called whenever @a mq is being
* destroyed.
GNUNET_MQ_destroy_notify_cancel (struct GNUNET_MQ_DestroyNotificationHandle *dnh)
{
struct GNUNET_MQ_Handle *mq = dnh->mq;
-
+
GNUNET_CONTAINER_DLL_remove (mq->dnh_head,
mq->dnh_tail,
dnh);