fjord/work_queue.odin

77 lines
1.9 KiB
Odin

#+private package
package fjord
import "base:runtime"
import "core:net"
import "core:sync"
WorkQueue :: struct {
items: [dynamic]net.TCP_Socket,
capacity: int,
mutex: sync.Mutex,
not_empty: sync.Cond,
shutdown: bool,
allocator: runtime.Allocator,
}
work_queue_init :: proc(
work_queue: ^WorkQueue,
capacity: int,
allocator := context.allocator,
) {
work_queue^ = {
items = make([dynamic]net.TCP_Socket, 0, capacity, allocator),
capacity = capacity,
shutdown = false,
allocator = allocator,
}
}
work_queue_destroy :: proc(work_queue: ^WorkQueue) {
sync.mutex_lock(&work_queue.mutex)
for socket in work_queue.items {
net.close(socket)
}
sync.mutex_unlock(&work_queue.mutex)
delete(work_queue.items)
}
work_queue_enqueue :: proc(work_queue: ^WorkQueue, socket: net.TCP_Socket) -> bool {
sync.mutex_lock(&work_queue.mutex)
defer sync.mutex_unlock(&work_queue.mutex)
if work_queue.shutdown do return false
if len(work_queue.items) >= work_queue.capacity {
return false
}
append(&work_queue.items, socket)
sync.cond_signal(&work_queue.not_empty)
return true
}
work_queue_dequeue :: proc(work_queue: ^WorkQueue) -> (socket: net.TCP_Socket, ok: bool) {
sync.mutex_lock(&work_queue.mutex)
defer sync.mutex_unlock(&work_queue.mutex)
for len(work_queue.items) == 0 && !work_queue.shutdown {
sync.cond_wait(&work_queue.not_empty, &work_queue.mutex)
}
if work_queue.shutdown && len(work_queue.items) == 0 {
return socket, false
}
socket = pop_front(&work_queue.items)
return socket, true
}
work_queue_shutdown :: proc(work_queue: ^WorkQueue) {
sync.mutex_lock(&work_queue.mutex)
defer sync.mutex_unlock(&work_queue.mutex)
work_queue.shutdown = true
sync.cond_broadcast(&work_queue.not_empty)
}