DoxigAlpha

pollWindows

Function parameters

Parameters

#
self:*Self
nanoseconds:?u64

Type definitions in this namespace

Types

#
AnyReader
Deprecated in favor of `Reader`.
AnyWriter
Deprecated in favor of `Writer`.

Deprecated in favor of `Reader`.

Functions

#
GenericReader
Deprecated in favor of `Reader`.
GenericWriter
Deprecated in favor of `Writer`.
FixedBufferStream
Deprecated in favor of `Reader`.
fixedBufferStream
Deprecated in favor of `Reader`.
CountingReader
Deprecated with no replacement; inefficient pattern
countingReader
Deprecated with no replacement; inefficient pattern
PollFiles
Given an enum, returns a struct with fields of that enum, each field

Deprecated in favor of `Writer.Discarding`.

Values

#
null_writer
Deprecated in favor of `Writer.Discarding`.

Source

Implementation

#
fn pollWindows(self: *Self, nanoseconds: ?u64) !bool {
    const bump_amt = 512;
    const gpa = self.gpa;

    if (!self.windows.first_read_done) {
        var already_read_data = false;
        for (0..enum_fields.len) |i| {
            const handle = self.windows.active.handles_buf[i];
            switch (try windowsAsyncReadToFifoAndQueueSmallRead(
                gpa,
                handle,
                &self.windows.overlapped[i],
                &self.readers[i],
                &self.windows.small_bufs[i],
                bump_amt,
            )) {
                .populated, .empty => |state| {
                    if (state == .populated) already_read_data = true;
                    self.windows.active.handles_buf[self.windows.active.count] = handle;
                    self.windows.active.stream_map[self.windows.active.count] = @as(StreamEnum, @enumFromInt(i));
                    self.windows.active.count += 1;
                },
                .closed => {}, // don't add to the wait_objects list
                .closed_populated => {
                    // don't add to the wait_objects list, but we did already get data
                    already_read_data = true;
                },
            }
        }
        self.windows.first_read_done = true;
        if (already_read_data) return true;
    }

    while (true) {
        if (self.windows.active.count == 0) return false;

        const status = windows.kernel32.WaitForMultipleObjects(
            self.windows.active.count,
            &self.windows.active.handles_buf,
            0,
            if (nanoseconds) |ns|
                @min(std.math.cast(u32, ns / std.time.ns_per_ms) orelse (windows.INFINITE - 1), windows.INFINITE - 1)
            else
                windows.INFINITE,
        );
        if (status == windows.WAIT_FAILED)
            return windows.unexpectedError(windows.GetLastError());
        if (status == windows.WAIT_TIMEOUT)
            return true;

        if (status < windows.WAIT_OBJECT_0 or status > windows.WAIT_OBJECT_0 + enum_fields.len - 1)
            unreachable;

        const active_idx = status - windows.WAIT_OBJECT_0;

        const stream_idx = @intFromEnum(self.windows.active.stream_map[active_idx]);
        const handle = self.windows.active.handles_buf[active_idx];

        const overlapped = &self.windows.overlapped[stream_idx];
        const stream_reader = &self.readers[stream_idx];
        const small_buf = &self.windows.small_bufs[stream_idx];

        const num_bytes_read = switch (try windowsGetReadResult(handle, overlapped, false)) {
            .success => |n| n,
            .closed => {
                self.windows.active.removeAt(active_idx);
                continue;
            },
            .aborted => unreachable,
        };
        const buf = small_buf[0..num_bytes_read];
        const dest = try writableSliceGreedyAlloc(stream_reader, gpa, buf.len);
        @memcpy(dest[0..buf.len], buf);
        advanceBufferEnd(stream_reader, buf.len);

        switch (try windowsAsyncReadToFifoAndQueueSmallRead(
            gpa,
            handle,
            overlapped,
            stream_reader,
            small_buf,
            bump_amt,
        )) {
            .empty => {}, // irrelevant, we already got data from the small buffer
            .populated => {},
            .closed,
            .closed_populated, // identical, since we already got data from the small buffer
            => self.windows.active.removeAt(active_idx),
        }
        return true;
    }
}