You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jo...@apache.org on 2015/12/15 00:49:04 UTC

mesos git commit: Windows: Added `WindowsError` to parallel `ErrnoError`.

Repository: mesos
Updated Branches:
  refs/heads/master 064b62a55 -> 5fbd65fbd


Windows: Added `WindowsError` to parallel `ErrnoError`.

Review: https://reviews.apache.org/r/39583/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5fbd65fb
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5fbd65fb
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5fbd65fb

Branch: refs/heads/master
Commit: 5fbd65fbd62424b003f75d916b63442e6e5050f1
Parents: 064b62a
Author: Alex Clemmer <cl...@gmail.com>
Authored: Mon Dec 14 14:26:26 2015 -0800
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Mon Dec 14 15:48:52 2015 -0800

----------------------------------------------------------------------
 .../3rdparty/stout/include/Makefile.am          |   2 +
 .../3rdparty/stout/include/stout/error.hpp      |  48 +++------
 .../3rdparty/stout/include/stout/errorbase.hpp  |  53 ++++++++++
 .../3rdparty/stout/include/stout/try.hpp        |   5 +
 .../stout/include/stout/windows/error.hpp       | 103 +++++++++++++++++++
 5 files changed, 175 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/5fbd65fb/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
index a25e2c1..a68de8b 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
@@ -22,6 +22,7 @@ nobase_include_HEADERS =		\
   stout/duration.hpp			\
   stout/dynamiclibrary.hpp		\
   stout/error.hpp			\
+  stout/errorbase.hpp			\
   stout/exit.hpp			\
   stout/flags.hpp			\
   stout/flags/fetch.hpp			\
@@ -139,6 +140,7 @@ nobase_include_HEADERS =		\
   stout/uuid.hpp			\
   stout/version.hpp			\
   stout/windows.hpp			\
+  stout/windows/error.hpp		\
   stout/windows/format.hpp		\
   stout/windows/gzip.hpp		\
   stout/windows/os.hpp

http://git-wip-us.apache.org/repos/asf/mesos/blob/5fbd65fb/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp
index 605c23b..cd1bad1 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp
@@ -13,41 +13,17 @@
 #ifndef __STOUT_ERROR_HPP__
 #define __STOUT_ERROR_HPP__
 
-#include <errno.h>
-
-#include <string>
-
-#include <stout/os/strerror.hpp>
-
-// A useful type that can be used to represent a Try that has
-// failed. You can also use 'ErrnoError' to append the error message
-// associated with the current 'errno' to your own error message.
-//
-// Examples:
-//
-//   Result<int> result = Error("uninitialized");
-//   Try<std::string> = Error("uninitialized");
-//
-//   void foo(Try<std::string> t) {}
-//
-//   foo(Error("some error here"));
-
-class Error
-{
-public:
-  explicit Error(const std::string& _message) : message(_message) {}
-
-  const std::string message;
-};
-
-
-class ErrnoError : public Error
-{
-public:
-  ErrnoError() : Error(os::strerror(errno)) {}
-
-  ErrnoError(const std::string& message)
-    : Error(message + ": " + os::strerror(errno)) {}
-};
+// NOTE: The order of these `#include`s is important. This file is structured
+// as a series of `#include`s for historical reasons. Before, `stout/error`
+// simply contained the definitions of `Error` and `ErrnoError`. The addition
+// of Windows required the addition of `WindowsError`. But, we try to avoid
+// `#ifdef`'ing code, opting instead to `#ifdef` `#include` statements. Hence,
+// we simply move the `error.hpp` code to `errorbase.hpp` and include the
+// Windows error code below it.
+#include <stout/errorbase.hpp>
+
+#ifdef __WINDOWS__
+#include <stout/windows/error.hpp>
+#endif // __WINDOWS__
 
 #endif // __STOUT_ERROR_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5fbd65fb/3rdparty/libprocess/3rdparty/stout/include/stout/errorbase.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/errorbase.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/errorbase.hpp
new file mode 100644
index 0000000..1e9db7e
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/errorbase.hpp
@@ -0,0 +1,53 @@
+// 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 __STOUT_ERROR_BASE_HPP__
+#define __STOUT_ERROR_BASE_HPP__
+
+#include <errno.h>
+
+#include <string>
+
+#include <stout/os/strerror.hpp>
+
+// A useful type that can be used to represent a Try that has
+// failed. You can also use 'ErrnoError' to append the error message
+// associated with the current 'errno' to your own error message.
+//
+// Examples:
+//
+//   Result<int> result = Error("uninitialized");
+//   Try<std::string> = Error("uninitialized");
+//
+//   void foo(Try<std::string> t) {}
+//
+//   foo(Error("some error here"));
+
+class Error
+{
+public:
+  explicit Error(const std::string& _message) : message(_message) {}
+
+  const std::string message;
+};
+
+
+class ErrnoError : public Error
+{
+public:
+  ErrnoError() : Error(os::strerror(errno)) {}
+
+  ErrnoError(const std::string& message)
+    : Error(message + ": " + os::strerror(errno)) {}
+};
+
+#endif // __STOUT_ERROR_BASE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5fbd65fb/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp
index 9e3b007..c444c01 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp
@@ -57,6 +57,11 @@ public:
   Try(const ErrnoError& error)
     : message(error.message) {}
 
