aboutsummaryrefslogtreecommitdiff
path: root/src/rps/gnunet-service-rps_sampler.c
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2018-09-20 22:34:18 +0200
committerJulius Bünger <buenger@mytum.de>2018-09-20 22:35:30 +0200
commit0ce2284452e86e3fb6991e573bed2d37b0be8331 (patch)
treea6245f1d30a37db149e23c26bb3caa7bd773ea8d /src/rps/gnunet-service-rps_sampler.c
parent33d8b5a803bf931822e3591a4d7387da3aedcc63 (diff)
downloadgnunet-0ce2284452e86e3fb6991e573bed2d37b0be8331.tar.gz
gnunet-0ce2284452e86e3fb6991e573bed2d37b0be8331.zip
Move from timer-based to callback-based updates in sampler
Diffstat (limited to 'src/rps/gnunet-service-rps_sampler.c')
-rw-r--r--src/rps/gnunet-service-rps_sampler.c164
1 files changed, 137 insertions, 27 deletions
diff --git a/src/rps/gnunet-service-rps_sampler.c b/src/rps/gnunet-service-rps_sampler.c
index 0de15bbc0..ff4bc9e42 100644
--- a/src/rps/gnunet-service-rps_sampler.c
+++ b/src/rps/gnunet-service-rps_sampler.c
@@ -64,6 +64,43 @@ typedef void
64 64
65 65
66/** 66/**
67 * @brief Callback called each time a new peer was put into the sampler
68 *
69 * @param cls A possibly given closure
70 */
71typedef void
72(*SamplerNotifyUpdateCB) (void *cls);
73
74/**
75 * @brief Context for a callback. Contains callback and closure.
76 *
77 * Meant to be an entry in an DLL.
78 */
79struct SamplerNotifyUpdateCTX
80{
81 /**
82 * @brief The Callback to call on updates
83 */
84 SamplerNotifyUpdateCB notify_cb;
85
86 /**
87 * @brief The according closure.
88 */
89 void *cls;
90
91 /**
92 * @brief Next element in DLL.
93 */
94 struct SamplerNotifyUpdateCTX *next;
95
96 /**
97 * @brief Previous element in DLL.
98 */
99 struct SamplerNotifyUpdateCTX *prev;
100};
101
102
103/**
67 * Closure for #sampler_mod_get_rand_peer() and #sampler_get_rand_peer 104 * Closure for #sampler_mod_get_rand_peer() and #sampler_get_rand_peer
68 */ 105 */
69struct GetPeerCls 106struct GetPeerCls
@@ -85,6 +122,11 @@ struct GetPeerCls
85 struct GNUNET_SCHEDULER_Task *get_peer_task; 122 struct GNUNET_SCHEDULER_Task *get_peer_task;
86 123
87 /** 124 /**
125 * @brief Context to the given callback.
126 */
127 struct SamplerNotifyUpdateCTX *notify_ctx;
128
129 /**
88 * The callback 130 * The callback
89 */ 131 */
90 RPS_sampler_rand_peer_ready_cont cont; 132 RPS_sampler_rand_peer_ready_cont cont;
@@ -164,6 +206,8 @@ struct RPS_Sampler
164 struct RPS_SamplerRequestHandle *req_handle_head; 206 struct RPS_SamplerRequestHandle *req_handle_head;
165 struct RPS_SamplerRequestHandle *req_handle_tail; 207 struct RPS_SamplerRequestHandle *req_handle_tail;
166 208
209 struct SamplerNotifyUpdateCTX *notify_ctx_head;
210 struct SamplerNotifyUpdateCTX *notify_ctx_tail;
167 #ifdef TO_FILE 211 #ifdef TO_FILE
168 /** 212 /**
169 * File name to log to 213 * File name to log to
@@ -248,6 +292,52 @@ static uint32_t client_get_index;
248 292
249 293
250/** 294/**
295 * @brief Add a callback that will be called when the next peer is inserted
296 * into the sampler
297 *
298 * @param sampler The sampler on which update it will be called
299 * @param notify_cb The callback
300 * @param cls Closure given to the callback
301 *
302 * @return The context containing callback and closure
303 */
304struct SamplerNotifyUpdateCTX *
305sampler_notify_on_update (struct RPS_Sampler *sampler,
306 SamplerNotifyUpdateCB notify_cb,
307 void *cls)
308{
309 struct SamplerNotifyUpdateCTX *notify_ctx;
310
311 LOG (GNUNET_ERROR_TYPE_DEBUG,
312 "Inserting new context for notification\n");
313 notify_ctx = GNUNET_new (struct SamplerNotifyUpdateCTX);
314 notify_ctx->notify_cb = notify_cb;
315 notify_ctx->cls = cls;
316 if (NULL != sampler->notify_ctx_head)
317 {
318 for (struct SamplerNotifyUpdateCTX *notify_iter = sampler->notify_ctx_head;
319 NULL != notify_iter->next;
320 notify_iter = notify_iter->next)
321 {
322 LOG (GNUNET_ERROR_TYPE_DEBUG,
323 "Pre: Context\n");
324 }
325 }
326 GNUNET_CONTAINER_DLL_insert (sampler->notify_ctx_head,
327 sampler->notify_ctx_tail,
328 notify_ctx);
329 for (struct SamplerNotifyUpdateCTX *notify_iter = sampler->notify_ctx_head;
330 NULL != notify_iter;
331 notify_iter = notify_iter->next)
332 {
333 LOG (GNUNET_ERROR_TYPE_DEBUG,
334 "Post: Context\n");
335 }
336 return notify_ctx;
337}
338
339
340/**
251 * Callback to _get_rand_peer() used by _get_n_rand_peers(). 341 * Callback to _get_rand_peer() used by _get_n_rand_peers().
252 * 342 *
253 * Checks whether all n peers are available. If they are, 343 * Checks whether all n peers are available. If they are,
@@ -469,7 +559,7 @@ RPS_sampler_mod_init (size_t init_size,
469 559
470 560
471/** 561/**
472 * A fuction to update every sampler in the given list 562 * Update every sampler element of this sampler with given peer
473 * 563 *
474 * @param sampler the sampler to update. 564 * @param sampler the sampler to update.
475 * @param id the PeerID that is put in the sampler 565 * @param id the PeerID that is put in the sampler
@@ -478,17 +568,33 @@ RPS_sampler_mod_init (size_t init_size,
478RPS_sampler_update (struct RPS_Sampler *sampler, 568RPS_sampler_update (struct RPS_Sampler *sampler,
479 const struct GNUNET_PeerIdentity *id) 569 const struct GNUNET_PeerIdentity *id)
480{ 570{
481 uint32_t i; 571 struct SamplerNotifyUpdateCTX *tmp_notify_head;
572 struct SamplerNotifyUpdateCTX *tmp_notify_tail;
482 573
483 to_file (sampler->file_name, 574 to_file (sampler->file_name,
484 "Got %s", 575 "Got %s",
485 GNUNET_i2s_full (id)); 576 GNUNET_i2s_full (id));
486 577
487 for (i = 0; i < sampler->sampler_size; i++) 578 for (uint32_t i = 0; i < sampler->sampler_size; i++)
488 { 579 {
489 RPS_sampler_elem_next (sampler->sampler_elements[i], 580 RPS_sampler_elem_next (sampler->sampler_elements[i],
490 id); 581 id);
491 } 582 }
583 tmp_notify_head = sampler->notify_ctx_head;
584 tmp_notify_tail = sampler->notify_ctx_tail;
585 sampler->notify_ctx_head = NULL;
586 sampler->notify_ctx_tail = NULL;
587 for (struct SamplerNotifyUpdateCTX *notify_iter = tmp_notify_head;
588 NULL != tmp_notify_head;
589 notify_iter = tmp_notify_head)
590 {
591 GNUNET_assert (NULL != notify_iter->notify_cb);
592 GNUNET_CONTAINER_DLL_remove (tmp_notify_head,
593 tmp_notify_tail,
594 notify_iter);
595 notify_iter->notify_cb (notify_iter->cls);
596 GNUNET_free (notify_iter);
597 }
492} 598}
493 599
494 600
@@ -535,6 +641,7 @@ sampler_get_rand_peer (void *cls)
535 struct RPS_Sampler *sampler; 641 struct RPS_Sampler *sampler;
536 642
537 gpc->get_peer_task = NULL; 643 gpc->get_peer_task = NULL;
644 gpc->notify_ctx = NULL;
538 sampler = gpc->req_handle->sampler; 645 sampler = gpc->req_handle->sampler;
539 646
540 /**; 647 /**;
@@ -549,15 +656,10 @@ sampler_get_rand_peer (void *cls)
549 //LOG (GNUNET_ERROR_TYPE_DEBUG, 656 //LOG (GNUNET_ERROR_TYPE_DEBUG,
550 // "Not returning randomly selected, empty PeerID. - Rescheduling.\n"); 657 // "Not returning randomly selected, empty PeerID. - Rescheduling.\n");
551 658
552 /* FIXME no active wait - get notified, when new id arrives? 659 gpc->notify_ctx =
553 * Might also be a freshly emptied one. Others might still contain ids. 660 sampler_notify_on_update (sampler,
554 * Counter? 661 &sampler_mod_get_rand_peer,
555 */ 662 gpc);
556 gpc->get_peer_task =
557 GNUNET_SCHEDULER_add_delayed (
558 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1),
559 &sampler_get_rand_peer,
560 cls);
561 return; 663 return;
562 } 664 }
563 665
@@ -585,6 +687,7 @@ sampler_mod_get_rand_peer (void *cls)
585 struct RPS_Sampler *sampler; 687 struct RPS_Sampler *sampler;
586 688
587 gpc->get_peer_task = NULL; 689 gpc->get_peer_task = NULL;
690 gpc->notify_ctx = NULL;
588 sampler = gpc->req_handle->sampler; 691 sampler = gpc->req_handle->sampler;
589 692
590 LOG (GNUNET_ERROR_TYPE_DEBUG, "Single peer was requested\n"); 693 LOG (GNUNET_ERROR_TYPE_DEBUG, "Single peer was requested\n");
@@ -600,11 +703,11 @@ sampler_mod_get_rand_peer (void *cls)
600 { 703 {
601 LOG (GNUNET_ERROR_TYPE_DEBUG, 704 LOG (GNUNET_ERROR_TYPE_DEBUG,
602 "Sampler_mod element empty, rescheduling.\n"); 705 "Sampler_mod element empty, rescheduling.\n");
603 GNUNET_assert (NULL == gpc->get_peer_task); 706 GNUNET_assert (NULL == gpc->notify_ctx);
604 gpc->get_peer_task = 707 gpc->notify_ctx =
605 GNUNET_SCHEDULER_add_delayed (sampler->max_round_interval, 708 sampler_notify_on_update (sampler,
606 &sampler_mod_get_rand_peer, 709 &sampler_mod_get_rand_peer,
607 cls); 710 gpc);
608 return; 711 return;
609 } 712 }
610 713
@@ -626,11 +729,11 @@ sampler_mod_get_rand_peer (void *cls)
626 // sampler->max_round_interval); 729 // sampler->max_round_interval);
627 // add a little delay 730 // add a little delay
628 /* Schedule it one round later */ 731 /* Schedule it one round later */
629 GNUNET_assert (NULL == gpc->get_peer_task); 732 GNUNET_assert (NULL == gpc->notify_ctx);
630 gpc->get_peer_task = 733 gpc->notify_ctx =
631 GNUNET_SCHEDULER_add_delayed (sampler->max_round_interval, 734 sampler_notify_on_update (sampler,
632 &sampler_mod_get_rand_peer, 735 &sampler_mod_get_rand_peer,
633 cls); 736 gpc);
634 return; 737 return;
635 } 738 }
636 } 739 }
@@ -638,11 +741,11 @@ sampler_mod_get_rand_peer (void *cls)
638 { 741 {
639 LOG (GNUNET_ERROR_TYPE_DEBUG, 742 LOG (GNUNET_ERROR_TYPE_DEBUG,
640 "This s_elem saw less than two peers -- scheduling for later\n"); 743 "This s_elem saw less than two peers -- scheduling for later\n");
641 GNUNET_assert (NULL == gpc->get_peer_task); 744 GNUNET_assert (NULL == gpc->notify_ctx);
642 gpc->get_peer_task = 745 gpc->notify_ctx =
643 GNUNET_SCHEDULER_add_delayed (sampler->max_round_interval, 746 sampler_notify_on_update (sampler,
644 &sampler_mod_get_rand_peer, 747 &sampler_mod_get_rand_peer,
645 cls); 748 gpc);
646 return; 749 return;
647 } 750 }
648 /* More reasons to wait could be added here */ 751 /* More reasons to wait could be added here */
@@ -747,6 +850,13 @@ RPS_sampler_request_cancel (struct RPS_SamplerRequestHandle *req_handle)
747 { 850 {
748 GNUNET_SCHEDULER_cancel (i->get_peer_task); 851 GNUNET_SCHEDULER_cancel (i->get_peer_task);
749 } 852 }
853 if (NULL != i->notify_ctx)
854 {
855 GNUNET_CONTAINER_DLL_remove (req_handle->sampler->notify_ctx_head,
856 req_handle->sampler->notify_ctx_tail,
857 i->notify_ctx);
858 GNUNET_free (i->notify_ctx);
859 }
750 GNUNET_free (i); 860 GNUNET_free (i);
751 } 861 }
752 GNUNET_free (req_handle->ids); 862 GNUNET_free (req_handle->ids);