-
Notifications
You must be signed in to change notification settings - Fork 132
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
Inconsistent behaviour of one-shot servers on macOS and Linux #378
Comments
I suspect the intention here is that a one-shot server can only be used to allow one client connection, but I need to check how Servo uses them right now. |
Thanks. It would be helpful to know the current Servo usage of one-shot servers, especially if there are platform-specific variations in that usage. Note that allowing only one client connection (the current behaviour on Unix variants) is race-prone. Essentially the first client to call connect() and have its connection request accepted wins (can send requests to the server) and clients subsequently calling connect() lose (their connections are never accepted and any requests they send are never received). When two or more connect() requests are issued concurrently (e.g. from distinct processes or threads), the race becomes more likely. |
Verified that Servo only uses one shot servers once, regardless of platform: https://github.com/servo/servo/blob/e74539404467cc31c03f52a419371258235a1d69/components/constellation/sandboxing.rs#L230 . We avoid races by only providing the token to a single process, so there are never multiple clients attempting to connect. |
Ok, that's good. Other users of ipc-channel, and perhaps Servo in the future, could run into the issue. So I suggest:
|
Introduce IpcConnector as a means of forcing at most one connect request to a one-shot server. For a smooth upgrade experience, deprecate new() and connect() in favour of new_with_connector() and its connect() method, respectively. new() will be deleted in a future release at which point new_with_connector() could be renamed new(). Note that new_with_connector() does not support all the usecases of new(), but should be sufficient for Servo. In particular, it does not support launching a process passing the name of a one-shot server to which the process may then connect. Ref: servo#378
I submitted draft PR #380 for review and comment. I couldn't see a reliable way to cause second and subsequent calls to connect() to fail for a given one-shot server, so this is an attempt to upgrade the programming model. The approach is to deprecate new() and connect() and then delete them in a later release. |
ipc::channel seems sufficient for Servo's needs. Ref: servo#378
While investigating the intended behaviour of one-shot servers, I found an inconsistency between macOS and Linux. I can't tell if the inconsistency is intentional (seems unlikely) or whether the behaviour should be consistent and match the behaviour on macOS or Linux or something else.
The inconsistency is as follows. If multiple client processes connect to a one-shot server and send requests to it, the server can receive all the requests on macOS, but can only receive the requests from one client on Linux.
I think what's happening on macOS is that each client process's connect request accesses the same unidirectional communication channel (described here) associated with the Mach port underlying the one-shot server and so the clients' requests all make their way to the channel resulting from the server's call to accept().
I think what's happening on Linux is that each client process's connect request would result in a distinct socket connection returned from the socket accept() underpinning one-shot server's accept(). However, because one-shot server's accept() can only be called once, only the first client connect request is processed and other connect requests wait indefinitely to be accepted.
To make this concrete, the following test passes on macOS, but fails on Linux:
I am raising this issue to clarify the intended behaviour and potentially to initiate a code change to make the behaviour consistent.
The text was updated successfully, but these errors were encountered: