Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions src/cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,7 @@
#include <stdint.h>
#include <stdio.h>

void swiftnet_cleanup() {
allocator_destroy(&packet_queue_node_memory_allocator);
allocator_destroy(&packet_callback_queue_node_memory_allocator);
allocator_destroy(&server_packet_data_memory_allocator);
allocator_destroy(&client_packet_data_memory_allocator);
allocator_destroy(&packet_buffer_memory_allocator);

#ifdef SWIFT_NET_REQUESTS
allocator_destroy(&requests_sent_memory_allocator);

vector_destroy(&requests_sent);
#endif

static inline void close_listeners() {
vector_lock(&listeners);

for (uint16_t i = 0; i < listeners.size; i++) {
Expand All @@ -32,7 +20,23 @@ void swiftnet_cleanup() {
}

vector_destroy(&listeners);
}

void swiftnet_cleanup() {
allocator_destroy(&packet_queue_node_memory_allocator);
allocator_destroy(&packet_callback_queue_node_memory_allocator);
allocator_destroy(&server_packet_data_memory_allocator);
allocator_destroy(&client_packet_data_memory_allocator);
allocator_destroy(&packet_buffer_memory_allocator);

#ifdef SWIFT_NET_REQUESTS
allocator_destroy(&requests_sent_memory_allocator);

vector_destroy(&requests_sent);
#endif

close_listeners();

allocator_destroy(&server_memory_allocator);
allocator_destroy(&client_connection_memory_allocator);

Expand Down
137 changes: 81 additions & 56 deletions src/cleanup_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,94 +4,119 @@
#include <stdint.h>
#include <unistd.h>

void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) {
allocator_destroy(&client->packets_sending_memory_allocator);
allocator_destroy(&client->pending_messages_memory_allocator);
allocator_destroy(&client->packets_completed_memory_allocator);

vector_destroy(&client->packets_sending);
vector_destroy(&client->pending_messages);
vector_destroy(&client->packets_completed);

const char* interface_name = client->loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface;
static inline void cleanup_connection_resources(const enum ConnectionType connection_type, void* const connection) {
if (connection_type == CONNECTION_TYPE_CLIENT) {
struct SwiftNetClientConnection* const client = (struct SwiftNetClientConnection*)connection;

allocator_destroy(&client->packets_sending_memory_allocator);
allocator_destroy(&client->pending_messages_memory_allocator);
allocator_destroy(&client->packets_completed_memory_allocator);

vector_destroy(&client->packets_sending);
vector_destroy(&client->pending_messages);
vector_destroy(&client->packets_completed);
} else {
struct SwiftNetServer* const server = (struct SwiftNetServer*)connection;

allocator_destroy(&server->packets_sending_memory_allocator);
allocator_destroy(&server->pending_messages_memory_allocator);
allocator_destroy(&server->packets_completed_memory_allocator);

vector_destroy(&server->packets_sending);
vector_destroy(&server->pending_messages);
vector_destroy(&server->packets_completed);
}
}

static inline void remove_listener(const enum ConnectionType connection_type, const char* interface_name, void* const connection) {
vector_lock(&listeners);

for (uint16_t i = 0; i < listeners.size; i++) {
struct Listener* const current_listener = vector_get(&listeners, i);
if (strcmp(interface_name, current_listener->interface_name) == 0) {
vector_lock(&current_listener->client_connections);
if (connection_type == CONNECTION_TYPE_CLIENT) {
vector_lock(&current_listener->client_connections);

for (uint16_t inx = 0; inx < current_listener->client_connections.size; inx++) {
struct SwiftNetClientConnection* const current_client_conn = vector_get(&current_listener->client_connections, i);
if (current_client_conn != client) {
continue;
for (uint16_t inx = 0; inx < current_listener->client_connections.size; inx++) {
struct SwiftNetClientConnection* const current_connection = vector_get(&current_listener->client_connections, i);
if (current_connection != connection) {
continue;
}

vector_remove(&current_listener->client_connections, inx);

break;
}

vector_remove(&current_listener->client_connections, inx);
vector_unlock(&current_listener->client_connections);
} else {
vector_lock(&current_listener->servers);

break;
}
for (uint16_t inx = 0; inx < current_listener->servers.size; inx++) {
struct SwiftNetClientConnection* const current_connection = vector_get(&current_listener->servers, i);
if (current_connection != connection) {
continue;
}

vector_remove(&current_listener->servers, inx);

vector_unlock(&current_listener->client_connections);
break;
}

vector_unlock(&current_listener->servers);
}

break;
}
}

vector_unlock(&listeners);
}

atomic_store_explicit(&client->closing, true, memory_order_release);

pthread_join(client->process_packets_thread, NULL);
pthread_join(client->execute_callback_thread, NULL);

pcap_close(client->pcap);

allocator_free(&client_connection_memory_allocator, client);
static inline const char* get_interface_name(const bool loopback) {
return loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface;
}

void swiftnet_server_cleanup(struct SwiftNetServer* const server) {
allocator_destroy(&server->packets_sending_memory_allocator);
allocator_destroy(&server->pending_messages_memory_allocator);
allocator_destroy(&server->packets_completed_memory_allocator);
static inline void close_threads(const enum ConnectionType connection_type, void* const connection) {
if (connection_type == CONNECTION_TYPE_CLIENT) {
struct SwiftNetClientConnection* const client = connection;

vector_destroy(&server->packets_sending);
vector_destroy(&server->pending_messages);
vector_destroy(&server->packets_completed);
atomic_store_explicit(&client->closing, true, memory_order_release);

const char* interface_name = server->loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface;
pthread_join(client->process_packets_thread, NULL);
pthread_join(client->execute_callback_thread, NULL);
} else {
struct SwiftNetServer* const server = connection;

vector_lock(&listeners);
atomic_store_explicit(&server->closing, true, memory_order_release);

for (uint16_t i = 0; i < listeners.size; i++) {
struct Listener* const current_listener = vector_get(&listeners, i);
if (strcmp(interface_name, current_listener->interface_name) == 0) {
vector_lock(&current_listener->servers);
pthread_join(server->process_packets_thread, NULL);
pthread_join(server->execute_callback_thread, NULL);
}
}

for (uint16_t inx = 0; inx < current_listener->servers.size; inx++) {
struct SwiftNetServer* const current_server = vector_get(&current_listener->servers, i);
if (current_server != server) {
continue;
}
void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) {
cleanup_connection_resources(CONNECTION_TYPE_CLIENT, client);

const char* interface_name = get_interface_name(client->loopback);

vector_remove(&current_listener->servers, inx);
remove_listener(CONNECTION_TYPE_CLIENT, interface_name, client);

break;
}
close_threads(CONNECTION_TYPE_CLIENT, client);

vector_unlock(&current_listener->servers);
pcap_close(client->pcap);

break;
}
}
allocator_free(&client_connection_memory_allocator, client);
}

vector_unlock(&listeners);
void swiftnet_server_cleanup(struct SwiftNetServer* const server) {
cleanup_connection_resources(CONNECTION_TYPE_SERVER, server);

const char* interface_name = get_interface_name(server->loopback);

atomic_store_explicit(&server->closing, true, memory_order_release);
remove_listener(CONNECTION_TYPE_SERVER, interface_name, server);

pthread_join(server->process_packets_thread, NULL);
pthread_join(server->execute_callback_thread, NULL);
close_threads(CONNECTION_TYPE_SERVER, server);

pcap_close(server->pcap);

Expand Down
30 changes: 19 additions & 11 deletions src/execute_packet_callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@
#include <unistd.h>
#include <pthread.h>

static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struct PacketCallbackQueue* const packet_queue) {
static inline void lock_packet_queue(struct PacketCallbackQueue* const packet_queue) {
uint32_t owner_none = PACKET_CALLBACK_QUEUE_OWNER_NONE;
while(!atomic_compare_exchange_strong_explicit(&packet_queue->owner, &owner_none, PACKET_CALLBACK_QUEUE_OWNER_EXECUTE_PACKET_CALLBACK, memory_order_acquire, memory_order_relaxed)) {
owner_none = PACKET_CALLBACK_QUEUE_OWNER_NONE;
}
}

static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struct PacketCallbackQueue* const packet_queue) {
lock_packet_queue(packet_queue);

if(packet_queue->first_node == NULL) {
atomic_store_explicit(&packet_queue->owner, PACKET_CALLBACK_QUEUE_OWNER_NONE, memory_order_release);
Expand All @@ -36,6 +40,19 @@ static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struc
return node_to_process;
}

static inline void remove_pending_message_from_vector(struct SwiftNetVector* const pending_messages, struct SwiftNetPendingMessage* const pending_message) {
vector_lock(pending_messages);

for (uint32_t i = 0; i < pending_messages->size; i++) {
const struct SwiftNetPendingMessage* const current_pending_message = vector_get(pending_messages, i);
if (current_pending_message == pending_message) {
vector_remove(pending_messages, i);
}
}

vector_unlock(pending_messages);
}

void execute_packet_callback(struct PacketCallbackQueue* const queue, void (* const _Atomic * const packet_handler) (void* const, void* const), const enum ConnectionType connection_type, struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, _Atomic bool* closing, void* const connection, struct SwiftNetVector* const pending_messages, _Atomic(void*)* user_data) {
while (1) {
if (atomic_load_explicit(closing, memory_order_acquire) == true) {
Expand All @@ -55,16 +72,7 @@ void execute_packet_callback(struct PacketCallbackQueue* const queue, void (* co
}

if(node->pending_message != NULL) {
vector_lock(pending_messages);

for (uint32_t i = 0; i < pending_messages->size; i++) {
const struct SwiftNetPendingMessage* const pending_message = vector_get(pending_messages, i);
if (pending_message == node->pending_message) {
vector_remove(pending_messages, i);
}
}

vector_unlock(pending_messages);
remove_pending_message_from_vector(pending_messages, node->pending_message);
}

void (*const packet_handler_loaded)(void* const, void* const) = atomic_load(packet_handler);
Expand Down
Loading