diff --git a/xbmc/input/linux/XKBCommonKeymap.cpp b/xbmc/input/linux/XKBCommonKeymap.cpp index 79959f55f38a9..d9f42f195163e 100644 --- a/xbmc/input/linux/XKBCommonKeymap.cpp +++ b/xbmc/input/linux/XKBCommonKeymap.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include "utils/ScopeExit.hxx" #include @@ -85,11 +85,11 @@ CXKBKeymap::ReceiveXKBKeymapFromSharedMemory(IDllXKBCommon &xkbCommonLibrary, st /* In every exit path, the keymap string memory region must be * unmapped */ - BOOST_SCOPE_EXIT((keymapString)(size)) + AtScopeExit(keymapString, size) { munmap(const_cast(static_cast(keymapString)), size); - } BOOST_SCOPE_EXIT_END + }; enum xkb_keymap_compile_flags flags = static_cast(0); diff --git a/xbmc/utils/ScopeExit.hxx b/xbmc/utils/ScopeExit.hxx new file mode 100644 index 0000000000000..c6c9d9cc82d73 --- /dev/null +++ b/xbmc/utils/ScopeExit.hxx @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SCOPE_EXIT_HXX +#define SCOPE_EXIT_HXX + +#include + +/** + * Internal class. Do not use directly. + */ +template +class ScopeExitGuard : F { + bool enabled = true; + +public: + explicit ScopeExitGuard(F &&f):F(std::forward(f)) {} + + ScopeExitGuard(ScopeExitGuard &&src) + :F(std::move(src)) { + src.enabled = false; + } + + ~ScopeExitGuard() { + if (enabled) + F::operator()(); + } + + ScopeExitGuard(const ScopeExitGuard &) = delete; + ScopeExitGuard &operator=(const ScopeExitGuard &) = delete; +}; + +/** + * Internal class. Do not use directly. + */ +struct ScopeExitTag { + /* this operator is a trick so we don't need to close + parantheses at the end of the expression AtScopeExit() + call */ + template + ScopeExitGuard operator+(F &&f) { + return ScopeExitGuard(std::forward(f)); + } +}; + +#define ScopeExitCat(a, b) a ## b +#define ScopeExitName(line) ScopeExitCat(at_scope_exit_, line) + +/** + * Call the block after this macro at the end of the current scope. + * Parameters are lambda captures. + * + * This is exception-safe, however the given code block must not throw + * exceptions. + * + * This attempts to be a better boost/scope_exit.hpp, without all of + * Boost's compile-time and runtime bloat. + */ +#define AtScopeExit(...) auto ScopeExitName(__LINE__) = ScopeExitTag() + [__VA_ARGS__]() + +#endif diff --git a/xbmc/windowing/wayland/Keyboard.cpp b/xbmc/windowing/wayland/Keyboard.cpp index 1ed76c0b549fc..1580640d907f3 100644 --- a/xbmc/windowing/wayland/Keyboard.cpp +++ b/xbmc/windowing/wayland/Keyboard.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include "utils/ScopeExit.hxx" #include @@ -152,10 +152,9 @@ void xw::Keyboard::HandleKeymap(uint32_t format, uint32_t size) { /* The file descriptor must always be closed */ - BOOST_SCOPE_EXIT((fd)) - { + AtScopeExit(fd) { close(fd); - } BOOST_SCOPE_EXIT_END + }; /* We don't understand anything other than xkbv1. If we get some * other keyboard, then we can't process keyboard events reliably @@ -172,11 +171,12 @@ void xw::Keyboard::HandleKeymap(uint32_t format, fd, size); - BOOST_SCOPE_EXIT((&m_xkbCommonLibrary)(&successfullyCreatedKeyboard)(keymap)) + auto &xkbCommonLibrary = m_xkbCommonLibrary; + AtScopeExit(&xkbCommonLibrary, &successfullyCreatedKeyboard, keymap) { if (!successfullyCreatedKeyboard) - m_xkbCommonLibrary.xkb_keymap_unref(keymap); - } BOOST_SCOPE_EXIT_END + xkbCommonLibrary.xkb_keymap_unref(keymap); + }; m_keymap.reset(new CXKBKeymap(m_xkbCommonLibrary, keymap));