Replace the class-based snooze alarm mechanism with a per-thread callback.
This makes it easy to block the current thread on an arbitrary condition:
void SomeDevice::wait_for_irq() {
m_interrupted = false;
current->block_until([this] { return m_interrupted; });
}
void SomeDevice::handle_irq() {
m_interrupted = true;
}
Use this in the SB16 driver, and in NetworkTask :^)
It was way too ambiguous who's the source and who's the destination, and it
didn't really follow a logical pattern. "Local port" vs "Peer port" is super
obvious, so let's call it that.
If connect() is called on a non-blocking socket, it will "fail" immediately
with -EINPROGRESS. After that, you select() on the socket and wait for it to
become writable.
This is useful for static locals that never need to be destroyed:
Thing& Thing::the()
{
static Eternal<Thing> the;
return the;
}
The object will be allocated in data segment memory and will never have
its destructor invoked.