You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2020/04/24 22:09:47 UTC

[mesos] 02/06: Added support for read readiness polling on Windows.

This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit fc5014c34f54ab6372781493d2d19aa6dc905535
Author: Benjamin Mahler <bm...@apache.org>
AuthorDate: Tue Apr 21 13:37:51 2020 -0400

    Added support for read readiness polling on Windows.
    
    This uses the zero byte read trick on Windows in order to
    implement read readiness polling on Windows.
    
    The documentation for io::read has also been updated to explain
    how zero byte reads are treated consistently across POSIX and
    Windows.
    
    Write readiness polling is left unimplemented since it's less
    straightforward. A good explanation of the Windows landscape
    for polling is here:
    
    https://github.com/python-trio/trio/issues/52
    
    A library providing an epoll like interface on Windows can
    be found here:
    
    https://github.com/piscisaureus/wepoll
    
    Review: https://reviews.apache.org/r/72405/
---
 3rdparty/libprocess/include/process/io.hpp | 15 +++++++++++----
 3rdparty/libprocess/src/io.cpp             |  4 ++++
 3rdparty/libprocess/src/io_internal.hpp    |  8 ++++++++
 3rdparty/libprocess/src/windows/io.cpp     | 19 +++++++++++++++++--
 4 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/3rdparty/libprocess/include/process/io.hpp b/3rdparty/libprocess/include/process/io.hpp
index 468b362..00519d4 100644
--- a/3rdparty/libprocess/include/process/io.hpp
+++ b/3rdparty/libprocess/include/process/io.hpp
@@ -26,7 +26,6 @@
 namespace process {
 namespace io {
 
-#ifndef ENABLE_LIBWINIO
 /**
  * A possible event while polling.
  *
@@ -34,6 +33,7 @@ namespace io {
  */
 const short READ = 0x01;
 
+#ifndef ENABLE_LIBWINIO
 /**
  * @copydoc process::io::READ
  */
@@ -72,17 +72,18 @@ Try<Nothing> prepare_async(int_fd fd);
 Try<bool> is_async(int_fd fd);
 
 
-#ifndef ENABLE_LIBWINIO
 /**
  * Returns the events (a subset of the events specified) that can be
  * performed on the specified file descriptor without blocking.
  *
+ * Note that on windows, only io::READ is available (under the
+ * covers this is achieved via a zero byte read).
+ *
  * @see process::io::READ
  * @see process::io::WRITE
  */
 // TODO(benh): Add a version which takes multiple file descriptors.
 Future<short> poll(int_fd fd, short events);
-#endif // ENABLE_LIBWINIO
 
 
 /**
@@ -93,7 +94,13 @@ Future<short> poll(int_fd fd, short events);
  * The future will become ready when some data is read (may be less than
  * the specified size).
  *
- * @return The number of bytes read or zero on EOF.
+ * To provide a consistent interface, a zero byte will immediately
+ * return a ready future with 0 bytes. For users looking to use
+ * the zero byte read trick on windows to achieve read readiness
+ * polling, just use io::poll with io::READ.
+ *
+ * @return The number of bytes read or zero on EOF (or if zero
+ *     bytes were requested).
  *     A failure will be returned if an error is detected.
  */
 Future<size_t> read(int_fd fd, void* data, size_t size);
diff --git a/3rdparty/libprocess/src/io.cpp b/3rdparty/libprocess/src/io.cpp
index 7288d5f..5cb275d 100644
--- a/3rdparty/libprocess/src/io.cpp
+++ b/3rdparty/libprocess/src/io.cpp
@@ -65,7 +65,11 @@ Future<size_t> read(int_fd fd, void* data, size_t size)
     return Failure("Expected an asynchronous file descriptor.");
   }
 
+#ifndef ENABLE_LIBWINIO
   return internal::read(fd, data, size);
+#else
+  return internal::read(fd, data, size, true);
+#endif // ENABLE_LIBWINIO
 }
 
 
diff --git a/3rdparty/libprocess/src/io_internal.hpp b/3rdparty/libprocess/src/io_internal.hpp
index 09bfa9a..6ad134a 100644
--- a/3rdparty/libprocess/src/io_internal.hpp
+++ b/3rdparty/libprocess/src/io_internal.hpp
@@ -21,7 +21,15 @@ namespace process {
 namespace io {
 namespace internal {
 
+#ifndef ENABLE_LIBWINIO
 Future<size_t> read(int_fd fd, void* data, size_t size);
+#else
+Future<size_t> read(
+    int_fd fd,
+    void* data,
+    size_t size,
+    bool bypassZeroByteRead);
+#endif // ENABLE_LIBWINIO
 
 Future<size_t> write(int_fd fd, const void* data, size_t size);
 
diff --git a/3rdparty/libprocess/src/windows/io.cpp b/3rdparty/libprocess/src/windows/io.cpp
index 90e780d..cca6f70 100644
--- a/3rdparty/libprocess/src/windows/io.cpp
+++ b/3rdparty/libprocess/src/windows/io.cpp
@@ -13,6 +13,7 @@
 #include <string>
 
 #include <process/future.hpp>
+#include <process/io.hpp>
 #include <process/process.hpp> // For process::initialize.
 
 #include <stout/error.hpp>
@@ -29,15 +30,29 @@
 
 namespace process {
 namespace io {
+
+
+Future<short> poll(int_fd fd, short events)
+{
+  if (events != io::READ) {
+    return Failure("Expected io::READ (" + stringify(io::READ) + ")"
+                   " but received " + stringify(events));
+  }
+
+  return io::internal::read(fd, nullptr, 0, false)
+    .then([]() { return io::READ; });
+}
+
+
 namespace internal {
 
-Future<size_t> read(int_fd fd, void* data, size_t size)
+Future<size_t> read(int_fd fd, void* data, size_t size, bool bypassZeroRead)
 {
   process::initialize();
 
   // TODO(benh): Let the system calls do what ever they're supposed to
   // rather than return 0 here?
-  if (size == 0) {
+  if (size == 0 && bypassZeroRead) {
     return 0;
   }