* Did the application call #GNUNET_MQ_env_set_options()?
*/
int have_custom_options;
-
+
};
*/
struct GNUNET_SCHEDULER_Task *continue_task;
+ /**
+ * Functions to call on queue destruction; kept in a DLL.
+ */
+ struct GNUNET_MQ_DestroyNotificationHandle *dnh_head;
+
+ /**
+ * Functions to call on queue destruction; kept in a DLL.
+ */
+ struct GNUNET_MQ_DestroyNotificationHandle *dnh_tail;
+
/**
* Additional options buffer set for this queue by
* #GNUNET_MQ_set_options(). Default is 0.
*/
const void *default_extra;
-
+
/**
* Flags that were set for this queue by
* #GNUNET_MQ_set_options(). Default is 0.
GNUNET_assert (NULL != mq);
GNUNET_assert (NULL == ev->parent_queue);
+ mq->queue_length++;
ev->parent_queue = mq;
/* is the implementation busy? queue it! */
if (NULL != mq->current_envelope)
GNUNET_CONTAINER_DLL_insert_tail (mq->envelope_head,
mq->envelope_tail,
ev);
- mq->queue_length++;
return;
}
mq->current_envelope = ev;
- mq->send_impl (mq, ev->mh, mq->impl_state);
+ mq->send_impl (mq,
+ ev->mh,
+ mq->impl_state);
}
current_envelope = mq->current_envelope;
GNUNET_assert (NULL != current_envelope);
current_envelope->parent_queue = NULL;
+ GNUNET_assert (0 < mq->queue_length);
+ mq->queue_length--;
if (NULL == mq->envelope_head)
{
mq->current_envelope = NULL;
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);
mq->queue_length--;
GNUNET_MQ_discard (ev);
}
- GNUNET_assert (0 == mq->queue_length);
if (NULL != mq->current_envelope)
{
/* we can only discard envelopes that
mq->current_envelope->parent_queue = NULL;
GNUNET_MQ_discard (mq->current_envelope);
mq->current_envelope = NULL;
+ mq->queue_length--;
}
+ GNUNET_assert (0 == mq->queue_length);
if (NULL != mq->assoc_map)
{
GNUNET_CONTAINER_multihashmap32_destroy (mq->assoc_map);
{
// complex case, we already started with transmitting
// the message
+ mq->queue_length--;
mq->cancel_impl (mq,
mq->impl_state);
// continue sending the next message, if any
/**
- * Function to obtain the current envelope from
- * within #GNUNET_MQ_SendImpl implementations.
+ * Function to obtain the current envelope
+ * from within #GNUNET_MQ_SendImpl implementations.
*
* @param mq message queue to interrogate
* @return the current envelope
}
+/**
+ * Function to obtain the last envelope in the queue.
+ *
+ * @param mq message queue to interrogate
+ * @return the last envelope in the queue
+ */
+struct GNUNET_MQ_Envelope *
+GNUNET_MQ_get_last_envelope (struct GNUNET_MQ_Handle *mq)
+{
+ if (NULL != mq->envelope_tail)
+ return mq->envelope_tail;
+
+ return mq->current_envelope;
+}
+
+
/**
* Set application-specific options for this envelope.
* Overrides the options set for the queue with
uint64_t *flags)
{
struct GNUNET_MQ_Handle *mq = env->parent_queue;
-
+
if (GNUNET_YES == env->have_custom_options)
{
*flags = env->flags;
}
+/**
+ * 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.
+ *
+ * @param mq message queue to watch
+ * @param cb function to call on @a mq destruction
+ * @param cb_cls closure for @a cb
+ * @return handle for #GNUNET_MQ_destroy_notify_cancel().
+ */
+struct GNUNET_MQ_DestroyNotificationHandle *
+GNUNET_MQ_destroy_notify (struct GNUNET_MQ_Handle *mq,
+ GNUNET_SCHEDULER_TaskCallback cb,
+ void *cb_cls)
+{
+ struct GNUNET_MQ_DestroyNotificationHandle *dnh;
+
+ dnh = GNUNET_new (struct GNUNET_MQ_DestroyNotificationHandle);
+ dnh->mq = mq;
+ dnh->cb = cb;
+ dnh->cb_cls = cb_cls;
+ GNUNET_CONTAINER_DLL_insert (mq->dnh_head,
+ mq->dnh_tail,
+ dnh);
+ return dnh;
+}
+
+
+/**
+ * Cancel registration from #GNUNET_MQ_destroy_notify().
+ *
+ * @param dnh handle for registration to cancel
+ */
+void
+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);
+ GNUNET_free (dnh);
+}
+
+
/* end of mq.c */