aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2014-05-17 17:39:50 +0000
committerFlorian Dold <florian.dold@gmail.com>2014-05-17 17:39:50 +0000
commit4c1a6478b3ae43bb009addd982390a5db949913b (patch)
tree16c336c3f3a7315fc22a508d45fd0fc7129c74c8
parent7eb684ec9f93d52ebae09729fcf01c16580b5cb9 (diff)
downloadgnunet-4c1a6478b3ae43bb009addd982390a5db949913b.tar.gz
gnunet-4c1a6478b3ae43bb009addd982390a5db949913b.zip
add missing cancel implementation for MQ
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/util/mq.c63
-rw-r--r--src/util/test_mq_client.c12
3 files changed, 75 insertions, 1 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d6774cacd..fa710ee58 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -232,6 +232,7 @@ src/peerinfo-tool/gnunet-peerinfo_plugins.c
232src/peerstore/gnunet-peerstore.c 232src/peerstore/gnunet-peerstore.c
233src/peerstore/gnunet-service-peerstore.c 233src/peerstore/gnunet-service-peerstore.c
234src/peerstore/peerstore_api.c 234src/peerstore/peerstore_api.c
235src/peerstore/peerstore_common.c
235src/peerstore/plugin_peerstore_sqlite.c 236src/peerstore/plugin_peerstore_sqlite.c
236src/postgres/postgres.c 237src/postgres/postgres.c
237src/psyc/gnunet-service-psyc.c 238src/psyc/gnunet-service-psyc.c
diff --git a/src/util/mq.c b/src/util/mq.c
index a4691ff2c..941a5c43e 100644
--- a/src/util/mq.c
+++ b/src/util/mq.c
@@ -94,6 +94,11 @@ struct GNUNET_MQ_Handle
94 GNUNET_MQ_DestroyImpl destroy_impl; 94 GNUNET_MQ_DestroyImpl destroy_impl;
95 95
96 /** 96 /**
97 * Implementation-dependent send cancel function
98 */
99 GNUNET_MQ_CancelImpl cancel_impl;
100
101 /**
97 * Implementation-specific state 102 * Implementation-specific state
98 */ 103 */
99 void *impl_state; 104 void *impl_state;
@@ -242,6 +247,8 @@ GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
242 GNUNET_assert (NULL != mq); 247 GNUNET_assert (NULL != mq);
243 GNUNET_assert (NULL == ev->parent_queue); 248 GNUNET_assert (NULL == ev->parent_queue);
244 249
250 ev->parent_queue = mq;
251
245 /* is the implementation busy? queue it! */ 252 /* is the implementation busy? queue it! */
246 if (NULL != mq->current_envelope) 253 if (NULL != mq->current_envelope)
247 { 254 {
@@ -276,6 +283,7 @@ impl_send_continue (void *cls,
276 * a message */ 283 * a message */
277 current_envelope = mq->current_envelope; 284 current_envelope = mq->current_envelope;
278 GNUNET_assert (NULL != current_envelope); 285 GNUNET_assert (NULL != current_envelope);
286 current_envelope->parent_queue = NULL;
279 if (NULL == mq->envelope_head) 287 if (NULL == mq->envelope_head)
280 { 288 {
281 mq->current_envelope = NULL; 289 mq->current_envelope = NULL;
@@ -337,6 +345,7 @@ GNUNET_MQ_queue_for_callbacks (GNUNET_MQ_SendImpl send,
337 mq = GNUNET_new (struct GNUNET_MQ_Handle); 345 mq = GNUNET_new (struct GNUNET_MQ_Handle);
338 mq->send_impl = send; 346 mq->send_impl = send;
339 mq->destroy_impl = destroy; 347 mq->destroy_impl = destroy;
348 mq->cancel_impl = cancel;
340 mq->handlers = handlers; 349 mq->handlers = handlers;
341 mq->handlers_cls = cls; 350 mq->handlers_cls = cls;
342 mq->impl_state = impl_state; 351 mq->impl_state = impl_state;
@@ -613,6 +622,17 @@ connection_client_send_impl (struct GNUNET_MQ_Handle *mq,
613} 622}
614 623
615 624
625static void
626connection_client_cancel_impl (struct GNUNET_MQ_Handle *mq,
627 void *impl_state)
628{
629 struct ClientConnectionState *state = impl_state;
630 GNUNET_assert (NULL != state->th);
631 GNUNET_CLIENT_notify_transmit_ready_cancel (state->th);
632 state->th = NULL;
633}
634
635
616struct GNUNET_MQ_Handle * 636struct GNUNET_MQ_Handle *
617GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection, 637GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
618 const struct GNUNET_MQ_MessageHandler *handlers, 638 const struct GNUNET_MQ_MessageHandler *handlers,
@@ -633,6 +653,7 @@ GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connecti
633 mq->impl_state = state; 653 mq->impl_state = state;
634 mq->send_impl = connection_client_send_impl; 654 mq->send_impl = connection_client_send_impl;
635 mq->destroy_impl = connection_client_destroy_impl; 655 mq->destroy_impl = connection_client_destroy_impl;
656 mq->cancel_impl = connection_client_cancel_impl;
636 if (NULL != handlers) 657 if (NULL != handlers)
637 state->receive_requested = GNUNET_YES; 658 state->receive_requested = GNUNET_YES;
638 659
@@ -777,3 +798,45 @@ GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh, uint16_t ba
777} 798}
778 799
779 800
801/**
802 * Cancel sending the message. Message must have been sent with
803 * #GNUNET_MQ_send before. May not be called after the notify sent
804 * callback has been called
805 *
806 * @param ev queued envelope to cancel
807 */
808void
809GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev)
810{
811 struct GNUNET_MQ_Handle *mq = ev->parent_queue;
812
813 GNUNET_assert (NULL != mq);
814 GNUNET_assert (NULL != mq->cancel_impl);
815
816 if (mq->current_envelope == ev) {
817 // complex case, we already started with transmitting
818 // the message
819 mq->cancel_impl (mq, mq->impl_state);
820 // continue sending the next message, if any
821 if (NULL == mq->envelope_head)
822 {
823 mq->current_envelope = NULL;
824 }
825 else
826 {
827 mq->current_envelope = mq->envelope_head;
828 GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
829 mq->envelope_tail,
830 mq->current_envelope);
831 mq->send_impl (mq, mq->current_envelope->mh, mq->impl_state);
832 }
833 } else {
834 // simple case, message is still waiting in the queue
835 GNUNET_CONTAINER_DLL_remove (mq->envelope_head, mq->envelope_tail, ev);
836 }
837
838 ev->parent_queue = NULL;
839 ev->mh = NULL;
840 GNUNET_free (ev);
841}
842
diff --git a/src/util/test_mq_client.c b/src/util/test_mq_client.c
index 1c1bcee86..88113ffd0 100644
--- a/src/util/test_mq_client.c
+++ b/src/util/test_mq_client.c
@@ -102,6 +102,12 @@ send_cb (void *cls)
102 notify = GNUNET_YES; 102 notify = GNUNET_YES;
103} 103}
104 104
105static void
106send_trap_cb (void *cls)
107{
108 GNUNET_abort ();
109}
110
105 111
106static void 112static void
107test_mq (struct GNUNET_CLIENT_Connection *client) 113test_mq (struct GNUNET_CLIENT_Connection *client)
@@ -116,10 +122,14 @@ test_mq (struct GNUNET_CLIENT_Connection *client)
116 GNUNET_MQ_send (mq, mqm); 122 GNUNET_MQ_send (mq, mqm);
117 123
118 mqm = GNUNET_MQ_msg_header (MY_TYPE); 124 mqm = GNUNET_MQ_msg_header (MY_TYPE);
125 GNUNET_MQ_notify_sent (mqm, send_trap_cb, NULL);
126 GNUNET_MQ_send (mq, mqm);
127 GNUNET_MQ_send_cancel (mqm);
128
129 mqm = GNUNET_MQ_msg_header (MY_TYPE);
119 GNUNET_MQ_notify_sent (mqm, send_cb, NULL); 130 GNUNET_MQ_notify_sent (mqm, send_cb, NULL);
120 GNUNET_MQ_send (mq, mqm); 131 GNUNET_MQ_send (mq, mqm);
121 132
122 /* FIXME: add a message that will be canceled */
123} 133}
124 134
125 135