Skip to content

Conversation

@castholm
Copy link
Contributor

@castholm castholm commented Nov 5, 2025

Closes #25776

This fixes the HTTPS/TLS and package manager problems on Windows. Tested against the repro in the linked issue as well as by zig build --fetching https://github.com/castholm/zig-examples/tree/master/breakout with an empty global package cache. (Déjà vu, anyone?)

Cheekiness aside, there were two separate issues unrelated to each other that regressed the package manager on Windows: TLS certificate lifetimes not being validated correctly and io.async() closure contexts not being correctly aligned, which have now hopefully been fixed.

Semi-important change: This PR redefines Clock.real such that implementations should always return timestamps relative to the POSIX/Unix epoch 1970-01-01 00:00:00+00:00. Previously, implementations were allowed to use implementation-specific epochs, which means that there's no way for the user to translate returned timestamps to actual calendar dates without digging into implementation details of any particular Io implementation and is obviously a problem if Io is supposed to be the "bring-your-own-OS" interface. Redefining it in this manner fixes this.

There are other ways to solve this, such as adding new vtable functions for returning the implementation-specific epoch, but in terms of complexity this redefinition is by far the simplest solution and only amounts to a simple 96-bit integer addition's worth of overhead for OSes like Windows that use non-POSIX/Unix epochs.

This fixes `std.http.Client` TLS certificate validation on Windows.
…Unix epoch

`Clock.real` being defined to return timestamps relative to an
implementation-specific epochs means that there's currently no way for
the user to translate returned timestamps to actual calendar dates
without digging into implementation details of any particular `Io`
implementation. Redefining it to return timestamps relative to
1970-01-01 00:00:00+00:00 fixes this problem.

There are other ways to solve this, such as adding new vtable functions
for returning the implementation-specific epoch, but in terms of
complexity this redefinition is by far the simplest solution and only
amounts to a simple 96-bit integer addition's worth of overhead for
OSes like Windows that use non-POSIX/Unix epochs.
This fixes package fetching on Windows.

Previously, `Async/GroupClosure` allocations were only aligned for the
closure struct type, which resulted in panics when `context_alignment`
(or `result_alignment` for that matter) had a greater alignment.
@castholm
Copy link
Contributor Author

castholm commented Nov 5, 2025

@squeek502 Sorry, I saw your PR #25814 with the same Clock.real change right as I was finishing this one up. I probably should have specified which time scale my "I don't have the time to make a PR right this moment" comment was in relation to 😅

@squeek502
Copy link
Member

squeek502 commented Nov 5, 2025

No worries, I've closed #25814 in favor of this. On the off chance it's helpful context, I'll put the OP of that here as well:

This is only one way of addressing this. Considering this change away from a Unix timestamp was seemingly intentional (before #25592, time.nanoTimestamp did perform the conversion to a Unix timestamp on Windows), this may not be the intended fix.


Enforcing a standard epoch in the Io.Clock API allows usage to be simplified, as it allows users to not have to constantly deal with implementation-defined epochs.

For example, this change fixes #25776 because on Windows (which previously would return a value relative to a different epoch), the crypto.Certificate code would compare a Unix timestamp to the value returned by the .real clock. To fix this while keeping the implementation-defined epoch, every usage of Clock.real would have to be audited and deal with converting between epochs in a platform-specific way.

Note also that Windows is the only odd-one out in the current implementation:

///
/// The epoch is implementation-defined. For example NTFS/Windows uses
/// 1601-01-01.
/// Timestamps returned by this implementations of this clock are
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Timestamps returned by this implementations of this clock are
/// Timestamps returned by implementations of this clock are

Typo, but I don't want to restart CI just for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't fetch package on Windows

2 participants