|
|
|
|
@ -1853,10 +1853,15 @@ void uasync_post(struct UASYNC* ua, uasync_post_callback_t callback, void* arg)
|
|
|
|
|
if (!ua || !callback) return; |
|
|
|
|
|
|
|
|
|
struct posted_task* task = u_malloc(sizeof(struct posted_task)); |
|
|
|
|
if (!task) return; |
|
|
|
|
if (!task) { DEBUG_ERROR(DEBUG_CATEGORY_SYS, "uasync_post: task allocation failed"); return; } |
|
|
|
|
|
|
|
|
|
task->callback = callback; |
|
|
|
|
task->arg = arg; |
|
|
|
|
uasync_post_reserved(ua, task); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Worker резервирует completion до запуска, поэтому завершение не требует памяти. */ |
|
|
|
|
void uasync_post_reserved(struct UASYNC* ua, struct posted_task* task) { |
|
|
|
|
task->next = NULL; |
|
|
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
@ -1883,6 +1888,31 @@ void uasync_post(struct UASYNC* ua, uasync_post_callback_t callback, void* arg)
|
|
|
|
|
uasync_wakeup(ua); // будим mainloop
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Владелец отменяет pending completion после join производителя вне callbacks. */ |
|
|
|
|
err_t uasync_cancel_post(struct UASYNC* ua, struct posted_task* task) { |
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
EnterCriticalSection(&ua->posted_lock); |
|
|
|
|
#else |
|
|
|
|
pthread_mutex_lock(&ua->posted_lock); |
|
|
|
|
#endif |
|
|
|
|
struct posted_task** p = &ua->posted_tasks_head; |
|
|
|
|
struct posted_task* previous = NULL; |
|
|
|
|
while (*p && *p != task) { previous = *p; p = &(*p)->next; } |
|
|
|
|
int found = *p != NULL; |
|
|
|
|
if (found) { |
|
|
|
|
*p = task->next; |
|
|
|
|
if (ua->posted_tasks_tail == task) ua->posted_tasks_tail = previous; |
|
|
|
|
} |
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
LeaveCriticalSection(&ua->posted_lock); |
|
|
|
|
#else |
|
|
|
|
pthread_mutex_unlock(&ua->posted_lock); |
|
|
|
|
#endif |
|
|
|
|
if (found) u_free(task); |
|
|
|
|
else DEBUG_ERROR(DEBUG_CATEGORY_SYS, "uasync_cancel_post: completion is not pending"); |
|
|
|
|
return found ? ERR_OK : ERR_FAIL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Wakeup mechanism
|
|
|
|
|
int uasync_wakeup(struct UASYNC* ua) { |
|
|
|
|
if (!ua || !ua->wakeup_initialized) return -1; |
|
|
|
|
|