Windows: Made `protobuf::write()` use CRT file descriptor explicitly. This is another edge case where a third-party library (protobuf) requires a CRT integer file descriptor. Thus we duplicate the `int_fd` and then explicitly allocate via `crt()`, which requires that we also manually close it via `_close()`.
Review: https://reviews.apache.org/r/66439 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c516741a Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c516741a Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c516741a Branch: refs/heads/master Commit: c516741a1348eee2d6b7e257fc2127f7d47c2a69 Parents: 9326f8f Author: Andrew Schwartzmeyer <[email protected]> Authored: Tue Mar 20 22:26:27 2018 -0700 Committer: Andrew Schwartzmeyer <[email protected]> Committed: Tue May 1 18:36:04 2018 -0700 ---------------------------------------------------------------------- 3rdparty/stout/include/stout/protobuf.hpp | 27 ++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/c516741a/3rdparty/stout/include/stout/protobuf.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/include/stout/protobuf.hpp b/3rdparty/stout/include/stout/protobuf.hpp index 2fa5072..1d03e1e 100644 --- a/3rdparty/stout/include/stout/protobuf.hpp +++ b/3rdparty/stout/include/stout/protobuf.hpp @@ -52,6 +52,10 @@ #include <stout/os/read.hpp> #include <stout/os/write.hpp> +#ifdef __WINDOWS__ +#include <stout/os/dup.hpp> +#endif // __WINDOWS__ + namespace protobuf { // TODO(bmahler): Re-use stout's 'recordio' facilities here. Note @@ -80,12 +84,31 @@ inline Try<Nothing> write(int_fd fd, const google::protobuf::Message& message) } #ifdef __WINDOWS__ - if (!message.SerializeToFileDescriptor(fd.crt())) { + // NOTE: On Windows, we need to explicitly allocate a CRT file + // descriptor because the Protobuf library requires it. Because + // users of `protobuf::write` are likely to call `os::close` on the + // `fd` we were given, we need to duplicate it before allocating the + // CRT fd. This is because once the CRT fd is allocated, it must be + // closed with `_close` instead of `os::close`. Since we need to + // call `_close` here, we duplicate the fd to prevent the users call + // of `os::close` from closing twice. + Try<int_fd> dup = os::dup(fd); + if (dup.isError()) { + return Error("Failed to duplicate handle: " + dup.error()); + } + + int crt = dup->crt(); + + if (!message.SerializeToFileDescriptor(crt)) { + ::_close(crt); + return Error("Failed to write/serialize message"); + } + ::_close(crt); #else if (!message.SerializeToFileDescriptor(fd)) { -#endif return Error("Failed to write/serialize message"); } +#endif return Nothing(); }