+#ifdef __WINDOWS__
+  Try(const WindowsError& error)
+    : message(error.message) {}
+#endif // __WINDOWS__
+
   // TODO(bmahler): Add move constructor.
 
   // We don't need to implement these because we are leveraging

http://git-wip-us.apache.org/repos/asf/mesos/blob/5fbd65fb/3rdparty/libprocess/3rdparty/stout/include/stout/windows/error.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/error.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/error.hpp
new file mode 100644
index 0000000..27c5d5d
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/error.hpp
@@ -0,0 +1,103 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 __STOUT_WINDOWS_ERROR_HPP__
+#define __STOUT_WINDOWS_ERROR_HPP__
+
+#include <stout/error.hpp>
+#include <stout/windows.hpp>
+
+
+// A useful type that can be used to represent a Try that has failed. This is a
+// lot like `ErrnoError`, except instead of wrapping an error coming from the C
+// standard libraries, it wraps an error coming from the Windows APIs.
+class WindowsError : public Error
+{
+public:
+  WindowsError()
+    : Error(get_last_error_as_string()) {}
+
+  WindowsError(const std::string& message)
+    : Error(message + ": " + get_last_error_as_string()) {}
+
+private:
+  static std::string get_last_error_as_string()
+  {
+    DWORD errorCode = ::GetLastError();
+
+    // Default if no error.
+    if (errorCode == 0) {
+      return std::string();
+    }
+
+    DWORD allocate_message_buffer =
+      FORMAT_MESSAGE_ALLOCATE_BUFFER |
+      FORMAT_MESSAGE_FROM_SYSTEM |
+      FORMAT_MESSAGE_IGNORE_INSERTS;
+
+    DWORD default_language = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
+
+    // This following function `FormatMessage` is a lot like `strerror`, except
+    // it pretty-prints errors from the Windows API instead of from the C
+    // standard library. Basically, the semantics are: we pass in `errorCode`,
+    // and it allocates room for a pretty-printed error message at
+    // `message_buffer`, and then dumps said pretty-printed error message at
+    // that address, in our `default_language`.
+    //
+    // The 5th actual parameter (namely `(LPSTR)&message_buffer`), may look
+    // strange to readers of this code. It is copied directly out of the
+    // documentation[1], and is unfortunately required to get the
+    // pretty-printed error message. The short story is:
+    //
+    //   * The flag `FORMAT_MESSAGE_ALLOCATE_BUFFER` tells `FormatMessage` to
+    //     point `message_buffer` (which is an `LPSTR` a.k.a. `char*`) at a
+    //     string error message. But, `message_buffer` to point a `char*` at a
+    //     different place, `FormatMessage` would need the address
+    //     `&message_buffer` so that it could change where it is pointing.
+    //   * So, to solve this problem, the API writers decided that when you
+    //     pass that flag in, `FormatMessage` will treat the 5th parameter not
+    //     as `LPSTR` (which is what the type is in the function signagure),
+    //     but as `LPSTR*` a.k.a. `char**`, which (assuming you've casted the
+    //     parameter correctly) allows it to allocate the message on your
+    //     behalf, and change `message_buffer` to point at this new error
+    //     string.
+    //   * This is why we need this strange cast that you see below.
+    //
+    // Finally, and this is important: it is up to the user to free the memory
+    // with `LocalFree`! The line below where we do this comes directly from
+    // the documentation as well.
+    //
+    // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx
+    LPSTR message_buffer;
+    size_t size = FormatMessage(
+        allocate_message_buffer,
+        NULL,                   // Ignored.
+        errorCode,
+        default_language,
+        (LPSTR) &message_buffer,// See comment above for note about quirky cast.
+        0,                      // Ignored.
+        NULL);                  // Ignored.
+
+    std::string message(message_buffer, size);
+
+    // Required per documentation above.
+    LocalFree(message_buffer);
+
+    return message;
+  }
+};
+
+#endif // __STOUT_WINDOWS_ERROR_HPP__