mirror-ac/driver/queue.c

79 lines
1.3 KiB
C
Raw Normal View History

2023-08-20 16:12:04 +02:00
#include "queue.h"
2023-08-20 17:04:53 +02:00
/*
* Basic thread-safe queue implementation that can be used to create queues for any data.
*/
2023-08-20 16:12:04 +02:00
PQUEUE_HEAD QueueCreate()
{
PQUEUE_HEAD head = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( PQUEUE_HEAD ), QUEUE_POOL_TAG );
if ( !head )
return NULL;
head->end = NULL;
head->start = NULL;
2023-08-20 17:04:53 +02:00
head->entries = 0;
2023-08-20 16:12:04 +02:00
2023-08-20 18:06:21 +02:00
KeInitializeSpinLock( &head->lock );
2023-08-20 16:12:04 +02:00
return head;
}
VOID QueuePush(
_In_ PQUEUE_HEAD Head,
_In_ PVOID Data
)
{
KIRQL irql = KeGetCurrentIrql();
2023-08-20 18:06:21 +02:00
KeAcquireSpinLock( &Head->lock, &irql );
2023-08-20 16:12:04 +02:00
PQUEUE_NODE temp = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( QUEUE_NODE ), QUEUE_POOL_TAG );
if ( !temp )
goto end;
2023-08-20 17:04:53 +02:00
Head->entries += 1;
2023-08-20 16:12:04 +02:00
temp->data = Data;
if ( Head->end != NULL )
Head->end->next = temp;
Head->end = temp;
if ( Head->start == NULL )
Head->start = temp;
end:
2023-08-20 18:06:21 +02:00
KeReleaseSpinLock( &Head->lock, irql );
2023-08-20 16:12:04 +02:00
}
PVOID QueuePop(
_In_ PQUEUE_HEAD Head
)
{
KIRQL irql = KeGetCurrentIrql();
2023-08-20 18:06:21 +02:00
KeAcquireSpinLock( &Head->lock, &irql );
2023-08-20 16:12:04 +02:00
PVOID data = NULL;
PQUEUE_NODE temp = Head->start;
if ( temp == NULL )
goto end;
2023-08-21 06:45:33 +02:00
Head->entries = Head->entries - 1;
2023-08-20 17:04:53 +02:00
2023-08-20 16:12:04 +02:00
data = temp->data;
Head->start = temp->next;
if ( Head->end == temp )
Head->end = NULL;
ExFreePoolWithTag( temp, QUEUE_POOL_TAG );
end:
2023-08-20 18:06:21 +02:00
KeReleaseSpinLock( &Head->lock, irql );
2023-08-20 16:12:04 +02:00
return data;
}