V version: V 0.5.2 bf6762e, Windows 11, default C backend (bundled tcc 0.9.27 from vlang/tccbin, branch thirdparty-windows-amd64).
What happened
The bundled tcc's lib/kernel32.def is missing the exports for two kernel32 APIs that high-performance IOCP servers need, so any V program calling them fails to link under the default Windows toolchain:
GetQueuedCompletionStatusEx— batch completion dequeue (one syscall returns N completions; the IOCP equivalent ofepoll_waitreturning many events). Available since Windows Vista.SetFileCompletionNotificationModes—FILE_SKIP_COMPLETION_PORT_ON_SUCCESS, the standard optimization that skips the completion-port round-trip when an overlapped op completes synchronously (used by libuv, mio, etc.). Available since Windows Vista.
The single-shot GetQueuedCompletionStatus, CreateIoCompletionPort, PostQueuedCompletionStatus and even CancelIoEx (also Vista+) are all already present in the .def, so this looks like an accidental gap rather than a deliberate XP-era cutoff.
Context: while implementing an IOCP backend for an HTTP server (vlang/vanilla-style, one completion port per worker), the single-dequeue path works fine with tcc, but the batch-dequeue upgrade cannot be linked — the only workarounds are GetProcAddress at runtime or switching to gcc/msvc.
Reproduction
module main
#include <winsock2.h>
#include <windows.h>
@[typedef]
pub struct C.OVERLAPPED {
pub mut:
Internal usize
InternalHigh usize
Offset u32
OffsetHigh u32
hEvent voidptr
}
// Declared as a plain V struct: tcc's bundled winapi headers do not define
// OVERLAPPED_ENTRY either (secondary gap; this part is easy to work around).
pub struct OverlappedEntry {
pub mut:
completion_key usize
overlapped &C.OVERLAPPED = unsafe { nil }
internal usize
bytes_transferred u32
}
fn C.CreateIoCompletionPort(file_handle voidptr, existing voidptr, key usize, n u32) voidptr
fn C.GetQueuedCompletionStatusEx(port voidptr, entries &OverlappedEntry, count u32, removed &u32, ms u32, alertable bool) bool
fn main() {
port := C.CreateIoCompletionPort(C.INVALID_HANDLE_VALUE, unsafe { nil }, 0, 1)
mut entries := [16]OverlappedEntry{}
mut removed := u32(0)
ok := C.GetQueuedCompletionStatusEx(port, &entries[0], 16, &removed, 0, false)
println('ok=${ok} removed=${removed}')
}$ v run gqcse.v
================== C compilation error (from thirdparty\tcc\tcc.exe): ==============
cc: tcc: error: undefined symbol 'GetQueuedCompletionStatusEx'Verification of the gap
$ grep -x "GetQueuedCompletionStatus" thirdparty/tcc/lib/kernel32.def
GetQueuedCompletionStatus
$ grep -x "GetQueuedCompletionStatusEx" thirdparty/tcc/lib/kernel32.def
(no match)
$ grep -x "SetFileCompletionNotificationModes" thirdparty/tcc/lib/kernel32.def
(no match)Same on the current vlang/tccbin thirdparty-windows-amd64 branch:
https://github.com/vlang/tccbin/blob/thirdparty-windows-amd64/lib/kernel32.def
Expected / proposed fix
Add two lines to lib/kernel32.def in the vlang/tccbin thirdparty-windows-* branches (tcc .def files are plain export-name lists, so this needs no rebuild of tcc itself):
GetQueuedCompletionStatusEx
SetFileCompletionNotificationModesOptionally also add the OVERLAPPED_ENTRY struct + GetQueuedCompletionStatusEx / SetFileCompletionNotificationModes prototypes to the bundled winapi headers, but the .def entries are the hard blocker — the prototypes can be declared from V.
NOTE
You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.
Activity
0No activity yet.