diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-03-27 11:00:57 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-03-27 11:00:57 +0000 |
commit | 79a55c154e2b706ad6fbc8d522955f240f33a8e4 (patch) | |
tree | 539b23e6463c9a85f9323c7d2e35a48af6e70183 /src/fs/gnunet-service-fs_cp.c | |
parent | c30009f3a51396348326b0591241af66203f29f1 (diff) | |
download | gnunet-79a55c154e2b706ad6fbc8d522955f240f33a8e4.tar.gz gnunet-79a55c154e2b706ad6fbc8d522955f240f33a8e4.zip |
delay as needed
Diffstat (limited to 'src/fs/gnunet-service-fs_cp.c')
-rw-r--r-- | src/fs/gnunet-service-fs_cp.c | 91 |
1 files changed, 73 insertions, 18 deletions
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c index 05638b657..a6f151e9e 100644 --- a/src/fs/gnunet-service-fs_cp.c +++ b/src/fs/gnunet-service-fs_cp.c | |||
@@ -153,11 +153,15 @@ struct GSF_ConnectedPeer | |||
153 | 153 | ||
154 | /** | 154 | /** |
155 | * Context of our GNUNET_CORE_peer_change_preference call (or NULL). | 155 | * Context of our GNUNET_CORE_peer_change_preference call (or NULL). |
156 | * NULL if we have successfully reserved 32k, otherwise non-NULL. | ||
157 | */ | 156 | */ |
158 | struct GNUNET_CORE_InformationRequestContext *irc; | 157 | struct GNUNET_CORE_InformationRequestContext *irc; |
159 | 158 | ||
160 | /** | 159 | /** |
160 | * Task scheduled if we need to retry bandwidth reservation later. | ||
161 | */ | ||
162 | GNUNET_SCHEDULER_TaskIdentifier irc_delay_task; | ||
163 | |||
164 | /** | ||
161 | * Active requests from this neighbour. | 165 | * Active requests from this neighbour. |
162 | */ | 166 | */ |
163 | struct GNUNET_CONTAINER_MultiHashMap *request_map; | 167 | struct GNUNET_CONTAINER_MultiHashMap *request_map; |
@@ -190,6 +194,12 @@ struct GSF_ConnectedPeer | |||
190 | */ | 194 | */ |
191 | unsigned int last_request_times_off; | 195 | unsigned int last_request_times_off; |
192 | 196 | ||
197 | /** | ||
198 | * GNUNET_YES if we did successfully reserve 32k bandwidth, | ||
199 | * GNUNET_NO if not. | ||
200 | */ | ||
201 | int did_reserve; | ||
202 | |||
193 | }; | 203 | }; |
194 | 204 | ||
195 | 205 | ||
@@ -340,32 +350,71 @@ core_reserve_callback (void *cls, | |||
340 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | 350 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, |
341 | int32_t amount, | 351 | int32_t amount, |
342 | struct GNUNET_TIME_Relative res_delay, | 352 | struct GNUNET_TIME_Relative res_delay, |
353 | uint64_t preference); | ||
354 | |||
355 | |||
356 | /** | ||
357 | * (re)try to reserve bandwidth from the given peer. | ||
358 | * | ||
359 | * @param cls the 'struct GSF_ConnectedPeer' to reserve from | ||
360 | * @param tc scheduler context | ||
361 | */ | ||
362 | static void | ||
363 | retry_reservation (void *cls, | ||
364 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
365 | { | ||
366 | struct GSF_ConnectedPeer *cp = cls; | ||
367 | uint64_t ip; | ||
368 | struct GNUNET_PeerIdentity target; | ||
369 | |||
370 | GNUNET_PEER_resolve (cp->ppd.pid, | ||
371 | &target); | ||
372 | cp->irc_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
373 | ip = cp->inc_preference; | ||
374 | cp->inc_preference = 0; | ||
375 | cp->irc = GNUNET_CORE_peer_change_preference (GSF_core, | ||
376 | &target, | ||
377 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
378 | GNUNET_BANDWIDTH_VALUE_MAX, | ||
379 | DBLOCK_SIZE, | ||
380 | ip, | ||
381 | &core_reserve_callback, | ||
382 | cp); | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Function called by core upon success or failure of our bandwidth reservation request. | ||
388 | * | ||
389 | * @param cls the 'struct GSF_ConnectedPeer' of the peer for which we made the request | ||
390 | * @param peer identifies the peer | ||
391 | * @param bandwidth_out available amount of outbound bandwidth | ||
392 | * @param amount set to the amount that was actually reserved or unreserved; | ||
393 | * either the full requested amount or zero (no partial reservations) | ||
394 | * @param res_delay if the reservation could not be satisfied (amount was 0), how | ||
395 | * long should the client wait until re-trying? | ||
396 | * @param preference current traffic preference for the given peer | ||
397 | */ | ||
398 | static void | ||
399 | core_reserve_callback (void *cls, | ||
400 | const struct GNUNET_PeerIdentity *peer, | ||
401 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
402 | int32_t amount, | ||
403 | struct GNUNET_TIME_Relative res_delay, | ||
343 | uint64_t preference) | 404 | uint64_t preference) |
344 | { | 405 | { |
345 | struct GSF_ConnectedPeer *cp = cls; | 406 | struct GSF_ConnectedPeer *cp = cls; |
346 | struct GSF_PeerTransmitHandle *pth; | 407 | struct GSF_PeerTransmitHandle *pth; |
347 | uint64_t ip; | ||
348 | 408 | ||
349 | cp->irc = NULL; | 409 | cp->irc = NULL; |
350 | if (0 == amount) | 410 | if (0 == amount) |
351 | { | 411 | { |
352 | /* failed; retry! (how did we get here!?) */ | 412 | cp->irc_delay_task = GNUNET_SCHEDULER_add_delayed (res_delay, |
353 | /* FIXME: wait res_delay before re-trying! */ | 413 | &retry_reservation, |
354 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 414 | cp); |
355 | _("Failed to reserve bandwidth to peer `%s'\n"), | ||
356 | GNUNET_i2s (peer)); | ||
357 | ip = cp->inc_preference; | ||
358 | cp->inc_preference = 0; | ||
359 | cp->irc = GNUNET_CORE_peer_change_preference (GSF_core, | ||
360 | peer, | ||
361 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
362 | GNUNET_BANDWIDTH_VALUE_MAX, | ||
363 | DBLOCK_SIZE, | ||
364 | ip, | ||
365 | &core_reserve_callback, | ||
366 | cp); | ||
367 | return; | 415 | return; |
368 | } | 416 | } |
417 | cp->did_reserve = GNUNET_YES; | ||
369 | pth = cp->pth_head; | 418 | pth = cp->pth_head; |
370 | if ( (NULL != pth) && | 419 | if ( (NULL != pth) && |
371 | (NULL == pth->cth) ) | 420 | (NULL == pth->cth) ) |
@@ -1089,8 +1138,9 @@ GSF_peer_transmit_ (struct GSF_ConnectedPeer *cp, | |||
1089 | { | 1138 | { |
1090 | /* query, need reservation */ | 1139 | /* query, need reservation */ |
1091 | cp->ppd.pending_queries++; | 1140 | cp->ppd.pending_queries++; |
1092 | if (NULL == cp->irc) | 1141 | if (GNUNET_YES == cp->did_reserve) |
1093 | { | 1142 | { |
1143 | cp->did_reserve = GNUNET_NO; | ||
1094 | /* reservation already done! */ | 1144 | /* reservation already done! */ |
1095 | is_ready = GNUNET_YES; | 1145 | is_ready = GNUNET_YES; |
1096 | ip = cp->inc_preference; | 1146 | ip = cp->inc_preference; |
@@ -1310,6 +1360,11 @@ GSF_peer_disconnect_handler_ (void *cls, | |||
1310 | GNUNET_CORE_peer_change_preference_cancel (cp->irc); | 1360 | GNUNET_CORE_peer_change_preference_cancel (cp->irc); |
1311 | cp->irc = NULL; | 1361 | cp->irc = NULL; |
1312 | } | 1362 | } |
1363 | if (GNUNET_SCHEDULER_NO_TASK != cp->irc_delay_task) | ||
1364 | { | ||
1365 | GNUNET_SCHEDULER_cancel (cp->irc_delay_task); | ||
1366 | cp->irc_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
1367 | } | ||
1313 | GNUNET_CONTAINER_multihashmap_iterate (cp->request_map, | 1368 | GNUNET_CONTAINER_multihashmap_iterate (cp->request_map, |
1314 | &cancel_pending_request, | 1369 | &cancel_pending_request, |
1315 | cp); | 1370 | cp); |