This is to better allow configuration on various, unknown compilers.
Previously, we hardcoded how thread local storage was specified for a
few different compilers, but we were not following and C standard. In
C11, there is a standardized storage specifier _Thread_local for this
storage class, however this is now deprecated in various C++ compilers
for a new keyword, confusingly. Janet also does not claim to require the
C11 standard, so for maximum flexibilty, the storage specifier must be
specified at configure time.
This was partially implemented before, but not in the case where the
await or other signal itself was created by a C function. We have to
separate code paths for generating signals - one via normal returns in
janet_vm_continue, and the other via longjump. This adds handling for
the longjump case, as well as improved messaging.
net/* API documentation was not consistent with the implementation. The
`ev/*` module documentation was, however. On timeout, all networking
function calls raise an error and do not return nil. That was the old
behavior.
These rules allow selecting from a number of sub-captures
while dropping the rest. `nth` is more succinct in many cases, but `only-tags` is
more general and corresponds to an internal mechanism already present.
Weak containers did not preserve their weakness when marshalled. This
fixes that for tables and arrays, as well as adds some tests for this.
Also exposes functions for creating weak tables in janet.h
Number literals can now take an optional "representation" suffix
- Use `:n` for normal numbers (IEEE-754 doubles)
- Use `:s` for signed 64 bit integers
- Use `:u` for unsigned 64 bit integers
- Other suffix will fallthrough the usual parseing logic. This means
that they will only possibly resolve to symbols if they start with -,
+, or .
The syntax does not collide with any existing valid Janet and is only
enabled with JANET_INTTYPES. This also leaves open a syntax for other
number types such as bignums, ratios, decimals, etc.
In the edge-trigger mode before this change, if a socket
receives 2 connections before one can be handled, then only a single
connection is handle and 1 connection will never be handled in some
cases. Reverting to level-trigger mode makes this impossible.
Big issue with IOCP vs. poll variants is that the overlapped
structures have a longer lifetime than intermediate state needed
for epoll. One cannot free overlapped structures after closing a
handle/socket, like one can do with any intermediate state when using
readiness-based IO.
This results in fewer system calls and presumably more effcient code. It
also brings the epoll (and kqueue) code more in line with how the
windows IOCP code works, incidentally.
Make more use of the built in GC code for abstracts to
be sure things are more correct. Issue before was streams could
be freed before IOCP events arrived.