diff options
author | Etienne Perot <eperot@google.com> | 2020-12-03 06:18:03 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-12-03 06:20:29 -0800 |
commit | 6f60a2b0a27a742690aa6acd5df1912ccb5fc8d3 (patch) | |
tree | b706a5e534592d9aaa7fb4dc6237b4ab3686af13 /pkg/waiter/waiter.go | |
parent | 80552b936d06e43ea77df09a6b6c5ce2600a6f6a (diff) |
Implement `fcntl` options `F_GETSIG` and `F_SETSIG`.
These options allow overriding the signal that gets sent to the process when
I/O operations are available on the file descriptor, rather than the default
`SIGIO` signal. Doing so also populates `siginfo` to contain extra information
about which file descriptor caused the event (`si_fd`) and what events happened
on it (`si_band`). The logic around which FD is populated within `si_fd`
matches Linux's, which means it has some weird edge cases where that value may
not actually refer to a file descriptor that is still valid.
This CL also ports extra S/R logic regarding async handler in VFS2.
Without this, async I/O handlers aren't properly re-registered after S/R.
PiperOrigin-RevId: 345436598
Diffstat (limited to 'pkg/waiter/waiter.go')
-rw-r--r-- | pkg/waiter/waiter.go | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index 08519d986..83d4f893a 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -119,7 +119,10 @@ type EntryCallback interface { // The callback is supposed to perform minimal work, and cannot call // any method on the queue itself because it will be locked while the // callback is running. - Callback(e *Entry) + // + // The mask indicates the events that occurred and that the entry is + // interested in. + Callback(e *Entry, mask EventMask) } // Entry represents a waiter that can be add to the a wait queue. It can @@ -140,7 +143,7 @@ type channelCallback struct { } // Callback implements EntryCallback.Callback. -func (c *channelCallback) Callback(*Entry) { +func (c *channelCallback) Callback(*Entry, EventMask) { select { case c.ch <- struct{}{}: default: @@ -193,8 +196,8 @@ func (q *Queue) EventUnregister(e *Entry) { func (q *Queue) Notify(mask EventMask) { q.mu.RLock() for e := q.list.Front(); e != nil; e = e.Next() { - if mask&e.mask != 0 { - e.Callback.Callback(e) + if m := mask & e.mask; m != 0 { + e.Callback.Callback(e, m) } } q.mu.RUnlock() |