-
Notifications
You must be signed in to change notification settings - Fork 5
Blocking Calls for Signals #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Is this on the critical path for what we're aiming at now? Is this a "nice to have" that we will need for compatibility later? |
Yes, I believe this is a required feature for getting postgres fully running, at least pgbench is trying to do signal interrupt on select syscall |
Yeah this is required to get postgres running in any stable way. Though the fixes for select/poll are most likely both the easiest to fix and the most common case. |
Did some quick research on this and wanted to provide some answers to help this along. As far as syscalls we implement I think this is the list of calls that need to be interrupted by signals:
Checking in code: Timeouts: Sleeps Read/write |
Note, that we did effectively the same thing in Repy for sockets / files
(nonblocking)
…On Wed, Feb 26, 2025 at 2:49 PM Nicholas Renner ***@***.***> wrote:
Did some quick research on this and wanted to provide some answers to help
this along. As far as syscalls we implement I think this is the list of
calls that need to be interrupted by signals:
- wait()/waitpid()
- sleep()/nanosleep() etc
- futex()
- read()/write()
- accept()/connect()
- send()/recv()
- poll()/select()/epoll_wait()
*Checking in code:*
For the wait() family as well as select/polling we never actually block in
the kernel, so we can just insert a check in RustPOSIX if a signal is set
and return with EINTR. This should be relatively easy.
*Timeouts:*
Both sockets (accept, connect, send, recv, read/write on sockets) and
futexes implement options for a timeout. I think the easiest way to deal
with these (and how we did it in rustposix) is to add a relatively short
timeout (100 ms? we'll need to investigate whats optimal here) on all
sockets/futexes we create and call the underlying syscall in a loop with a
check in between calls until it returns something relevant.
*Sleeps*
We'll probably have to do something inventive here to make this return
early.
*Read/write*
Since reads and writes can go to a number of subsystems, particularly
pipes and sockets this is a bit tricky we'll need to discuss a more complex
game plan here but is most likely a mix of timeouts and playing around with
O_NONBLOCK.
—
Reply to this email directly, view it on GitHub
<#118 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGROD4TWGO5HY3SRFILP6T2RYLF5AVCNFSM6AAAAABXY5IV6WVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBWGA2DCMBSGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
[image: rennergade]*rennergade* left a comment
(Lind-Project/lind-wasm#118)
<#118 (comment)>
Did some quick research on this and wanted to provide some answers to help
this along. As far as syscalls we implement I think this is the list of
calls that need to be interrupted by signals:
- wait()/waitpid()
- sleep()/nanosleep() etc
- futex()
- read()/write()
- accept()/connect()
- send()/recv()
- poll()/select()/epoll_wait()
*Checking in code:*
For the wait() family as well as select/polling we never actually block in
the kernel, so we can just insert a check in RustPOSIX if a signal is set
and return with EINTR. This should be relatively easy.
*Timeouts:*
Both sockets (accept, connect, send, recv, read/write on sockets) and
futexes implement options for a timeout. I think the easiest way to deal
with these (and how we did it in rustposix) is to add a relatively short
timeout (100 ms? we'll need to investigate whats optimal here) on all
sockets/futexes we create and call the underlying syscall in a loop with a
check in between calls until it returns something relevant.
*Sleeps*
We'll probably have to do something inventive here to make this return
early.
*Read/write*
Since reads and writes can go to a number of subsystems, particularly
pipes and sockets this is a bit tricky we'll need to discuss a more complex
game plan here but is most likely a mix of timeouts and playing around with
O_NONBLOCK.
—
Reply to this email directly, view it on GitHub
<#118 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGROD4TWGO5HY3SRFILP6T2RYLF5AVCNFSM6AAAAABXY5IV6WVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBWGA2DCMBSGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
This SO answer about creating an interruptible sleep using a mpsc channel could possibly be our best bet for sleeps. Using kernel sleeps is probably much harder to handle correctly. |
Let's also check to see how slow this is (does this delay short sleeps)? I think we should only need this for longer sleep periods. A lot of this can be pushed until later, unless it is causing an immediate problem. |
Had some additional thoughts when talking with Chinmay about futexes. Above I mention that futexes have timeouts and we could use them to check for signal interrupts, but I'm thinking this through and that probably would cause unintended behavior. I believe it makes the most sense to store futex addresses when futex() is called with FUTEX_WAIT in some sort of list in the cage struct, and when a cage receives a signal to wake those addresses. |
We'll need to deal with anytime a signal is received by a cage but that cage is in a blocking call. There's various ways we can do this including syscall timeouts.
Some calls I know should block are: read, recv, connect/accept, select/poll, futex...
Let's start out by getting a full list of blocking system calls we currently implement. @ChinmayShringi can you help us generate this.
The text was updated successfully, but these errors were encountered: