aboutsummaryrefslogtreecommitdiff
path: root/src/lockmanager/lockmanager_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockmanager/lockmanager_api.c')
-rw-r--r--src/lockmanager/lockmanager_api.c729
1 files changed, 0 insertions, 729 deletions
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c
deleted file mode 100644
index 8f66cf00b..000000000
--- a/src/lockmanager/lockmanager_api.c
+++ /dev/null
@@ -1,729 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2008--2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file lockmanager/lockmanager_api.c
23 * @brief API implementation of gnunet_lockmanager_service.h
24 * @author Sree Harsha Totakura
25 */
26
27
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_lockmanager_service.h"
31#include "gnunet_protocols.h"
32
33#include "lockmanager.h"
34
35#define LOG(kind,...) \
36 GNUNET_log_from (kind, "lockmanager-api",__VA_ARGS__)
37
38#define TIME_REL_MINS(min) \
39 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, min)
40
41#define TIMEOUT TIME_REL_MINS(3)
42
43
44/**
45 * The message queue
46 */
47struct MessageQueue
48{
49 /**
50 * The next pointer for doubly linked list
51 */
52 struct MessageQueue *next;
53
54 /**
55 * The prev pointer for doubly linked list
56 */
57 struct MessageQueue *prev;
58
59 /**
60 * The LOCKMANAGER Message
61 */
62 struct GNUNET_LOCKMANAGER_Message *msg;
63
64 /**
65 * If this is a AQUIRE_LOCK message, this is the
66 * affiliated locking request.
67 */
68 struct GNUNET_LOCKMANAGER_LockingRequest *lr;
69};
70
71
72/**
73 * Handler for the lockmanager service
74 */
75struct GNUNET_LOCKMANAGER_Handle
76{
77 /**
78 * The client connection to the service
79 */
80 struct GNUNET_CLIENT_Connection *conn;
81
82 /**
83 * The transmit handle for transmissions using conn
84 */
85 struct GNUNET_CLIENT_TransmitHandle *transmit_handle;
86
87 /**
88 * Hashmap handle
89 */
90 struct GNUNET_CONTAINER_MultiHashMap *hashmap;
91
92 /**
93 * Double linked list head for message queue
94 */
95 struct MessageQueue *mq_head;
96
97 /**
98 * Double linked list tail for message queue
99 */
100 struct MessageQueue *mq_tail;
101
102 /**
103 * Are we currently handling replies?
104 */
105 int in_replies;
106};
107
108
109/**
110 * Structure for Locking Request
111 */
112struct GNUNET_LOCKMANAGER_LockingRequest
113{
114 /**
115 * The handle associated with this request
116 */
117 struct GNUNET_LOCKMANAGER_Handle *handle;
118
119 /**
120 * The status callback
121 */
122 GNUNET_LOCKMANAGER_StatusCallback status_cb;
123
124 /**
125 * Entry in the request message queue for aquiring this
126 * lock; NULL after request has been sent.
127 */
128 struct MessageQueue *mqe;
129
130 /**
131 * Closure for the status callback
132 */
133 void *status_cb_cls;
134
135 /**
136 * The locking domain of this request
137 */
138 char *domain;
139
140 /**
141 * The lock
142 */
143 uint32_t lock;
144
145 /**
146 * The status of the lock
147 */
148 enum GNUNET_LOCKMANAGER_Status status;
149
150 /**
151 * set to GNUNET_YES if acquire message for this lock is till in messga queue
152 */
153 int acquire_sent;
154};
155
156
157/**
158 * Structure for matching a lock
159 */
160struct LockingRequestMatch
161{
162 /**
163 * The matched LockingRequest entry; Should be NULL if no entry is found
164 */
165 struct GNUNET_LOCKMANAGER_LockingRequest *matched_entry;
166
167 /**
168 * The locking domain name of the lock
169 */
170 const char *domain;
171
172 /**
173 * The lock number
174 */
175 uint32_t lock;
176};
177
178
179/**
180 * Handler for server replies
181 *
182 * @param cls the LOCKMANAGER_Handle
183 * @param msg received message, NULL on timeout or fatal error
184 */
185static void
186handle_replies (void *cls, const struct GNUNET_MessageHeader *msg);
187
188
189/**
190 * Transmit notify for sending message to server
191 *
192 * @param cls the lockmanager handle
193 * @param size number of bytes available in buf
194 * @param buf where the callee should write the message
195 * @return number of bytes written to buf
196 */
197static size_t
198transmit_notify (void *cls, size_t size, void *buf)
199{
200 struct GNUNET_LOCKMANAGER_Handle *handle = cls;
201 struct MessageQueue *queue_entity;
202 uint16_t msg_size;
203
204 handle->transmit_handle = NULL;
205 queue_entity = handle->mq_head;
206 GNUNET_assert (NULL != queue_entity);
207 if ((0 == size) || (NULL == buf))
208 {
209 handle->transmit_handle =
210 GNUNET_CLIENT_notify_transmit_ready (handle->conn,
211 ntohs (queue_entity->msg->
212 header.size),
213 GNUNET_TIME_UNIT_FOREVER_REL,
214 GNUNET_YES, &transmit_notify,
215 handle);
216 return 0;
217 }
218 msg_size = ntohs (queue_entity->msg->header.size);
219 GNUNET_assert (size >= msg_size);
220 memcpy (buf, queue_entity->msg, msg_size);
221 LOG (GNUNET_ERROR_TYPE_DEBUG, "Message of size %u sent\n", msg_size);
222 if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE ==
223 ntohs (queue_entity->msg->header.type))
224 {
225 GNUNET_break (GNUNET_NO == queue_entity->lr->acquire_sent);
226 queue_entity->lr->acquire_sent = GNUNET_YES;
227 queue_entity->lr->mqe = NULL;
228 }
229 GNUNET_free (queue_entity->msg);
230 GNUNET_CONTAINER_DLL_remove (handle->mq_head, handle->mq_tail, queue_entity);
231 GNUNET_free (queue_entity);
232 queue_entity = handle->mq_head;
233 if (NULL != queue_entity)
234 {
235 handle->transmit_handle =
236 GNUNET_CLIENT_notify_transmit_ready (handle->conn,
237 ntohs (queue_entity->msg->
238 header.size), TIMEOUT,
239 GNUNET_YES, &transmit_notify,
240 handle);
241 }
242 if (GNUNET_NO == handle->in_replies)
243 {
244 handle->in_replies = GNUNET_YES;
245 GNUNET_CLIENT_receive (handle->conn, &handle_replies, handle,
246 GNUNET_TIME_UNIT_FOREVER_REL);
247 }
248 return msg_size;
249}
250
251
252/**
253 * Queues a message into handle's send message queue
254 *
255 * @param handle the lockmanager handle whose queue will be used
256 * @param msg the message to be queued
257 * @param request the locking reqeust responsible for queueing this message
258 * @return the MessageQueue entity that has been queued
259 */
260static struct MessageQueue *
261queue_message (struct GNUNET_LOCKMANAGER_Handle *handle,
262 struct GNUNET_LOCKMANAGER_Message *msg,
263 struct GNUNET_LOCKMANAGER_LockingRequest *request)
264{
265 struct MessageQueue *queue_entity;
266
267 GNUNET_assert (NULL != msg);
268 queue_entity = GNUNET_malloc (sizeof (struct MessageQueue));
269 queue_entity->msg = msg;
270 queue_entity->lr = request;
271 GNUNET_CONTAINER_DLL_insert_tail (handle->mq_head, handle->mq_tail,
272 queue_entity);
273 if (NULL == handle->transmit_handle)
274 {
275 handle->transmit_handle =
276 GNUNET_CLIENT_notify_transmit_ready (handle->conn,
277 ntohs (msg->header.size), TIMEOUT,
278 GNUNET_YES, &transmit_notify,
279 handle);
280 }
281 return queue_entity;
282}
283
284
285/**
286 * Get the key for the given lock in the 'lock_map'.
287 *
288 * @param domain_name
289 * @param lock_number
290 * @param key set to the key
291 */
292static void
293get_key (const char *domain_name, uint32_t lock_number,
294 struct GNUNET_HashCode *key)
295{
296 uint32_t *last_32;
297
298 GNUNET_CRYPTO_hash (domain_name, strlen (domain_name), key);
299 last_32 = (uint32_t *) key;
300 *last_32 ^= lock_number;
301}
302
303
304/**
305 * Hashmap iterator for matching a LockingRequest
306 *
307 * @param cls the LockingRequestMatch structure
308 * @param key current key code
309 * @param value value in the hash map (struct GNUNET_LOCKMANAGER_LockingRequest)
310 * @return GNUNET_YES if we should continue to
311 * iterate,
312 * GNUNET_NO if not.
313 */
314static int
315match_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
316{
317 struct LockingRequestMatch *match = cls;
318 struct GNUNET_LOCKMANAGER_LockingRequest *lr = value;
319
320 if ((match->lock == lr->lock) && (0 == strcmp (match->domain, lr->domain)))
321 {
322 match->matched_entry = lr;
323 return GNUNET_NO;
324 }
325 return GNUNET_YES;
326}
327
328
329/**
330 * Function to find a LockingRequest associated with the given domain and lock
331 * attributes in the map
332 *
333 * @param map the map where the LockingRequests are stored
334 * @param domain the locking domain name
335 * @param lock the lock number
336 * @return the found LockingRequest; NULL if a matching LockingRequest wasn't
337 * found
338 */
339static struct GNUNET_LOCKMANAGER_LockingRequest *
340hashmap_find_lockingrequest (const struct GNUNET_CONTAINER_MultiHashMap *map,
341 const char *domain, uint32_t lock)
342{
343 struct GNUNET_HashCode hash;
344 struct LockingRequestMatch lock_match;
345
346 lock_match.matched_entry = NULL;
347 lock_match.domain = domain;
348 lock_match.lock = lock;
349 get_key (domain, lock, &hash);
350 GNUNET_CONTAINER_multihashmap_get_multiple (map, &hash, &match_iterator,
351 &lock_match);
352 return lock_match.matched_entry;
353}
354
355
356/**
357 * Task for calling status change callback for a lock
358 *
359 * @param cls the LockingRequest associated with this lock
360 * @param tc the TaskScheduler context
361 */
362static void
363call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
364{
365 const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls;
366
367 if (NULL != r->status_cb)
368 {
369 LOG (GNUNET_ERROR_TYPE_DEBUG,
370 "Calling status change for SUCCESS on lock num: %d, domain: %s\n",
371 r->lock, r->domain);
372 r->status_cb (r->status_cb_cls, r->domain, r->lock, r->status);
373 }
374}
375
376
377/**
378 * Function to generate acquire message for a lock
379 *
380 * @param domain_name the domain name of the lock
381 * @param lock the lock number
382 * @return the generated GNUNET_LOCKMANAGER_Message
383 */
384static struct GNUNET_LOCKMANAGER_Message *
385generate_acquire_msg (const char *domain_name, uint32_t lock)
386{
387 struct GNUNET_LOCKMANAGER_Message *msg;
388 size_t domain_name_len;
389 uint16_t msg_size;
390
391 domain_name_len = strlen (domain_name) + 1;
392 msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_len;
393 msg = GNUNET_malloc (msg_size);
394 msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE);
395 msg->header.size = htons (msg_size);
396 msg->lock = htonl (lock);
397 memcpy (&msg[1], domain_name, domain_name_len);
398 return msg;
399}
400
401
402/**
403 * Iterator to call relase on locks; acquire messages are sent for all
404 * locks. In addition, if a lock is acquired before, it is not released and its
405 * status callback is called to signal its release
406 *
407 * @param cls the lockmanager handle
408 * @param key current key code
409 * @param value the Locking request
410 * @return GNUNET_YES if we should continue to
411 * iterate,
412 * GNUNET_NO if not.
413 */
414static int
415release_n_retry_iterator (void *cls, const struct GNUNET_HashCode *key,
416 void *value)
417{
418 struct GNUNET_LOCKMANAGER_LockingRequest *r = value;
419 struct GNUNET_LOCKMANAGER_Handle *h = cls;
420 struct GNUNET_LOCKMANAGER_Message *msg;
421
422 if (GNUNET_NO == r->acquire_sent) /* an acquire is still in queue */
423 return GNUNET_YES;
424 r->acquire_sent = GNUNET_NO;
425 msg = generate_acquire_msg (r->domain, r->lock);
426 r->mqe = queue_message (h, msg, r);
427 if (GNUNET_LOCKMANAGER_RELEASE == r->status)
428 return GNUNET_YES;
429 if (NULL != r->status_cb)
430 {
431 LOG (GNUNET_ERROR_TYPE_DEBUG,
432 "Calling status change for RELEASE on lock num: %d, domain: %s\n",
433 r->lock, r->domain);
434 r->status = GNUNET_LOCKMANAGER_RELEASE;
435 r->status_cb (r->status_cb_cls, r->domain, r->lock,
436 GNUNET_LOCKMANAGER_RELEASE);
437 }
438 return GNUNET_YES;
439}
440
441
442/**
443 * Handler for server replies
444 *
445 * @param cls the LOCKMANAGER_Handle
446 * @param msg received message, NULL on timeout or fatal error
447 */
448static void
449handle_replies (void *cls, const struct GNUNET_MessageHeader *msg)
450{
451 struct GNUNET_LOCKMANAGER_Handle *handle = cls;
452 const struct GNUNET_LOCKMANAGER_Message *m;
453 struct GNUNET_LOCKMANAGER_LockingRequest *lr;
454 const char *domain;
455 struct GNUNET_HashCode hash;
456 uint32_t lock;
457 uint16_t msize;
458
459 handle->in_replies = GNUNET_NO;
460 if (NULL == msg)
461 {
462 LOG (GNUNET_ERROR_TYPE_DEBUG,
463 "Lockmanager service not available or went down\n");
464 /* Should release all locks and retry to acquire them */
465 GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap,
466 &release_n_retry_iterator, handle);
467 return;
468 }
469 handle->in_replies = GNUNET_YES;
470 GNUNET_CLIENT_receive (handle->conn, &handle_replies, handle,
471 GNUNET_TIME_UNIT_FOREVER_REL);
472 if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS != ntohs (msg->type))
473 {
474 GNUNET_break (0);
475 return;
476 }
477 msize = ntohs (msg->size);
478 if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message))
479 {
480 GNUNET_break (0);
481 return;
482 }
483 m = (const struct GNUNET_LOCKMANAGER_Message *) msg;
484 domain = (const char *) &m[1];
485 msize -= sizeof (struct GNUNET_LOCKMANAGER_Message);
486 if ('\0' != domain[msize - 1])
487 {
488 GNUNET_break (0);
489 return;
490 }
491
492 lock = ntohl (m->lock);
493 get_key (domain, lock, &hash);
494 LOG (GNUNET_ERROR_TYPE_DEBUG,
495 "Received SUCCESS message for lock: %d, domain %s\n", lock, domain);
496 if (NULL ==
497 (lr = hashmap_find_lockingrequest (handle->hashmap, domain, lock)))
498 {
499 GNUNET_break (0);
500 return;
501 }
502 if (GNUNET_LOCKMANAGER_SUCCESS == lr->status)
503 {
504 GNUNET_break (0);
505 return;
506 }
507 LOG (GNUNET_ERROR_TYPE_DEBUG,
508 "Changing status for lock: %d in domain: %s to SUCCESS\n", lr->lock,
509 lr->domain);
510 lr->status = GNUNET_LOCKMANAGER_SUCCESS;
511 GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, lr,
512 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
513}
514
515
516/**
517 * Iterator to free hash map entries.
518 *
519 * @param cls the lockmanger handle
520 * @param key current key code
521 * @param value the Locking request
522 * @return GNUNET_YES if we should continue to
523 * iterate,
524 * GNUNET_NO if not.
525 */
526static int
527free_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
528{
529 struct GNUNET_LOCKMANAGER_Handle *h = cls;
530 struct GNUNET_LOCKMANAGER_LockingRequest *r = value;
531
532 LOG (GNUNET_ERROR_TYPE_DEBUG, "Clearing locking request\n");
533 GNUNET_assert (GNUNET_YES ==
534 GNUNET_CONTAINER_multihashmap_remove (h->hashmap, key, value));
535 GNUNET_free (r->domain);
536 GNUNET_free (r);
537 return GNUNET_YES;
538}
539
540
541/*******************/
542/* API Definitions */
543/*******************/
544
545
546/**
547 * Connect to the lockmanager service
548 *
549 * @param cfg the configuration to use
550 *
551 * @return upon success the handle to the service; NULL upon error
552 */
553struct GNUNET_LOCKMANAGER_Handle *
554GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
555{
556 struct GNUNET_LOCKMANAGER_Handle *h;
557
558 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
559 h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle));
560 h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg);
561 if (NULL == h->conn)
562 {
563 GNUNET_free (h);
564 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
565 return NULL;
566 }
567 h->hashmap = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
568 GNUNET_assert (NULL != h->hashmap);
569 h->in_replies = GNUNET_YES;
570 GNUNET_CLIENT_receive (h->conn, &handle_replies, h,
571 GNUNET_TIME_UNIT_FOREVER_REL);
572 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
573 return h;
574}
575
576
577/**
578 * Disconnect from the lockmanager service
579 *
580 * @param handle the handle to the lockmanager service
581 */
582void
583GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle)
584{
585 struct MessageQueue *head;
586
587 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
588 if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap))
589 {
590 LOG (GNUNET_ERROR_TYPE_WARNING,
591 "Some locking requests are still present. Cancel them before "
592 "calling %s\n", __func__);
593 GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, &free_iterator,
594 handle);
595 }
596 GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap);
597 /* Clear the message queue */
598 if (NULL != handle->transmit_handle)
599 {
600 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->transmit_handle);
601 }
602 head = handle->mq_head;
603 while (NULL != head)
604 {
605 GNUNET_CONTAINER_DLL_remove (handle->mq_head, handle->mq_tail, head);
606 GNUNET_free (head->msg);
607 GNUNET_free (head);
608 head = handle->mq_head;
609 }
610 GNUNET_CLIENT_disconnect (handle->conn);
611 GNUNET_free (handle);
612 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
613}
614
615
616/**
617 * Tries to acquire the given lock(even if the lock has been lost) until the
618 * request is called. If the lock is available the status_cb will be
619 * called. If the lock is busy then the request is queued and status_cb
620 * will be called when the lock has been made available and acquired by us.
621 *
622 * @param handle the handle to the lockmanager service
623 *
624 * @param domain_name name of the locking domain. Clients who want to share
625 * locks must use the same name for the locking domain. Also the
626 * domain_name should be selected with the prefix
627 * "GNUNET_<PROGRAM_NAME>_" to avoid domain name collisions.
628 *
629 *
630 * @param lock which lock to lock
631 *
632 * @param status_cb the callback for signalling when the lock is acquired and
633 * when it is lost
634 *
635 * @param status_cb_cls the closure to the above callback
636 *
637 * @return the locking request handle for this request
638 */
639struct GNUNET_LOCKMANAGER_LockingRequest *
640GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
641 const char *domain_name, uint32_t lock,
642 GNUNET_LOCKMANAGER_StatusCallback status_cb,
643 void *status_cb_cls)
644{
645 struct GNUNET_LOCKMANAGER_LockingRequest *r;
646 struct GNUNET_LOCKMANAGER_Message *msg;
647 struct GNUNET_HashCode hash;
648 size_t domain_name_length;
649
650 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
651 r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest));
652 domain_name_length = strlen (domain_name) + 1;
653 r->handle = handle;
654 r->lock = lock;
655 r->domain = GNUNET_malloc (domain_name_length);
656 r->status = GNUNET_LOCKMANAGER_RELEASE;
657 r->status_cb = status_cb;
658 r->status_cb_cls = status_cb_cls;
659 r->acquire_sent = GNUNET_NO;
660 memcpy (r->domain, domain_name, domain_name_length);
661 msg = generate_acquire_msg (r->domain, r->lock);
662 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n");
663 r->mqe = queue_message (handle, msg, r);
664 get_key (r->domain, r->lock, &hash);
665 GNUNET_assert (GNUNET_OK ==
666 GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, &hash,
667 r,
668 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
669 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
670 return r;
671}
672
673
674/**
675 * Function to cancel the locking request generated by
676 * GNUNET_LOCKMANAGER_acquire_lock. If the lock is acquired by us then the lock
677 * is released. GNUNET_LOCKMANAGER_StatusCallback will not be called upon any
678 * status changes resulting due to this call.
679 *
680 * @param request the LockingRequest to cancel
681 */
682void
683GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
684 *request)
685{
686 struct GNUNET_LOCKMANAGER_Message *msg;
687 struct GNUNET_HashCode hash;
688 uint16_t msg_size;
689 size_t domain_name_length;
690
691 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
692 if (GNUNET_NO == request->acquire_sent)
693 {
694 GNUNET_assert (NULL != request->mqe);
695 if ((NULL != request->handle->transmit_handle) &&
696 (request->handle->mq_head == request->mqe))
697 {
698 GNUNET_CLIENT_notify_transmit_ready_cancel (request->
699 handle->transmit_handle);
700 request->handle->transmit_handle = NULL;
701 }
702 GNUNET_CONTAINER_DLL_remove (request->handle->mq_head,
703 request->handle->mq_tail, request->mqe);
704 GNUNET_free (request->mqe->msg);
705 GNUNET_free (request->mqe);
706 request->status = GNUNET_LOCKMANAGER_RELEASE;
707 }
708 if (GNUNET_LOCKMANAGER_SUCCESS == request->status)
709 {
710 domain_name_length = strlen (request->domain) + 1;
711 msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_length;
712 msg = GNUNET_malloc (msg_size);
713 msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE);
714 msg->header.size = htons (msg_size);
715 msg->lock = htonl (request->lock);
716 memcpy (&msg[1], request->domain, domain_name_length);
717 GNUNET_assert (NULL == request->mqe);
718 (void) queue_message (request->handle, msg, request);
719 }
720 get_key (request->domain, request->lock, &hash);
721 GNUNET_assert (GNUNET_YES ==
722 GNUNET_CONTAINER_multihashmap_remove (request->handle->hashmap,
723 &hash, request));
724 GNUNET_free (request->domain);
725 GNUNET_free (request);
726 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
727}
728
729/* end of lockmanager_api.c */