You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
4.1 KiB
187 lines
4.1 KiB
// simple_uasync.c - Minimal uasync implementation for tests |
|
#include "u_async.h" |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <stdint.h> |
|
|
|
// Timer entry |
|
typedef struct timer_entry { |
|
void* id; |
|
uint32_t expiry_time; |
|
timeout_callback_t callback; |
|
void* user_arg; |
|
struct timer_entry* next; |
|
} timer_entry_t; |
|
|
|
// Socket entry (not used in ETCP tests) |
|
typedef struct socket_entry { |
|
void* id; |
|
int fd; |
|
socket_callback_t read_cbk; |
|
socket_callback_t write_cbk; |
|
socket_callback_t except_cbk; |
|
void* user_arg; |
|
struct socket_entry* next; |
|
} socket_entry_t; |
|
|
|
// Dummy uasync instance structure |
|
struct uasync_s { |
|
int dummy; |
|
}; |
|
static uasync_t g_ua = {0}; |
|
|
|
// Global state |
|
static timer_entry_t* timer_list = NULL; |
|
static socket_entry_t* socket_list = NULL; |
|
static uint32_t current_time = 0; |
|
static void* next_id = (void*)1; |
|
|
|
// Generate unique ID |
|
static void* generate_id(void) { |
|
void* id = next_id; |
|
next_id = (void*)((uintptr_t)next_id + 1); |
|
return id; |
|
} |
|
|
|
// Initialize - does nothing in mock |
|
void uasync_init(void) { |
|
current_time = 0; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Instance API |
|
uasync_t* uasync_create(void) { |
|
uasync_t* ua = malloc(sizeof(uasync_t)); |
|
if (ua) { |
|
ua->dummy = 0; |
|
} |
|
return ua; |
|
} |
|
|
|
void uasync_destroy(uasync_t* ua) { |
|
free(ua); |
|
} |
|
|
|
void uasync_init_instance(uasync_t* ua) { |
|
(void)ua; |
|
} |
|
|
|
void* uasync_set_timeout(uasync_t* ua, int timeout_tb, void* user_arg, timeout_callback_t callback) { |
|
(void)ua; |
|
timer_entry_t* timer = malloc(sizeof(timer_entry_t)); |
|
if (!timer) return NULL; |
|
|
|
timer->id = generate_id(); |
|
timer->expiry_time = current_time + (uint32_t)timeout_tb; |
|
timer->callback = callback; |
|
timer->user_arg = user_arg; |
|
timer->next = timer_list; |
|
timer_list = timer; |
|
|
|
return timer->id; |
|
} |
|
|
|
err_t uasync_cancel_timeout(uasync_t* ua, void* t_id) { |
|
(void)ua; |
|
timer_entry_t** pp = &timer_list; |
|
while (*pp) { |
|
if ((*pp)->id == t_id) { |
|
timer_entry_t* to_free = *pp; |
|
*pp = to_free->next; |
|
free(to_free); |
|
return ERR_OK; |
|
} |
|
pp = &(*pp)->next; |
|
} |
|
return ERR_FAIL; |
|
} |
|
|
|
void* uasync_add_socket(uasync_t* ua, int fd, socket_callback_t read_cbk, |
|
socket_callback_t write_cbk, |
|
socket_callback_t except_cbk, |
|
void* user_arg) { |
|
(void)ua; (void)fd; (void)read_cbk; (void)write_cbk; (void)except_cbk; (void)user_arg; |
|
return NULL; |
|
} |
|
|
|
err_t uasync_remove_socket(uasync_t* ua, void* s_id) { |
|
(void)ua; (void)s_id; |
|
return ERR_FAIL; |
|
} |
|
|
|
void uasync_poll(uasync_t* ua, int timeout_tb) { |
|
(void)ua; |
|
(void)timeout_tb; |
|
} |
|
|
|
void uasync_mainloop(uasync_t* ua) { |
|
(void)ua; |
|
// Should not be called in tests |
|
while (1) {} |
|
} |
|
|
|
uasync_t* uasync_get_global_instance(void) { |
|
return &g_ua; |
|
} |
|
|
|
// Test helper: advance time and process expired timers |
|
void simple_uasync_advance_time(uint32_t delta_tb) { |
|
current_time += delta_tb; |
|
|
|
// Process all expired timers |
|
while (1) { |
|
timer_entry_t* earliest = NULL; |
|
timer_entry_t** earliest_pp = NULL; |
|
uint32_t earliest_time = UINT32_MAX; |
|
|
|
// Find earliest expired timer |
|
timer_entry_t** pp = &timer_list; |
|
while (*pp) { |
|
if ((*pp)->expiry_time <= current_time && (*pp)->expiry_time < earliest_time) { |
|
earliest = *pp; |
|
earliest_pp = pp; |
|
earliest_time = (*pp)->expiry_time; |
|
} |
|
pp = &(*pp)->next; |
|
} |
|
|
|
if (!earliest) break; |
|
|
|
// Remove from list |
|
*earliest_pp = earliest->next; |
|
|
|
// Call callback |
|
timeout_callback_t cb = earliest->callback; |
|
void* arg = earliest->user_arg; |
|
free(earliest); |
|
|
|
if (cb) { |
|
cb(arg); |
|
} |
|
} |
|
} |
|
|
|
// Test helper: get current time |
|
uint32_t simple_uasync_get_time(void) { |
|
return current_time; |
|
} |
|
|
|
// Test helper: clear all timers |
|
void simple_uasync_clear(void) { |
|
while (timer_list) { |
|
timer_entry_t* next = timer_list->next; |
|
free(timer_list); |
|
timer_list = next; |
|
} |
|
} |