aboutsummaryrefslogtreecommitdiff
path: root/src/lockmanager
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-06-21 11:35:54 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-06-21 11:35:54 +0000
commit7b350ba3726b1476ed446ea939c95456829084e4 (patch)
tree09aa6f19fa79a581923328495af0979a6f8adad2 /src/lockmanager
parentcbe53564d0bb4b42d5549854c6f16cc1b7781257 (diff)
downloadgnunet-7b350ba3726b1476ed446ea939c95456829084e4.tar.gz
gnunet-7b350ba3726b1476ed446ea939c95456829084e4.zip
-fixing #2440 - cancel messages if RELEASE called when ACQUIRE still in queue
Diffstat (limited to 'src/lockmanager')
-rw-r--r--src/lockmanager/lockmanager_api.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c
index 7a47da65b..d648d1c5c 100644
--- a/src/lockmanager/lockmanager_api.c
+++ b/src/lockmanager/lockmanager_api.c
@@ -149,6 +149,11 @@ struct GNUNET_LOCKMANAGER_LockingRequest
149 * The status of the lock 149 * The status of the lock
150 */ 150 */
151 enum GNUNET_LOCKMANAGER_Status status; 151 enum GNUNET_LOCKMANAGER_Status status;
152
153 /**
154 * set to GNUNET_YES if acquire message for this lock is till in messga queue
155 */
156 int acquire_sent;
152}; 157};
153 158
154 159
@@ -220,10 +225,17 @@ transmit_notify (void *cls, size_t size, void *buf)
220 memcpy (buf, queue_entity->msg, msg_size); 225 memcpy (buf, queue_entity->msg, msg_size);
221 LOG (GNUNET_ERROR_TYPE_DEBUG, 226 LOG (GNUNET_ERROR_TYPE_DEBUG,
222 "Message of size %u sent\n", msg_size); 227 "Message of size %u sent\n", msg_size);
223 GNUNET_free (queue_entity->msg); 228 if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE
229 == ntohs (queue_entity->msg->header.type))
230 {
231 GNUNET_break (GNUNET_NO == queue_entity->lr->acquire_sent);
232 queue_entity->lr->acquire_sent = GNUNET_YES;
233 queue_entity->lr->mqe = NULL;
234 }
235 GNUNET_free (queue_entity->msg);
224 GNUNET_CONTAINER_DLL_remove (handle->mq_head, 236 GNUNET_CONTAINER_DLL_remove (handle->mq_head,
225 handle->mq_tail, 237 handle->mq_tail,
226 queue_entity); 238 queue_entity);
227 GNUNET_free (queue_entity); 239 GNUNET_free (queue_entity);
228 queue_entity = handle->mq_head; 240 queue_entity = handle->mq_head;
229 if (NULL != queue_entity) 241 if (NULL != queue_entity)
@@ -254,16 +266,20 @@ transmit_notify (void *cls, size_t size, void *buf)
254 * 266 *
255 * @param handle the lockmanager handle whose queue will be used 267 * @param handle the lockmanager handle whose queue will be used
256 * @param msg the message to be queued 268 * @param msg the message to be queued
269 * @param request the locking reqeust responsible for queueing this message
270 * @return the MessageQueue entity that has been queued
257 */ 271 */
258static void 272static struct MessageQueue *
259queue_message (struct GNUNET_LOCKMANAGER_Handle *handle, 273queue_message (struct GNUNET_LOCKMANAGER_Handle *handle,
260 struct GNUNET_LOCKMANAGER_Message *msg) 274 struct GNUNET_LOCKMANAGER_Message *msg,
275 struct GNUNET_LOCKMANAGER_LockingRequest *request)
261{ 276{
262 struct MessageQueue *queue_entity; 277 struct MessageQueue *queue_entity;
263 278
264 GNUNET_assert (NULL != msg); 279 GNUNET_assert (NULL != msg);
265 queue_entity = GNUNET_malloc (sizeof (struct MessageQueue)); 280 queue_entity = GNUNET_malloc (sizeof (struct MessageQueue));
266 queue_entity->msg = msg; 281 queue_entity->msg = msg;
282 queue_entity->lr = request;
267 GNUNET_CONTAINER_DLL_insert_tail (handle->mq_head, 283 GNUNET_CONTAINER_DLL_insert_tail (handle->mq_head,
268 handle->mq_tail, 284 handle->mq_tail,
269 queue_entity); 285 queue_entity);
@@ -277,6 +293,7 @@ queue_message (struct GNUNET_LOCKMANAGER_Handle *handle,
277 &transmit_notify, 293 &transmit_notify,
278 handle); 294 handle);
279 } 295 }
296 return queue_entity;
280} 297}
281 298
282 299
@@ -407,7 +424,9 @@ generate_acquire_msg (const char *domain_name, uint32_t lock)
407 424
408 425
409/** 426/**
410 * Iterator to call relase on locks 427 * Iterator to call relase on locks; acquire messages are sent for all
428 * locks. In addition, if a lock is acquired before, it is not released and its
429 * status callback is called to signal its release
411 * 430 *
412 * @param cls the lockmanager handle 431 * @param cls the lockmanager handle
413 * @param key current key code 432 * @param key current key code
@@ -425,8 +444,11 @@ release_n_retry_iterator (void *cls,
425 struct GNUNET_LOCKMANAGER_Handle *h = cls; 444 struct GNUNET_LOCKMANAGER_Handle *h = cls;
426 struct GNUNET_LOCKMANAGER_Message *msg; 445 struct GNUNET_LOCKMANAGER_Message *msg;
427 446
447 if (GNUNET_NO == r->acquire_sent) /* an acquire is still in queue */
448 return GNUNET_YES;
449 r->acquire_sent = GNUNET_NO;
428 msg = generate_acquire_msg (r->domain, r->lock); 450 msg = generate_acquire_msg (r->domain, r->lock);
429 queue_message (h, msg); 451 r->mqe = queue_message (h, msg, r);
430 if (GNUNET_LOCKMANAGER_RELEASE == r->status) 452 if (GNUNET_LOCKMANAGER_RELEASE == r->status)
431 return GNUNET_YES; 453 return GNUNET_YES;
432 if (NULL != r->status_cb) 454 if (NULL != r->status_cb)
@@ -680,10 +702,11 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
680 r->status = GNUNET_LOCKMANAGER_RELEASE; 702 r->status = GNUNET_LOCKMANAGER_RELEASE;
681 r->status_cb = status_cb; 703 r->status_cb = status_cb;
682 r->status_cb_cls = status_cb_cls; 704 r->status_cb_cls = status_cb_cls;
705 r->acquire_sent = GNUNET_NO;
683 memcpy (r->domain, domain_name, domain_name_length); 706 memcpy (r->domain, domain_name, domain_name_length);
684 msg = generate_acquire_msg (r->domain, r->lock); 707 msg = generate_acquire_msg (r->domain, r->lock);
685 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); 708 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n");
686 queue_message (handle, msg); 709 r->mqe = queue_message (handle, msg, r);
687 get_key (r->domain, r->lock, &hash); 710 get_key (r->domain, r->lock, &hash);
688 GNUNET_assert (GNUNET_OK == 711 GNUNET_assert (GNUNET_OK ==
689 GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, 712 GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap,
@@ -713,7 +736,23 @@ GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
713 size_t domain_name_length; 736 size_t domain_name_length;
714 737
715 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); 738 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
716 /* FIXME: Stop ACQUIRE retransmissions */ 739 if (GNUNET_NO == request->acquire_sent)
740 {
741 GNUNET_assert (NULL != request->mqe);
742 if ((NULL != request->handle->transmit_handle)
743 && (request->handle->mq_head == request->mqe))
744 {
745 GNUNET_CLIENT_notify_transmit_ready_cancel
746 (request->handle->transmit_handle);
747 request->handle->transmit_handle = NULL;
748 }
749 GNUNET_CONTAINER_DLL_remove (request->handle->mq_head,
750 request->handle->mq_tail,
751 request->mqe);
752 GNUNET_free (request->mqe->msg);
753 GNUNET_free (request->mqe);
754 request->status = GNUNET_LOCKMANAGER_RELEASE;
755 }
717 if (GNUNET_LOCKMANAGER_SUCCESS == request->status) 756 if (GNUNET_LOCKMANAGER_SUCCESS == request->status)
718 { 757 {
719 domain_name_length = strlen (request->domain) + 1; 758 domain_name_length = strlen (request->domain) + 1;
@@ -724,7 +763,8 @@ GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
724 msg->header.size = htons (msg_size); 763 msg->header.size = htons (msg_size);
725 msg->lock = htonl (request->lock); 764 msg->lock = htonl (request->lock);
726 memcpy (&msg[1], request->domain, domain_name_length); 765 memcpy (&msg[1], request->domain, domain_name_length);
727 queue_message (request->handle, msg); 766 GNUNET_assert (NULL == request->mqe);
767 (void) queue_message (request->handle, msg, request);
728 } 768 }
729 get_key (request->domain, request->lock, &hash); 769 get_key (request->domain, request->lock, &hash);
730 GNUNET_assert (GNUNET_YES == 770 GNUNET_assert (GNUNET_YES ==