The SF_SYNC flag causes sendfile(2) to "sleep until the network stack no
longer references the VM pages of the file." This is implemented using
a struct sendfile_sync which is referenced by each mbuf cluster
containing file data, and sendfile(2) sleeps uninterruptibly until all
references are gone.
Suppose a single-threaded process uses sendfile(SF_SYNC) to transmit a
file over a unix socket pair that is private to the process (e.g.,
created with socketpair(2)). Then sendfile() will block until the data
is read from the receiving socket buffer, but this cannot happen unless
the socket is closed, so the process is unkillable.
Fix the problem by making the sendfile(2) wait interruptible. When the
wait is interrupted, sendfile's mbuf destructor callbacks are
responsible for freeing the structure. Make the implementation a bit
lighter by using a refcount (for sendfile_sync structure refs) and a
blockcount (to wait for mbuf references to decrement to zero), instead
of a mutex and condition variable.
Extend blockcount to support interruptible sleeps.