From ac621d96d3139ca09eeebd509d6f6b92380f4f41 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 20 Aug 2013 14:47:32 -0400 Subject: Refactor of core done. --- core/DHT.c | 24 ++--- core/DHT.h | 2 +- core/Messenger.c | 18 ++-- core/Messenger.h | 20 ++-- core/net_crypto.c | 1 - core/net_crypto.h | 2 - core/ping.c | 95 +++++++++--------- core/ping.h | 11 ++- core/timer.c | 290 ------------------------------------------------------ core/timer.h | 104 -------------------- 10 files changed, 85 insertions(+), 482 deletions(-) delete mode 100644 core/timer.c delete mode 100644 core/timer.h (limited to 'core') diff --git a/core/DHT.c b/core/DHT.c index d58c6d2c..a139f2c5 100644 --- a/core/DHT.c +++ b/core/DHT.c @@ -603,7 +603,7 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint uint32_t i; for (i = 0; i < num_nodes; ++i) { - send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); + send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); } @@ -709,7 +709,7 @@ static void do_DHT_friends(DHT * dht) /* if node is not dead. */ if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { - send_ping_request( dht->friends_list[i].client_list[j].ip_port, + send_ping_request(dht->ping, dht->c, dht->friends_list[i].client_list[j].ip_port, (clientid_t *) &dht->friends_list[i].client_list[j].client_id ); dht->friends_list[i].client_list[j].last_pinged = temp_time; } @@ -747,7 +747,7 @@ static void do_Close(DHT * dht) /* if node is not dead. */ if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { - send_ping_request( dht->close_clientlist[i].ip_port, + send_ping_request(dht->ping, dht->c, dht->close_clientlist[i].ip_port, (clientid_t *) &dht->close_clientlist[i].client_id ); dht->close_clientlist[i].last_pinged = temp_time; } @@ -772,8 +772,7 @@ static void do_Close(DHT * dht) void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key) { getnodes(dht, ip_port, public_key, dht->c->self_public_key); - //send_ping_request(dht, ip_port, (clientid_t *) public_key); - send_ping_request(ip_port, (clientid_t *) public_key); + send_ping_request(dht->ping, dht->c, ip_port, (clientid_t *) public_key); } /* send the given packet to node with client_id @@ -1039,8 +1038,7 @@ static void punch_holes(DHT * dht, IP ip, uint16_t *port_list, uint16_t numports /*TODO: improve port guessing algorithm*/ uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); IP_Port pinging = {ip, htons(port)}; - //send_ping_request(dht, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); - send_ping_request(pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); + send_ping_request(dht->ping, dht->c, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); } dht->friends_list[friend_num].punching_index = i; @@ -1139,8 +1137,7 @@ static void do_toping(DHT * dht) if (dht->toping[i].ip_port.ip.i == 0) return; - //send_ping_request(dht, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); - send_ping_request(dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); + send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); dht->toping[i].ip_port.ip.i = 0; } } @@ -1151,13 +1148,17 @@ DHT * new_DHT(Net_Crypto *c) DHT * temp = calloc(1, sizeof(DHT)); if (temp == NULL) return NULL; + temp->ping = new_ping(); + if (temp->ping == NULL){ + kill_DHT(temp); + return NULL; + } temp->c = c; networking_registerhandler(c->lossless_udp->net, 0, &handle_ping_request, temp); networking_registerhandler(c->lossless_udp->net, 1, &handle_ping_response, temp); networking_registerhandler(c->lossless_udp->net, 2, &handle_getnodes, temp); networking_registerhandler(c->lossless_udp->net, 3, &handle_sendnodes, temp); cryptopacket_registerhandler(c, 254, &handle_NATping, temp); - temp_DHT = temp; return temp; } @@ -1170,6 +1171,7 @@ void do_DHT(DHT * dht) } void kill_DHT(DHT * dht) { + kill_ping(dht->ping); free(dht->friends_list); free(dht); } @@ -1193,8 +1195,6 @@ void DHT_save(DHT * dht, uint8_t *data) */ int DHT_load(DHT * dht, uint8_t *data, uint32_t size) { - init_ping(); - if (size < sizeof(dht->close_clientlist)) return -1; diff --git a/core/DHT.h b/core/DHT.h index 0ecc0b50..7d926b13 100644 --- a/core/DHT.h +++ b/core/DHT.h @@ -100,9 +100,9 @@ typedef struct { Node_format toping[MAX_TOPING]; uint64_t last_toping; uint64_t close_lastgetnodes; + void * ping; } DHT; /*----------------------------------------------------------------------------------*/ -DHT * temp_DHT; //TODO: remove Client_data *DHT_get_close_list(DHT * dht); diff --git a/core/Messenger.c b/core/Messenger.c index 25a4ff98..a6cbb3ac 100644 --- a/core/Messenger.c +++ b/core/Messenger.c @@ -22,7 +22,6 @@ */ #include "Messenger.h" -#include "timer.h" #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -608,17 +607,17 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); } - /*Interval in seconds between LAN discovery packet sending*/ #define LAN_DISCOVERY_INTERVAL 60 #define PORT 33445 /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ -int LANdiscovery(timer *t, void *arg) +static void LANdiscovery(Messenger *m) { - send_LANdiscovery(htons(PORT), temp_net_crypto); - timer_start(t, LAN_DISCOVERY_INTERVAL); - return 0; + if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { + send_LANdiscovery(htons(PORT), m->net_crypto); + m->last_LANdiscovery = unix_time(); + } } /* run this at startup */ @@ -655,9 +654,6 @@ Messenger *initMessenger(void) set_nospam(&(m->fr), random_int()); init_cryptopackets(m->dht); - send_LANdiscovery(htons(PORT), m->net_crypto); - timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL); - return m; } @@ -885,7 +881,6 @@ void doInbound(Messenger *m) } } - /* the main loop that needs to be run at least 20 times per second. */ void doMessenger(Messenger *m) { @@ -895,8 +890,7 @@ void doMessenger(Messenger *m) do_net_crypto(m->net_crypto); doInbound(m); doFriends(m); - - timer_poll(); + LANdiscovery(m); } /* returns the size of the messenger data (for saving) */ diff --git a/core/Messenger.h b/core/Messenger.h index c4e7cc1e..518becc9 100644 --- a/core/Messenger.h +++ b/core/Messenger.h @@ -128,6 +128,8 @@ typedef struct Messenger { Friend *friendlist; uint32_t numfriends; + uint64_t last_LANdiscovery; + void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *); void *friend_message_userdata; void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *); @@ -222,17 +224,13 @@ int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t lengt return -1 if failure */ int setname(Messenger *m, uint8_t *name, uint16_t length); -/** - * @brief Get your nickname. - * - * @param[in] m The messanger context to use. - * - * @param[inout] name Pointer to a string for the name. - * - * @param[in] nlen The length of the string buffer. - * - * @return Return the length of the name, 0 on error. - */ +/* + Get your nickname. + m The messanger context to use. + name Pointer to a string for the name. + nlen The length of the string buffer. + returns Return the length of the name, 0 on error. +*/ uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen); /* get name of friendnumber diff --git a/core/net_crypto.c b/core/net_crypto.c index 2e63d2f1..e36a1666 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c @@ -706,7 +706,6 @@ Net_Crypto * new_net_crypto(Networking_Core * net) if (temp->lossless_udp == NULL) return NULL; memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); - temp_net_crypto = temp; //TODO remove return temp; } diff --git a/core/net_crypto.h b/core/net_crypto.h index 887b432b..7b9e9b97 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h @@ -73,8 +73,6 @@ typedef struct { #include "DHT.h" -Net_Crypto * temp_net_crypto; //TODO: remove this - #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) /* returns zero if the buffer contains only zeros */ diff --git a/core/ping.c b/core/ping.c index 10b9b19f..5da3c0ca 100644 --- a/core/ping.c +++ b/core/ping.c @@ -23,16 +23,20 @@ typedef struct { uint64_t timestamp; } pinged_t; -static pinged_t pings[PING_NUM_MAX]; -static size_t num_pings; -static size_t pos_pings; +typedef struct { + pinged_t pings[PING_NUM_MAX]; + size_t num_pings; + size_t pos_pings; +} PING; -extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c +void * new_ping(void) +{ + return calloc(1, sizeof(PING)); +} -void init_ping() +void kill_ping(void * ping) { - num_pings = 0; - pos_pings = 0; + free(ping); } static bool is_timeout(uint64_t time) @@ -40,17 +44,18 @@ static bool is_timeout(uint64_t time) return (time + PING_TIMEOUT) < now(); } -static void remove_timeouts() // O(n) +static void remove_timeouts(void * ping) // O(n) { + PING * png = ping; size_t i, id; - size_t new_pos = pos_pings; - size_t new_num = num_pings; + size_t new_pos = png->pos_pings; + size_t new_num = png->num_pings; // Loop through buffer, oldest first - for (i = 0; i < num_pings; i++) { - id = (pos_pings + i) % PING_NUM_MAX; + for (i = 0; i < png->num_pings; i++) { + id = (png->pos_pings + i) % PING_NUM_MAX; - if (is_timeout(pings[id].timestamp)) { + if (is_timeout(png->pings[id].timestamp)) { new_pos++; new_num--; } @@ -60,47 +65,49 @@ static void remove_timeouts() // O(n) } } - num_pings = new_num; - pos_pings = new_pos % PING_NUM_MAX; + png->num_pings = new_num; + png->pos_pings = new_pos % PING_NUM_MAX; } -uint64_t add_ping(IP_Port ipp) // O(n) +uint64_t add_ping(void * ping, IP_Port ipp) // O(n) { + PING * png = ping; size_t p; - remove_timeouts(); + remove_timeouts(ping); // Remove oldest ping if full buffer - if (num_pings == PING_NUM_MAX) { - num_pings--; - pos_pings = (pos_pings + 1) % PING_NUM_MAX; + if (png->num_pings == PING_NUM_MAX) { + png->num_pings--; + png->pos_pings = (png->pos_pings + 1) % PING_NUM_MAX; } // Insert new ping at end of list - p = (pos_pings + num_pings) % PING_NUM_MAX; + p = (png->pos_pings + png->num_pings) % PING_NUM_MAX; - pings[p].ipp = ipp; - pings[p].timestamp = now(); - pings[p].id = random_64b(); + png->pings[p].ipp = ipp; + png->pings[p].timestamp = now(); + png->pings[p].id = random_64b(); - num_pings++; - return pings[p].id; + png->num_pings++; + return png->pings[p].id; } -bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. +bool is_pinging(void * ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. { + PING * png = ping; if (ipp.ip.i == 0 && ping_id == 0) return false; size_t i, id; - remove_timeouts(); + remove_timeouts(ping); - for (i = 0; i < num_pings; i++) { - id = (pos_pings + i) % PING_NUM_MAX; + for (i = 0; i < png->num_pings; i++) { + id = (png->pos_pings + i) % PING_NUM_MAX; // ping_id = 0 means match any id - if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { + if ((ipp_eq(png->pings[id].ipp, ipp) || ipp.ip.i == 0) && (png->pings[id].id == ping_id || ping_id == 0)) { return true; } } @@ -108,25 +115,25 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with return false; } -int send_ping_request(IP_Port ipp, clientid_t *client_id) +int send_ping_request(void * ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id) { pingreq_t pk; int rc; uint64_t ping_id; - if (is_pinging(ipp, 0) || id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) + if (is_pinging(ping, ipp, 0) || id_eq(client_id, (clientid_t *)c->self_public_key)) return 1; // Generate random ping_id - ping_id = add_ping(ipp); + ping_id = add_ping(ping, ipp); pk.magic = PACKET_PING_REQ; - id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey + id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey random_nonce((uint8_t *) &pk.nonce); // Generate random nonce // Encrypt ping_id using recipient privkey rc = encrypt_data((uint8_t *) client_id, - temp_net_crypto->self_secret_key, + c->self_secret_key, (uint8_t *) &pk.nonce, (uint8_t *) &ping_id, sizeof(ping_id), (uint8_t *) &pk.ping_id); @@ -134,24 +141,24 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id) if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) return 1; - return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); + return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); } -int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) +int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id) { pingres_t pk; int rc; - if (id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) + if (id_eq(client_id, (clientid_t *)c->self_public_key)) return 1; pk.magic = PACKET_PING_RES; - id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey + id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey random_nonce((uint8_t *) &pk.nonce); // Generate random nonce // Encrypt ping_id using recipient privkey rc = encrypt_data((uint8_t *) client_id, - temp_net_crypto->self_secret_key, + c->self_secret_key, (uint8_t *) &pk.nonce, (uint8_t *) &ping_id, sizeof(ping_id), (uint8_t *) &pk.ping_id); @@ -159,7 +166,7 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) return 1; - return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); + return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); } int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) @@ -184,7 +191,7 @@ int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t return 1; // Send response - send_ping_response(source, &p->client_id, ping_id); + send_ping_response(dht->c, source, &p->client_id, ping_id); add_toping(dht, (uint8_t *) &p->client_id, source); return 0; @@ -212,7 +219,7 @@ int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_ return 1; // Make sure ping_id is correct - if (!is_pinging(source, ping_id)) + if (!is_pinging(dht->ping, source, ping_id)) return 1; // Associate source ip with client_id diff --git a/core/ping.h b/core/ping.h index 6d5a0ea6..1f30392c 100644 --- a/core/ping.h +++ b/core/ping.h @@ -7,10 +7,11 @@ #include -void init_ping(); -uint64_t add_ping(IP_Port ipp); -bool is_pinging(IP_Port ipp, uint64_t ping_id); -int send_ping_request(IP_Port ipp, clientid_t *client_id); -int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id); +void * new_ping(void); +void kill_ping(void * ping); +uint64_t add_ping(void * ping, IP_Port ipp); +bool is_pinging(void * ping, IP_Port ipp, uint64_t ping_id); +int send_ping_request(void * ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id); +int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id); int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length); int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length); diff --git a/core/timer.c b/core/timer.c deleted file mode 100644 index 29190921..00000000 --- a/core/timer.c +++ /dev/null @@ -1,290 +0,0 @@ -#define __STDC_FORMAT_MACROS -#include - -#include "timer.h" -#include "network.h" - -/* -A nested linked list increases efficiency of insertions. -Depending on the number of timers we have, we might need to have nested linked lists -in order to improve insertion efficiency. -The code below is preperation for that end, should it be necessary. - -typedef struct { - struct timer_package* _next; - union { - timer_packet* _inner; - timer* queue; - }; - uint64_t pkgtime; -} timer_package; - -timer_package* timer_package_pool; - -static timer_package* new_package() -{ - timer_package* ret; - if (timer_package_pool) { - ret = timer_package_pool; - timer_package_pool = timer_package_pool->_next; - } else { - ret = calloc(1, sizeof(struct timer_package)); - } - return ret; -} - -static void delete_package(timer_package* p) -{ - p->_next = timer_package_pool; - timer_package_pool = p; -} -*/ - -enum timer_state { - STATE_INACTIVE = 0, - STATE_ACTIVE, - STATE_CALLBACK -}; - -struct timer { - enum timer_state state; - timer *_prev; - timer *_next; - timer_callback cb; - void *userdata; - uint64_t deadline; -}; - -static timer *timer_main_queue; -static timer *timer_us_queue; /* hi-speed queue */ - -inline static void timer_dequeue(timer *t, timer **queue) -{ - if (t->state == STATE_INACTIVE) return; /* not in a queue */ - - if (t->_prev) { - t->_prev->_next = t->_next; - } else { - *queue = t->_next; - } - - if (t->_next) t->_next->_prev = t->_prev; - - t->state = STATE_INACTIVE; -} - -static void timer_enqueue(timer *t, timer **queue, timer *prev) -{ - t->state = STATE_ACTIVE; - - while (true) { - if (!*queue) { - t->_next = 0; - t->_prev = prev; - *queue = t; - return; - } - - if ((*queue)->deadline > t->deadline) { - (*queue)->_prev = t; - t->_next = *queue; - t->_prev = prev; - *queue = t; - return; - } - - prev = *queue; - queue = &((*queue)->_next); - } -} - -/*** interface ***/ - -void timer_init() -{ - /* Nothing needs to be done... yet. */ -} - -/* Do not depend on fields being zeroed */ -static timer *timer_pool; /* timer_pool is SINGLY LINKED!! */ - -timer *new_timer(void) -{ - timer *ret; - - if (timer_pool) { - ret = timer_pool; - timer_pool = timer_pool->_next; - } else { - ret = calloc(1, sizeof(struct timer)); - } - - ret->state = STATE_INACTIVE; - return ret; -} - -void delete_timer(timer *t) -{ - timer_dequeue(t, &timer_main_queue); - t->_next = timer_pool; - t->state = STATE_INACTIVE; - timer_pool = t; -} - -void timer_setup(timer *t, timer_callback cb, void *userarg) -{ - t->cb = cb; - t->userdata = userarg; -} - -void *timer_get_userdata(timer *t) -{ - return t->userdata; -} - -static void timer_delay_us(timer *t, int us) -{ - t->deadline += us; - timer **queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue; - timer_dequeue(t, &timer_main_queue); - timer_enqueue(t, queue, t->_prev); -} - -/* Starts the timer so that it's called in sec seconds in the future. - * A non-positive value of sec results in the callback being called immediately. - * This function may be called again after a timer has been started to adjust - * the expiry time. */ -void timer_start(timer *t, int sec) -{ - uint64_t newdeadline = current_time() + sec * US_PER_SECOND; - - if (timer_is_active(t)) { - if (t->deadline < newdeadline) { - timer_delay_us(t, newdeadline - t->deadline); - return; - } - - timer_dequeue(t, &timer_main_queue); - } - - t->deadline = newdeadline; - timer_enqueue(t, &timer_main_queue, 0); -} - -/* Stops the timer. Returns -1 if the timer was not active. */ -int timer_stop(timer *t) -{ - int ret = timer_is_active(t) ? -1 : 0; - timer_dequeue(t, &timer_main_queue); - return ret; -} - -/* Adds additionalsec seconds to the timer. - * Returns -1 and does nothing if the timer was not active. */ -int timer_delay(timer *t, int additonalsec) -{ - if (!timer_is_active(t)) return -1; - - timer_delay_us(t, additonalsec * US_PER_SECOND); - return 0; -} - -static uint64_t timer_diff(timer *t, uint64_t time) -{ - if (t->deadline <= time) return 0; - - return time - t->deadline; -} - -/* Returns the time remaining on a timer in seconds. - * Returns -1 if the timer is not active. - * Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */ -int timer_time_remaining(timer *t) -{ - if (!timer_is_active(t)) return -1; - - return timer_diff(t, current_time()) / US_PER_SECOND; -} - -bool timer_is_active(timer *t) -{ - return t->state != STATE_INACTIVE; -} - -/* Single-use timer. - * Creates a new timer, preforms setup and starts it. */ -void timer_single(timer_callback cb, void *userarg, int sec) -{ - timer *t = new_timer(); - timer_setup(t, cb, userarg); - timer_start(t, sec); -} - -/* Single-use microsecond timer. */ -void timer_us(timer_callback cb, void *userarg, int us) -{ - timer *t = new_timer(); - timer_setup(t, cb, userarg); - t->deadline = current_time() + us; - t->state = STATE_ACTIVE; - timer_enqueue(t, &timer_us_queue, 0); -} - -uint64_t prevtime = 0; -void timer_poll(void) -{ - uint64_t time = current_time(); - - /* Handle millisecond timers */ - while (timer_us_queue) { - if (timer_diff(timer_us_queue, time) != 0) break; - - timer *t = timer_us_queue; - timer_dequeue(t, &timer_us_queue); - t->cb(0, t->userdata); - delete_timer(t); - } - - if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) { - /* time moving backwards is just a sanity check */ - prevtime = time; - - while (timer_main_queue) { - if (timer_diff(timer_main_queue, time) != 0) break; - - timer *t = timer_main_queue; - t->state = STATE_CALLBACK; - int rv = t->cb(t, t->userdata); - - if (rv != 0) { - timer_dequeue(t, &timer_main_queue); - delete_timer(t); - continue; - } - - if (t->state != STATE_ACTIVE) { - timer_dequeue(t, &timer_main_queue); - } - } - } -} - -/*** Internal Testing ***/ - -/* I do not want to expose internals to the public, - * which is why internals testing is done this way. */ -void timer_internal_tests(bool (*assert)(bool, char *)) -{ - -} - -void timer_debug_print() -{ - timer *t = timer_main_queue; - printf("Queue:\n"); - - while (t) { - printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline / US_PER_SECOND, (char *)t->userdata); - t = t->_next; - } -} diff --git a/core/timer.h b/core/timer.h deleted file mode 100644 index 15491326..00000000 --- a/core/timer.h +++ /dev/null @@ -1,104 +0,0 @@ -/* timer.h - * - * Timing subsystem. Provides deadline timers. - * All times are aliased to a second for efficiency. - * - * Timer Guarantees: - * - The callback will not be called before the timer expires. - * - The callback will be called sometime after the timer expires, - * on a best effort basis. - * - If timer_poll is called at least once a second, the callback - * will be called at most one second after it expires. - * - * Copyright (C) 2013 Tox project All Rights Reserved. - * - * This file is part of Tox. - * - * Tox is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see . - * - */ - -#ifndef TIMER_H -#define TIMER_H - -#include -#include - -#define US_PER_SECOND 1000000 /* 1 s = 10^6 us */ - -struct timer; -typedef struct timer timer; - -/* If time_callback returns a non-zero value, timer t is deleted. - * You may call any of the timer functions within the callback: - * For example, you may call timer_start to restart the timer from - * within a callback. */ -typedef int (*timer_callback)(timer *t, void *userarg); - -/* Initisalise timer subsystem */ -void timer_init(void); - -/* Poll. (I will eventually replace all polling in Tox with an async system.) */ -void timer_poll(void); - -/* Creates a new timer. Does not enqueue/start it. */ -timer *new_timer(void); - -/* Destroys a timer instance. */ -void delete_timer(timer *t); - -/* Sets up the timer callback. */ -void timer_setup(timer *t, timer_callback cb, void *userarg); - -/* Accessor Function. */ -void *timer_get_userdata(timer *t); - -/* Starts the timer so that it's called in sec seconds in the future from now. - * A non-positive value of sec results in the callback being called immediately. - * This function may be called again after a timer has been started to adjust - * the expiry time. */ -void timer_start(timer *t, int sec); - -/* Stops the timer. Returns -1 if the timer was not active. */ -int timer_stop(timer *t); - -/* Adds additionalsec seconds to the timer. - * Returns -1 and does nothing if the timer was not active. */ -int timer_delay(timer *t, int additonalsec); - -/* Returns the time remaining on a timer in seconds. - * Returns -1 if the timer is not active. - * Returns 0 if the timer has expired and the callback hasn't been called yet. */ -int timer_time_remaining(timer *t); - -/* Determines if timer is active. Returns TRUE if it is active */ -bool timer_is_active(timer *t); - -/* Single-use timer. - * Creates a new timer, preforms setup and starts it. - * Callback must return a non-zero value to prevent memory leak. */ -void timer_single(timer_callback cb, void *userarg, int sec); - -/* Single-use microsecond timer. - * Creates a new timer, preforms setup and starts it. - * Please do not use this when accuracy is not absolutely required. - * Use when one needs to time a period < 1 s. - * Use the more coarse timers above for periods > 5 s. - * WARNING: the callback will be called with NULL as the first argument */ -void timer_us(timer_callback cb, void *userarg, int us); - -/* Internal Testing */ -void timer_internal_tests(bool( *)(bool, char *)); - -#endif -- cgit v1.2.3