[TCPIP] Fix "mbox" queue synchronization

Use a KSEMAPHORE instead of a NotificationEvent to signal availability. This is to prevent satisfying the wait for multiple waiters, when only a single entry is on the list.
Fixes crashes on SMP builds.
This commit is contained in:
Timo Kreuzer
2025-07-18 13:53:58 +03:00
parent 069fc049db
commit b7066b9232
2 changed files with 5 additions and 7 deletions

View File

@@ -11,7 +11,7 @@ typedef struct _sys_mbox_t
{
KSPIN_LOCK Lock;
LIST_ENTRY ListHead;
KEVENT Event;
KSEMAPHORE Semaphore;
int Valid;
} sys_mbox_t;

View File

@@ -137,7 +137,7 @@ sys_mbox_new(sys_mbox_t *mbox, int size)
InitializeListHead(&mbox->ListHead);
KeInitializeEvent(&mbox->Event, NotificationEvent, FALSE);
KeInitializeSemaphore(&mbox->Semaphore, 0, MAXLONG);
mbox->Valid = 1;
@@ -176,7 +176,7 @@ sys_mbox_post(sys_mbox_t *mbox, void *msg)
&Container->ListEntry,
&mbox->Lock);
KeSetEvent(&mbox->Event, IO_NO_INCREMENT, FALSE);
KeReleaseSemaphore(&mbox->Semaphore, IO_NO_INCREMENT, 1, FALSE);
}
u32_t
@@ -189,7 +189,7 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
PLWIP_MESSAGE_CONTAINER Container;
PLIST_ENTRY Entry;
KIRQL OldIrql;
PVOID WaitObjects[] = {&mbox->Event, &TerminationEvent};
PVOID WaitObjects[] = {&mbox->Semaphore, &TerminationEvent};
LargeTimeout.QuadPart = Int32x32To64(timeout, -10000);
@@ -207,10 +207,8 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
if (Status == STATUS_WAIT_0)
{
KeAcquireSpinLock(&mbox->Lock, &OldIrql);
ASSERT(!IsListEmpty(&mbox->ListHead));
Entry = RemoveHeadList(&mbox->ListHead);
ASSERT(Entry);
if (IsListEmpty(&mbox->ListHead))
KeClearEvent(&mbox->Event);
KeReleaseSpinLock(&mbox->Lock, OldIrql);
Container = CONTAINING_RECORD(Entry, LWIP_MESSAGE_CONTAINER, ListEntry);