Skip to content

Commit

Permalink
slight refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
iphydf committed Dec 29, 2021
1 parent 9d57d32 commit 87b3876
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 61 deletions.
37 changes: 23 additions & 14 deletions auto_tests/tox_loop_test.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include "../toxcore/tox.h"

#include "check_compat.h"
#include "../testing/misc_tools.h"

#define TCP_RELAY_PORT 33448
/* The Travis-CI container responds poorly to ::1 as a localhost address
Expand All @@ -17,30 +17,34 @@
#endif

typedef struct Loop_Test {
int start_count;
int stop_count;
volatile int start_count;
volatile int stop_count;
pthread_mutex_t mutex;
Tox *tox;
} Loop_Test;

static void tox_loop_cb_start(Tox *tox, void *user_data)
static void tox_loop_cb_start(Tox *tox, void *data)
{
Loop_Test *userdata = (Loop_Test *)user_data;
Loop_Test *userdata = (Loop_Test *)data;
pthread_mutex_lock(&userdata->mutex);
userdata->start_count++;
fprintf(stderr, "br1: %p (%d)\n", (volatile void *)&userdata->start_count, userdata->start_count);
fputs("br2\n", stderr);
++userdata->start_count;
}

static void tox_loop_cb_stop(Tox *tox, void *user_data)
static void tox_loop_cb_stop(Tox *tox, void *data)
{
Loop_Test *userdata = (Loop_Test *) user_data;
userdata->stop_count++;
Loop_Test *userdata = (Loop_Test *)data;
++userdata->stop_count;
pthread_mutex_unlock(&userdata->mutex);
}

static void *tox_loop_worker(void *data)
{
Loop_Test *userdata = (Loop_Test *) data;
tox_loop(userdata->tox, data, nullptr);
Loop_Test *userdata = (Loop_Test *)data;
Tox_Err_Loop err;
tox_loop(userdata->tox, userdata, &err);
ck_assert_msg(err == TOX_ERR_LOOP_OK, "tox_loop error: %d", err);
return nullptr;
}

Expand All @@ -62,6 +66,7 @@ static void test_tox_loop(void)
tox_callback_loop_end(userdata.tox, tox_loop_cb_stop);
pthread_create(&worker, nullptr, tox_loop_worker, &userdata);

fprintf(stderr, "br0: udp %p\n", (volatile void *)&userdata.start_count);
tox_self_get_dht_id(userdata.tox, dpk);

tox_options_default(opts);
Expand All @@ -81,21 +86,25 @@ static void test_tox_loop(void)
ck_assert_msg(tox_bootstrap(userdata_tcp.tox, TOX_LOCALHOST, 33445, dpk, &error), "Bootstrap error, %i", error);
pthread_mutex_unlock(&userdata_tcp.mutex);

sleep(10);
c_sleep(1000);

tox_loop_stop(userdata.tox);
pthread_join(worker, (void **)(void *)&retval);
ck_assert_msg(retval == 0, "tox_loop didn't return 0");

tox_kill(userdata.tox);
ck_assert_msg(userdata.start_count == userdata.stop_count, "start and stop must match");
fprintf(stderr, "br3: udp %p (%d)\n", (volatile void *)&userdata.start_count, userdata.start_count);
ck_assert_msg(userdata.start_count == userdata.stop_count, "start and stop must match (start = %d, stop = %d)",
userdata.start_count, userdata.stop_count);

tox_loop_stop(userdata_tcp.tox);
pthread_join(worker_tcp, (void **)(void *)&retval);
ck_assert_msg(retval == 0, "tox_loop didn't return 0");

tox_kill(userdata_tcp.tox);
ck_assert_msg(userdata_tcp.start_count == userdata_tcp.stop_count, "start and stop must match");
fprintf(stderr, "br4: tcp %p (%d)\n", (volatile void *)&userdata_tcp.start_count, userdata_tcp.start_count);
ck_assert_msg(userdata_tcp.start_count == userdata_tcp.stop_count, "start and stop must match (start = %d, stop = %d)",
userdata_tcp.start_count, userdata_tcp.stop_count);
}

int main(int argc, char *argv[])
Expand Down
26 changes: 26 additions & 0 deletions toxcore/TCP_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,32 @@ TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con)
{
return con->status;
}

#ifdef HAVE_LIBEV
bool tcp_con_ev_is_active(TCP_Client_Connection *con)
{
return ev_is_active(&con->sock_listener.listener)
|| ev_is_pending(&con->sock_listener.listener);
}

void tcp_con_ev_listen(TCP_Client_Connection *con, struct ev_loop *dispatcher, tcp_con_ev_listen_cb *callback,
void *data)
{
con->sock_listener.dispatcher = dispatcher;
con->sock_listener.listener.data = data;

ev_io_init(&con->sock_listener.listener, callback, con->sock.socket, EV_READ);
ev_io_start(dispatcher, &con->sock_listener.listener);
}
#endif

void tcp_con_ev_stop(TCP_Client_Connection *con)
{
#ifdef HAVE_LIBEV
ev_io_stop(con->sock_listener.dispatcher, &con->sock_listener.listener);
#endif
}

void *tcp_con_custom_object(const TCP_Client_Connection *con)
{
return con->custom_object;
Expand Down
13 changes: 13 additions & 0 deletions toxcore/TCP_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#include "TCP_server.h"
#include "crypto_core.h"

#ifdef HAVE_LIBEV
#include <ev.h>
#endif

#define TCP_CONNECTION_TIMEOUT 10

typedef enum TCP_Proxy_Type {
Expand Down Expand Up @@ -43,6 +47,15 @@ IP_Port tcp_con_ip_port(const TCP_Client_Connection *con);
Socket tcp_con_sock(const TCP_Client_Connection *con);
TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con);

#ifdef HAVE_LIBEV
bool tcp_con_ev_is_active(TCP_Client_Connection *con);

typedef void tcp_con_ev_listen_cb(struct ev_loop *dispatcher, ev_io *sock_listener, int events);
void tcp_con_ev_listen(TCP_Client_Connection *con, struct ev_loop *dispatcher, tcp_con_ev_listen_cb *callback,
void *data);
#endif
void tcp_con_ev_stop(TCP_Client_Connection *con);

void *tcp_con_custom_object(const TCP_Client_Connection *con);
uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con);
void tcp_con_set_custom_object(TCP_Client_Connection *con, void *object);
Expand Down
27 changes: 24 additions & 3 deletions toxcore/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,29 @@ Socket net_sock(const Networking_Core *net)
return net->sock;
}

#ifdef HAVE_LIBEV
bool net_ev_is_active(Networking_Core *net)
{
return ev_is_active(&net->sock_listener.listener) || ev_is_pending(&net->sock_listener.listener);
}

void net_ev_listen(Networking_Core *net, struct ev_loop *dispatcher, net_ev_listen_cb *callback, void *data)
{
net->sock_listener.dispatcher = dispatcher;
net->sock_listener.listener.data = data;

ev_io_init(&net->sock_listener.listener, callback, net->sock.socket, EV_READ);
ev_io_start(dispatcher, &net->sock_listener.listener);
}
#endif

void net_ev_stop(Networking_Core *net)
{
#ifdef HAVE_LIBEV
ev_io_stop(net->sock_listener.dispatcher, &net->sock_listener.listener);
#endif
}

/* Basic network functions:
*/

