From 44dd293a4bbbe74e2a2aeeaf91dd618b10adae46 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Fri, 15 Feb 2019 13:52:38 +0900 Subject: [PATCH] Add itercall() to HashMap, more work on UDPC --- src/UDPC_HashMap.c | 19 ++ src/UDPC_HashMap.h | 5 + src/UDPConnection.c | 564 +++++++++++++++++++++++++------------------- src/UDPConnection.h | 16 +- 4 files changed, 360 insertions(+), 244 deletions(-) diff --git a/src/UDPC_HashMap.c b/src/UDPC_HashMap.c index 6b31f2e..502ac87 100644 --- a/src/UDPC_HashMap.c +++ b/src/UDPC_HashMap.c @@ -341,6 +341,25 @@ uint32_t UDPC_HashMap_get_capacity(UDPC_HashMap *hm) return hm->capacity; } +void UDPC_HashMap_itercall(UDPC_HashMap *hm, void (*fn)(void*, char*), void *userData) +{ + for(int x = 0; x < hm->capacity; ++x) + { + for(int y = 0; y * (4 + hm->unitSize) < hm->buckets[x]->size; ++y) + { + char *data = UDPC_Deque_index_ptr( + hm->buckets[x], 4 + hm->unitSize, y); + fn(userData, data + 4); + } + } + for(int x = 0; x * (4 + hm->unitSize) < hm->overflow->size; ++x) + { + char *data = UDPC_Deque_index_ptr( + hm->overflow, 4 + hm->unitSize, x); + fn(userData, data + 4); + } +} + void* UDPC_HashMap_INTERNAL_reinsert(UDPC_HashMap *hm, uint32_t key, void *data) { if(hm->capacity <= hm->size) diff --git a/src/UDPC_HashMap.h b/src/UDPC_HashMap.h index bbe35b0..de163aa 100644 --- a/src/UDPC_HashMap.h +++ b/src/UDPC_HashMap.h @@ -91,6 +91,11 @@ uint32_t UDPC_HashMap_get_size(UDPC_HashMap *hm); uint32_t UDPC_HashMap_get_capacity(UDPC_HashMap *hm); +/*! + * \brief Calls a fn with a ptr to each entry in the hash map + */ +void UDPC_HashMap_itercall(UDPC_HashMap *hm, void (*fn)(void*, char*), void *userData); + /*! * \brief A variant of insert that does not try to realloc() on no more space */ diff --git a/src/UDPConnection.c b/src/UDPConnection.c index bbd5478..54fb9e5 100644 --- a/src/UDPConnection.c +++ b/src/UDPConnection.c @@ -63,8 +63,7 @@ UDPC_Context* UDPC_init(uint16_t listenPort, int isClient) return context; } - context->connected = UDPC_Deque_init(sizeof(UDPC_INTERNAL_ConnectionData) - * (isClient != 0 ? 1 : UDPC_CD_AMOUNT)); + context->conMap = UDPC_HashMap_init(13, sizeof(UDPC_INTERNAL_ConnectionData)); timespec_get(&context->lastUpdated, TIME_UTC); @@ -133,32 +132,8 @@ UDPC_Context* UDPC_init_threaded_update(uint16_t listenPort, int isClient) void UDPC_destroy(UDPC_Context *ctx) { CleanupSocket(ctx->socketHandle); - for(int x = 0; x * sizeof(UDPC_INTERNAL_ConnectionData) < ctx->connected->size; ++x) - { - UDPC_INTERNAL_ConnectionData *cd = UDPC_Deque_index_ptr( - ctx->connected, sizeof(UDPC_INTERNAL_ConnectionData), x); - for(int y = 0; y * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sentPkts->size; ++y) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( - cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo), y); - if(pinfo->data) - { - free(pinfo->data); - } - } - UDPC_Deque_destroy(cd->sentPkts); - for(int y = 0; y * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sendPktQueue->size; ++y) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( - cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo), y); - if(pinfo->data) - { - free(pinfo->data); - } - } - UDPC_Deque_destroy(cd->sendPktQueue); - } - UDPC_Deque_destroy(ctx->connected); + UDPC_HashMap_itercall(ctx->conMap, UDPC_INTERNAL_destroy_conMap, NULL); + UDPC_HashMap_destroy(ctx->conMap); if((ctx->flags & 0x1) != 0) { @@ -177,6 +152,31 @@ void UDPC_destroy(UDPC_Context *ctx) free(ctx); } +void UDPC_INTERNAL_destroy_conMap(void *unused, char *data) +{ + UDPC_INTERNAL_ConnectionData *cd = (UDPC_INTERNAL_ConnectionData*)data; + for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sentPkts->size; ++x) + { + UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( + cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo), x); + if(pinfo->data) + { + free(pinfo->data); + } + } + UDPC_Deque_destroy(cd->sentPkts); + for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sendPktQueue->size; ++x) + { + UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( + cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo), x); + if(pinfo->data) + { + free(pinfo->data); + } + } + UDPC_Deque_destroy(cd->sendPktQueue); +} + uint32_t UDPC_get_error(UDPC_Context *ctx) { uint32_t error = ctx->error; @@ -226,227 +226,30 @@ void UDPC_set_logging_type(UDPC_Context *ctx, uint32_t logType) void UDPC_update(UDPC_Context *ctx) { - // get dt - struct timespec tsNow; - timespec_get(&tsNow, TIME_UTC); - float dt = UDPC_ts_diff_to_seconds(&tsNow, &ctx->lastUpdated); - ctx->lastUpdated = tsNow; + UDPC_INTERNAL_update_struct us = { + {0, 0}, + 0.0f, + NULL, + ctx + }; + timespec_get(&us.tsNow, TIME_UTC); + us.dt = UDPC_ts_diff_to_seconds(&us.tsNow, &ctx->lastUpdated); + ctx->lastUpdated = us.tsNow; + us.removedQueue = UDPC_Deque_init(4 * (ctx->conMap->size)); - // check timed-out/rtt/send-interval - UDPC_INTERNAL_ConnectionData *cd; - UDPC_Deque *removedQueue = UDPC_Deque_init( - ctx->connected->alloc_size / sizeof(UDPC_INTERNAL_ConnectionData) * sizeof(int)); - for(int x = 0; x * sizeof(UDPC_INTERNAL_ConnectionData) < ctx->connected->size; ++x) - { - cd = UDPC_Deque_index_ptr(ctx->connected, sizeof(UDPC_INTERNAL_ConnectionData), x); + UDPC_HashMap_itercall(ctx->conMap, UDPC_INTERNAL_update_to_rtt_si, &us); - // check if connected timed out - if(UDPC_ts_diff_to_seconds(&tsNow, &cd->received) >= UDPC_TIMEOUT_SECONDS) - { - UDPC_Deque_push_back(removedQueue, &x, sizeof(int)); - UDPC_INTERNAL_log(ctx, 2, "Connection timed out with addr %s port %d", - UDPC_INTERNAL_atostr(ctx, cd->addr), - cd->port); - continue; - } - - // check good/bad mode - cd->toggleTimer += dt; - cd->toggledTimer += dt; - if((cd->flags & 0x2) != 0 && (cd->flags & 0x4) == 0) - { - // good mode, bad rtt - UDPC_INTERNAL_log(ctx, 2, "Connection with %s switching to bad mode", - UDPC_INTERNAL_atostr(ctx, cd->addr)); - - cd->flags = cd->flags & 0xFFFFFFFD; - if(cd->toggledTimer >= 10.0f) - { - cd->toggleT *= 2.0f; - if(cd->toggleT > 60.0f) - { - cd->toggleT = 60.0f; - } - } - cd->toggledTimer = 0.0f; - } - else if((cd->flags & 0x2) != 0) - { - // good mode, good rtt - if(cd->toggleTimer >= 10.0f) - { - cd->toggleTimer = 0.0f; - cd->toggleT /= 2.0f; - if(cd->toggleT < 1.0f) - { - cd->toggleT = 1.0f; - } - } - } - else if((cd->flags & 0x2) == 0 && (cd->flags & 0x4) != 0) - { - // bad mode, good rtt - if(cd->toggledTimer >= cd->toggleT) - { - cd->toggleTimer = 0.0f; - cd->toggledTimer = 0.0f; - UDPC_INTERNAL_log(ctx, 2, "Connection with %s switching to good mode", - UDPC_INTERNAL_atostr(ctx, cd->addr)); - cd->flags |= 0x2; - } - } - else - { - // bad mode, bad rtt - cd->toggledTimer = 0.0f; - } - - // check send interval - cd->timer += dt; - if(cd->timer >= ((cd->flags & 0x2) != 0 - ? UDPC_GOOD_MODE_SEND_INTERVAL : UDPC_BAD_MODE_SEND_INTERVAL)) - { - cd->timer = 0.0f; - cd->flags |= 0x1; - } - - } // remove timed out - for(int x = 0; x * sizeof(int) < removedQueue->size; ++x) + for(int x = 0; x * 4 < us.removedQueue->size; ++x) { - UDPC_Deque_remove(ctx->connected, sizeof(UDPC_INTERNAL_ConnectionData), - *((int*)UDPC_Deque_index_rev_ptr(removedQueue, sizeof(int), x))); + uint32_t *key = UDPC_Deque_index_ptr(us.removedQueue, 4, x); + UDPC_HashMap_remove(ctx->conMap, *key); } - UDPC_Deque_destroy(removedQueue); + UDPC_Deque_destroy(us.removedQueue); + us.removedQueue = NULL; // check triggerSend to send packets to connected - for(int x = 0; x * sizeof(UDPC_INTERNAL_ConnectionData) < ctx->connected->size; ++x) - { - cd = UDPC_Deque_index_ptr(ctx->connected, sizeof(UDPC_INTERNAL_ConnectionData), x); - if((cd->flags & 0x1) != 0) - { - cd->flags &= 0xFFFFFFFE; - if(cd->sendPktQueue->size == 0) - { - // send packet queue is empty, send heartbeat packet - if(UDPC_ts_diff_to_seconds(&tsNow, &cd->sent) < UDPC_HEARTBEAT_PKT_INTERVAL) - { - continue; - } - - char *data = malloc(20); - UDPC_INTERNAL_prepare_pkt(data, cd->id, cd->rseq, cd->ack, &cd->lseq, 0); - - struct sockaddr_in destinationInfo; - destinationInfo.sin_family = AF_INET; - destinationInfo.sin_addr.s_addr = cd->addr; - destinationInfo.sin_port = htons(cd->port); - long int sentBytes = sendto( - ctx->socketHandle, - data, - 20, - 0, - (struct sockaddr*) &destinationInfo, - sizeof(struct sockaddr_in)); - if(sentBytes != 20) - { - UDPC_INTERNAL_log(ctx, 0, "Failed to send packet to %s port %s", - UDPC_INTERNAL_atostr(ctx, cd->addr), cd->port); - } - else - { - UDPC_INTERNAL_PacketInfo sentInfo = { - cd->addr, - cd->lseq - 1, - 0, - NULL, - 0, - tsNow - }; - UDPC_Deque_push_back( - cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - while(cd->sentPkts->size / sizeof(UDPC_INTERNAL_PacketInfo) - > UDPC_SENT_PKTS_MAX_SIZE) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfo->data && pinfo->size != 0) - { - free(pinfo->data); - } - UDPC_Deque_pop_front(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - } - } - free(data); - } - else // sendPktQueue not empty - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr( - cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - char *data = malloc(20 + pinfo->size); - UDPC_INTERNAL_prepare_pkt(data, cd->id, cd->rseq, cd->ack, &cd->lseq, ((pinfo->flags & 0x3) << 1)); - memcpy(&data[20], pinfo->data, pinfo->size); - - struct sockaddr_in destinationInfo; - destinationInfo.sin_family = AF_INET; - destinationInfo.sin_addr.s_addr = cd->addr; - destinationInfo.sin_port = htons(cd->port); - long int sentBytes = sendto( - ctx->socketHandle, - data, - 20 + pinfo->size, - 0, - (struct sockaddr*) &destinationInfo, - sizeof(struct sockaddr_in)); - if(sentBytes != 20 + pinfo->size) - { - UDPC_INTERNAL_log(ctx, 0, "Failed to send packet to %s port %s", - UDPC_INTERNAL_atostr(ctx, cd->addr), cd->port); - } - else - { - if((pinfo->flags & 0x2) != 0) - { - UDPC_INTERNAL_PacketInfo sentInfo = { - cd->addr, - cd->lseq - 1, - 0x2, - data, - 20 + pinfo->size, - tsNow - }; - UDPC_Deque_push_back( - cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - } - else - { - UDPC_INTERNAL_PacketInfo sentInfo = { - cd->addr, - cd->lseq - 1, - 0, - NULL, - 0, - tsNow - }; - UDPC_Deque_push_back( - cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - } - - while(cd->sentPkts->size / sizeof(UDPC_INTERNAL_PacketInfo) - > UDPC_SENT_PKTS_MAX_SIZE) - { - UDPC_INTERNAL_PacketInfo *pinfoCached = UDPC_Deque_get_front_ptr(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfoCached->data && pinfoCached->size != 0) - { - free(pinfoCached->data); - } - UDPC_Deque_pop_front(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - } - } - free(pinfo->data); - UDPC_Deque_pop_front(cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - } - } + UDPC_HashMap_itercall(ctx->conMap, UDPC_INTERNAL_update_send, &us); // receive packet #if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS @@ -491,7 +294,282 @@ void UDPC_update(UDPC_Context *ctx) if(isConnect != 0 && (ctx->flags & 0x40) != 0) { - // TODO after impl hash map of connected + if(!UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr)) + { + UDPC_INTERNAL_log(ctx, 2, "Establishing connection with %s port %d", + UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr), + ntohs(receivedData.sin_port)); + UDPC_INTERNAL_ConnectionData newCD = { + 1, + 0, + 0, + 0, + 0xFFFFFFFF, + 0.0f, + 30.0f, + 0.0f, + 0.0f, + receivedData.sin_addr.s_addr, + ntohs(receivedData.sin_port), + UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SENT_PKTS_ALLOC_SIZE), + UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SENT_PKTS_ALLOC_SIZE), + {0, 0}, + {0, 0}, + {1, 0} + }; + timespec_get(&newCD.received, TIME_UTC); + timespec_get(&newCD.sent, TIME_UTC); + UDPC_HashMap_insert(ctx->conMap, newCD.addr, &newCD); + } + return; + } + else if(isPing != 0) + { + UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr); + if(cd) + { + cd->flags |= 0x1; + } + } + + UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr); + if(!cd) + { + // Received packet from unknown, ignoring + return; + } + else if(conID != cd->id) + { + // Received packet id and known id does not match, ignoring + return; + } + + // packet is valid + UDPC_INTERNAL_log(ctx, 2, "Valid packet %d from %s", seqID, + UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr)); + + int isOutOfOrder = 0; + // TODO rest of received packet actions +} + +void UDPC_INTERNAL_update_to_rtt_si(void *userData, char *data) +{ + UDPC_INTERNAL_update_struct *us = + (UDPC_INTERNAL_update_struct*)userData; + UDPC_INTERNAL_ConnectionData *cd = (UDPC_INTERNAL_ConnectionData*)data; + + // check for timed out connection + if(UDPC_ts_diff_to_seconds(&us->tsNow, &cd->received) >= UDPC_TIMEOUT_SECONDS) + { + UDPC_Deque_push_back(us->removedQueue, &cd->addr, 4); + UDPC_INTERNAL_log(us->ctx, 2, "Connection timed out with addr %s port %d", + UDPC_INTERNAL_atostr(us->ctx, cd->addr), + cd->port); + return; + } + + // check good/bad mode + cd->toggleTimer += us->dt; + cd->toggledTimer += us->dt; + if((cd->flags & 0x2) != 0 && (cd->flags & 0x4) == 0) + { + // good mode, bad rtt + UDPC_INTERNAL_log(us->ctx, 2, "Connection with %s switching to bad mode", + UDPC_INTERNAL_atostr(us->ctx, cd->addr)); + + cd->flags = cd->flags & 0xFFFFFFFD; + if(cd->toggledTimer <= 10.0f) + { + cd->toggleT *= 2.0f; + if(cd->toggleT > 60.0f) + { + cd->toggleT = 60.0f; + } + } + cd->toggledTimer = 0.0f; + } + else if((cd->flags & 0x2) != 0) + { + // good mode, good rtt + if(cd->toggleTimer >= 10.0f) + { + cd->toggleTimer = 0.0f; + cd->toggleT /= 2.0f; + if(cd->toggleT < 1.0f) + { + cd->toggleT = 1.0f; + } + } + } + else if((cd->flags & 0x2) == 0 && (cd->flags & 0x4) != 0) + { + // bad mode, good rtt + if(cd->toggledTimer >= cd->toggleT) + { + cd->toggleTimer = 0.0f; + cd->toggledTimer = 0.0f; + UDPC_INTERNAL_log(us->ctx, 2, "Connection with %s switching to good mode", + UDPC_INTERNAL_atostr(us->ctx, cd->addr)); + cd->flags |= 0x2; + } + } + else + { + // bad mode, bad rtt + cd->toggledTimer = 0.0f; + } + + // check send interval + cd->timer += us->dt; + if(cd->timer >= ((cd->flags & 0x2) != 0 + ? UDPC_GOOD_MODE_SEND_INTERVAL : UDPC_BAD_MODE_SEND_INTERVAL)) + { + cd->timer = 0.0f; + cd->flags |= 0x1; + } +} + +void UDPC_INTERNAL_update_send(void *userData, char *data) +{ + UDPC_INTERNAL_update_struct *us = + (UDPC_INTERNAL_update_struct*)userData; + UDPC_INTERNAL_ConnectionData *cd = (UDPC_INTERNAL_ConnectionData*)data; + + if((cd->flags & 0x1) == 0) + { + return; + } + + cd->flags = cd->flags & 0xFFFFFFFE; + if(cd->sendPktQueue->size == 0) + { + // send packet queue is empty, send heartbeat packet + if(UDPC_ts_diff_to_seconds(&us->tsNow, &cd->sent) < UDPC_HEARTBEAT_PKT_INTERVAL) + { + return; + } + + char *data = malloc(20); + UDPC_INTERNAL_prepare_pkt(data, cd->id, cd->rseq, cd->ack, &cd->lseq, 0); + + struct sockaddr_in destinationInfo; + destinationInfo.sin_family = AF_INET; + destinationInfo.sin_addr.s_addr = cd->addr; + destinationInfo.sin_port = htons(cd->port); + long int sentBytes = sendto( + us->ctx->socketHandle, + data, + 20, + 0, + (struct sockaddr*) &destinationInfo, + sizeof(struct sockaddr_in)); + if(sentBytes != 20) + { + UDPC_INTERNAL_log(us->ctx, 0, "Failed to send packet to %s port %d", + UDPC_INTERNAL_atostr(us->ctx, cd->addr), cd->port); + free(data); + return; + } + + UDPC_INTERNAL_PacketInfo sentInfo = { + cd->addr, + cd->lseq - 1, + 0, + NULL, + 0, + us->tsNow + }; + UDPC_Deque_push_back( + cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); + while(cd->sentPkts->size / sizeof(UDPC_INTERNAL_PacketInfo) > UDPC_SENT_PKTS_MAX_SIZE) + { + UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr( + cd->sentPkts, + sizeof(UDPC_INTERNAL_PacketInfo)); + if(pinfo->data && pinfo->size != 0) + { + free(pinfo->data); + } + UDPC_Deque_pop_front(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); + } + free(data); + } + else // sendPktQueue not empty + { + UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr( + cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); + char *data = malloc(20 + pinfo->size); + UDPC_INTERNAL_prepare_pkt( + data, + cd->id, + cd->rseq, + cd->ack, + &cd->lseq, + ((pinfo->flags & 0x3) << 1)); + memcpy(&data[20], pinfo->data, pinfo->size); + + struct sockaddr_in destinationInfo; + destinationInfo.sin_family = AF_INET; + destinationInfo.sin_addr.s_addr = cd->addr; + destinationInfo.sin_port = htons(cd->port); + long int sentBytes = sendto( + us->ctx->socketHandle, + data, + 20 + pinfo->size, + 0, + (struct sockaddr*) &destinationInfo, + sizeof(struct sockaddr_in)); + if(sentBytes != 20 + pinfo->size) + { + UDPC_INTERNAL_log(us->ctx, 0, "Failed to send packet to %s port %d", + UDPC_INTERNAL_atostr(us->ctx, cd->addr), cd->port); + free(data); + free(pinfo->data); + UDPC_Deque_pop_front(cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); + return; + } + + if((pinfo->flags & 0x2) != 0) + { + UDPC_INTERNAL_PacketInfo sentInfo = { + cd->addr, + cd->lseq - 1, + 0x2, + data, + 20 + pinfo->size, + us->tsNow + }; + UDPC_Deque_push_back( + cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); + } + else + { + UDPC_INTERNAL_PacketInfo sentInfo = { + cd->addr, + cd->lseq - 1, + 0, + NULL, + 0, + us->tsNow + }; + UDPC_Deque_push_back( + cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); + free(data); + } + + while(cd->sentPkts->size / sizeof(UDPC_INTERNAL_PacketInfo) > UDPC_SENT_PKTS_MAX_SIZE) + { + UDPC_INTERNAL_PacketInfo *pinfoCached = UDPC_Deque_get_front_ptr( + cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); + if(pinfoCached->data && pinfoCached->size != 0) + { + free(pinfoCached->data); + } + UDPC_Deque_pop_front(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); + } + + free(pinfo->data); + UDPC_Deque_pop_front(cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); } } diff --git a/src/UDPConnection.h b/src/UDPConnection.h index 9a1c86c..0780b3c 100644 --- a/src/UDPConnection.h +++ b/src/UDPConnection.h @@ -8,6 +8,7 @@ #include "UDPC_Defines.h" #include "UDPC_Deque.h" +#include "UDPC_HashMap.h" #if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS #include @@ -89,18 +90,27 @@ typedef struct { mtx_t tCVMtx; mtx_t tflagsMtx; cnd_t threadCV; - UDPC_Deque *connected; + UDPC_HashMap *conMap; struct timespec lastUpdated; char atostrBuf[UDPC_ATOSTR_BUF_SIZE]; char recvBuf[UDPC_PACKET_MAX_SIZE]; } UDPC_Context; +typedef struct { + struct timespec tsNow; + float dt; + UDPC_Deque *removedQueue; + UDPC_Context *ctx; +} UDPC_INTERNAL_update_struct; + UDPC_Context* UDPC_init(uint16_t listenPort, int isClient); UDPC_Context* UDPC_init_threaded_update(uint16_t listenPort, int isClient); void UDPC_destroy(UDPC_Context *ctx); +void UDPC_INTERNAL_destroy_conMap(void *unused, char *data); + uint32_t UDPC_get_error(UDPC_Context *ctx); const char* UDPC_get_error_str(uint32_t error); @@ -119,6 +129,10 @@ void UDPC_set_logging_type(UDPC_Context *ctx, uint32_t logType); /// If threaded, this function is called automatically void UDPC_update(UDPC_Context *ctx); +void UDPC_INTERNAL_update_to_rtt_si(void *userData, char *data); + +void UDPC_INTERNAL_update_send(void *userData, char *data); + float UDPC_ts_diff_to_seconds(struct timespec *ts0, struct timespec *ts1); int UDPC_INTERNAL_threadfn(void *context); // internal usage only