Using SOCK_SEQPACKET
Instead of using PlashObjectCapabilityProtocol with SOCK_STREAM sockets, Plash could use SOCK_SEQPACKET sockets.
SOCK_STREAM Unix domain sockets are byte stream sockets. We have to go to some trouble to layer a message-based protocol on top of them. The underlying socket FDs cannot be used by multiple processes at a time, so we have to provide a way to duplicate a connection and export existing objects across it. The socket FDs cannot be used by multiple threads at a time, so PlashGlibc has to protect them with locks to be thread-safe. We have to go to some trouble to share the sockets between ld.so and libc.so.
SOCK_SEQPACKET sockets are message-based. They are Linux-specific, and were introduced into the kernel in early 2004. Unlike datagram sockets (SOCK_DGRAM), they are reliable (they don't lose messages) and ordering is preserved.
Why didn't I use SOCK_SEQPACKET originally? Firstly, Plash's protocol had a precursor in some hacking I did in 2001 when SOCK_SEQPACKET didn't exist. Secondly, SOCK_SEQPACKET may not have been available in the kernel I was using in late 2004 when I started developing Plash. See PlashHistory. I'm not sure if I was aware of the existence of SOCK_SEQPACKET at the time. I remember trying SOCK_DGRAM in 2001 and finding that it crashed the machine (!).
Using SOCK_SEQPACKET might help in fixing PlashIssues/CallsNotAsyncSignalSafe.
Calling conventions
There is one socket FD per object. Objects are created using socketpair().
Though the sockets are bidirectional, we only ever use one direction.
To send a message M to an object X and get a reply, we do the following:
Create a return continuation: send_fd, receive_fd = socketpair()
Send the message: sendmsg(X, M + send_fd)
Close the temporary FD: close(send_fd)
Wait for the reply: recvmsg(receive_fd) -> reply
Close the temporary FD: close(receive_fd)
This might be more expensive than PlashObjectCapabilityProtocol because we are creating, sending and closing extra socket FDs for every method call.
Large messages
SOCK_SEQPACKET sockets have a message size limit. To send large messages, we need a convention for splitting a large logical message into many smaller physical messages.
References
unix(7), Linux man page
