mirror of
https://github.com/token2/snapd.git
synced 2026-03-13 11:15:47 -07:00
* mailmap: map new commits from zygmunt.krynicki@canonical.com to me@zygoon.pl Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * Initial commit Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com> Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * Correct references to old name Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * osutil/epoll: fixed epoll test import Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * osutil/epoll: make Close() set epoll fd to -1 Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: renamed `FromSys()` epoll event parameter name to `ev` Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: added unit tests, but `Register()` always fails, as does ioctl syscall to prepare fd to register Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: removed unused `modeSet` type from epoll_test.go Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: replaced `syscall` with vendored `x/sys/unix` Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: simplified `Readiness` type to match `EPOLL{IN,OUT}` flags Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: fix unit tests using socketpair Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: fixed typo in test Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: tie events list to instance with entry for each registered fd, and add unit tests Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: add `WaitTimeout(msec)` with configurable timeout Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: remove comment about using internal/poll instead of epoll Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: improve error message when epoll create syscall fails Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: use time.Duration instead of int in `WaitTimeout()` Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: make epoll package thread safe Replace the instance-specific event buffer with a mutex-guarded registered FD count, allowing an event buffer with a number of slots equal to the current number of registered FDs to be allocated in `Wait()`, and thus allowing events from all FDs to be handled by a single `Wait()` call. Previously, the instance-specific event buffer was shared by separate calls to `Wait()`, with the address of the start of the buffer passed into the EPOLL_WAIT syscall, so multiple concurrent calls to `Wait()` could cause race conditions where the contents of the buffer was overwritten by multiple threads at once. Now, since the event buffer is allocated within the `Wait()` function, this race condition is avoided. Whenever a new FD is registered, the registeredFdCount variable is incremented, and whenever an FD is deregistered, that variable is decremented, in both cases guarded by the mutex for the epoll instance. So what happens if there are n FDs registered, a call to `Wait()` begins, and then while waiting, another FD is registered with the epoll instance? Could this result in a buffer with too few entries for the now (n+1) registered FDs? No, because beyond race conditions where the kernel receives two write syscalls simultaneously and these end up in the same epoll response (extremely unlikely), the only way that multiple events are returned by the same call to `Wait()` is if there were previous write events which had been caught by epoll but hadn't yet been handled with an EPOLL_WAIT syscall. In this case, `Wait()` would immediately return all those previous events, before the new FD is able to be registered and written to. The way around this would be if `Wait()` began, allocated the buffer with size n, and then the thread were interrupted, and the new FD registered and written to before the EPOLL_WAIT syscall occurred. In this case, if all the initial n FDs had pending activity, then the `Wait()` call would return an event buffer of size n, presumably with the events for the original n FDs, and a subsequent call to `Wait()` would return the event on the newly-registered FD. No event is lost in any case. Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: simplified duration in `Wait()` Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: `s/waitMillisecondsThenWriteToFile/waitMillisecondsThenWriteToFd` Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: simplified timeout duration definitions in tests Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: gracefully handle `EINT` errors from `EPOLL_WAIT` syscall Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: clarified handling of EINTR from EPOLL_WAIT syscall Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: replaced mutex with atomic Int32 calls wrapped in helper functions Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: added handling for waiting with no registered FDs It may be the case that one wishes to wait for epoll events without first registering any file descriptors to which to listen. Perhaps those file descriptors will be registered later by another thread, and we want to capture any activity on them as soon as that occurs. In any case, we do not wish to deny the ability to call `Wait()` if there are no registered FDs. However, the `EpollWait` syscall requires a nonzero-length buffer to be passed in (technically a nonzero length value, along with a pointer to the buffer). Thus, in order to allow future registered FDs to be handled by an existing wait call which was initiated when no FDs were registered, it is necessary to ensure that a buffer of at least length 1 is passed into the `EpollWait` syscall. Unit tests were added to check for correct waiting behavior when no FDs are registered, when waiting is initiated before FD is registered, and when the final FD is deregistered after wait has been initiated. The `TestWaitThenRegister` function was rewritten to be more salient. In particular, it now tests behavior when no FDs are registered at the time `Wait()` is called, and then a new FD is registered and activity occurs on it. Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: added tests for {,de}registering bad file descriptors Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: improved the arbitrary nonexistent FD used by {,de}register tests Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: cleaned up increment/decrement order on error, and unneeded `runtime.KeepAlive()` Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: added early return if epoll_wait returned 0 events Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: clean up opened sockets, and ensure Assert not called before reading from channels Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: use proper checker methods when applicable Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: Add comment about minimum buffer size for epoll_wait Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: added unit test for EINTR handling Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: reduced test sleep and timeout durations to make unit tests faster Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: defined `defaultDuration` for use in timing-sensitive unit tests Signed-off-by: Oliver Calder <oliver.calder@canonical.com> * epoll: replaced `Errno` magic numbers with defined values Signed-off-by: Oliver Calder <oliver.calder@canonical.com> --------- Signed-off-by: Oliver Calder <oliver.calder@canonical.com> Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com> Co-authored-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
4 lines
262 B
Plaintext
4 lines
262 B
Plaintext
Sergio Cazzolato <sergiocazzolato@gmail.com> sergio-j-cazzolato <sergio.cazzolato@canonical.com>
|
|
John R. Lenton <jlenton@gmail.com> John Lenton <chipaca@users.noreply.github.com>
|
|
Zygmunt Krynicki <me@zygoon.pl> Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
|