diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | CMakeLists.txt | 20 | ||||
-rw-r--r-- | auto_tests/Makefile.inc | 11 | ||||
-rw-r--r-- | auto_tests/tox_loop_test.c | 61 | ||||
-rw-r--r-- | circle.yml | 1 | ||||
-rw-r--r-- | cmake/Dependencies.cmake | 32 | ||||
-rw-r--r-- | cmake/ModulePackage.cmake | 27 | ||||
-rw-r--r-- | configure.ac | 251 | ||||
-rw-r--r-- | libtoxcore.pc.in | 2 | ||||
-rw-r--r-- | toxcore/Makefile.inc | 6 | ||||
-rw-r--r-- | toxcore/Messenger.c | 28 | ||||
-rw-r--r-- | toxcore/Messenger.h | 20 | ||||
-rw-r--r-- | toxcore/TCP_client.c | 11 | ||||
-rw-r--r-- | toxcore/TCP_client.h | 16 | ||||
-rw-r--r-- | toxcore/TCP_connection.c | 31 | ||||
-rw-r--r-- | toxcore/TCP_connection.h | 4 | ||||
-rw-r--r-- | toxcore/network.c | 10 | ||||
-rw-r--r-- | toxcore/network.h | 13 | ||||
-rw-r--r-- | toxcore/tox.api.h | 34 | ||||
-rw-r--r-- | toxcore/tox.c | 338 | ||||
-rw-r--r-- | toxcore/tox.h | 41 |
21 files changed, 852 insertions, 107 deletions
diff --git a/.travis.yml b/.travis.yml index 2e636552..95924133 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -33,6 +33,8 @@ addons: | |||
33 | packages: | 33 | packages: |
34 | - check | 34 | - check |
35 | - libcv-dev # For av_test. | 35 | - libcv-dev # For av_test. |
36 | - libev-dev # For tox_loop. | ||
37 | - libevent-dev # For tox_loop. | ||
36 | - libhighgui-dev # For av_test. | 38 | - libhighgui-dev # For av_test. |
37 | - libopencv-contrib-dev # For av_test. | 39 | - libopencv-contrib-dev # For av_test. |
38 | - libsndfile1-dev # For av_test. | 40 | - libsndfile1-dev # For av_test. |
diff --git a/CMakeLists.txt b/CMakeLists.txt index e9743d49..5bcafaf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -183,6 +183,12 @@ if (BUILD_TOXAV) | |||
183 | endif() | 183 | endif() |
184 | endif() | 184 | endif() |
185 | 185 | ||
186 | if(LIBEV_FOUND) | ||
187 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_LIBEV") | ||
188 | elseif(LIBEVENT_FOUND) | ||
189 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_LIBEVENT") | ||
190 | endif() | ||
191 | |||
186 | ################################################################################ | 192 | ################################################################################ |
187 | # | 193 | # |
188 | # :: Tox Core Library | 194 | # :: Tox Core Library |
@@ -234,6 +240,18 @@ if(RT_LIBRARIES) | |||
234 | set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} "-lrt") | 240 | set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} "-lrt") |
235 | endif() | 241 | endif() |
236 | 242 | ||
243 | if(LIBEV_FOUND) | ||
244 | target_link_modules(toxnetwork ${LIBEV_LIBRARIES}) | ||
245 | set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} "-lev") | ||
246 | elseif(LIBEVENT_FOUND) | ||
247 | target_link_modules(toxnetwork ${LIBEVENT_LIBRARIES}) | ||
248 | if(NOT WIN32) | ||
249 | set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} "-levent -levent_pthreads") | ||
250 | else() | ||
251 | set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} "-levent") | ||
252 | endif() | ||
253 | endif() | ||
254 | |||
237 | if(WIN32) | 255 | if(WIN32) |
238 | target_link_modules(toxnetwork ws2_32 iphlpapi) | 256 | target_link_modules(toxnetwork ws2_32 iphlpapi) |
239 | set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} "-lws2_32 -liphlpapi") | 257 | set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} "-lws2_32 -liphlpapi") |
@@ -425,7 +443,7 @@ auto_test(resource_leak) | |||
425 | auto_test(save_friend) | 443 | auto_test(save_friend) |
426 | auto_test(skeleton) | 444 | auto_test(skeleton) |
427 | auto_test(tox) | 445 | auto_test(tox) |
428 | auto_test(tox_loop_test) | 446 | auto_test(tox_loop) |
429 | auto_test(tox_many) | 447 | auto_test(tox_many) |
430 | auto_test(tox_many_tcp) | 448 | auto_test(tox_many_tcp) |
431 | auto_test(tox_one) | 449 | auto_test(tox_one) |
diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc index 698064c4..d8d8b1eb 100644 --- a/auto_tests/Makefile.inc +++ b/auto_tests/Makefile.inc | |||
@@ -1,7 +1,7 @@ | |||
1 | if BUILD_TESTS | 1 | if BUILD_TESTS |
2 | 2 | ||
3 | TESTS = encryptsave_test messenger_autotest crypto_test network_test onion_test TCP_test tox_test dht_autotest tox_strncasecmp_test | 3 | TESTS = encryptsave_test messenger_autotest crypto_test network_test onion_test TCP_test tox_loop_test tox_test dht_autotest tox_strncasecmp_test |
4 | check_PROGRAMS = encryptsave_test messenger_autotest crypto_test network_test onion_test TCP_test tox_test dht_autotest tox_strncasecmp_test | 4 | check_PROGRAMS = encryptsave_test messenger_autotest crypto_test network_test onion_test TCP_test tox_loop_test tox_test dht_autotest tox_strncasecmp_test |
5 | 5 | ||
6 | AUTOTEST_CFLAGS = \ | 6 | AUTOTEST_CFLAGS = \ |
7 | $(LIBSODIUM_CFLAGS) \ | 7 | $(LIBSODIUM_CFLAGS) \ |
@@ -61,6 +61,13 @@ TCP_test_CFLAGS = $(AUTOTEST_CFLAGS) | |||
61 | TCP_test_LDADD = $(AUTOTEST_LDADD) | 61 | TCP_test_LDADD = $(AUTOTEST_LDADD) |
62 | 62 | ||
63 | 63 | ||
64 | tox_loop_test_SOURCES = ../auto_tests/tox_loop_test.c | ||
65 | |||
66 | tox_loop_test_CFLAGS = $(AUTOTEST_CFLAGS) | ||
67 | |||
68 | tox_loop_test_LDADD = $(AUTOTEST_LDADD) | ||
69 | |||
70 | |||
64 | tox_test_SOURCES = ../auto_tests/tox_test.c | 71 | tox_test_SOURCES = ../auto_tests/tox_test.c |
65 | 72 | ||
66 | tox_test_CFLAGS = $(AUTOTEST_CFLAGS) | 73 | tox_test_CFLAGS = $(AUTOTEST_CFLAGS) |
diff --git a/auto_tests/tox_loop_test.c b/auto_tests/tox_loop_test.c index 56e78bda..7589cc4b 100644 --- a/auto_tests/tox_loop_test.c +++ b/auto_tests/tox_loop_test.c | |||
@@ -1,15 +1,13 @@ | |||
1 | |||
2 | |||
3 | #include "helpers.h" | ||
4 | |||
5 | #include "../toxcore/tox.h" | ||
6 | |||
7 | #include <check.h> | 1 | #include <check.h> |
8 | #include <pthread.h> | 2 | #include <pthread.h> |
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <time.h> | ||
11 | #include <unistd.h> | 5 | #include <unistd.h> |
12 | 6 | ||
7 | #include "../toxcore/tox.h" | ||
8 | |||
9 | #include "helpers.h" | ||
10 | |||
13 | #define TCP_RELAY_PORT 33448 | 11 | #define TCP_RELAY_PORT 33448 |
14 | /* The Travis-CI container responds poorly to ::1 as a localhost address | 12 | /* The Travis-CI container responds poorly to ::1 as a localhost address |
15 | * You're encouraged to -D FORCE_TESTS_IPV6 on a local test */ | 13 | * You're encouraged to -D FORCE_TESTS_IPV6 on a local test */ |
@@ -19,38 +17,38 @@ | |||
19 | #define TOX_LOCALHOST "127.0.0.1" | 17 | #define TOX_LOCALHOST "127.0.0.1" |
20 | #endif | 18 | #endif |
21 | 19 | ||
22 | struct loop_test { | 20 | typedef struct { |
23 | int start_count, stop_count; | 21 | int start_count, stop_count; |
24 | pthread_mutex_t mutex; | 22 | pthread_mutex_t mutex; |
25 | Tox *tox; | 23 | Tox *tox; |
26 | }; | 24 | } loop_test; |
27 | 25 | ||
28 | void tox_loop_cb_start(Tox *tox, void *user_data) | 26 | void tox_loop_cb_start(Tox *tox, void *user_data) |
29 | { | 27 | { |
30 | struct loop_test *userdata = user_data; | 28 | loop_test *userdata = (loop_test *) user_data; |
31 | pthread_mutex_lock(&userdata->mutex); | 29 | pthread_mutex_lock(&userdata->mutex); |
32 | userdata->start_count++; | 30 | userdata->start_count++; |
33 | } | 31 | } |
34 | 32 | ||
35 | void tox_loop_cb_stop(Tox *tox, void *user_data) | 33 | void tox_loop_cb_stop(Tox *tox, void *user_data) |
36 | { | 34 | { |
37 | struct loop_test *userdata = user_data; | 35 | loop_test *userdata = (loop_test *) user_data; |
38 | userdata->stop_count++; | 36 | userdata->stop_count++; |
39 | pthread_mutex_unlock(&userdata->mutex); | 37 | pthread_mutex_unlock(&userdata->mutex); |
40 | } | 38 | } |
41 | 39 | ||
42 | void *tox_loop_worker(void *data) | 40 | void *tox_loop_worker(void *data) |
43 | { | 41 | { |
44 | struct loop_test *userdata = data; | 42 | loop_test *userdata = (loop_test *) data; |
45 | int retval = tox_loop(userdata->tox, data); | 43 | tox_loop(userdata->tox, data, NULL); |
46 | return (void *)retval; | 44 | return NULL; |
47 | } | 45 | } |
48 | 46 | ||
49 | START_TEST(test_tox_loop) | 47 | START_TEST(test_tox_loop) |
50 | { | 48 | { |
51 | pthread_t worker1, worker2; | 49 | pthread_t worker, worker_tcp; |
52 | struct Tox_Options opts; | 50 | struct Tox_Options *opts = tox_options_new(NULL); |
53 | struct loop_test userdata; | 51 | loop_test userdata; |
54 | uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; | 52 | uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; |
55 | int retval; | 53 | int retval; |
56 | 54 | ||
@@ -58,43 +56,42 @@ START_TEST(test_tox_loop) | |||
58 | userdata.stop_count = 0; | 56 | userdata.stop_count = 0; |
59 | pthread_mutex_init(&userdata.mutex, NULL); | 57 | pthread_mutex_init(&userdata.mutex, NULL); |
60 | 58 | ||
61 | tox_options_default(&opts); | 59 | tox_options_set_tcp_port(opts, TCP_RELAY_PORT); |
62 | opts.tcp_port = TCP_RELAY_PORT; | 60 | userdata.tox = tox_new(opts, NULL); |
63 | userdata.tox = tox_new(&opts, 0); | ||
64 | tox_callback_loop_begin(userdata.tox, tox_loop_cb_start); | 61 | tox_callback_loop_begin(userdata.tox, tox_loop_cb_start); |
65 | tox_callback_loop_end(userdata.tox, tox_loop_cb_stop); | 62 | tox_callback_loop_end(userdata.tox, tox_loop_cb_stop); |
66 | pthread_create(&worker1, NULL, tox_loop_worker, &userdata); | 63 | pthread_create(&worker, NULL, tox_loop_worker, &userdata); |
67 | 64 | ||
68 | tox_self_get_dht_id(userdata.tox, dpk); | 65 | tox_self_get_dht_id(userdata.tox, dpk); |
69 | 66 | ||
70 | tox_options_default(&opts); | 67 | tox_options_default(opts); |
71 | struct loop_test userdata_tcp; | 68 | loop_test userdata_tcp; |
72 | userdata_tcp.start_count = 0; | 69 | userdata_tcp.start_count = 0; |
73 | userdata_tcp.stop_count = 0; | 70 | userdata_tcp.stop_count = 0; |
74 | pthread_mutex_init(&userdata_tcp.mutex, NULL); | 71 | pthread_mutex_init(&userdata_tcp.mutex, NULL); |
75 | userdata_tcp.tox = tox_new(&opts, 0); | 72 | userdata_tcp.tox = tox_new(opts, NULL); |
76 | tox_callback_loop_begin(userdata_tcp.tox, tox_loop_cb_start); | 73 | tox_callback_loop_begin(userdata_tcp.tox, tox_loop_cb_start); |
77 | tox_callback_loop_end(userdata_tcp.tox, tox_loop_cb_stop); | 74 | tox_callback_loop_end(userdata_tcp.tox, tox_loop_cb_stop); |
78 | pthread_create(&worker2, NULL, tox_loop_worker, &userdata_tcp); | 75 | pthread_create(&worker_tcp, NULL, tox_loop_worker, &userdata_tcp); |
79 | 76 | ||
80 | pthread_mutex_lock(&userdata_tcp.mutex); | 77 | pthread_mutex_lock(&userdata_tcp.mutex); |
81 | TOX_ERR_BOOTSTRAP error = 0; | 78 | TOX_ERR_BOOTSTRAP error; |
82 | ck_assert_msg(tox_add_tcp_relay(userdata_tcp.tox, TOX_LOCALHOST, TCP_RELAY_PORT, dpk, &error), "add relay error, %i", | 79 | ck_assert_msg(tox_add_tcp_relay(userdata_tcp.tox, TOX_LOCALHOST, TCP_RELAY_PORT, dpk, &error), "Add relay error, %i", |
83 | error); | 80 | error); |
84 | ck_assert_msg(tox_bootstrap(userdata_tcp.tox, TOX_LOCALHOST, 33445, dpk, 0), "Bootstrap error"); | 81 | ck_assert_msg(tox_bootstrap(userdata_tcp.tox, TOX_LOCALHOST, 33445, dpk, &error), "Bootstrap error, %i", error); |
85 | pthread_mutex_unlock(&userdata_tcp.mutex); | 82 | pthread_mutex_unlock(&userdata_tcp.mutex); |
86 | 83 | ||
87 | sleep(10); | 84 | sleep(10); |
88 | 85 | ||
89 | tox_loop_stop(userdata.tox); | 86 | tox_loop_stop(userdata.tox); |
90 | pthread_join(worker1, (void **)&retval); | 87 | pthread_join(worker, (void **)&retval); |
91 | ck_assert_msg(retval == 0, "tox_loop didn't return 0"); | 88 | ck_assert_msg(retval == 0, "tox_loop didn't return 0"); |
92 | 89 | ||
93 | tox_kill(userdata.tox); | 90 | tox_kill(userdata.tox); |
94 | ck_assert_msg(userdata.start_count == userdata.stop_count, "start and stop must match"); | 91 | ck_assert_msg(userdata.start_count == userdata.stop_count, "start and stop must match"); |
95 | 92 | ||
96 | tox_loop_stop(userdata_tcp.tox); | 93 | tox_loop_stop(userdata_tcp.tox); |
97 | pthread_join(worker2, (void **)&retval); | 94 | pthread_join(worker_tcp, (void **)&retval); |
98 | ck_assert_msg(retval == 0, "tox_loop didn't return 0"); | 95 | ck_assert_msg(retval == 0, "tox_loop didn't return 0"); |
99 | 96 | ||
100 | tox_kill(userdata_tcp.tox); | 97 | tox_kill(userdata_tcp.tox); |
@@ -103,9 +100,9 @@ START_TEST(test_tox_loop) | |||
103 | END_TEST | 100 | END_TEST |
104 | 101 | ||
105 | #ifdef TRAVIS_ENV | 102 | #ifdef TRAVIS_ENV |
106 | uint8_t timeout_mux = 20; | 103 | static uint8_t timeout_mux = 20; |
107 | #else | 104 | #else |
108 | uint8_t timeout_mux = 10; | 105 | static uint8_t timeout_mux = 10; |
109 | #endif | 106 | #endif |
110 | 107 | ||
111 | static Suite *tox_suite(void) | 108 | static Suite *tox_suite(void) |
@@ -15,6 +15,7 @@ dependencies: | |||
15 | - sudo apt-get install clang | 15 | - sudo apt-get install clang |
16 | - sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm | 16 | - sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm |
17 | - sudo apt-get install libopus-dev libvpx-dev pkg-config | 17 | - sudo apt-get install libopus-dev libvpx-dev pkg-config |
18 | - sudo apt-get install libev-dev libevent-dev | ||
18 | 19 | ||
19 | # ------------ network_test requires that "localhost" resolves to ::1 ------------ | 20 | # ------------ network_test requires that "localhost" resolves to ::1 ------------ |
20 | - sudo bash -c "echo '::1 localhost ipv6-localhost ipv6-loopback' >> /etc/hosts" # ipv6 localhost entry | 21 | - sudo bash -c "echo '::1 localhost ipv6-localhost ipv6-loopback' >> /etc/hosts" # ipv6 localhost entry |
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 5ad332bd..4cb96594 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake | |||
@@ -8,30 +8,38 @@ include(ModulePackage) | |||
8 | 8 | ||
9 | find_package(Threads REQUIRED) | 9 | find_package(Threads REQUIRED) |
10 | 10 | ||
11 | find_library(NCURSES_LIBRARIES ncurses ) | 11 | find_library(NCURSES_LIBRARIES ncurses ) |
12 | find_library(UTIL_LIBRARIES util ) | 12 | find_library(UTIL_LIBRARIES util ) |
13 | find_library(RT_LIBRARIES rt ) | 13 | find_library(RT_LIBRARIES rt ) |
14 | 14 | ||
15 | # For toxcore. | 15 | # For toxcore. |
16 | pkg_use_module(LIBSODIUM libsodium ) | 16 | pkg_use_module(LIBSODIUM libsodium ) |
17 | pkg_use_module(LIBEV ev ) | ||
18 | if(NOT LIBEV_FOUND) | ||
19 | if(NOT WIN32) | ||
20 | pkg_use_module(LIBEVENT libevent_pthreads ) | ||
21 | else() | ||
22 | pkg_use_module(LIBEVENT libevent ) | ||
23 | endif() | ||
24 | endif() | ||
17 | 25 | ||
18 | # For toxav. | 26 | # For toxav. |
19 | pkg_use_module(OPUS opus ) | 27 | pkg_use_module(OPUS opus ) |
20 | pkg_use_module(VPX vpx ) | 28 | pkg_use_module(VPX vpx ) |
21 | 29 | ||
22 | # For tox-bootstrapd. | 30 | # For tox-bootstrapd. |
23 | pkg_use_module(LIBCONFIG libconfig ) | 31 | pkg_use_module(LIBCONFIG libconfig ) |
24 | 32 | ||
25 | # For auto tests. | 33 | # For auto tests. |
26 | pkg_use_module(CHECK check ) | 34 | pkg_use_module(CHECK check ) |
27 | 35 | ||
28 | # For tox-spectest. | 36 | # For tox-spectest. |
29 | pkg_use_module(MSGPACK msgpack ) | 37 | pkg_use_module(MSGPACK msgpack ) |
30 | 38 | ||
31 | # For av_test. | 39 | # For av_test. |
32 | pkg_use_module(OPENCV opencv ) | 40 | pkg_use_module(OPENCV opencv ) |
33 | pkg_use_module(PORTAUDIO portaudio-2.0) | 41 | pkg_use_module(PORTAUDIO portaudio-2.0 ) |
34 | pkg_use_module(SNDFILE sndfile ) | 42 | pkg_use_module(SNDFILE sndfile ) |
35 | 43 | ||
36 | ############################################################################### | 44 | ############################################################################### |
37 | # | 45 | # |
diff --git a/cmake/ModulePackage.cmake b/cmake/ModulePackage.cmake index 3a4eb9b9..4d22ee41 100644 --- a/cmake/ModulePackage.cmake +++ b/cmake/ModulePackage.cmake | |||
@@ -2,6 +2,8 @@ option(ENABLE_SHARED "Build shared (dynamic) libraries for all modules" ON) | |||
2 | option(ENABLE_STATIC "Build static libraries for all modules" ON) | 2 | option(ENABLE_STATIC "Build static libraries for all modules" ON) |
3 | option(COMPILE_AS_CXX "Compile all C code as C++ code" OFF) | 3 | option(COMPILE_AS_CXX "Compile all C code as C++ code" OFF) |
4 | 4 | ||
5 | include(FindPackageHandleStandardArgs) | ||
6 | |||
5 | if(NOT ENABLE_SHARED AND NOT ENABLE_STATIC) | 7 | if(NOT ENABLE_SHARED AND NOT ENABLE_STATIC) |
6 | message(WARNING | 8 | message(WARNING |
7 | "Both static and shared libraries are disabled; " | 9 | "Both static and shared libraries are disabled; " |
@@ -48,6 +50,31 @@ function(pkg_use_module mod pkg) | |||
48 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem ${dir}" PARENT_SCOPE) | 50 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem ${dir}" PARENT_SCOPE) |
49 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${dir}" PARENT_SCOPE) | 51 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${dir}" PARENT_SCOPE) |
50 | endforeach() | 52 | endforeach() |
53 | else() | ||
54 | set(${mod}_DEFINITIONS ${${mod}_CFLAGS_OTHER}) | ||
55 | find_path(${mod}_INCLUDE_DIR NAMES ${ARGV1}.h | ||
56 | HINTS ${${mod}_INCLUDEDIR} ${${mod}_INCLUDE_DIRS} | ||
57 | PATH_SUFFIXES ${ARGV1}) | ||
58 | find_library(${mod}_LIBRARY NAMES ${ARGV1} lib${ARGV1} | ||
59 | HINTS ${${mod}_LIBDIR} ${${mod}_LIBRARY_DIRS}) | ||
60 | find_package_handle_standard_args(${mod} DEFAULT_MSG | ||
61 | ${mod}_LIBRARY ${mod}_INCLUDE_DIR) | ||
62 | |||
63 | if(${mod}_FOUND) | ||
64 | mark_as_advanced(${mod}_INCLUDE_DIR ${mod}_LIBRARY) | ||
65 | set(${mod}_LIBRARIES ${${mod}_LIBRARY} PARENT_SCOPE) | ||
66 | set(${mod}_INCLUDE_DIRS ${${mod}_INCLUDE_DIR} PARENT_SCOPE) | ||
67 | set(${mod}_FOUND TRUE PARENT_SCOPE) | ||
68 | link_directories(${${mod}_LIBRARY_DIRS}) | ||
69 | include_directories(${${mod}_INCLUDE_DIRS}) | ||
70 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE) | ||
71 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE) | ||
72 | |||
73 | foreach(dir ${${mod}_INCLUDE_DIRS}) | ||
74 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem ${dir}" PARENT_SCOPE) | ||
75 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${dir}" PARENT_SCOPE) | ||
76 | endforeach() | ||
77 | endif() | ||
51 | endif() | 78 | endif() |
52 | endfunction() | 79 | endfunction() |
53 | 80 | ||
diff --git a/configure.ac b/configure.ac index 9eaa840f..18bc9234 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -31,6 +31,8 @@ LIBCHECK_FOUND="no" | |||
31 | WANT_NACL="no" | 31 | WANT_NACL="no" |
32 | ADD_NACL_OBJECTS_TO_PKGCONFIG="yes" | 32 | ADD_NACL_OBJECTS_TO_PKGCONFIG="yes" |
33 | SET_SO_VERSION="yes" | 33 | SET_SO_VERSION="yes" |
34 | WANT_LIBEV="no" | ||
35 | WANT_LIBEVENT="no" | ||
34 | 36 | ||
35 | AC_ARG_ENABLE([soname-versions], | 37 | AC_ARG_ENABLE([soname-versions], |
36 | [AC_HELP_STRING([--enable-soname-versions], [enable soname versions (must be disabled for android) (default: enabled)]) ], | 38 | [AC_HELP_STRING([--enable-soname-versions], [enable soname versions (must be disabled for android) (default: enabled)]) ], |
@@ -55,6 +57,32 @@ AC_ARG_ENABLE([nacl], | |||
55 | ] | 57 | ] |
56 | ) | 58 | ) |
57 | 59 | ||
60 | AC_ARG_ENABLE([libev], | ||
61 | [AC_HELP_STRING([--enable-libev], [use libev to watch for events (default: disabled)]) ], | ||
62 | [ | ||
63 | if test "x$enableval" = "xyes"; then | ||
64 | WANT_LIBEV="yes" | ||
65 | elif test "x$enableval" = "xno"; then | ||
66 | WANT_LIBEV="no" | ||
67 | fi | ||
68 | ] | ||
69 | ) | ||
70 | |||
71 | AC_ARG_ENABLE([libevent], | ||
72 | [AC_HELP_STRING([--enable-libevent], [use libevent to watch for events (default: disabled)]) ], | ||
73 | [ | ||
74 | if test "x$enableval" = "xyes"; then | ||
75 | WANT_LIBEVENT="yes" | ||
76 | elif test "x$enableval" = "xno"; then | ||
77 | WANT_LIBEVENT="no" | ||
78 | fi | ||
79 | ] | ||
80 | ) | ||
81 | |||
82 | if test "x$WANT_LIBEV" = "xyes" && test "x$WANT_LIBEVENT" = "xyes"; then | ||
83 | AC_MSG_ERROR([cannot enable both libev and libevent, please choose one]) | ||
84 | fi | ||
85 | |||
58 | AC_ARG_ENABLE([randombytes-stir], | 86 | AC_ARG_ENABLE([randombytes-stir], |
59 | [AC_HELP_STRING([--enable-randombytes-stir], [use randombytes_stir() instead of sodium_init() for faster startup on android (default: disabled)]) ], | 87 | [AC_HELP_STRING([--enable-randombytes-stir], [use randombytes_stir() instead of sodium_init() for faster startup on android (default: disabled)]) ], |
60 | [ | 88 | [ |
@@ -211,6 +239,10 @@ LIBSODIUM_SEARCH_HEADERS= | |||
211 | LIBSODIUM_SEARCH_LIBS= | 239 | LIBSODIUM_SEARCH_LIBS= |
212 | NACL_SEARCH_HEADERS= | 240 | NACL_SEARCH_HEADERS= |
213 | NACL_SEARCH_LIBS= | 241 | NACL_SEARCH_LIBS= |
242 | LIBEV_SEARCH_HEADERS= | ||
243 | LIBEV_SEARCH_LIBS= | ||
244 | LIBEVENT_SEARCH_HEADERS= | ||
245 | LIBEVENT_SEARCH_LIBS= | ||
214 | 246 | ||
215 | AC_ARG_WITH(dependency-search, | 247 | AC_ARG_WITH(dependency-search, |
216 | AC_HELP_STRING([--with-dependency-search=DIR], | 248 | AC_HELP_STRING([--with-dependency-search=DIR], |
@@ -264,6 +296,42 @@ AC_ARG_WITH(libsodium-libs, | |||
264 | ] | 296 | ] |
265 | ) | 297 | ) |
266 | 298 | ||
299 | AC_ARG_WITH(libev-headers, | ||
300 | AC_HELP_STRING([--with-libev-headers=DIR], | ||
301 | [search for libev header files in DIR]), | ||
302 | [ | ||
303 | LIBEV_SEARCH_HEADERS="$withval" | ||
304 | AC_MSG_NOTICE([will search for libev header files in $withval]) | ||
305 | ] | ||
306 | ) | ||
307 | |||
308 | AC_ARG_WITH(libev-libs, | ||
309 | AC_HELP_STRING([--with-libev-libs=DIR], | ||
310 | [search for libev libraries in DIR]), | ||
311 | [ | ||
312 | LIBEV_SEARCH_LIBS="$withval" | ||
313 | AC_MSG_NOTICE([will search for libev libraries in $withval]) | ||
314 | ] | ||
315 | ) | ||
316 | |||
317 | AC_ARG_WITH(libevent-headers, | ||
318 | AC_HELP_STRING([--with-libevent-headers=DIR], | ||
319 | [search for libevent header files in DIR]), | ||
320 | [ | ||
321 | LIBEVENT_SEARCH_HEADERS="$withval" | ||
322 | AC_MSG_NOTICE([will search for libevent header files in $withval]) | ||
323 | ] | ||
324 | ) | ||
325 | |||
326 | AC_ARG_WITH(libevent-libs, | ||
327 | AC_HELP_STRING([--with-libevent-libs=DIR], | ||
328 | [search for libevent libraries in DIR]), | ||
329 | [ | ||
330 | LIBEVENT_SEARCH_LIBS="$withval" | ||
331 | AC_MSG_NOTICE([will search for libevent libraries in $withval]) | ||
332 | ] | ||
333 | ) | ||
334 | |||
267 | if test "x$WANT_NACL" = "xyes"; then | 335 | if test "x$WANT_NACL" = "xyes"; then |
268 | enable_shared=no | 336 | enable_shared=no |
269 | enable_static=yes | 337 | enable_static=yes |
@@ -394,6 +462,123 @@ elif test "x$LIBSODIUM_FOUND" = "xno"; then | |||
394 | AC_SUBST(LIBSODIUM_LDFLAGS) | 462 | AC_SUBST(LIBSODIUM_LDFLAGS) |
395 | fi | 463 | fi |
396 | 464 | ||
465 | if test "x$WANT_LIBEV" = "xyes"; then | ||
466 | if test -n "$PKG_CONFIG"; then | ||
467 | PKG_CHECK_MODULES([LIBEV], [libev], | ||
468 | [ | ||
469 | LIBEV_PKG_CONFIG="yes" | ||
470 | ], | ||
471 | [ | ||
472 | LIBEV_PKG_CONFIG="no" | ||
473 | ] | ||
474 | ) | ||
475 | else | ||
476 | LIBEV_PKG_CONFIG="no" | ||
477 | fi | ||
478 | |||
479 | if test "x$LIBEV_PKG_CONFIG" = "xno"; then | ||
480 | LIBEV_LIBS= | ||
481 | LIBEV_LDFLAGS= | ||
482 | LDFLAGS_SAVE="$LDFLAGS" | ||
483 | |||
484 | if test -n "$LIBEV_SEARCH_LIBS"; then | ||
485 | LDFLAGS="-L$LIBEV_SEARCH_LIBS $LDFLAGS" | ||
486 | AC_CHECK_LIB(ev, ev_run, | ||
487 | [ | ||
488 | LIBEV_LDFLAGS="-L$LIBEV_SEARCH_LIBS" | ||
489 | LIBEV_LIBS="-lev" | ||
490 | ], | ||
491 | [ | ||
492 | AC_MSG_ERROR([required library libev was not found in requested location $LIBEV_SEARCH_LIBS]) | ||
493 | ] | ||
494 | ) | ||
495 | else | ||
496 | AC_CHECK_LIB(ev, ev_run, | ||
497 | [ | ||
498 | LIBEV_LIBS="-lev" | ||
499 | ], | ||
500 | [ | ||
501 | AC_MSG_ERROR([required library libev was not found in requested location $LIBEV_SEARCH_LIBS]) | ||
502 | ] | ||
503 | ) | ||
504 | fi | ||
505 | |||
506 | LDFLAGS="$LDFLAGS_SAVE" | ||
507 | fi | ||
508 | |||
509 | AC_SUBST(LIBEV_LIBS) | ||
510 | AC_SUBST(LIBEV_LDFLAGS) | ||
511 | AC_DEFINE([HAVE_LIBEV], [1], [Define to 1 if you have the 'libev' library (-lev).]) | ||
512 | fi | ||
513 | |||
514 | if test "x$WANT_LIBEVENT" = "xyes"; then | ||
515 | if test -n "$PKG_CONFIG"; then | ||
516 | if test "x$WIN32" = "xno"; then | ||
517 | PKG_CHECK_MODULES([LIBEVENT], [libevent_pthreads], | ||
518 | [ | ||
519 | LIBEVENT_PKG_CONFIG="yes" | ||
520 | ], | ||
521 | [ | ||
522 | LIBEVENT_PKG_CONFIG="no" | ||
523 | ], | ||
524 | ) | ||
525 | else | ||
526 | PKG_CHECK_MODULES([LIBEVENT], [libevent], | ||
527 | [ | ||
528 | LIBEVENT_PKG_CONFIG="yes" | ||
529 | ], | ||
530 | [ | ||
531 | LIBEVENT_PKG_CONFIG="no" | ||
532 | ], | ||
533 | ) | ||
534 | fi | ||
535 | else | ||
536 | LIBEVENT_PKG_CONFIG="no" | ||
537 | fi | ||
538 | |||
539 | if test "x$LIBEVENT_PKG_CONFIG" = "xno"; then | ||
540 | LIBEVENT_LIBS= | ||
541 | LIBEVENT_LDFLAGS= | ||
542 | LDFLAGS_SAVE="$LDFLAGS" | ||
543 | |||
544 | if test -n "$LIBEVENT_SEARCH_LIBS"; then | ||
545 | LDFLAGS="-L$LIBEVENT_SEARCH_LIBS $LDFLAGS" | ||
546 | AC_CHECK_LIB(event, event_base_loop, | ||
547 | [ | ||
548 | LIBEVENT_LDFLAGS="-L$LIBEVENT_SEARCH_LIBS" | ||
549 | if test "x$WIN32" = "xno"; then | ||
550 | LIBEVENT_LIBS="-levent -levent_pthreads" | ||
551 | else | ||
552 | LIBEVENT_LIBS="-levent" | ||
553 | fi | ||
554 | ], | ||
555 | [ | ||
556 | AC_MSG_ERROR([required library libevent was not found in requested location $LIBEVENT_SEARCH_LIBS]) | ||
557 | ] | ||
558 | ) | ||
559 | else | ||
560 | AC_CHECK_LIB(event, event_base_loop, | ||
561 | [ | ||
562 | if test "x$WIN32" = "xno"; then | ||
563 | LIBEVENT_LIBS="-levent -levent_pthreads" | ||
564 | else | ||
565 | LIBEVENT_LIBS="-levent" | ||
566 | fi | ||
567 | ], | ||
568 | [ | ||
569 | AC_MSG_ERROR([required library libevent was not found in requested location $LIBEVENT_SEARCH_LIBS]) | ||
570 | ] | ||
571 | ) | ||
572 | fi | ||
573 | |||
574 | LDFLAGS="$LDFLAGS_SAVE" | ||
575 | fi | ||
576 | |||
577 | AC_SUBST(LIBEVENT_LIBS) | ||
578 | AC_SUBST(LIBEVENT_LDFLAGS) | ||
579 | AC_DEFINE([HAVE_LIBEVENT], [1], [Define to 1 if you have the 'libevent' library (-levent).]) | ||
580 | fi | ||
581 | |||
397 | # Checks for header files. | 582 | # Checks for header files. |
398 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) | 583 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) |
399 | 584 | ||
@@ -453,6 +638,72 @@ elif test "x$LIBSODIUM_FOUND" = "xno"; then | |||
453 | AC_SUBST(LIBSODIUM_CFLAGS) | 638 | AC_SUBST(LIBSODIUM_CFLAGS) |
454 | fi | 639 | fi |
455 | 640 | ||
641 | if test "x$WANT_LIBEV" = "xyes"; then | ||
642 | if test "x$LIBEV_PKG_CONFIG" = "xno"; then | ||
643 | LIBEV_CFLAGS= | ||
644 | CFLAGS_SAVE="$CFLAGS" | ||
645 | CPPFLAGS_SAVE="$CPPFLAGS" | ||
646 | |||
647 | if test -n "$LIBEV_SEARCH_HEADERS"; then | ||
648 | CFLAGS="-I$LIBEV_SEARCH_HEADERS $CFLAGS" | ||
649 | CPPFLAGS="-I$LIBEV_SEARCH_HEADERS $CPPFLAGS" | ||
650 | AC_CHECK_HEADER(ev.h, | ||
651 | [ | ||
652 | LIBEV_CFLAGS="-I$LIBEV_SEARCH_HEADERS" | ||
653 | ], | ||
654 | [ | ||
655 | AC_MSG_ERROR([header files for required library libev were not found in requested location $LIBEV_SEARCH_HEADERS]) | ||
656 | ] | ||
657 | ) | ||
658 | else | ||
659 | AC_CHECK_HEADER(ev.h, | ||
660 | [], | ||
661 | [ | ||
662 | AC_MSG_ERROR([header files for required library libev was not found on your system, please check http://libev.schmorp.de/]) | ||
663 | ] | ||
664 | ) | ||
665 | fi | ||
666 | |||
667 | CFLAGS="$CFLAGS_SAVE" | ||
668 | CPPFLAGS="$CPPFLAGS_SAVE" | ||
669 | fi | ||
670 | |||
671 | AC_SUBST(LIBEV_CFLAGS) | ||
672 | fi | ||
673 | |||
674 | if test "x$WANT_LIBEVENT" = "xyes"; then | ||
675 | if test "x$LIBEVENT_PKG_CONFIG" = "xno"; then | ||
676 | LIBEVENT_CFLAGS= | ||
677 | CFLAGS_SAVE="$CFLAGS" | ||
678 | CPPFLAGS_SAVE="$CPPFLAGS" | ||
679 | |||
680 | if test -n "$LIBEVENT_SEARCH_HEADERS"; then | ||
681 | CFLAGS="-I$LIBEVENT_SEARCH_HEADERS $CFLAGS" | ||
682 | CPPFLAGS="-I$LIBEVENT_SEARCH_HEADERS $CPPFLAGS" | ||
683 | AC_CHECK_HEADERS([event2/event.h event2/thread.h], | ||
684 | [ | ||
685 | LIBEVENT_CFLAGS="-I$LIBEVENT_SEARCH_HEADERS" | ||
686 | ], | ||
687 | [ | ||
688 | AC_MSG_ERROR([header files for required library libevent were not found in requested location $LIBEVENT_SEARCH_HEADERS]) | ||
689 | ] | ||
690 | ) | ||
691 | else | ||
692 | AC_CHECK_HEADERS([event2/event.h event2/thread.h], | ||
693 | [], | ||
694 | [ | ||
695 | AC_MSG_ERROR([header files for required library libevent was not found on your system, please check http://libevent.org/]) | ||
696 | ] | ||
697 | ) | ||
698 | fi | ||
699 | |||
700 | CFLAGS="$CFLAGS_SAVE" | ||
701 | CPPFLAGS="$CPPFLAGS_SAVE" | ||
702 | fi | ||
703 | |||
704 | AC_SUBST(LIBEVENT_CFLAGS) | ||
705 | fi | ||
706 | |||
456 | # Checks for typedefs, structures, and compiler characteristics. | 707 | # Checks for typedefs, structures, and compiler characteristics. |
457 | AC_HEADER_STDBOOL | 708 | AC_HEADER_STDBOOL |
458 | AC_TYPE_INT16_T | 709 | AC_TYPE_INT16_T |
diff --git a/libtoxcore.pc.in b/libtoxcore.pc.in index 90bb6c28..1ecb2272 100644 --- a/libtoxcore.pc.in +++ b/libtoxcore.pc.in | |||
@@ -7,5 +7,5 @@ Name: libtoxcore | |||
7 | Description: Tox protocol library | 7 | Description: Tox protocol library |
8 | Requires: | 8 | Requires: |
9 | Version: @PACKAGE_VERSION@ | 9 | Version: @PACKAGE_VERSION@ |
10 | Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} -ltoxcore @NACL_LDFLAGS@ -ltoxdns -ltoxencryptsave @NACL_LIBS@ @LIBS@ @MATH_LDFLAGS@ @PTHREAD_LDFLAGS@ | 10 | Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} -ltoxcore @NACL_LDFLAGS@ -ltoxdns -ltoxencryptsave @NACL_LIBS@ @LIBEV_LIBS@ @LIBEVENT_LIBS@ @LIBS@ @MATH_LDFLAGS@ @PTHREAD_LDFLAGS@ |
11 | Cflags: -I${includedir} | 11 | Cflags: -I${includedir} |
diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index 2ca25650..7501530c 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc | |||
@@ -55,12 +55,16 @@ libtoxcore_la_CFLAGS = -I$(top_srcdir) \ | |||
55 | -I$(top_srcdir)/toxcore \ | 55 | -I$(top_srcdir)/toxcore \ |
56 | $(LIBSODIUM_CFLAGS) \ | 56 | $(LIBSODIUM_CFLAGS) \ |
57 | $(NACL_CFLAGS) \ | 57 | $(NACL_CFLAGS) \ |
58 | $(LIBEV_CFLAGS) \ | ||
59 | $(LIBEVENT_CFLAGS) \ | ||
58 | $(PTHREAD_CFLAGS) | 60 | $(PTHREAD_CFLAGS) |
59 | 61 | ||
60 | libtoxcore_la_LDFLAGS = $(LT_LDFLAGS) \ | 62 | libtoxcore_la_LDFLAGS = $(LT_LDFLAGS) \ |
61 | $(EXTRA_LT_LDFLAGS) \ | 63 | $(EXTRA_LT_LDFLAGS) \ |
62 | $(LIBSODIUM_LDFLAGS) \ | 64 | $(LIBSODIUM_LDFLAGS) \ |
63 | $(NACL_LDFLAGS) \ | 65 | $(NACL_LDFLAGS) \ |
66 | $(LIBEV_LDFLAGS) \ | ||
67 | $(LIBEVENT_LDFLAGS) \ | ||
64 | $(MATH_LDFLAGS) \ | 68 | $(MATH_LDFLAGS) \ |
65 | $(RT_LIBS) \ | 69 | $(RT_LIBS) \ |
66 | $(WINSOCK2_LIBS) | 70 | $(WINSOCK2_LIBS) |
@@ -68,6 +72,8 @@ libtoxcore_la_LDFLAGS = $(LT_LDFLAGS) \ | |||
68 | libtoxcore_la_LIBADD = $(LIBSODIUM_LIBS) \ | 72 | libtoxcore_la_LIBADD = $(LIBSODIUM_LIBS) \ |
69 | $(NACL_OBJECTS) \ | 73 | $(NACL_OBJECTS) \ |
70 | $(NAC_LIBS) \ | 74 | $(NAC_LIBS) \ |
75 | $(LIBEV_LIBS) \ | ||
76 | $(LIBEVENT_LIBS) \ | ||
71 | $(PTHREAD_LIBS) | 77 | $(PTHREAD_LIBS) |
72 | 78 | ||
73 | if SET_SO_VERSION | 79 | if SET_SO_VERSION |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 5dda5b30..24aa8a9b 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -1930,6 +1930,28 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) | |||
1930 | return NULL; | 1930 | return NULL; |
1931 | } | 1931 | } |
1932 | 1932 | ||
1933 | #ifdef HAVE_LIBEV | ||
1934 | m->dispatcher = ev_loop_new(0); | ||
1935 | #elif HAVE_LIBEVENT | ||
1936 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) | ||
1937 | evthread_use_windows_threads(); | ||
1938 | #else | ||
1939 | evthread_use_pthreads(); | ||
1940 | #endif /* WIN32 || _WIN32 || __WIN32__ */ | ||
1941 | m->dispatcher = event_base_new(); | ||
1942 | #else | ||
1943 | m->loop_run = false; | ||
1944 | #endif /* HAVE_LIBEV */ | ||
1945 | |||
1946 | #if defined(HAVE_LIBEV) || defined(HAVE_LIBEVENT) | ||
1947 | |||
1948 | if (!m->dispatcher) { | ||
1949 | free(m); | ||
1950 | return NULL; | ||
1951 | } | ||
1952 | |||
1953 | #endif /* HAVE_LIBEV || HAVE_LIBEVENT */ | ||
1954 | |||
1933 | Logger *log = NULL; | 1955 | Logger *log = NULL; |
1934 | 1956 | ||
1935 | if (options->log_callback) { | 1957 | if (options->log_callback) { |
@@ -2057,6 +2079,12 @@ void kill_messenger(Messenger *m) | |||
2057 | clear_receipts(m, i); | 2079 | clear_receipts(m, i); |
2058 | } | 2080 | } |
2059 | 2081 | ||
2082 | #ifdef HAVE_LIBEV | ||
2083 | ev_loop_destroy(m->dispatcher); | ||
2084 | #elif HAVE_LIBEVENT | ||
2085 | event_base_free(m->dispatcher); | ||
2086 | #endif | ||
2087 | |||
2060 | logger_kill(m->log); | 2088 | logger_kill(m->log); |
2061 | free(m->friendlist); | 2089 | free(m->friendlist); |
2062 | free(m); | 2090 | free(m); |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 7275ffbf..300e7f25 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -29,6 +29,13 @@ | |||
29 | #include "friend_requests.h" | 29 | #include "friend_requests.h" |
30 | #include "logger.h" | 30 | #include "logger.h" |
31 | 31 | ||
32 | #ifdef HAVE_LIBEV | ||
33 | #include <ev.h> | ||
34 | #elif HAVE_LIBEVENT | ||
35 | #include <event2/event.h> | ||
36 | #include <event2/thread.h> | ||
37 | #endif | ||
38 | |||
32 | #define MAX_NAME_LENGTH 128 | 39 | #define MAX_NAME_LENGTH 128 |
33 | /* TODO(irungentoo): this must depend on other variable. */ | 40 | /* TODO(irungentoo): this must depend on other variable. */ |
34 | #define MAX_STATUSMESSAGE_LENGTH 1007 | 41 | #define MAX_STATUSMESSAGE_LENGTH 1007 |
@@ -273,9 +280,16 @@ struct Messenger { | |||
273 | void (*core_connection_change)(struct Messenger *m, unsigned int, void *); | 280 | void (*core_connection_change)(struct Messenger *m, unsigned int, void *); |
274 | unsigned int last_connection_status; | 281 | unsigned int last_connection_status; |
275 | 282 | ||
276 | uint8_t loop_run; | 283 | #ifdef HAVE_LIBEV |
277 | void (*loop_begin_cb)(struct Messenger *tox, void *user_data); | 284 | struct ev_loop *dispatcher; |
278 | void (*loop_end_cb)(struct Messenger *tox, void *user_data); | 285 | ev_async stop_loop; |
286 | #elif HAVE_LIBEVENT | ||
287 | struct event_base *dispatcher; | ||
288 | #else | ||
289 | bool loop_run; | ||
290 | #endif | ||
291 | void (*loop_begin_cb)(struct Messenger *m, void *user_data); | ||
292 | void (*loop_end_cb)(struct Messenger *m, void *user_data); | ||
279 | 293 | ||
280 | Messenger_Options options; | 294 | Messenger_Options options; |
281 | }; | 295 | }; |
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 3e6de14a..8989f244 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c | |||
@@ -985,6 +985,17 @@ void kill_TCP_connection(TCP_Client_Connection *TCP_connection) | |||
985 | 985 | ||
986 | wipe_priority_list(TCP_connection); | 986 | wipe_priority_list(TCP_connection); |
987 | kill_sock(TCP_connection->sock); | 987 | kill_sock(TCP_connection->sock); |
988 | |||
989 | #ifdef HAVE_LIBEV | ||
990 | ev_io_stop(TCP_connection->sock_listener.dispatcher, &TCP_connection->sock_listener.listener); | ||
991 | #elif HAVE_LIBEVENT | ||
992 | |||
993 | if (TCP_connection->sock_listener) { | ||
994 | event_free(TCP_connection->sock_listener); | ||
995 | } | ||
996 | |||
997 | #endif | ||
998 | |||
988 | crypto_memzero(TCP_connection, sizeof(TCP_Client_Connection)); | 999 | crypto_memzero(TCP_connection, sizeof(TCP_Client_Connection)); |
989 | free(TCP_connection); | 1000 | free(TCP_connection); |
990 | } | 1001 | } |
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index 21254314..8a698869 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h | |||
@@ -27,6 +27,12 @@ | |||
27 | #include "TCP_server.h" | 27 | #include "TCP_server.h" |
28 | #include "crypto_core.h" | 28 | #include "crypto_core.h" |
29 | 29 | ||
30 | #ifdef HAVE_LIBEV | ||
31 | #include <ev.h> | ||
32 | #elif HAVE_LIBEVENT | ||
33 | #include <event2/event.h> | ||
34 | #endif | ||
35 | |||
30 | #define TCP_CONNECTION_TIMEOUT 10 | 36 | #define TCP_CONNECTION_TIMEOUT 10 |
31 | 37 | ||
32 | typedef enum { | 38 | typedef enum { |
@@ -52,7 +58,15 @@ enum { | |||
52 | }; | 58 | }; |
53 | typedef struct { | 59 | typedef struct { |
54 | uint8_t status; | 60 | uint8_t status; |
55 | Socket sock; | 61 | Socket sock; |
62 | #ifdef HAVE_LIBEV | ||
63 | struct { | ||
64 | ev_io listener; | ||
65 | struct ev_loop *dispatcher; | ||
66 | } sock_listener; | ||
67 | #elif HAVE_LIBEVENT | ||
68 | struct event *sock_listener; | ||
69 | #endif | ||
56 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */ | 70 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */ |
57 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */ | 71 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */ |
58 | IP_Port ip_port; /* The ip and port of the server */ | 72 | IP_Port ip_port; /* The ip and port of the server */ |
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index 18c1e76e..9b51443d 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c | |||
@@ -67,6 +67,37 @@ const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
70 | /** | ||
71 | * Return number of elements of TCP connection array. | ||
72 | * | ||
73 | * @param tcp_c struct containing TCP_con array | ||
74 | * | ||
75 | * @return number of elements of TCP connection array | ||
76 | */ | ||
77 | uint32_t tcp_connections_length(const TCP_Connections *tcp_c) | ||
78 | { | ||
79 | return tcp_c->tcp_connections_length; | ||
80 | } | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Return TCP connection stored at "idx" position. | ||
85 | * | ||
86 | * @param tcp_c struct containing TCP_con array | ||
87 | * @param idx index of TCP connection to return (values from 0 to tcp_connections_length() - 1) | ||
88 | * | ||
89 | * @return TCP connection stored at "idx" position, or NULL if errors occurred | ||
90 | */ | ||
91 | const TCP_con *tcp_connections_connection_at(const TCP_Connections *tcp_c, uint32_t idx) | ||
92 | { | ||
93 | if (idx >= tcp_c->tcp_connections_length) { | ||
94 | return NULL; | ||
95 | } | ||
96 | |||
97 | return &tcp_c->tcp_connections[idx]; | ||
98 | } | ||
99 | |||
100 | |||
70 | /* Set the size of the array to num. | 101 | /* Set the size of the array to num. |
71 | * | 102 | * |
72 | * return -1 if realloc fails. | 103 | * return -1 if realloc fails. |
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index f023b1ab..276303e7 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h | |||
@@ -82,6 +82,10 @@ typedef struct TCP_Connections TCP_Connections; | |||
82 | 82 | ||
83 | const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c); | 83 | const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c); |
84 | 84 | ||
85 | uint32_t tcp_connections_length(const TCP_Connections *tcp_c); | ||
86 | |||
87 | const TCP_con *tcp_connections_connection_at(const TCP_Connections *tcp_c, uint32_t idx); | ||
88 | |||
85 | /* Send a packet to the TCP connection. | 89 | /* Send a packet to the TCP connection. |
86 | * | 90 | * |
87 | * return -1 on failure. | 91 | * return -1 on failure. |
diff --git a/toxcore/network.c b/toxcore/network.c index 215ab8e0..62b36ae6 100644 --- a/toxcore/network.c +++ b/toxcore/network.c | |||
@@ -797,6 +797,16 @@ void kill_networking(Networking_Core *net) | |||
797 | kill_sock(net->sock); | 797 | kill_sock(net->sock); |
798 | } | 798 | } |
799 | 799 | ||
800 | #ifdef HAVE_LIBEV | ||
801 | ev_io_stop(net->sock_listener.dispatcher, &net->sock_listener.listener); | ||
802 | #elif HAVE_LIBEVENT | ||
803 | |||
804 | if (net->sock_listener) { | ||
805 | event_free(net->sock_listener); | ||
806 | } | ||
807 | |||
808 | #endif | ||
809 | |||
800 | free(net); | 810 | free(net); |
801 | } | 811 | } |
802 | 812 | ||
diff --git a/toxcore/network.h b/toxcore/network.h index 28795602..4f27a81d 100644 --- a/toxcore/network.h +++ b/toxcore/network.h | |||
@@ -33,6 +33,11 @@ | |||
33 | #include "ccompat.h" | 33 | #include "ccompat.h" |
34 | #include "logger.h" | 34 | #include "logger.h" |
35 | 35 | ||
36 | #ifdef HAVE_LIBEV | ||
37 | #include <ev.h> | ||
38 | #elif HAVE_LIBEVENT | ||
39 | #include <event2/event.h> | ||
40 | #endif | ||
36 | #include <stdint.h> | 41 | #include <stdint.h> |
37 | #include <stdio.h> | 42 | #include <stdio.h> |
38 | #include <stdlib.h> | 43 | #include <stdlib.h> |
@@ -316,6 +321,14 @@ typedef struct { | |||
316 | uint16_t port; | 321 | uint16_t port; |
317 | /* Our UDP socket. */ | 322 | /* Our UDP socket. */ |
318 | Socket sock; | 323 | Socket sock; |
324 | #ifdef HAVE_LIBEV | ||
325 | struct { | ||
326 | ev_io listener; | ||
327 | struct ev_loop *dispatcher; | ||
328 | } sock_listener; | ||
329 | #elif HAVE_LIBEVENT | ||
330 | struct event *sock_listener; | ||
331 | #endif | ||
319 | } Networking_Core; | 332 | } Networking_Core; |
320 | 333 | ||
321 | /* Run this before creating sockets. | 334 | /* Run this before creating sockets. |
diff --git a/toxcore/tox.api.h b/toxcore/tox.api.h index 0bcf40e1..cacfa26c 100644 --- a/toxcore/tox.api.h +++ b/toxcore/tox.api.h | |||
@@ -838,19 +838,45 @@ const uint32_t iteration_interval(); | |||
838 | */ | 838 | */ |
839 | void iterate(any user_data); | 839 | void iterate(any user_data); |
840 | 840 | ||
841 | |||
841 | /** | 842 | /** |
842 | * Run $iterate() any time a packet arrives, only returns after ${loop.stop}(). | 843 | * Error codes for $loop(). |
843 | */ | 844 | */ |
844 | uint32_t loop(any user_data); | 845 | error for loop { |
846 | /** | ||
847 | * Invalid arguments passed. | ||
848 | */ | ||
849 | NULL, | ||
850 | /** | ||
851 | * Failed running events dispatcher. | ||
852 | */ | ||
853 | BREAK, | ||
854 | /** | ||
855 | * Failed running select(). | ||
856 | */ | ||
857 | SELECT, | ||
858 | /** | ||
859 | * Failed getting sockets file descriptors. | ||
860 | */ | ||
861 | GET_FDS, | ||
862 | } | ||
863 | |||
864 | |||
865 | /** | ||
866 | * Run $iterate() any time a packet arrives, returns after ${loop.stop}() or ${kill}(). | ||
867 | */ | ||
868 | bool loop(any user_data) with error for loop; | ||
869 | |||
845 | 870 | ||
846 | namespace loop { | 871 | namespace loop { |
872 | |||
847 | /** | 873 | /** |
848 | * Tell $loop() to return. | 874 | * Tell $loop() to return. |
849 | */ | 875 | */ |
850 | void stop(); | 876 | void stop(); |
851 | 877 | ||
852 | /** | 878 | /** |
853 | * Callback ran when $loop() calls into $iterate(), the client can lock a mutex here. | 879 | * This callback is invoked when $loop() calls into $iterate(), the client can lock a mutex here. |
854 | */ | 880 | */ |
855 | event begin const { | 881 | event begin const { |
856 | /** | 882 | /** |
@@ -860,7 +886,7 @@ namespace loop { | |||
860 | } | 886 | } |
861 | 887 | ||
862 | /** | 888 | /** |
863 | * Callback ran when $loop() is finished with $iterate(), the client can unlock the mutex here. | 889 | * This callback is invoked when $loop() is finished with $iterate(), the client can unlock the mutex here. |
864 | */ | 890 | */ |
865 | event end const { | 891 | event end const { |
866 | /** | 892 | /** |
diff --git a/toxcore/tox.c b/toxcore/tox.c index 5e2f14d2..0234fbf3 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -34,9 +34,19 @@ typedef struct Messenger Tox; | |||
34 | #include "Messenger.h" | 34 | #include "Messenger.h" |
35 | #include "group.h" | 35 | #include "group.h" |
36 | #include "logger.h" | 36 | #include "logger.h" |
37 | #include "net_crypto.h" | ||
37 | 38 | ||
38 | #include "../toxencryptsave/defines.h" | 39 | #include "../toxencryptsave/defines.h" |
39 | 40 | ||
41 | #include <errno.h> | ||
42 | #if !defined(HAVE_LIBEV) && !defined(HAVE_LIBEVENT) | ||
43 | #if defined (WIN32) || defined(_WIN32) || defined(__WIN32__) | ||
44 | #include <winsock2.h> | ||
45 | #else | ||
46 | #include <sys/select.h> | ||
47 | #endif /* WIN32 || _WIN32 || __WIN32__ */ | ||
48 | #endif /* !HAVE_LIBEV && !HAVE_LIBEVENT */ | ||
49 | |||
40 | #define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} | 50 | #define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} |
41 | 51 | ||
42 | #if TOX_HASH_LENGTH != CRYPTO_SHA256_SIZE | 52 | #if TOX_HASH_LENGTH != CRYPTO_SHA256_SIZE |
@@ -71,6 +81,12 @@ typedef struct Messenger Tox; | |||
71 | #error TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH | 81 | #error TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH |
72 | #endif | 82 | #endif |
73 | 83 | ||
84 | #if defined(HAVE_LIBEV) || defined(HAVE_LIBEVENT) | ||
85 | typedef struct { | ||
86 | Tox *tox; | ||
87 | void *user_data; | ||
88 | } Event_Arg; | ||
89 | #endif | ||
74 | 90 | ||
75 | bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch) | 91 | bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch) |
76 | { | 92 | { |
@@ -203,6 +219,8 @@ void tox_kill(Tox *tox) | |||
203 | } | 219 | } |
204 | 220 | ||
205 | Messenger *m = tox; | 221 | Messenger *m = tox; |
222 | |||
223 | tox_loop_stop(tox); | ||
206 | kill_groupchats((Group_Chats *)m->conferences_object); | 224 | kill_groupchats((Group_Chats *)m->conferences_object); |
207 | kill_messenger(m); | 225 | kill_messenger(m); |
208 | } | 226 | } |
@@ -342,68 +360,261 @@ void tox_iterate(Tox *tox, void *user_data) | |||
342 | do_groupchats((Group_Chats *)m->conferences_object, user_data); | 360 | do_groupchats((Group_Chats *)m->conferences_object, user_data); |
343 | } | 361 | } |
344 | 362 | ||
345 | uint32_t tox_fd_count(Tox *tox) | 363 | void tox_callback_loop_begin(Tox *tox, tox_loop_begin_cb *callback) |
346 | { | 364 | { |
365 | if (tox == NULL) { | ||
366 | return; | ||
367 | } | ||
368 | |||
347 | Messenger *m = tox; | 369 | Messenger *m = tox; |
348 | return 1 + m->net_crypto->tcp_c->tcp_connections_length; | 370 | m->loop_begin_cb = callback; |
349 | } | 371 | } |
350 | 372 | ||
351 | /** | 373 | void tox_callback_loop_end(Tox *tox, tox_loop_end_cb *callback) |
352 | * Gathers a list of every network FD activity is expected on | ||
353 | * @param sockets an array of size tox_fd_count() | ||
354 | */ | ||
355 | uint32_t tox_fds(Tox *tox, uint32_t *sockets, uint32_t max_sockets) | ||
356 | { | 374 | { |
375 | if (tox == NULL) { | ||
376 | return; | ||
377 | } | ||
378 | |||
357 | Messenger *m = tox; | 379 | Messenger *m = tox; |
358 | int count = 0; | 380 | m->loop_end_cb = callback; |
381 | } | ||
359 | 382 | ||
360 | if (max_sockets >= 1) { | 383 | #ifdef HAVE_LIBEV |
361 | sockets[count] = m->net->sock; | 384 | static void tox_stop_loop_cb(struct ev_loop *dispatcher, ev_async *listener, int events) |
362 | max_sockets--; | 385 | { |
363 | count++; | 386 | if (dispatcher == NULL || listener == NULL) { |
387 | return; | ||
364 | } | 388 | } |
365 | 389 | ||
366 | TCP_Connections *conns = m->net_crypto->tcp_c; | 390 | Event_Arg *tmp = (Event_Arg *) listener->data; |
367 | int x; | 391 | Messenger *m = tmp->tox; |
368 | 392 | ||
369 | for (x = 0; x < conns->tcp_connections_length; x++) { | 393 | if (ev_is_active(&m->net->sock_listener.listener) || ev_is_pending(&m->net->sock_listener.listener)) { |
370 | if (max_sockets == 0) { | 394 | ev_io_stop(dispatcher, &m->net->sock_listener.listener); |
371 | break; | 395 | } |
372 | } | ||
373 | 396 | ||
374 | TCP_con *conn = &conns->tcp_connections[x]; | 397 | uint32_t len = tcp_connections_length(m->net_crypto->tcp_c); |
375 | sockets[count] = conn->connection->sock; | 398 | |
376 | count++; | 399 | for (uint32_t i = 0; i < len; i++) { |
377 | max_sockets--; | 400 | const TCP_con *conn = tcp_connections_connection_at(m->net_crypto->tcp_c, i); |
401 | |||
402 | if (ev_is_active(&conn->connection->sock_listener.listener) | ||
403 | || ev_is_pending(&conn->connection->sock_listener.listener)) { | ||
404 | ev_io_stop(dispatcher, &conn->connection->sock_listener.listener); | ||
405 | } | ||
378 | } | 406 | } |
379 | 407 | ||
380 | return count; | 408 | ev_async_stop(dispatcher, listener); |
409 | |||
410 | ev_break(dispatcher, EVBREAK_ALL); | ||
381 | } | 411 | } |
382 | 412 | ||
383 | void tox_callback_loop_begin(Tox *tox, tox_loop_begin_cb *callback) | 413 | static void tox_do_iterate(struct ev_loop *dispatcher, ev_io *sock_listener, int events) |
384 | { | 414 | { |
385 | Messenger *m = tox; | 415 | if (dispatcher == NULL || sock_listener == NULL) { |
386 | m->loop_begin_cb = callback; | 416 | return; |
417 | } | ||
418 | |||
419 | Event_Arg *tmp = (Event_Arg *) sock_listener->data; | ||
420 | Messenger *m = tmp->tox; | ||
421 | |||
422 | if (m->loop_begin_cb) { | ||
423 | m->loop_begin_cb(m, tmp->user_data); | ||
424 | } | ||
425 | |||
426 | tox_iterate(tmp->tox, tmp->user_data); | ||
427 | |||
428 | if (!ev_is_active(&m->net->sock_listener.listener) && !ev_is_pending(&m->net->sock_listener.listener)) { | ||
429 | m->net->sock_listener.dispatcher = dispatcher; | ||
430 | ev_io_init(&m->net->sock_listener.listener, tox_do_iterate, m->net->sock, EV_READ); | ||
431 | m->net->sock_listener.listener.data = sock_listener->data; | ||
432 | ev_io_start(dispatcher, &m->net->sock_listener.listener); | ||
433 | } | ||
434 | |||
435 | uint32_t len = tcp_connections_length(m->net_crypto->tcp_c); | ||
436 | |||
437 | for (uint32_t i = 0; i < len; i++) { | ||
438 | const TCP_con *conn = tcp_connections_connection_at(m->net_crypto->tcp_c, i); | ||
439 | |||
440 | if (!ev_is_active(&conn->connection->sock_listener.listener) | ||
441 | && !ev_is_pending(&conn->connection->sock_listener.listener)) { | ||
442 | conn->connection->sock_listener.dispatcher = dispatcher; | ||
443 | ev_io_init(&conn->connection->sock_listener.listener, tox_do_iterate, conn->connection->sock, EV_READ); | ||
444 | conn->connection->sock_listener.listener.data = sock_listener->data; | ||
445 | ev_io_start(m->dispatcher, &conn->connection->sock_listener.listener); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | if (m->loop_end_cb) { | ||
450 | m->loop_end_cb(m, tmp->user_data); | ||
451 | } | ||
387 | } | 452 | } |
453 | #elif HAVE_LIBEVENT | ||
454 | static void tox_do_iterate(evutil_socket_t fd, short events, void *arg) | ||
455 | { | ||
456 | if (arg == NULL) { | ||
457 | return; | ||
458 | } | ||
388 | 459 | ||
389 | void tox_callback_loop_end(Tox *tox, tox_loop_end_cb *callback) | 460 | Event_Arg *tmp = (Event_Arg *) arg; |
461 | Messenger *m = tmp->tox; | ||
462 | struct timeval timeout; | ||
463 | |||
464 | if (m->loop_begin_cb) { | ||
465 | m->loop_begin_cb(m, tmp->user_data); | ||
466 | } | ||
467 | |||
468 | tox_iterate(tmp->tox, tmp->user_data); | ||
469 | |||
470 | timeout.tv_sec = 0; | ||
471 | |||
472 | // TODO(cleverca22): use a longer timeout. | ||
473 | timeout.tv_usec = tox_iteration_interval(tmp->tox) * 1000 * 2; | ||
474 | |||
475 | if (!m->net->sock_listener) { | ||
476 | m->net->sock_listener = event_new(m->dispatcher, m->net->sock, EV_READ | EV_PERSIST, tox_do_iterate, arg); | ||
477 | } | ||
478 | |||
479 | event_add(m->net->sock_listener, &timeout); | ||
480 | |||
481 | uint32_t len = tcp_connections_length(m->net_crypto->tcp_c); | ||
482 | |||
483 | for (uint32_t i = 0; i < len; i++) { | ||
484 | const TCP_con *conn = tcp_connections_connection_at(m->net_crypto->tcp_c, i); | ||
485 | |||
486 | if (!conn->connection->sock_listener) { | ||
487 | conn->connection->sock_listener = event_new(m->dispatcher, conn->connection->sock, EV_READ | EV_PERSIST, tox_do_iterate, | ||
488 | arg); | ||
489 | } | ||
490 | |||
491 | event_add(conn->connection->sock_listener, NULL); | ||
492 | } | ||
493 | |||
494 | if (m->loop_end_cb) { | ||
495 | m->loop_end_cb(m, tmp->user_data); | ||
496 | } | ||
497 | } | ||
498 | #else | ||
499 | /** | ||
500 | * Gathers a list of every network file descriptor, | ||
501 | * where an activity is expected on. | ||
502 | * | ||
503 | * @param sockets a pointer to an array (the pointed array can be NULL). | ||
504 | * @param sockets_num the number of current known sockets (will be updated by the funciton). | ||
505 | * | ||
506 | * @return false if errors occurred, true otherwise. | ||
507 | */ | ||
508 | static bool tox_fds(Messenger *m, Socket **sockets, uint32_t *sockets_num) | ||
390 | { | 509 | { |
391 | Messenger *m = tox; | 510 | if (m == NULL || sockets == NULL || sockets_num == NULL) { |
392 | m->loop_end_cb = callback; | 511 | return false; |
512 | } | ||
513 | |||
514 | uint32_t len = tcp_connections_length(m->net_crypto->tcp_c); | ||
515 | uint32_t fdcount = 1 + len; | ||
516 | |||
517 | if (fdcount != *sockets_num || *sockets == NULL) { | ||
518 | Socket *tmp_sockets = (Socket *) realloc(*sockets, fdcount * sizeof(Socket)); | ||
519 | |||
520 | if (tmp_sockets == NULL) { | ||
521 | return false; | ||
522 | } | ||
523 | |||
524 | *sockets = tmp_sockets; | ||
525 | *sockets_num = fdcount; | ||
526 | } | ||
527 | |||
528 | (*sockets)[0] = m->net->sock; | ||
529 | |||
530 | uint32_t i = 0; | ||
531 | |||
532 | while (i < fdcount - 1 && i < len) { | ||
533 | const TCP_con *conn = tcp_connections_connection_at(m->net_crypto->tcp_c, i); | ||
534 | i++; | ||
535 | |||
536 | if (conn != NULL) { | ||
537 | (*sockets)[i] = conn->connection->sock; | ||
538 | } else { | ||
539 | (*sockets)[i] = 0; | ||
540 | } | ||
541 | } | ||
542 | |||
543 | return true; | ||
393 | } | 544 | } |
545 | #endif | ||
394 | 546 | ||
395 | uint32_t tox_loop(Tox *tox, void *user_data) | 547 | bool tox_loop(Tox *tox, void *user_data, TOX_ERR_LOOP *error) |
396 | { | 548 | { |
397 | struct timeval timeout; | 549 | if (tox == NULL) { |
398 | int maxfd; | 550 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_NULL); |
399 | uint32_t i, list_size = 0; | 551 | |
400 | uint32_t *fdlist = NULL; | 552 | return false; |
553 | } | ||
554 | |||
401 | Messenger *m = tox; | 555 | Messenger *m = tox; |
402 | m->loop_run = true; | ||
403 | fd_set readable; | ||
404 | 556 | ||
557 | #ifdef HAVE_LIBEV | ||
558 | bool ret = true; | ||
559 | Event_Arg *tmp = (Event_Arg *) calloc(1, sizeof(Event_Arg)); | ||
560 | |||
561 | tmp->tox = tox; | ||
562 | tmp->user_data = user_data; | ||
563 | |||
564 | ev_async_init(&m->stop_loop, tox_stop_loop_cb); | ||
565 | m->stop_loop.data = tmp; | ||
566 | ev_async_start(m->dispatcher, &m->stop_loop); | ||
567 | |||
568 | ev_io stub_listener; | ||
569 | ev_init(&stub_listener, tox_do_iterate); | ||
570 | stub_listener.data = tmp; | ||
571 | tox_do_iterate(m->dispatcher, &stub_listener, 0); | ||
572 | |||
573 | // TODO(Ansa89): travis states that "ev_run" returns "void", | ||
574 | // but "man 3 ev" states it returns "bool" | ||
575 | #if 0 | ||
576 | ret = !ev_run(m->dispatcher, 0); | ||
577 | |||
578 | if (ret) { | ||
579 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_OK); | ||
580 | } else { | ||
581 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_BREAK); | ||
582 | } | ||
583 | |||
584 | #endif | ||
585 | |||
586 | ev_run(m->dispatcher, 0); | ||
587 | |||
588 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_OK); | ||
589 | |||
590 | free(tmp); | ||
591 | #elif HAVE_LIBEVENT | ||
592 | Event_Arg *tmp = (Event_Arg *) calloc(1, sizeof(Event_Arg)); | ||
593 | |||
594 | tmp->tox = tox; | ||
595 | tmp->user_data = user_data; | ||
596 | |||
597 | tox_do_iterate(0, 0, tmp); | ||
598 | bool ret = event_base_dispatch(m->dispatcher) < 0 ? false : true; | ||
599 | |||
600 | if (ret) { | ||
601 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_OK); | ||
602 | } else { | ||
603 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_BREAK); | ||
604 | } | ||
605 | |||
606 | free(tmp); | ||
607 | #else | ||
608 | bool ret = true; | ||
609 | uint32_t fdcount = 0; | ||
610 | Socket *fdlist = NULL; | ||
611 | |||
612 | m->loop_run = true; | ||
405 | 613 | ||
406 | while (m->loop_run) { | 614 | while (m->loop_run) { |
615 | Socket maxfd; | ||
616 | fd_set readable; | ||
617 | |||
407 | if (m->loop_begin_cb) { | 618 | if (m->loop_begin_cb) { |
408 | m->loop_begin_cb(tox, user_data); | 619 | m->loop_begin_cb(tox, user_data); |
409 | } | 620 | } |
@@ -413,16 +624,27 @@ uint32_t tox_loop(Tox *tox, void *user_data) | |||
413 | maxfd = 0; | 624 | maxfd = 0; |
414 | FD_ZERO(&readable); | 625 | FD_ZERO(&readable); |
415 | 626 | ||
416 | uint32_t fdcount = tox_fd_count(tox); | 627 | // TODO(cleverca22): is it a good idea to reuse previous fdlist when |
628 | // fdcount!=0 && tox_fds()==false? | ||
629 | if (fdcount == 0 && !tox_fds(m, &fdlist, &fdcount)) { | ||
630 | // We must stop because maxfd won't be set. | ||
631 | // TODO(cleverca22): should we call loop_end_cb() on error? | ||
632 | if (m->loop_end_cb) { | ||
633 | m->loop_end_cb(tox, user_data); | ||
634 | } | ||
635 | |||
636 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_GET_FDS); | ||
637 | |||
638 | free(fdlist); | ||
417 | 639 | ||
418 | if (fdcount > list_size) { | 640 | return false; |
419 | fdlist = realloc(fdlist, fdcount * sizeof(uint32_t)); | ||
420 | list_size = fdcount; | ||
421 | } | 641 | } |
422 | 642 | ||
423 | fdcount = tox_fds(tox, fdlist, list_size); | 643 | for (uint32_t i = 0; i < fdcount; i++) { |
644 | if (fdlist[i] == 0) { | ||
645 | continue; | ||
646 | } | ||
424 | 647 | ||
425 | for (i = 0; i < fdcount; i++) { | ||
426 | FD_SET(fdlist[i], &readable); | 648 | FD_SET(fdlist[i], &readable); |
427 | 649 | ||
428 | if (fdlist[i] > maxfd) { | 650 | if (fdlist[i] > maxfd) { |
@@ -430,27 +652,49 @@ uint32_t tox_loop(Tox *tox, void *user_data) | |||
430 | } | 652 | } |
431 | } | 653 | } |
432 | 654 | ||
655 | struct timeval timeout; | ||
656 | |||
433 | timeout.tv_sec = 0; | 657 | timeout.tv_sec = 0; |
434 | timeout.tv_usec = tox_iteration_interval(tox) * 1000 * 2; // TODO, use a longer timeout (cleverca22) | 658 | |
659 | // TODO(cleverca22): use a longer timeout. | ||
660 | timeout.tv_usec = tox_iteration_interval(tox) * 1000 * 2; | ||
435 | 661 | ||
436 | if (m->loop_end_cb) { | 662 | if (m->loop_end_cb) { |
437 | m->loop_end_cb(tox, user_data); | 663 | m->loop_end_cb(tox, user_data); |
438 | } | 664 | } |
439 | 665 | ||
440 | int ret = select(maxfd, &readable, NULL, NULL, &timeout); | 666 | if (select(maxfd, &readable, NULL, NULL, &timeout) < 0 && errno != EBADF) { |
667 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_SELECT); | ||
668 | |||
669 | free(fdlist); | ||
441 | 670 | ||
442 | if (ret < 0) { | 671 | return false; |
443 | return ret; | ||
444 | } | 672 | } |
445 | } | 673 | } |
446 | 674 | ||
447 | return 0; | 675 | SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_OK); |
676 | |||
677 | free(fdlist); | ||
678 | #endif | ||
679 | |||
680 | return ret; | ||
448 | } | 681 | } |
449 | 682 | ||
450 | void tox_loop_stop(Tox *tox) | 683 | void tox_loop_stop(Tox *tox) |
451 | { | 684 | { |
685 | if (tox == NULL) { | ||
686 | return; | ||
687 | } | ||
688 | |||
452 | Messenger *m = tox; | 689 | Messenger *m = tox; |
690 | |||
691 | #ifdef HAVE_LIBEV | ||
692 | ev_async_send(m->dispatcher, &m->stop_loop); | ||
693 | #elif HAVE_LIBEVENT | ||
694 | event_base_loopbreak(m->dispatcher); | ||
695 | #else | ||
453 | m->loop_run = false; | 696 | m->loop_run = false; |
697 | #endif | ||
454 | } | 698 | } |
455 | 699 | ||
456 | void tox_self_get_address(const Tox *tox, uint8_t *address) | 700 | void tox_self_get_address(const Tox *tox, uint8_t *address) |
diff --git a/toxcore/tox.h b/toxcore/tox.h index 0be019cd..ab4ae7b1 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -991,9 +991,42 @@ uint32_t tox_iteration_interval(const Tox *tox); | |||
991 | void tox_iterate(Tox *tox, void *user_data); | 991 | void tox_iterate(Tox *tox, void *user_data); |
992 | 992 | ||
993 | /** | 993 | /** |
994 | * Run tox_iterate() any time a packet arrives, only returns after tox_loop_stop(). | 994 | * Error codes for tox_loop(). |
995 | */ | 995 | */ |
996 | uint32_t tox_loop(Tox *tox, void *user_data); | 996 | typedef enum TOX_ERR_LOOP { |
997 | |||
998 | /** | ||
999 | * The function returned successfully. | ||
1000 | */ | ||
1001 | TOX_ERR_LOOP_OK, | ||
1002 | |||
1003 | /** | ||
1004 | * Invalid arguments passed. | ||
1005 | */ | ||
1006 | TOX_ERR_LOOP_NULL, | ||
1007 | |||
1008 | /** | ||
1009 | * Failed running events dispatcher. | ||
1010 | */ | ||
1011 | TOX_ERR_LOOP_BREAK, | ||
1012 | |||
1013 | /** | ||
1014 | * Failed running select(). | ||
1015 | */ | ||
1016 | TOX_ERR_LOOP_SELECT, | ||
1017 | |||
1018 | /** | ||
1019 | * Failed getting sockets file descriptors. | ||
1020 | */ | ||
1021 | TOX_ERR_LOOP_GET_FDS, | ||
1022 | |||
1023 | } TOX_ERR_LOOP; | ||
1024 | |||
1025 | |||
1026 | /** | ||
1027 | * Run tox_iterate() any time a packet arrives, returns after tox_loop_stop() or tox_kill(). | ||
1028 | */ | ||
1029 | bool tox_loop(Tox *tox, void *user_data, TOX_ERR_LOOP *error); | ||
997 | 1030 | ||
998 | /** | 1031 | /** |
999 | * Tell tox_loop() to return. | 1032 | * Tell tox_loop() to return. |
@@ -1009,7 +1042,7 @@ typedef void tox_loop_begin_cb(Tox *tox, void *user_data); | |||
1009 | /** | 1042 | /** |
1010 | * Set the callback for the `loop_begin` event. Pass NULL to unset. | 1043 | * Set the callback for the `loop_begin` event. Pass NULL to unset. |
1011 | * | 1044 | * |
1012 | * Callback ran when tox_loop() calls into tox_iterate(), the client can lock a mutex here. | 1045 | * This callback is invoked when tox_loop() calls into tox_iterate(), the client can lock a mutex here. |
1013 | */ | 1046 | */ |
1014 | void tox_callback_loop_begin(Tox *tox, tox_loop_begin_cb *callback); | 1047 | void tox_callback_loop_begin(Tox *tox, tox_loop_begin_cb *callback); |
1015 | 1048 | ||
@@ -1022,7 +1055,7 @@ typedef void tox_loop_end_cb(Tox *tox, void *user_data); | |||
1022 | /** | 1055 | /** |
1023 | * Set the callback for the `loop_end` event. Pass NULL to unset. | 1056 | * Set the callback for the `loop_end` event. Pass NULL to unset. |
1024 | * | 1057 | * |
1025 | * Callback ran when tox_loop() is finished with tox_iterate(), the client can unlock the mutex here. | 1058 | * This callback is invoked when tox_loop() is finished with tox_iterate(), the client can unlock the mutex here. |
1026 | */ | 1059 | */ |
1027 | void tox_callback_loop_end(Tox *tox, tox_loop_end_cb *callback); | 1060 | void tox_callback_loop_end(Tox *tox, tox_loop_end_cb *callback); |
1028 | 1061 | ||