Expand Down Expand Up @@ -1023,9 +1046,7 @@ void kill_networking(Networking_Core *net)
}


#ifdef HAVE_LIBEV
ev_io_stop(net->sock_listener.dispatcher, &net->sock_listener.listener);
#endif
net_ev_stop(net);

free(net);
}
Expand Down
12 changes: 12 additions & 0 deletions toxcore/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include <stddef.h> // size_t
#include <stdint.h> // uint*_t

#ifdef HAVE_LIBEV
#include <ev.h> // uint*_t
#endif

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -324,6 +328,14 @@ Family net_family(const Networking_Core *net);
uint16_t net_port(const Networking_Core *net);
Socket net_sock(const Networking_Core *net);

#ifdef HAVE_LIBEV
bool net_ev_is_active(Networking_Core *net);

typedef void net_ev_listen_cb(struct ev_loop *dispatcher, ev_io *sock_listener, int events);
void net_ev_listen(Networking_Core *net, struct ev_loop *dispatcher, net_ev_listen_cb *callback, void *data);
#endif
void net_ev_stop(Networking_Core *net);

/** Run this before creating sockets.
*
* return 0 on success
Expand Down
69 changes: 25 additions & 44 deletions toxcore/tox.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,6 @@ static_assert(TOX_MAX_NAME_LENGTH == MAX_NAME_LENGTH,
static_assert(TOX_MAX_STATUS_MESSAGE_LENGTH == MAX_STATUSMESSAGE_LENGTH,
"TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH");

#if defined(HAVE_LIBEV)
typedef struct Event_Arg {
Tox *tox;
void *user_data;
} Event_Arg;
#endif

struct Tox {
// XXX: Messenger *must* be the first member, because toxav casts its
// `Tox *` to `Messenger **`.
Expand Down Expand Up @@ -840,19 +833,13 @@ void tox_iterate(Tox *tox, void *user_data)

void tox_callback_loop_begin(Tox *tox, tox_loop_begin_cb *callback)
{
if (tox == nullptr) {
return;
}

assert(tox != nullptr);
tox->loop_begin_callback = callback;
}

void tox_callback_loop_end(Tox *tox, tox_loop_end_cb *callback)
{
if (tox == nullptr) {
return;
}

assert(tox != nullptr);
tox->loop_end_callback = callback;
}

Expand All @@ -863,21 +850,20 @@ static void tox_stop_loop_async(struct ev_loop *dispatcher, ev_async *listener,
return;
}

Event_Arg *tmp = (Event_Arg *) listener->data;
Messenger *m = tmp->tox;
Tox_Userdata *tmp = (Tox_Userdata *)listener->data;
Messenger *m = tmp->tox->m;

if (ev_is_active(&m->net->sock_listener.listener) || ev_is_pending(&m->net->sock_listener.listener)) {
ev_io_stop(dispatcher, &m->net->sock_listener.listener);
if (net_ev_is_active(m->net)) {
net_ev_stop(m->net);
}

uint32_t len = tcp_connections_length(nc_get_tcp_c(m->net_crypto));

for (uint32_t i = 0; i < len; ++i) {
const TCP_con *conn = tcp_connections_connection_at(nc_get_tcp_c(m->net_crypto), i);

if (ev_is_active(&conn->connection->sock_listener.listener)
|| ev_is_pending(&conn->connection->sock_listener.listener)) {
ev_io_stop(dispatcher, &conn->connection->sock_listener.listener);
if (tcp_con_ev_is_active(conn->connection)) {
tcp_con_ev_stop(conn->connection);
}
}

Expand All @@ -892,38 +878,32 @@ static void tox_do_iterate(struct ev_loop *dispatcher, ev_io *sock_listener, int
return;
}

Event_Arg *tmp = (Event_Arg *)sock_listener->data;
Messenger *m = tmp->tox->m;
Tox_Userdata *tmp = (Tox_Userdata *)sock_listener->data;
Tox *tox = tmp->tox;
Messenger *m = tox->m;

if (tmp->tox->loop_begin_callback) {
tmp->tox->loop_begin_callback(tmp->tox, tmp->user_data);
}

tox_iterate(tmp->tox, tmp->user_data);

if (!ev_is_active(&m->net->sock_listener.listener) && !ev_is_pending(&m->net->sock_listener.listener)) {
m->net->sock_listener.dispatcher = dispatcher;
ev_io_init(&m->net->sock_listener.listener, tox_do_iterate, net_sock(m->net), EV_READ);
m->net->sock_listener.listener.data = sock_listener->data;
ev_io_start(dispatcher, &m->net->sock_listener.listener);
if (!net_ev_is_active(m->net)) {
net_ev_listen(m->net, dispatcher, tox_do_iterate, tmp);
}

uint32_t len = tcp_connections_length(nc_get_tcp_c(m->net_crypto));

for (uint32_t i = 0; i < len; ++i) {
const TCP_con *conn = tcp_connections_connection_at(nc_get_tcp_c(m->net_crypto), i);

if (!ev_is_active(&conn->connection->sock_listener.listener)
&& !ev_is_pending(&conn->connection->sock_listener.listener)) {
conn->connection->sock_listener.dispatcher = dispatcher;
ev_io_init(&conn->connection->sock_listener.listener, tox_do_iterate, tcp_con_sock(conn->connection), EV_READ);
conn->connection->sock_listener.listener.data = sock_listener->data;
ev_io_start(m->dispatcher, &conn->connection->sock_listener.listener);
if (!tcp_con_ev_is_active(conn->connection)) {
tcp_con_ev_listen(conn->connection, dispatcher, tox_do_iterate, tmp);
}
}

if (m->loop_end_callback) {
m->loop_end_callback(m, tmp->user_data);
if (tox->loop_end_callback) {
tox->loop_end_callback(tox, tmp->user_data);
}
}
#else
Expand All @@ -938,7 +918,8 @@ static void tox_do_iterate(struct ev_loop *dispatcher, ev_io *sock_listener, int
*/
static bool tox_fds(Messenger *m, Socket **sockets, uint32_t *sockets_num)
{
if (m == nullptr || sockets == nullptr || sockets_num == nullptr) {
assert(m != nullptr);
if (sockets == nullptr || sockets_num == nullptr) {
return false;
}

Expand Down Expand Up @@ -981,11 +962,13 @@ static bool tox_fds(Messenger *m, Socket **sockets, uint32_t *sockets_num)

bool tox_loop(Tox *tox, void *user_data, Tox_Err_Loop *error)
{
assert(tox != nullptr);

Messenger *m = tox->m;

#ifdef HAVE_LIBEV
bool ret = true;
Event_Arg *tmp = (Event_Arg *) calloc(1, sizeof(Event_Arg));
Tox_Userdata *tmp = (Tox_Userdata *) calloc(1, sizeof(Tox_Userdata));

if (tmp == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_LOOP_MALLOC);
Expand Down Expand Up @@ -1034,7 +1017,7 @@ bool tox_loop(Tox *tox, void *user_data, Tox_Err_Loop *error)
Socket maxfd;
fd_set readable;

if (tox->loop_begin_callback) {
if (tox->loop_begin_callback != nullptr) {
tox->loop_begin_callback(tox, user_data);
}

Expand All @@ -1050,7 +1033,7 @@ bool tox_loop(Tox *tox, void *user_data, Tox_Err_Loop *error)
if (fdcount == 0 && !tox_fds(m, &fdlist, &fdcount)) {
// We must stop because maxfd won't be set.
// TODO(cleverca22): should we call loop_end_callback() on error?
if (tox->loop_end_callback) {
if (tox->loop_end_callback != nullptr) {
tox->loop_end_callback(tox, user_data);
}

Expand Down Expand Up @@ -1103,9 +1086,7 @@ bool tox_loop(Tox *tox, void *user_data, Tox_Err_Loop *error)

void tox_loop_stop(Tox *tox)
{
if (tox == nullptr) {
return;
}
assert(tox != nullptr);

Messenger *m = tox->m;

Expand Down

0 comments on commit 87b3876

Please sign in to comment.