
#if OS == win

header "sys" as sys

use mem

@shared WSA_OBJ : ?WSA
@shared WSA_mutex : Mutex[void] (Mutex[void].new())

class WSA {

    static fn init() void {
        let obj = WSA_OBJ
        if isset(obj) : return
        WSA_mutex.lock()
        obj = WSA_OBJ
        if isset(obj) : return

        let v : u16 = 0 
        let v_ptr = @ref(v)
        @ptrv(v_ptr, u8, 0) = 2
        @ptrv(v_ptr, u8, 1) = 2

        // let data = mem:alloc(size_of(<sys:WSADATA>)).@cast(sys:WSADATA)
        let data = mem:alloc(560)
        let err = sys:WSAStartup(v, data)
        if err != 0 {
    		println("WSA startup error: " + sys:WSAGetLastError())
            panic("Windows WSAStartup failed")
        }

        WSA_OBJ = WSA {}
        mem:free(data)

        WSA_mutex.unlock()
    }

    static fn error() i32 {
        return sys:WSAGetLastError()
    }

    fn gc_free() {
        sys:WSACleanup()
    }
}
#end
