diff options
author | Julius Bünger <buenger@mytum.de> | 2018-09-20 22:34:18 +0200 |
---|---|---|
committer | Julius Bünger <buenger@mytum.de> | 2018-09-20 22:35:30 +0200 |
commit | 0ce2284452e86e3fb6991e573bed2d37b0be8331 (patch) | |
tree | a6245f1d30a37db149e23c26bb3caa7bd773ea8d /src/rps/gnunet-service-rps_sampler.c | |
parent | 33d8b5a803bf931822e3591a4d7387da3aedcc63 (diff) | |
download | gnunet-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.c | 164 |
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 | */ | ||
71 | typedef 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 | */ | ||
79 | struct 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 | */ |
69 | struct GetPeerCls | 106 | struct 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 | */ | ||
304 | struct SamplerNotifyUpdateCTX * | ||
305 | sampler_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, | |||
478 | RPS_sampler_update (struct RPS_Sampler *sampler, | 568 | RPS_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); |