diff --git a/configure.py b/configure.py index 1d49ba0a59..d0fb3d2903 100755 --- a/configure.py +++ b/configure.py @@ -189,6 +189,8 @@ arg_parser.add_argument('--with-osv', action = 'store', dest = 'with_osv', defau help = 'Shortcut for compile for OSv') arg_parser.add_argument('--dpdk-target', action = 'store', dest = 'dpdk_target', default = '', help = 'Path to DPDK SDK target location (e.g. /x86_64-native-linuxapp-gcc)') +arg_parser.add_argument('--debuginfo', action = 'store', dest = 'debuginfo', type = int, default = 1, + help = 'Enable(1)/disable(0)compiler debug information generation') add_tristate(arg_parser, name = 'hwloc', dest = 'hwloc', help = 'hwloc support') add_tristate(arg_parser, name = 'xen', dest = 'xen', help = 'Xen support') args = arg_parser.parse_args() @@ -371,7 +373,7 @@ warnings = [w warnings = ' '.join(warnings) -dbgflag = debug_flag(args.cxx) +dbgflag = debug_flag(args.cxx) if args.debuginfo else '' def have_hwloc(): return try_compile(compiler = args.cxx, source = '#include \n#include ') diff --git a/core/future.hh b/core/future.hh index 9e5a5baf3a..d54c68ddd5 100644 --- a/core/future.hh +++ b/core/future.hh @@ -70,6 +70,8 @@ make_task(Func&& func) { return std::unique_ptr(new lambda_task(std::move(func))); } +void report_failed_future(std::exception_ptr ex); + // // A future/promise pair maintain one logical value (a future_state). // To minimize allocations, the value is stored in exactly one of three @@ -169,10 +171,17 @@ struct future_state { _state = state::exception; new (&_u.ex) std::exception_ptr(ex); } + std::exception_ptr get_exception() noexcept { + assert(_state == state::exception); + // Move ex out so future::~future() knows we've handled it + return std::move(_u.ex); + } std::tuple get() { assert(_state != state::future); if (_state == state::exception) { - std::rethrow_exception(_u.ex); + _state = state::invalid; + // Move ex out so future::~future() knows we've handled it + std::rethrow_exception(std::move(_u.ex)); } return std::move(_u.value); } @@ -212,6 +221,8 @@ struct future_state<> { if (x._u.st < state::exception_min) { _u.st = x._u.st; } else { + // Move ex out so future::~future() knows we've handled it + // Moving it will reset us to invalid state new (&_u.ex) std::exception_ptr(std::move(x._u.ex)); } } @@ -249,10 +260,18 @@ struct future_state<> { std::tuple<> get() { assert(_u.st != state::future); if (_u.st >= state::exception_min) { - std::rethrow_exception(_u.ex); + // Move ex out so future::~future() knows we've handled it + // Moving it will reset us to invalid state + std::rethrow_exception(std::move(_u.ex)); } return {}; } + std::exception_ptr get_exception() noexcept { + assert(_u.st >= state::exception_min); + // Move ex out so future::~future() knows we've handled it + // Moving it will reset us to invalid state + return std::move(_u.ex); + } void forward_to(promise<>& pr) noexcept; }; @@ -486,6 +505,9 @@ public: if (_promise) { _promise->_future = nullptr; } + if (failed()) { + report_failed_future(state()->get_exception()); + } } std::tuple get() { return state()->get(); diff --git a/core/reactor.cc b/core/reactor.cc index 7842647993..1533223c68 100644 --- a/core/reactor.cc +++ b/core/reactor.cc @@ -1198,6 +1198,16 @@ void schedule(std::unique_ptr t) { engine().add_task(std::move(t)); } +void report_failed_future(std::exception_ptr exp) { + try { + std::rethrow_exception(std::move(exp)); + } catch (std::exception& ex) { + std::cerr << "WARNING: exceptional future ignored: " << ex.what() << "\n"; + } catch (...) { + std::cerr << "WARNING: exceptional future ignored\n"; + } +} + bool operator==(const ::sockaddr_in a, const ::sockaddr_in b) { return (a.sin_addr.s_addr == b.sin_addr.s_addr) && (a.sin_port == b.sin_port); } diff --git a/core/sleep.hh b/core/sleep.hh new file mode 100644 index 0000000000..24b3f54c34 --- /dev/null +++ b/core/sleep.hh @@ -0,0 +1,44 @@ +/* + * This file is open source software, licensed to you under the terms + * of the Apache License, Version 2.0 (the "License"). See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. 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. + */ + +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +#pragma once + +#include +#include + +#include "core/shared_ptr.hh" +#include "core/reactor.hh" +#include "core/future.hh" + +template +future<> sleep(std::chrono::duration dur) { + struct sleeper { + promise<> done; + timer tmr; + sleeper(std::chrono::duration dur) + : tmr([this] { done.set_value(); delete this; }) + { + tmr.arm(dur); + } + }; + return (new sleeper(dur))->done.get_future(); +} diff --git a/core/sstring.hh b/core/sstring.hh index ae6b336a77..5d688e2d52 100644 --- a/core/sstring.hh +++ b/core/sstring.hh @@ -178,7 +178,7 @@ public: size_t find(char_type t, size_t pos = 0) const noexcept { const char_type* it = str() + pos; - const char_type* end = it + size(); + const char_type* end = str() + size(); while (it < end) { if (*it == t) { return it - str(); @@ -190,7 +190,7 @@ public: size_t find(const basic_sstring& s, size_t pos = 0) const noexcept { const char_type* it = str() + pos; - const char_type* end = it + size(); + const char_type* end = str() + size(); const char_type* c_str = s.str(); const char_type* c_str_end = s.str() + s.size();