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 <[email protected]> Authored: Mon Dec 14 14:26:26 2015 -0800 Committer: Joris Van Remoortere <[email protected]> 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__
