X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Feal%2Fwindows%2Feal_interrupts.c;h=bb0585cb345f22fb2cc21a72b5f89e3b18a55b29;hb=4042dc2037a1509596f7eb48370185434bad39cc;hp=9cde02b00329002f1a2d06764cf2b220dc96099a;hpb=35dff5d3b7fb0d8e559e0d82d329333f365e7273;p=dpdk.git diff --git a/lib/eal/windows/eal_interrupts.c b/lib/eal/windows/eal_interrupts.c index 9cde02b003..bb0585cb34 100644 --- a/lib/eal/windows/eal_interrupts.c +++ b/lib/eal/windows/eal_interrupts.c @@ -7,9 +7,12 @@ #include "eal_private.h" #include "eal_windows.h" +#define IOCP_KEY_SHUTDOWN UINT32_MAX + static pthread_t intr_thread; static HANDLE intr_iocp; +static HANDLE intr_thread_handle; static void eal_intr_process(const OVERLAPPED_ENTRY *event) @@ -17,10 +20,30 @@ eal_intr_process(const OVERLAPPED_ENTRY *event) RTE_SET_USED(event); } +static int +eal_intr_thread_handle_init(void) +{ + DWORD thread_id = GetCurrentThreadId(); + + intr_thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); + if (intr_thread_handle == NULL) { + RTE_LOG_WIN32_ERR("OpenThread(%lu)", thread_id); + return -1; + } + return 0; +} + static void * eal_intr_thread_main(LPVOID arg __rte_unused) { - while (1) { + bool finished = false; + + if (eal_intr_thread_handle_init() < 0) { + RTE_LOG(ERR, EAL, "Cannot open interrupt thread handle\n"); + goto cleanup; + } + + while (!finished) { OVERLAPPED_ENTRY events[16]; ULONG event_count, i; BOOL result; @@ -42,10 +65,19 @@ eal_intr_thread_main(LPVOID arg __rte_unused) continue; } - for (i = 0; i < event_count; i++) + for (i = 0; i < event_count; i++) { + if (events[i].lpCompletionKey == IOCP_KEY_SHUTDOWN) { + finished = true; + break; + } eal_intr_process(&events[i]); + } } + CloseHandle(intr_thread_handle); + intr_thread_handle = NULL; + +cleanup: intr_thread = 0; CloseHandle(intr_iocp); @@ -93,15 +125,8 @@ rte_intr_rx_ctl(__rte_unused struct rte_intr_handle *intr_handle, int eal_intr_thread_schedule(void (*func)(void *arg), void *arg) { - HANDLE handle; - - handle = OpenThread(THREAD_ALL_ACCESS, FALSE, intr_thread); - if (handle == NULL) { - RTE_LOG_WIN32_ERR("OpenThread(%llu)", intr_thread); - return -ENOENT; - } - - if (!QueueUserAPC((PAPCFUNC)(ULONG_PTR)func, handle, (ULONG_PTR)arg)) { + if (!QueueUserAPC((PAPCFUNC)(ULONG_PTR)func, + intr_thread_handle, (ULONG_PTR)arg)) { RTE_LOG_WIN32_ERR("QueueUserAPC()"); return -EINVAL; } @@ -109,6 +134,19 @@ eal_intr_thread_schedule(void (*func)(void *arg), void *arg) return 0; } +void +eal_intr_thread_cancel(void) +{ + if (!PostQueuedCompletionStatus( + intr_iocp, 0, IOCP_KEY_SHUTDOWN, NULL)) { + RTE_LOG_WIN32_ERR("PostQueuedCompletionStatus()"); + RTE_LOG(ERR, EAL, "Cannot cancel interrupt thread\n"); + return; + } + + WaitForSingleObject(intr_thread_handle, INFINITE); +} + int rte_intr_callback_register( __rte_unused const struct rte_intr_handle *intr_handle,