summaryrefslogtreecommitdiffhomepage
path: root/test/util
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-12-27 14:58:41 -0800
committerShentubot <shentubot@google.com>2018-12-27 14:59:50 -0800
commit46e6577014c849d7306c63905db25f3c695fa7e7 (patch)
treef0beec40f3bbda38bf209809b091cf537b66cba8 /test/util
parentbce2f9751f415da869d04ccb53833b024373666d (diff)
Fix deadlock between epoll_wait and getdents
epoll_wait acquires EventPoll.listsMu (in EventPoll.ReadEvents) and then calls Inotify.Readiness which tries to acquire Inotify.evMu. getdents acquires Inotify.evMu (in Inotify.queueEvent) and then calls readyCallback.Callback which tries to acquire EventPoll.listsMu. The fix is to release Inotify.evMu before calling Queue.Notify. Queue is thread-safe and doesn't require Inotify.evMu to be held. Closes #121 PiperOrigin-RevId: 227066695 Change-Id: Id29364bb940d1727f33a5dff9a3c52f390c15761
Diffstat (limited to 'test/util')
-rw-r--r--test/util/BUILD13
-rw-r--r--test/util/epoll_util.cc52
-rw-r--r--test/util/epoll_util.h36
3 files changed, 101 insertions, 0 deletions
diff --git a/test/util/BUILD b/test/util/BUILD
index f981a8d1d..10507eae4 100644
--- a/test/util/BUILD
+++ b/test/util/BUILD
@@ -259,3 +259,16 @@ cc_library(
srcs = ["test_main.cc"],
deps = [":test_util"],
)
+
+cc_library(
+ name = "epoll_util",
+ testonly = 1,
+ srcs = ["epoll_util.cc"],
+ hdrs = ["epoll_util.h"],
+ deps = [
+ ":file_descriptor",
+ ":posix_error",
+ ":save_util",
+ "@com_google_googletest//:gtest",
+ ],
+)
diff --git a/test/util/epoll_util.cc b/test/util/epoll_util.cc
new file mode 100644
index 000000000..0b95aa8cd
--- /dev/null
+++ b/test/util/epoll_util.cc
@@ -0,0 +1,52 @@
+// Copyright 2018 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "test/util/epoll_util.h"
+
+#include <sys/epoll.h>
+
+#include "gmock/gmock.h"
+#include "test/util/file_descriptor.h"
+#include "test/util/posix_error.h"
+#include "test/util/save_util.h"
+
+namespace gvisor {
+namespace testing {
+
+PosixErrorOr<FileDescriptor> NewEpollFD(int size) {
+ // "Since Linux 2.6.8, the size argument is ignored, but must be greater than
+ // zero." - epoll_create(2)
+ int fd = epoll_create(size);
+ MaybeSave();
+ if (fd < 0) {
+ return PosixError(errno, "epoll_create");
+ }
+ return FileDescriptor(fd);
+}
+
+PosixError RegisterEpollFD(int epoll_fd, int target_fd, int events,
+ uint64_t data) {
+ struct epoll_event event;
+ event.events = events;
+ event.data.u64 = data;
+ int rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, target_fd, &event);
+ MaybeSave();
+ if (rc < 0) {
+ return PosixError(errno, "epoll_ctl");
+ }
+ return NoError();
+}
+
+} // namespace testing
+} // namespace gvisor
diff --git a/test/util/epoll_util.h b/test/util/epoll_util.h
new file mode 100644
index 000000000..521e7a3d3
--- /dev/null
+++ b/test/util/epoll_util.h
@@ -0,0 +1,36 @@
+// Copyright 2018 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GVISOR_TEST_UTIL_EPOLL_UTIL_H_
+#define GVISOR_TEST_UTIL_EPOLL_UTIL_H_
+
+#include "test/util/file_descriptor.h"
+#include "test/util/posix_error.h"
+
+namespace gvisor {
+namespace testing {
+
+// Returns a new epoll file descriptor.
+PosixErrorOr<FileDescriptor> NewEpollFD(int size = 1);
+
+// Registers `target_fd` with the epoll instance represented by `epoll_fd` for
+// the epoll events `events`. Events on `target_fd` will be indicated by setting
+// data.u64 to `data` in the returned epoll_event.
+PosixError RegisterEpollFD(int epoll_fd, int target_fd, int events,
+ uint64_t data);
+
+} // namespace testing
+} // namespace gvisor
+
+#endif // GVISOR_TEST_UTIL_EPOLL_UTIL_H_