diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-06-09 15:12:03 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-06-09 15:12:03 +0000 |
commit | 7831efe09b1e8d30c7361e4b6c17b6966ad0fafa (patch) | |
tree | b4824d071fc9721bbec6609d98ef1fd069dfb232 /src/core | |
parent | 7ae3bcd234e062c28f66db9758f61af401d0a707 (diff) | |
download | gnunet-7831efe09b1e8d30c7361e4b6c17b6966ad0fafa.tar.gz gnunet-7831efe09b1e8d30c7361e4b6c17b6966ad0fafa.zip |
-fixing #2400
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/core.h | 4 | ||||
-rw-r--r-- | src/core/core_api.c | 289 |
2 files changed, 98 insertions, 195 deletions
diff --git a/src/core/core.h b/src/core/core.h index 03e328ca8..9b1802fbc 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
@@ -257,9 +257,9 @@ struct SendMessageRequest | |||
257 | struct GNUNET_PeerIdentity peer; | 257 | struct GNUNET_PeerIdentity peer; |
258 | 258 | ||
259 | /** | 259 | /** |
260 | * How large is the client's message queue for this peer? | 260 | * Always zero. |
261 | */ | 261 | */ |
262 | uint32_t queue_size GNUNET_PACKED; | 262 | uint32_t reserved GNUNET_PACKED; |
263 | 263 | ||
264 | /** | 264 | /** |
265 | * How large is the message? | 265 | * How large is the message? |
diff --git a/src/core/core_api.c b/src/core/core_api.c index 2b6407b6e..5c16adeae 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c | |||
@@ -31,6 +31,65 @@ | |||
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "core-api",__VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "core-api",__VA_ARGS__) |
33 | 33 | ||
34 | |||
35 | /** | ||
36 | * Handle for a transmission request. | ||
37 | */ | ||
38 | struct GNUNET_CORE_TransmitHandle | ||
39 | { | ||
40 | |||
41 | /** | ||
42 | * Corresponding peer record. | ||
43 | */ | ||
44 | struct PeerRecord *peer; | ||
45 | |||
46 | /** | ||
47 | * Corresponding SEND_REQUEST message. Only non-NULL | ||
48 | * while SEND_REQUEST message is pending. | ||
49 | */ | ||
50 | struct ControlMessage *cm; | ||
51 | |||
52 | /** | ||
53 | * Function that will be called to get the actual request | ||
54 | * (once we are ready to transmit this request to the core). | ||
55 | * The function will be called with a NULL buffer to signal | ||
56 | * timeout. | ||
57 | */ | ||
58 | GNUNET_CONNECTION_TransmitReadyNotify get_message; | ||
59 | |||
60 | /** | ||
61 | * Closure for get_message. | ||
62 | */ | ||
63 | void *get_message_cls; | ||
64 | |||
65 | /** | ||
66 | * Timeout for this handle. | ||
67 | */ | ||
68 | struct GNUNET_TIME_Absolute timeout; | ||
69 | |||
70 | /** | ||
71 | * How important is this message? | ||
72 | */ | ||
73 | uint32_t priority; | ||
74 | |||
75 | /** | ||
76 | * Size of this request. | ||
77 | */ | ||
78 | uint16_t msize; | ||
79 | |||
80 | /** | ||
81 | * Send message request ID for this request. | ||
82 | */ | ||
83 | uint16_t smr_id; | ||
84 | |||
85 | /** | ||
86 | * Is corking allowed? | ||
87 | */ | ||
88 | int cork; | ||
89 | |||
90 | }; | ||
91 | |||
92 | |||
34 | /** | 93 | /** |
35 | * Information we track for each peer. | 94 | * Information we track for each peer. |
36 | */ | 95 | */ |
@@ -62,16 +121,10 @@ struct PeerRecord | |||
62 | struct GNUNET_CORE_Handle *ch; | 121 | struct GNUNET_CORE_Handle *ch; |
63 | 122 | ||
64 | /** | 123 | /** |
65 | * Head of doubly-linked list of pending requests. | 124 | * Pending request, if any. 'th->peer' is set to NULL if the |
66 | * Requests are sorted by deadline *except* for HEAD, | 125 | * request is not active. |
67 | * which is only modified upon transmission to core. | ||
68 | */ | 126 | */ |
69 | struct GNUNET_CORE_TransmitHandle *pending_head; | 127 | struct GNUNET_CORE_TransmitHandle th; |
70 | |||
71 | /** | ||
72 | * Tail of doubly-linked list of pending requests. | ||
73 | */ | ||
74 | struct GNUNET_CORE_TransmitHandle *pending_tail; | ||
75 | 128 | ||
76 | /** | 129 | /** |
77 | * ID of timeout task for the 'pending_head' handle | 130 | * ID of timeout task for the 'pending_head' handle |
@@ -85,11 +138,6 @@ struct PeerRecord | |||
85 | GNUNET_SCHEDULER_TaskIdentifier ntr_task; | 138 | GNUNET_SCHEDULER_TaskIdentifier ntr_task; |
86 | 139 | ||
87 | /** | 140 | /** |
88 | * Current size of the queue of pending requests. | ||
89 | */ | ||
90 | unsigned int queue_size; | ||
91 | |||
92 | /** | ||
93 | * SendMessageRequest ID generator for this peer. | 141 | * SendMessageRequest ID generator for this peer. |
94 | */ | 142 | */ |
95 | uint16_t smr_id_gen; | 143 | uint16_t smr_id_gen; |
@@ -247,11 +295,6 @@ struct GNUNET_CORE_Handle | |||
247 | struct GNUNET_TIME_Relative retry_backoff; | 295 | struct GNUNET_TIME_Relative retry_backoff; |
248 | 296 | ||
249 | /** | 297 | /** |
250 | * Number of messages we are allowed to queue per target. | ||
251 | */ | ||
252 | unsigned int queue_size; | ||
253 | |||
254 | /** | ||
255 | * Number of entries in the handlers array. | 298 | * Number of entries in the handlers array. |
256 | */ | 299 | */ |
257 | unsigned int hcnt; | 300 | unsigned int hcnt; |
@@ -278,74 +321,6 @@ struct GNUNET_CORE_Handle | |||
278 | 321 | ||
279 | 322 | ||
280 | /** | 323 | /** |
281 | * Handle for a transmission request. | ||
282 | */ | ||
283 | struct GNUNET_CORE_TransmitHandle | ||
284 | { | ||
285 | |||
286 | /** | ||
287 | * We keep active transmit handles in a doubly-linked list. | ||
288 | */ | ||
289 | struct GNUNET_CORE_TransmitHandle *next; | ||
290 | |||
291 | /** | ||
292 | * We keep active transmit handles in a doubly-linked list. | ||
293 | */ | ||
294 | struct GNUNET_CORE_TransmitHandle *prev; | ||
295 | |||
296 | /** | ||
297 | * Corresponding peer record. | ||
298 | */ | ||
299 | struct PeerRecord *peer; | ||
300 | |||
301 | /** | ||
302 | * Corresponding SEND_REQUEST message. Only non-NULL | ||
303 | * while SEND_REQUEST message is pending. | ||
304 | */ | ||
305 | struct ControlMessage *cm; | ||
306 | |||
307 | /** | ||
308 | * Function that will be called to get the actual request | ||
309 | * (once we are ready to transmit this request to the core). | ||
310 | * The function will be called with a NULL buffer to signal | ||
311 | * timeout. | ||
312 | */ | ||
313 | GNUNET_CONNECTION_TransmitReadyNotify get_message; | ||
314 | |||
315 | /** | ||
316 | * Closure for get_message. | ||
317 | */ | ||
318 | void *get_message_cls; | ||
319 | |||
320 | /** | ||
321 | * Timeout for this handle. | ||
322 | */ | ||
323 | struct GNUNET_TIME_Absolute timeout; | ||
324 | |||
325 | /** | ||
326 | * How important is this message? | ||
327 | */ | ||
328 | uint32_t priority; | ||
329 | |||
330 | /** | ||
331 | * Size of this request. | ||
332 | */ | ||
333 | uint16_t msize; | ||
334 | |||
335 | /** | ||
336 | * Send message request ID for this request. | ||
337 | */ | ||
338 | uint16_t smr_id; | ||
339 | |||
340 | /** | ||
341 | * Is corking allowed? | ||
342 | */ | ||
343 | int cork; | ||
344 | |||
345 | }; | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Our current client connection went down. Clean it up | 324 | * Our current client connection went down. Clean it up |
350 | * and try to reconnect! | 325 | * and try to reconnect! |
351 | * | 326 | * |
@@ -404,23 +379,18 @@ disconnect_and_free_peer_entry (void *cls, const GNUNET_HashCode * key, | |||
404 | if (h->disconnects != NULL) | 379 | if (h->disconnects != NULL) |
405 | h->disconnects (h->cls, &pr->peer); | 380 | h->disconnects (h->cls, &pr->peer); |
406 | /* all requests should have been cancelled, clean up anyway, just in case */ | 381 | /* all requests should have been cancelled, clean up anyway, just in case */ |
407 | GNUNET_break (pr->queue_size == 0); | 382 | th = &pr->th; |
408 | while (NULL != (th = pr->pending_head)) | 383 | if (NULL != th->peer) |
409 | { | 384 | { |
410 | GNUNET_break (0); | 385 | GNUNET_break (0); |
411 | GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); | 386 | th->peer = NULL; |
412 | pr->queue_size--; | ||
413 | if (th->cm != NULL) | 387 | if (th->cm != NULL) |
414 | th->cm->th = NULL; | 388 | th->cm->th = NULL; |
415 | GNUNET_free (th); | ||
416 | } | 389 | } |
417 | /* done with 'voluntary' cleanups, now on to normal freeing */ | 390 | /* done with 'voluntary' cleanups, now on to normal freeing */ |
418 | GNUNET_assert (GNUNET_YES == | 391 | GNUNET_assert (GNUNET_YES == |
419 | GNUNET_CONTAINER_multihashmap_remove (h->peers, key, pr)); | 392 | GNUNET_CONTAINER_multihashmap_remove (h->peers, key, pr)); |
420 | GNUNET_assert (pr->pending_head == NULL); | ||
421 | GNUNET_assert (pr->pending_tail == NULL); | ||
422 | GNUNET_assert (pr->ch == h); | 393 | GNUNET_assert (pr->ch == h); |
423 | GNUNET_assert (pr->queue_size == 0); | ||
424 | GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK); | 394 | GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK); |
425 | GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK); | 395 | GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK); |
426 | GNUNET_free (pr); | 396 | GNUNET_free (pr); |
@@ -517,7 +487,8 @@ request_next_transmission (struct PeerRecord *pr) | |||
517 | GNUNET_SCHEDULER_cancel (pr->timeout_task); | 487 | GNUNET_SCHEDULER_cancel (pr->timeout_task); |
518 | pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 488 | pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
519 | } | 489 | } |
520 | if (NULL == (th = pr->pending_head)) | 490 | th = &pr->th; |
491 | if (NULL == th->peer) | ||
521 | { | 492 | { |
522 | trigger_next_request (h, GNUNET_NO); | 493 | trigger_next_request (h, GNUNET_NO); |
523 | return; | 494 | return; |
@@ -539,7 +510,7 @@ request_next_transmission (struct PeerRecord *pr) | |||
539 | smr->priority = htonl (th->priority); | 510 | smr->priority = htonl (th->priority); |
540 | smr->deadline = GNUNET_TIME_absolute_hton (th->timeout); | 511 | smr->deadline = GNUNET_TIME_absolute_hton (th->timeout); |
541 | smr->peer = pr->peer; | 512 | smr->peer = pr->peer; |
542 | smr->queue_size = htonl (pr->queue_size); | 513 | smr->reserved = htonl (0); |
543 | smr->size = htons (th->msize); | 514 | smr->size = htons (th->msize); |
544 | smr->smr_id = htons (th->smr_id = pr->smr_id_gen++); | 515 | smr->smr_id = htons (th->smr_id = pr->smr_id_gen++); |
545 | GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, | 516 | GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, |
@@ -566,9 +537,8 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
566 | struct GNUNET_CORE_TransmitHandle *th; | 537 | struct GNUNET_CORE_TransmitHandle *th; |
567 | 538 | ||
568 | pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 539 | pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
569 | th = pr->pending_head; | 540 | th = &pr->th; |
570 | GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); | 541 | th->peer = NULL; |
571 | pr->queue_size--; | ||
572 | if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head)) | 542 | if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head)) |
573 | { | 543 | { |
574 | /* the request that was 'approved' by core was | 544 | /* the request that was 'approved' by core was |
@@ -587,7 +557,6 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
587 | "Signalling timeout of request for transmission to CORE service\n"); | 557 | "Signalling timeout of request for transmission to CORE service\n"); |
588 | request_next_transmission (pr); | 558 | request_next_transmission (pr); |
589 | GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL)); | 559 | GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL)); |
590 | GNUNET_free (th); | ||
591 | } | 560 | } |
592 | 561 | ||
593 | 562 | ||
@@ -647,16 +616,15 @@ transmit_message (void *cls, size_t size, void *buf) | |||
647 | /* now check for 'ready' P2P messages */ | 616 | /* now check for 'ready' P2P messages */ |
648 | if (NULL != (pr = h->ready_peer_head)) | 617 | if (NULL != (pr = h->ready_peer_head)) |
649 | { | 618 | { |
650 | GNUNET_assert (pr->pending_head != NULL); | 619 | GNUNET_assert (NULL != pr->th.peer); |
651 | th = pr->pending_head; | 620 | th = &pr->th; |
652 | if (size < th->msize + sizeof (struct SendMessage)) | 621 | if (size < th->msize + sizeof (struct SendMessage)) |
653 | { | 622 | { |
654 | trigger_next_request (h, GNUNET_NO); | 623 | trigger_next_request (h, GNUNET_NO); |
655 | return 0; | 624 | return 0; |
656 | } | 625 | } |
657 | GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); | 626 | GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); |
658 | GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); | 627 | th->peer = NULL; |
659 | pr->queue_size--; | ||
660 | if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK) | 628 | if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK) |
661 | { | 629 | { |
662 | GNUNET_SCHEDULER_cancel (pr->timeout_task); | 630 | GNUNET_SCHEDULER_cancel (pr->timeout_task); |
@@ -679,7 +647,6 @@ transmit_message (void *cls, size_t size, void *buf) | |||
679 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 647 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
680 | "Transmitting SEND request to `%s' yielded %u bytes.\n", | 648 | "Transmitting SEND request to `%s' yielded %u bytes.\n", |
681 | GNUNET_i2s (&pr->peer), ret); | 649 | GNUNET_i2s (&pr->peer), ret); |
682 | GNUNET_free (th); | ||
683 | if (0 == ret) | 650 | if (0 == ret) |
684 | { | 651 | { |
685 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 652 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -738,7 +705,7 @@ trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down) | |||
738 | control_pending_head[1])->size); | 705 | control_pending_head[1])->size); |
739 | else if (h->ready_peer_head != NULL) | 706 | else if (h->ready_peer_head != NULL) |
740 | msize = | 707 | msize = |
741 | h->ready_peer_head->pending_head->msize + sizeof (struct SendMessage); | 708 | h->ready_peer_head->th.msize + sizeof (struct SendMessage); |
742 | else | 709 | else |
743 | { | 710 | { |
744 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 711 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -782,8 +749,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
782 | if (NULL == msg) | 749 | if (NULL == msg) |
783 | { | 750 | { |
784 | LOG (GNUNET_ERROR_TYPE_INFO, | 751 | LOG (GNUNET_ERROR_TYPE_INFO, |
785 | _ | 752 | _("Client was disconnected from core service, trying to reconnect.\n")); |
786 | ("Client was disconnected from core service, trying to reconnect.\n")); | ||
787 | reconnect_later (h); | 753 | reconnect_later (h); |
788 | return; | 754 | return; |
789 | } | 755 | } |
@@ -1032,14 +998,14 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
1032 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 998 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1033 | "Received notification about transmission readiness to `%s'.\n", | 999 | "Received notification about transmission readiness to `%s'.\n", |
1034 | GNUNET_i2s (&smr->peer)); | 1000 | GNUNET_i2s (&smr->peer)); |
1035 | if (NULL == pr->pending_head) | 1001 | if (NULL == pr->th.peer) |
1036 | { | 1002 | { |
1037 | /* request must have been cancelled between the original request | 1003 | /* request must have been cancelled between the original request |
1038 | * and the response from core, ignore core's readiness */ | 1004 | * and the response from core, ignore core's readiness */ |
1039 | break; | 1005 | break; |
1040 | } | 1006 | } |
1041 | 1007 | ||
1042 | th = pr->pending_head; | 1008 | th = &pr->th; |
1043 | if (ntohs (smr->smr_id) != th->smr_id) | 1009 | if (ntohs (smr->smr_id) != th->smr_id) |
1044 | { | 1010 | { |
1045 | /* READY message is for expired or cancelled message, | 1011 | /* READY message is for expired or cancelled message, |
@@ -1191,7 +1157,6 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1191 | 1157 | ||
1192 | h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle)); | 1158 | h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle)); |
1193 | h->cfg = cfg; | 1159 | h->cfg = cfg; |
1194 | h->queue_size = 1; // FIXME: remove entirely... | ||
1195 | h->cls = cls; | 1160 | h->cls = cls; |
1196 | h->init = init; | 1161 | h->init = init; |
1197 | h->connects = connects; | 1162 | h->connects = connects; |
@@ -1318,89 +1283,34 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork, | |||
1318 | { | 1283 | { |
1319 | struct PeerRecord *pr; | 1284 | struct PeerRecord *pr; |
1320 | struct GNUNET_CORE_TransmitHandle *th; | 1285 | struct GNUNET_CORE_TransmitHandle *th; |
1321 | struct GNUNET_CORE_TransmitHandle *pos; | ||
1322 | struct GNUNET_CORE_TransmitHandle *prev; | ||
1323 | struct GNUNET_CORE_TransmitHandle *minp; | ||
1324 | 1286 | ||
1287 | GNUNET_assert (NULL != notify); | ||
1325 | pr = GNUNET_CONTAINER_multihashmap_get (handle->peers, &target->hashPubKey); | 1288 | pr = GNUNET_CONTAINER_multihashmap_get (handle->peers, &target->hashPubKey); |
1326 | if (NULL == pr) | 1289 | if (NULL == pr) |
1327 | { | 1290 | { |
1328 | /* attempt to send to peer that is not connected */ | 1291 | /* attempt to send to peer that is not connected */ |
1329 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1292 | GNUNET_break (0); |
1330 | "Attempting to send to peer `%s' from peer `%s', but not connected!\n", | 1293 | return NULL; |
1331 | GNUNET_i2s (target), GNUNET_h2s (&handle->me.hashPubKey)); | 1294 | } |
1295 | if (NULL != pr->th.peer) | ||
1296 | { | ||
1297 | /* attempting to queue a second request for the same destination */ | ||
1332 | GNUNET_break (0); | 1298 | GNUNET_break (0); |
1333 | return NULL; | 1299 | return NULL; |
1334 | } | 1300 | } |
1335 | GNUNET_assert (notify_size + sizeof (struct SendMessage) < | 1301 | GNUNET_assert (notify_size + sizeof (struct SendMessage) < |
1336 | GNUNET_SERVER_MAX_MESSAGE_SIZE); | 1302 | GNUNET_SERVER_MAX_MESSAGE_SIZE); |
1337 | th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle)); | 1303 | th = &pr->th; |
1338 | th->peer = pr; | 1304 | th->peer = pr; |
1339 | GNUNET_assert (NULL != notify); | ||
1340 | th->get_message = notify; | 1305 | th->get_message = notify; |
1341 | th->get_message_cls = notify_cls; | 1306 | th->get_message_cls = notify_cls; |
1342 | th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay); | 1307 | th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay); |
1343 | th->priority = priority; | 1308 | th->priority = priority; |
1344 | th->msize = notify_size; | 1309 | th->msize = notify_size; |
1345 | th->cork = cork; | 1310 | th->cork = cork; |
1346 | /* bound queue size */ | 1311 | pr->ntr_task = |
1347 | if (pr->queue_size == handle->queue_size) | 1312 | GNUNET_SCHEDULER_add_now (&run_request_next_transmission, pr); |
1348 | { | ||
1349 | /* find lowest-priority entry, but skip the head of the list */ | ||
1350 | minp = pr->pending_head->next; | ||
1351 | prev = minp; | ||
1352 | while (prev != NULL) | ||
1353 | { | ||
1354 | if (prev->priority < minp->priority) | ||
1355 | minp = prev; | ||
1356 | prev = prev->next; | ||
1357 | } | ||
1358 | if (minp == NULL) | ||
1359 | { | ||
1360 | GNUNET_break (handle->queue_size != 0); | ||
1361 | GNUNET_break (pr->queue_size == 1); | ||
1362 | GNUNET_free (th); | ||
1363 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1364 | "Dropping transmission request: cannot drop queue head and limit is one\n"); | ||
1365 | return NULL; | ||
1366 | } | ||
1367 | if (priority <= minp->priority) | ||
1368 | { | ||
1369 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1370 | "Dropping transmission request: priority too low\n"); | ||
1371 | GNUNET_free (th); | ||
1372 | return NULL; /* priority too low */ | ||
1373 | } | ||
1374 | GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, minp); | ||
1375 | pr->queue_size--; | ||
1376 | GNUNET_assert (0 == minp->get_message (minp->get_message_cls, 0, NULL)); | ||
1377 | GNUNET_free (minp); | ||
1378 | } | ||
1379 | |||
1380 | /* Order entries by deadline, but SKIP 'HEAD' (as we may have transmitted | ||
1381 | * that request already or might even already be approved to transmit that | ||
1382 | * message to core) */ | ||
1383 | pos = pr->pending_head; | ||
1384 | if (pos != NULL) | ||
1385 | pos = pos->next; /* skip head */ | ||
1386 | |||
1387 | /* insertion sort */ | ||
1388 | prev = pos; | ||
1389 | while ((NULL != pos) && (pos->timeout.abs_value < th->timeout.abs_value)) | ||
1390 | { | ||
1391 | prev = pos; | ||
1392 | pos = pos->next; | ||
1393 | } | ||
1394 | GNUNET_CONTAINER_DLL_insert_after (pr->pending_head, pr->pending_tail, prev, | ||
1395 | th); | ||
1396 | pr->queue_size++; | ||
1397 | /* was the request queue previously empty? */ | ||
1398 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission request added to queue\n"); | 1313 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission request added to queue\n"); |
1399 | if ((pr->pending_head == th) && (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK) && | ||
1400 | (pr->next == NULL) && (pr->prev == NULL) && | ||
1401 | (handle->ready_peer_head != pr)) | ||
1402 | pr->ntr_task = | ||
1403 | GNUNET_SCHEDULER_add_now (&run_request_next_transmission, pr); | ||
1404 | return th; | 1314 | return th; |
1405 | } | 1315 | } |
1406 | 1316 | ||
@@ -1414,12 +1324,11 @@ void | |||
1414 | GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th) | 1324 | GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th) |
1415 | { | 1325 | { |
1416 | struct PeerRecord *pr = th->peer; | 1326 | struct PeerRecord *pr = th->peer; |
1417 | struct GNUNET_CORE_Handle *h = pr->ch; | 1327 | struct GNUNET_CORE_Handle *h; |
1418 | int was_head; | ||
1419 | 1328 | ||
1420 | was_head = (pr->pending_head == th); | 1329 | GNUNET_assert (NULL != pr); |
1421 | GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); | 1330 | th->peer = NULL; |
1422 | pr->queue_size--; | 1331 | h = pr->ch; |
1423 | if (NULL != th->cm) | 1332 | if (NULL != th->cm) |
1424 | { | 1333 | { |
1425 | /* we're currently in the control queue, remove */ | 1334 | /* we're currently in the control queue, remove */ |
@@ -1427,18 +1336,12 @@ GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th) | |||
1427 | h->control_pending_tail, th->cm); | 1336 | h->control_pending_tail, th->cm); |
1428 | GNUNET_free (th->cm); | 1337 | GNUNET_free (th->cm); |
1429 | } | 1338 | } |
1430 | GNUNET_free (th); | 1339 | if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head)) |
1431 | if (was_head) | ||
1432 | { | 1340 | { |
1433 | if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head)) | 1341 | /* the request that was 'approved' by core was |
1434 | { | 1342 | * canceled before it could be transmitted; remove |
1435 | /* the request that was 'approved' by core was | 1343 | * us from the 'ready' list */ |
1436 | * canceled before it could be transmitted; remove | 1344 | GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); |
1437 | * us from the 'ready' list */ | ||
1438 | GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); | ||
1439 | } | ||
1440 | if (NULL != h->client) | ||
1441 | request_next_transmission (pr); | ||
1442 | } | 1345 | } |
1443 | } | 1346 | } |
1444 | 1347 | ||