diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/Messenger.c | 19 | ||||
-rw-r--r-- | toxcore/Messenger.h | 7 | ||||
-rw-r--r-- | toxcore/network.c | 71 | ||||
-rw-r--r-- | toxcore/network.h | 7 | ||||
-rw-r--r-- | toxcore/tox.c | 19 | ||||
-rw-r--r-- | toxcore/tox.h | 40 |
6 files changed, 106 insertions, 57 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 81a347be..e48fa5fc 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -2342,19 +2342,24 @@ void do_messenger(Messenger *m) | |||
2342 | /* | 2342 | /* |
2343 | * functions to avoid excessive polling | 2343 | * functions to avoid excessive polling |
2344 | */ | 2344 | */ |
2345 | int wait_prepare_messenger(Messenger *m, uint8_t *data, uint16_t *lenptr) | 2345 | size_t wait_data_size() |
2346 | { | 2346 | { |
2347 | return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data, lenptr); | 2347 | return networking_wait_data_size(); |
2348 | } | 2348 | } |
2349 | 2349 | ||
2350 | int wait_execute_messenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds) | 2350 | int wait_prepare_messenger(Messenger *m, uint8_t *data) |
2351 | { | 2351 | { |
2352 | return networking_wait_execute(data, len, milliseconds); | 2352 | return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data); |
2353 | }; | 2353 | } |
2354 | |||
2355 | int wait_execute_messenger(uint8_t *data, long seconds, long microseconds) | ||
2356 | { | ||
2357 | return networking_wait_execute(data, seconds, microseconds); | ||
2358 | } | ||
2354 | 2359 | ||
2355 | void wait_cleanup_messenger(Messenger *m, uint8_t *data, uint16_t len) | 2360 | int wait_cleanup_messenger(Messenger *m, uint8_t *data) |
2356 | { | 2361 | { |
2357 | networking_wait_cleanup(m->net, data, len); | 2362 | return networking_wait_cleanup(m->net, data); |
2358 | } | 2363 | } |
2359 | 2364 | ||
2360 | /* new messenger format for load/save, more robust and forward compatible */ | 2365 | /* new messenger format for load/save, more robust and forward compatible */ |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 213f8586..32b1f1b3 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -715,9 +715,10 @@ void do_messenger(Messenger *m); | |||
715 | /* | 715 | /* |
716 | * functions to avoid excessive polling | 716 | * functions to avoid excessive polling |
717 | */ | 717 | */ |
718 | int wait_prepare_messenger(Messenger *m, uint8_t *data, uint16_t *lenptr); | 718 | size_t wait_data_size(); |
719 | int wait_execute_messenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds); | 719 | int wait_prepare_messenger(Messenger *m, uint8_t *data); |
720 | void wait_cleanup_messenger(Messenger *m, uint8_t *data, uint16_t len); | 720 | int wait_execute_messenger(uint8_t *data, long seconds, long microseconds); |
721 | int wait_cleanup_messenger(Messenger *m, uint8_t *data); | ||
721 | 722 | ||
722 | /* SAVING AND LOADING FUNCTIONS: */ | 723 | /* SAVING AND LOADING FUNCTIONS: */ |
723 | 724 | ||
diff --git a/toxcore/network.c b/toxcore/network.c index 839618bf..35b55bf1 100644 --- a/toxcore/network.c +++ b/toxcore/network.c | |||
@@ -315,17 +315,17 @@ typedef struct { | |||
315 | uint64_t send_fail_eagain; | 315 | uint64_t send_fail_eagain; |
316 | } select_info; | 316 | } select_info; |
317 | 317 | ||
318 | int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr) | 318 | size_t networking_wait_data_size() |
319 | { | 319 | { |
320 | if ((data == NULL) || !lenptr || (*lenptr < sizeof(select_info))) { | 320 | return sizeof(select_info); |
321 | if (lenptr) { | 321 | } |
322 | *lenptr = sizeof(select_info); | 322 | |
323 | return 0; | 323 | int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data) |
324 | } else | 324 | { |
325 | return -1; | 325 | if (data == NULL) { |
326 | return 0; | ||
326 | } | 327 | } |
327 | 328 | ||
328 | *lenptr = sizeof(select_info); | ||
329 | select_info *s = (select_info *)data; | 329 | select_info *s = (select_info *)data; |
330 | s->sock = net->sock; | 330 | s->sock = net->sock; |
331 | s->sendqueue_length = sendqueue_length; | 331 | s->sendqueue_length = sendqueue_length; |
@@ -335,25 +335,41 @@ int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uin | |||
335 | return 1; | 335 | return 1; |
336 | } | 336 | } |
337 | 337 | ||
338 | int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) | 338 | /* *** Function MUSTN'T poll. *** |
339 | * The function mustn't modify anything at all, so it can be called completely | ||
340 | * asynchronously without any worry. | ||
341 | */ | ||
342 | int networking_wait_execute(uint8_t *data, long seconds, long microseconds) | ||
339 | { | 343 | { |
340 | /* WIN32: supported since Win2K, but might need some adjustements */ | 344 | /* WIN32: supported since Win2K, but might need some adjustements */ |
341 | /* UNIX: this should work for any remotely Unix'ish system */ | 345 | /* UNIX: this should work for any remotely Unix'ish system */ |
342 | 346 | ||
347 | if (data == NULL) { | ||
348 | return 0; | ||
349 | } | ||
350 | |||
343 | select_info *s = (select_info *)data; | 351 | select_info *s = (select_info *)data; |
344 | 352 | ||
345 | /* add only if we had a failed write */ | 353 | /* add only if we had a failed write */ |
346 | int writefds_add = 0; | 354 | int writefds_add = 0; |
347 | 355 | ||
356 | /* if send_fail_eagain is set, that means that socket's buffer was full and couldn't fit data we tried to send, | ||
357 | * so this is the only case when we need to know when the socket becomes write-ready, i.e. socket's buffer gets | ||
358 | * some free space for us to put data to be sent in, but select will tell us that the socket is writable even | ||
359 | * if we can fit a small part of our data (say 1 byte), so we wait some time, in hope that large enough chunk | ||
360 | * of socket's buffer will be available (at least that's how I understand intentions of the previous author of | ||
361 | * that code) | ||
362 | */ | ||
348 | if (s->send_fail_eagain != 0) { | 363 | if (s->send_fail_eagain != 0) { |
349 | // current_time(): microseconds | 364 | // current_time(): microseconds |
350 | uint64_t now = current_time(); | 365 | uint64_t now = current_time(); |
351 | 366 | ||
352 | /* s->sendqueue_length: might be used to guess how long we keep checking */ | 367 | /* s->sendqueue_length: might be used to guess how long we keep checking */ |
353 | /* for now, threshold is hardcoded to 500ms, too long for a really really | 368 | /* for now, threshold is hardcoded to 250ms, too long for a really really |
354 | * fast link, but too short for a sloooooow link... */ | 369 | * fast link, but too short for a sloooooow link... */ |
355 | if (now - s->send_fail_eagain < 500000) | 370 | if (now - s->send_fail_eagain < 250000) { |
356 | writefds_add = 1; | 371 | writefds_add = 1; |
372 | } | ||
357 | } | 373 | } |
358 | 374 | ||
359 | int nfds = 1 + s->sock; | 375 | int nfds = 1 + s->sock; |
@@ -366,27 +382,34 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) | |||
366 | fd_set writefds; | 382 | fd_set writefds; |
367 | FD_ZERO(&writefds); | 383 | FD_ZERO(&writefds); |
368 | 384 | ||
369 | if (writefds_add) | 385 | if (writefds_add) { |
370 | FD_SET(s->sock, &writefds); | 386 | FD_SET(s->sock, &writefds); |
387 | } | ||
371 | 388 | ||
372 | fd_set exceptfds; | 389 | fd_set exceptfds; |
373 | FD_ZERO(&exceptfds); | 390 | FD_ZERO(&exceptfds); |
374 | FD_SET(s->sock, &exceptfds); | 391 | FD_SET(s->sock, &exceptfds); |
375 | 392 | ||
376 | struct timeval timeout; | 393 | struct timeval timeout; |
377 | timeout.tv_sec = 0; | 394 | struct timeval *timeout_ptr = &timeout; |
378 | timeout.tv_usec = milliseconds * 1000; | 395 | |
396 | if (seconds < 0 || microseconds < 0) { | ||
397 | timeout_ptr = NULL; | ||
398 | } else { | ||
399 | timeout.tv_sec = seconds; | ||
400 | timeout.tv_usec = microseconds; | ||
401 | } | ||
379 | 402 | ||
380 | #ifdef LOGGING | 403 | #ifdef LOGGING |
381 | errno = 0; | 404 | errno = 0; |
382 | #endif | 405 | #endif |
383 | /* returns -1 on error, 0 on timeout, the socket on activity */ | 406 | /* returns -1 on error, 0 on timeout, the socket on activity */ |
384 | int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout); | 407 | int res = select(nfds, &readfds, &writefds, &exceptfds, timeout_ptr); |
385 | #ifdef LOGGING | 408 | #ifdef LOGGING |
386 | 409 | ||
387 | /* only dump if not timeout */ | 410 | /* only dump if not timeout */ |
388 | if (res) { | 411 | if (res) { |
389 | sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, | 412 | sprintf(logbuffer, "select(%d, %d): %d (%d, %s) - %d %d %d\n", microseconds, seconds, res, errno, |
390 | strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), | 413 | strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), |
391 | FD_ISSET(s->sock, &exceptfds)); | 414 | FD_ISSET(s->sock, &exceptfds)); |
392 | loglog(logbuffer); | 415 | loglog(logbuffer); |
@@ -394,18 +417,26 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) | |||
394 | 417 | ||
395 | #endif | 418 | #endif |
396 | 419 | ||
397 | if (FD_ISSET(s->sock, &writefds)) | 420 | if (FD_ISSET(s->sock, &writefds)) { |
398 | s->send_fail_reset = 1; | 421 | s->send_fail_reset = 1; |
422 | } | ||
399 | 423 | ||
400 | return res > 0 ? 1 : 0; | 424 | return res > 0 ? 2 : 1; |
401 | } | 425 | } |
402 | 426 | ||
403 | void networking_wait_cleanup(Networking_Core *net, uint8_t *data, uint16_t len) | 427 | int networking_wait_cleanup(Networking_Core *net, uint8_t *data) |
404 | { | 428 | { |
429 | if (data == NULL) { | ||
430 | return 0; | ||
431 | } | ||
432 | |||
405 | select_info *s = (select_info *)data; | 433 | select_info *s = (select_info *)data; |
406 | 434 | ||
407 | if (s->send_fail_reset) | 435 | if (s->send_fail_reset) { |
408 | net->send_fail_eagain = 0; | 436 | net->send_fail_eagain = 0; |
437 | } | ||
438 | |||
439 | return 1; | ||
409 | } | 440 | } |
410 | 441 | ||
411 | uint8_t at_startup_ran = 0; | 442 | uint8_t at_startup_ran = 0; |
diff --git a/toxcore/network.h b/toxcore/network.h index aaf89f19..97a73014 100644 --- a/toxcore/network.h +++ b/toxcore/network.h | |||
@@ -312,9 +312,10 @@ void networking_poll(Networking_Core *net); | |||
312 | /* | 312 | /* |
313 | * functions to avoid excessive polling | 313 | * functions to avoid excessive polling |
314 | */ | 314 | */ |
315 | int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr); | 315 | size_t networking_wait_data_size(); |
316 | int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds); | 316 | int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data); |
317 | void networking_wait_cleanup(Networking_Core *net, uint8_t *data, uint16_t len); | 317 | int networking_wait_execute(uint8_t *data, long seconds, long microseconds); |
318 | int networking_wait_cleanup(Networking_Core *net, uint8_t *data); | ||
318 | 319 | ||
319 | /* Initialize networking. | 320 | /* Initialize networking. |
320 | * bind to ip and port. | 321 | * bind to ip and port. |
diff --git a/toxcore/tox.c b/toxcore/tox.c index d3e596ba..aec0d902 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -767,22 +767,27 @@ void tox_do(Tox *tox) | |||
767 | /* | 767 | /* |
768 | * functions to avoid excessive polling | 768 | * functions to avoid excessive polling |
769 | */ | 769 | */ |
770 | int tox_wait_prepare(Tox *tox, uint8_t *data, uint16_t *lenptr) | 770 | |
771 | size_t tox_wait_data_size() | ||
771 | { | 772 | { |
772 | Messenger *m = tox; | 773 | return wait_data_size(); |
773 | return wait_prepare_messenger(m, data, lenptr); | ||
774 | } | 774 | } |
775 | 775 | ||
776 | int tox_wait_execute(Tox *tox, uint8_t *data, uint16_t len, uint16_t milliseconds) | 776 | int tox_wait_prepare(Tox *tox, uint8_t *data) |
777 | { | 777 | { |
778 | Messenger *m = tox; | 778 | Messenger *m = tox; |
779 | return wait_execute_messenger(m, data, len, milliseconds); | 779 | return wait_prepare_messenger(m, data); |
780 | } | ||
781 | |||
782 | int tox_wait_execute(uint8_t *data, long seconds, long microseconds) | ||
783 | { | ||
784 | return wait_execute_messenger(data, seconds, microseconds); | ||
780 | } | 785 | } |
781 | 786 | ||
782 | void tox_wait_cleanup(Tox *tox, uint8_t *data, uint16_t len) | 787 | int tox_wait_cleanup(Tox *tox, uint8_t *data) |
783 | { | 788 | { |
784 | Messenger *m = tox; | 789 | Messenger *m = tox; |
785 | wait_cleanup_messenger(m, data, len); | 790 | return wait_cleanup_messenger(m, data); |
786 | } | 791 | } |
787 | 792 | ||
788 | /* SAVING AND LOADING FUNCTIONS: */ | 793 | /* SAVING AND LOADING FUNCTIONS: */ |
diff --git a/toxcore/tox.h b/toxcore/tox.h index 5b619cd0..1c84c1cb 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -662,37 +662,43 @@ void tox_kill(Tox *tox); | |||
662 | void tox_do(Tox *tox); | 662 | void tox_do(Tox *tox); |
663 | 663 | ||
664 | /* | 664 | /* |
665 | * tox_wait_prepare(): function should be called under lock | 665 | * tox_wait_data_size(): |
666 | * | ||
667 | * returns a size of data buffer to allocate. the size is constant. | ||
668 | * | ||
669 | * tox_wait_prepare(): function should be called under lock every time we want to call tox_wait_execute() | ||
666 | * Prepares the data required to call tox_wait_execute() asynchronously | 670 | * Prepares the data required to call tox_wait_execute() asynchronously |
667 | * | 671 | * |
668 | * data[] is reserved and kept by the caller | 672 | * data[] should be of at least tox_wait_data_size() size and it's reserved and kept by the caller |
669 | * *lenptr is in/out: in = reserved data[], out = required data[] | 673 | * Use that data[] to call tox_wait_execute() |
670 | * | 674 | * |
671 | * returns 1 on success | 675 | * returns 1 on success |
672 | * returns 0 if *lenptr is insufficient | 676 | * returns 0 if data was NULL |
673 | * returns -1 if lenptr is NULL | ||
674 | * | 677 | * |
675 | * | 678 | * |
676 | * tox_wait_execute(): function can be called asynchronously | 679 | * tox_wait_execute(): function can be called asynchronously |
677 | * Waits for something to happen on the socket for up to milliseconds milliseconds. | 680 | * Waits for something to happen on the socket for up to seconds seconds and mircoseconds microseconds. |
678 | * *** Function MUSTN'T poll. *** | 681 | * mircoseconds should be between 0 and 999999. |
679 | * The function mustn't modify anything at all, so it can be called completely | 682 | * If you set either or both seconds and microseconds to negatives, it will block indefinetly until there |
680 | * asynchronously without any worry. | 683 | * is an activity. |
681 | * | 684 | * |
682 | * returns 1 if there is socket activity (i.e. tox_do() should be called) | 685 | * returns 2 if there is socket activity (i.e. tox_do() should be called) |
683 | * returns 0 if the timeout was reached | 686 | * returns 1 if the timeout was reached (tox_do() should be called anyway. it's advised to call it at least |
684 | * returns -1 if data was NULL or len too short | 687 | * once per second) |
688 | * returns 0 if data was NULL | ||
685 | * | 689 | * |
686 | * | 690 | * |
687 | * tox_wait_cleanup(): function should be called under lock | 691 | * tox_wait_cleanup(): function should be called under lock, every time tox_wait_execute() finishes |
688 | * Stores results from tox_wait_execute(). | 692 | * Stores results from tox_wait_execute(). |
689 | * | 693 | * |
690 | * data[]/len shall be the exact same as given to tox_wait_execute() | 694 | * returns 1 on success |
695 | * returns 0 if data was NULL | ||
691 | * | 696 | * |
692 | */ | 697 | */ |
693 | int tox_wait_prepare(Tox *tox, uint8_t *data, uint16_t *lenptr); | 698 | size_t tox_wait_data_size(); |
694 | int tox_wait_execute(Tox *tox, uint8_t *data, uint16_t len, uint16_t milliseconds); | 699 | int tox_wait_prepare(Tox *tox, uint8_t *data); |
695 | void tox_wait_cleanup(Tox *tox, uint8_t *data, uint16_t len); | 700 | int tox_wait_execute(uint8_t *data, long seconds, long microseconds); |
701 | int tox_wait_cleanup(Tox *tox, uint8_t *data); | ||
696 | 702 | ||
697 | 703 | ||
698 | /* SAVING AND LOADING FUNCTIONS: */ | 704 | /* SAVING AND LOADING FUNCTIONS: */ |