aboutsummaryrefslogtreecommitdiff
path: root/src/lockmanager
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-05-09 08:29:17 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-05-09 08:29:17 +0000
commitde21b0b29055c33ed2ee1ce36abecacf77836808 (patch)
tree52da4c004206505fe29add12e23e0facf23636f1 /src/lockmanager
parentdfbb0d07f39a68d9e11e8956b66a979527a397a7 (diff)
downloadgnunet-de21b0b29055c33ed2ee1ce36abecacf77836808.tar.gz
gnunet-de21b0b29055c33ed2ee1ce36abecacf77836808.zip
lock acquire and release
Diffstat (limited to 'src/lockmanager')
-rw-r--r--src/lockmanager/gnunet-service-lockmanager.c243
1 files changed, 208 insertions, 35 deletions
diff --git a/src/lockmanager/gnunet-service-lockmanager.c b/src/lockmanager/gnunet-service-lockmanager.c
index ed85d3e3d..f959a3c5e 100644
--- a/src/lockmanager/gnunet-service-lockmanager.c
+++ b/src/lockmanager/gnunet-service-lockmanager.c
@@ -82,11 +82,6 @@ struct LockList
82 struct LockList *prev; 82 struct LockList *prev;
83 83
84 /** 84 /**
85 * The client whizch is currently holding this lock
86 */
87 struct GNUNET_SERVER_Client *client;
88
89 /**
90 * List head of clients waiting for this lock 85 * List head of clients waiting for this lock
91 */ 86 */
92 struct WaitList *wait_list_head; 87 struct WaitList *wait_list_head;
@@ -97,6 +92,11 @@ struct LockList
97 struct WaitList *wait_list_tail; 92 struct WaitList *wait_list_tail;
98 93
99 /** 94 /**
95 * The client which is currently holding this lock
96 */
97 struct GNUNET_SERVER_Client *client;
98
99 /**
100 * The name of the locking domain this lock belongs to 100 * The name of the locking domain this lock belongs to
101 */ 101 */
102 char *domain_name; 102 char *domain_name;
@@ -151,7 +151,6 @@ static struct ClientList *cl_head;
151static struct ClientList *cl_tail; 151static struct ClientList *cl_tail;
152 152
153 153
154
155/** 154/**
156 * Function to search for a lock in lock_list matching the given domain_name and 155 * Function to search for a lock in lock_list matching the given domain_name and
157 * lock number 156 * lock number
@@ -164,8 +163,8 @@ static struct ClientList *cl_tail;
164 */ 163 */
165static int 164static int
166ll_find_lock (const char *domain_name, 165ll_find_lock (const char *domain_name,
167 const uint32_t lock_num, 166 const uint32_t lock_num,
168 struct LockList **ret) 167 struct LockList **ret)
169{ 168{
170 struct LockList *current_lock; 169 struct LockList *current_lock;
171 170
@@ -176,14 +175,49 @@ ll_find_lock (const char *domain_name,
176 if ( (0 == strcmp (domain_name, current_lock->domain_name)) 175 if ( (0 == strcmp (domain_name, current_lock->domain_name))
177 && (lock_num == current_lock->lock_num)) 176 && (lock_num == current_lock->lock_num))
178 { 177 {
179 *ret = current_lock; 178 if (NULL != ret)
179 *ret = current_lock;
180 return GNUNET_YES; 180 return GNUNET_YES;
181 } 181 }
182 182
183 current_lock = current_lock->next; 183 current_lock = current_lock->next;
184 } 184 }
185 if (NULL != ret)
186 *ret = current_lock;
187 return GNUNET_NO;
188}
189
190
191/**
192 * Function to search for a lock in lock_list matching the given domain_name and
193 * lock number
194 *
195 * @param client the client owning this lock currently
196 * @param ret this will be the pointer to the corresponding Lock if found; else
197 * it will be the last element in the locks list
198 * @return GNUNET_YES if a matching lock is present in lock_list; GNUNET_NO if not
199 */
200static int
201ll_find_lock_by_owner (const struct GNUNET_SERVER_Client *client,
202 struct LockList **ret)
203{
204 struct LockList *current_lock;
205
206 current_lock = ll_head;
185 207
186 *ret = current_lock; 208 while (NULL != current_lock)
209 {
210 if (client == current_lock->client)
211 {
212 if (NULL != ret)
213 *ret = current_lock;
214 return GNUNET_YES;
215 }
216
217 current_lock = current_lock->next;
218 }
219 if (NULL != ret)
220 *ret = current_lock;
187 return GNUNET_NO; 221 return GNUNET_NO;
188} 222}
189 223
@@ -191,22 +225,29 @@ ll_find_lock (const char *domain_name,
191/** 225/**
192 * Function to append a lock to the global lock list 226 * Function to append a lock to the global lock list
193 * 227 *
228 * @param client the client which currently owns this lock
194 * @param domain_name the name of the locking domain 229 * @param domain_name the name of the locking domain
195 * @param domain_name_len the length of the domain name
196 * @param lock_num the number of the lock 230 * @param lock_num the number of the lock
197 * @param tail the pointer to the tail of the global lock list 231 * @param tail the pointer to the tail of the global lock list
198 */ 232 */
199static void 233static void
200ll_add_lock (const char *domain_name, 234ll_add_lock (struct GNUNET_SERVER_Client *client,
201 size_t domain_name_len, 235 const char *domain_name,
202 const uint32_t lock_num) 236 const uint32_t lock_num)
203{ 237{
204 struct LockList *lock; 238 struct LockList *lock;
239 size_t domain_name_len;
240
241 LOG (GNUNET_ERROR_TYPE_DEBUG,
242 "Adding a lock with num: %u and domain: %s to lock list\n",
243 lock_num, domain_name);
205 244
206 lock = GNUNET_malloc (sizeof (struct LockList)); 245 lock = GNUNET_malloc (sizeof (struct LockList));
246 domain_name_len = strlen (domain_name) + 1;
207 lock->domain_name = GNUNET_malloc (domain_name_len); 247 lock->domain_name = GNUNET_malloc (domain_name_len);
208 strncpy (lock->domain_name, domain_name, domain_name_len); 248 strncpy (lock->domain_name, domain_name, domain_name_len);
209 lock->lock_num = lock_num; 249 lock->lock_num = lock_num;
250 lock->client = client;
210 251
211 GNUNET_CONTAINER_DLL_insert_tail (ll_head, 252 GNUNET_CONTAINER_DLL_insert_tail (ll_head,
212 ll_tail, 253 ll_tail,
@@ -222,6 +263,9 @@ ll_add_lock (const char *domain_name,
222static void 263static void
223ll_remove_lock (struct LockList *lock) 264ll_remove_lock (struct LockList *lock)
224{ 265{
266 LOG (GNUNET_ERROR_TYPE_DEBUG,
267 "Removing lock with num: %u, domain: %s\n",
268 lock->lock_num, lock->domain_name);
225 GNUNET_assert (NULL != ll_head); 269 GNUNET_assert (NULL != ll_head);
226 GNUNET_CONTAINER_DLL_remove (ll_head, 270 GNUNET_CONTAINER_DLL_remove (ll_head,
227 ll_tail, 271 ll_tail,
@@ -252,18 +296,20 @@ ll_wl_find_client (struct LockList *lock,
252 { 296 {
253 if (client == current_wl_entry->client) 297 if (client == current_wl_entry->client)
254 { 298 {
255 *ret = current_wl_entry; 299 if (NULL != ret)
300 *ret = current_wl_entry;
256 return GNUNET_YES; 301 return GNUNET_YES;
257 } 302 }
258 current_wl_entry = current_wl_entry->next; 303 current_wl_entry = current_wl_entry->next;
259 } 304 }
260 *ret = current_wl_entry; 305 if (NULL != ret)
306 *ret = current_wl_entry;
261 return GNUNET_NO; 307 return GNUNET_NO;
262} 308}
263 309
264 310
265/** 311/**
266 * Add a client to the wait list of a lock 312 * Add a client to the wait list of given lock
267 * 313 *
268 * @param lock the lock list entry of a lock 314 * @param lock the lock list entry of a lock
269 * @param client the client to queue for the lock's wait list 315 * @param client the client to queue for the lock's wait list
@@ -274,6 +320,12 @@ ll_wl_add_client (struct LockList *lock,
274{ 320{
275 struct WaitList *wl_entry; 321 struct WaitList *wl_entry;
276 322
323 LOG (GNUNET_ERROR_TYPE_DEBUG,
324 "Adding a client to lock's wait list\n"
325 "\t lock num: %u, domain: %s\n",
326 lock->lock_num,
327 lock->domain_name);
328
277 wl_entry = GNUNET_malloc (sizeof (struct WaitList)); 329 wl_entry = GNUNET_malloc (sizeof (struct WaitList));
278 wl_entry->client = client; 330 wl_entry->client = client;
279 GNUNET_CONTAINER_DLL_insert_tail (lock->wait_list_head, 331 GNUNET_CONTAINER_DLL_insert_tail (lock->wait_list_head,
@@ -282,6 +334,12 @@ ll_wl_add_client (struct LockList *lock,
282} 334}
283 335
284 336
337/**
338 * Remove a client from the wait list of the given lock
339 *
340 * @param lock the lock list entry of the lock
341 * @param wl_client the wait list entry to be removed
342 */
285static void 343static void
286ll_wl_remove_client (struct LockList *lock, 344ll_wl_remove_client (struct LockList *lock,
287 struct WaitList *wl_client) 345 struct WaitList *wl_client)
@@ -314,14 +372,16 @@ cl_find_client (const struct GNUNET_SERVER_Client *client,
314 { 372 {
315 if (client == current->client) 373 if (client == current->client)
316 { 374 {
317 *ret = current; 375 if (NULL != ret)
376 *ret = current;
318 return GNUNET_YES; 377 return GNUNET_YES;
319 } 378 }
320 379
321 current = current->next; 380 current = current->next;
322 } 381 }
323 382
324 *ret = current; 383 if (NULL != ret)
384 *ret = current;
325 return GNUNET_NO; 385 return GNUNET_NO;
326} 386}
327 387
@@ -335,8 +395,12 @@ static void
335cl_add_client (struct GNUNET_SERVER_Client *client) 395cl_add_client (struct GNUNET_SERVER_Client *client)
336{ 396{
337 struct ClientList *new_client; 397 struct ClientList *new_client;
398
399 LOG (GNUNET_ERROR_TYPE_DEBUG,
400 "Adding a client to the client list\n");
338 401
339 new_client = GNUNET_malloc (sizeof (struct ClientList)); 402 new_client = GNUNET_malloc (sizeof (struct ClientList));
403 GNUNET_SERVER_client_keep (client);
340 new_client->client = client; 404 new_client->client = client;
341 GNUNET_CONTAINER_DLL_insert_tail (cl_head, 405 GNUNET_CONTAINER_DLL_insert_tail (cl_head,
342 cl_tail, 406 cl_tail,
@@ -352,6 +416,9 @@ cl_add_client (struct GNUNET_SERVER_Client *client)
352static void 416static void
353cl_remove_client (struct ClientList *client) 417cl_remove_client (struct ClientList *client)
354{ 418{
419 LOG (GNUNET_ERROR_TYPE_DEBUG,
420 "Removing a client from the client list\n");
421 GNUNET_SERVER_client_drop (client->client);
355 GNUNET_CONTAINER_DLL_remove (cl_head, 422 GNUNET_CONTAINER_DLL_remove (cl_head,
356 cl_tail, 423 cl_tail,
357 client); 424 client);
@@ -389,6 +456,37 @@ transmit_notify (void *cls, size_t size, void *buf)
389 456
390 457
391/** 458/**
459 * Send SUCCESS message to the client
460 *
461 * @param client the client to which the message has to be sent
462 * @param domain_name the locking domain of the successfully acquried lock
463 * @param lock_num the number of the successfully acquired lock
464 */
465static void
466send_success_msg (struct GNUNET_SERVER_Client *client,
467 const char *domain_name,
468 int lock_num)
469{
470 struct GNUNET_LOCKMANAGER_Message *reply;
471 size_t domain_name_len;
472 uint16_t reply_size;
473
474 domain_name_len = strlen (domain_name) + 1;
475 reply_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_len;
476 reply = GNUNET_malloc (reply_size);
477 reply->header.size = htons (reply_size);
478 reply->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS);
479 reply->lock = htonl (lock_num);
480 strncpy ((char *) &reply[1], domain_name, domain_name_len);
481 GNUNET_SERVER_notify_transmit_ready (client,
482 reply_size,
483 TIMEOUT,
484 &transmit_notify,
485 reply);
486}
487
488
489/**
392 * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE 490 * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE
393 * 491 *
394 * @param cls NULL 492 * @param cls NULL
@@ -401,26 +499,36 @@ handle_acquire (void *cls,
401 const struct GNUNET_MessageHeader *message) 499 const struct GNUNET_MessageHeader *message)
402{ 500{
403 const struct GNUNET_LOCKMANAGER_Message *request; 501 const struct GNUNET_LOCKMANAGER_Message *request;
404 struct GNUNET_LOCKMANAGER_Message *reply; 502 const char *domain_name;
405 int16_t request_size; 503 struct LockList *ll_entry;
504 uint32_t lock_num;
406 505
407 506
408 LOG (GNUNET_ERROR_TYPE_DEBUG, 507 LOG (GNUNET_ERROR_TYPE_DEBUG,
409 "Received an ACQUIRE message\n"); 508 "Received an ACQUIRE message\n");
410
411 request = (struct GNUNET_LOCKMANAGER_Message *) message;
412 509
413 /* FIXME: Dummy implementation; just echos success for every lock */
414 request_size = ntohs (message->size);
415 reply = GNUNET_malloc (request_size);
416 memcpy (reply, request, request_size);
417 reply->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS);
418 GNUNET_SERVER_notify_transmit_ready (client,
419 request_size,
420 TIMEOUT,
421 &transmit_notify,
422 reply);
423 510
511 /* Check if the client is in client list */
512 if (GNUNET_NO == cl_find_client (client, NULL))
513 {
514 cl_add_client (client);
515 }
516
517 request = (struct GNUNET_LOCKMANAGER_Message *) message;
518 lock_num = ntohl (request->lock);
519 domain_name = (char *) &request[1];
520 if (GNUNET_YES == ll_find_lock (domain_name,
521 lock_num,
522 &ll_entry))
523 {/* Add client to the lock's wait list */
524 ll_wl_add_client (ll_entry, client);
525 }
526 else
527 {
528 ll_add_lock (client, domain_name, lock_num);
529 send_success_msg (client, domain_name, lock_num);
530 }
531
424 GNUNET_SERVER_receive_done (client, GNUNET_OK); 532 GNUNET_SERVER_receive_done (client, GNUNET_OK);
425} 533}
426 534
@@ -437,14 +545,75 @@ handle_release (void *cls,
437 struct GNUNET_SERVER_Client *client, 545 struct GNUNET_SERVER_Client *client,
438 const struct GNUNET_MessageHeader *message) 546 const struct GNUNET_MessageHeader *message)
439{ 547{
440 LOG (GNUNET_ERROR_TYPE_DEBUG, 548 const struct GNUNET_LOCKMANAGER_Message *request;
441 "Received a RELEASE message\n"); 549 const char *domain_name;
550 struct LockList *ll_entry;
551 uint32_t lock_num;
442 552
553 request = (struct GNUNET_LOCKMANAGER_Message *) message;
554 lock_num = ntohl (request->lock);
555 domain_name = (char *) &request[1];
556 LOG (GNUNET_ERROR_TYPE_DEBUG,
557 "Received a RELEASE message on lock with num: %d, domain: %s\n",
558 lock_num, domain_name);
559 if (GNUNET_YES == ll_find_lock (domain_name, lock_num, &ll_entry))
560 {
561 if (NULL == ll_entry->wait_list_head)
562 {
563 ll_remove_lock (ll_entry);
564 }
565 else
566 {
567 /* Do furthur processing on lock's wait list here */
568 }
569 }
570 else
571 {
572 LOG (GNUNET_ERROR_TYPE_DEBUG,
573 "\t give lock doesn't exist\n");
574 }
575
576
443 GNUNET_SERVER_receive_done (client, GNUNET_OK); 577 GNUNET_SERVER_receive_done (client, GNUNET_OK);
444} 578}
445 579
446 580
447/** 581/**
582 * Callback for client disconnect
583 *
584 * @param cls NULL
585 * @param client the client which has disconnected
586 */
587static void
588client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
589{
590 struct ClientList *cl_entry;
591
592 LOG (GNUNET_ERROR_TYPE_DEBUG,
593 "A client has been disconnected -- freeing its locks and resources\n");
594
595 if (GNUNET_YES == cl_find_client (client, &cl_entry))
596 {
597 struct LockList *lock;
598
599 cl_remove_client (cl_entry);
600 while (GNUNET_YES == ll_find_lock_by_owner (client, &lock))
601 {
602 if (NULL == lock->wait_list_head)
603 {
604 ll_remove_lock (lock);
605 }
606 else
607 {
608 /* Do furthur processing on lock's wait list here */
609 }
610 }
611 }
612 else GNUNET_break (0);
613}
614
615
616/**
448 * Lock manager setup 617 * Lock manager setup
449 * 618 *
450 * @param cls closure 619 * @param cls closure
@@ -466,6 +635,10 @@ lockmanager_run (void *cls,
466 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting lockmanager\n"); 635 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting lockmanager\n");
467 GNUNET_SERVER_add_handlers (server, 636 GNUNET_SERVER_add_handlers (server,
468 message_handlers); 637 message_handlers);
638 GNUNET_SERVER_disconnect_notify (server,
639 &client_disconnect_cb,
640 NULL);
641
469 642
470} 643}
471 644