77 lines
1.9 KiB
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)
|
|
}
|