3131#include < stdexcept>
3232#include < type_traits>
3333#include < utility>
34+ #include < source_location>
3435#endif
3536
3637#include < seastar/core/task.hh>
@@ -1231,13 +1232,14 @@ private:
12311232 future_base::schedule (tws, &tws->_state );
12321233 }
12331234 template <typename Pr, typename Func, typename Wrapper>
1234- void schedule (Pr&& pr, Func&& func, Wrapper&& wrapper) noexcept {
1235+ void schedule (Pr&& pr, Func&& func, Wrapper&& wrapper, std::source_location sl ) noexcept {
12351236 // If this new throws a std::bad_alloc there is nothing that
12361237 // can be done about it. The corresponding future is not ready
12371238 // and we cannot break the chain. Since this function is
12381239 // noexcept, it will call std::terminate if new throws.
12391240 memory::scoped_critical_alloc_section _;
12401241 auto tws = new continuation<Pr, Func, Wrapper, T>(std::move (pr), std::move (func), std::move (wrapper));
1242+ tws->update_resume_point (sl);
12411243 // In a debug build we schedule ready futures, but not in
12421244 // other build modes.
12431245#ifdef SEASTAR_DEBUG
@@ -1355,9 +1357,9 @@ public:
13551357 requires std::invocable<Func, T>
13561358 || (std::same_as<void , T> && std::invocable<Func>)
13571359 Result
1358- then (Func&& func) noexcept {
1360+ then (Func&& func, std::source_location sl = std::source_location::current () ) noexcept {
13591361#ifndef SEASTAR_TYPE_ERASE_MORE
1360- return then_impl (std::move (func));
1362+ return then_impl (std::move (func), sl );
13611363#else
13621364 using func_type = typename internal::future_result<Func, T>::func_type;
13631365 noncopyable_function<func_type> ncf;
@@ -1367,7 +1369,7 @@ public:
13671369 return futurize_invoke (func, std::forward<decltype (args)>(args)...);
13681370 });
13691371 }
1370- return then_impl (std::move (ncf));
1372+ return then_impl (std::move (ncf), sl );
13711373#endif
13721374 }
13731375
@@ -1393,18 +1395,18 @@ public:
13931395 template <typename Func, typename Result = futurize_t <internal::result_of_apply_t <Func, T>>>
13941396 requires ::seastar::CanApplyTuple<Func, T>
13951397 Result
1396- then_unpack (Func&& func) noexcept {
1398+ then_unpack (Func&& func, std::source_location sl = std::source_location::current () ) noexcept {
13971399 return then ([func = std::forward<Func>(func)] (T&& tuple) mutable {
13981400 // sizeof...(tuple) is required to be 1
13991401 return std::apply (func, std::move (tuple));
1400- });
1402+ }, sl );
14011403 }
14021404
14031405private:
14041406
14051407 // Keep this simple so that Named Return Value Optimization is used.
14061408 template <typename Func, typename Result>
1407- Result then_impl_nrvo (Func&& func) noexcept {
1409+ Result then_impl_nrvo (Func&& func, std::source_location sl ) noexcept {
14081410 using futurator = futurize<internal::future_result_t <Func, T>>;
14091411 typename futurator::type fut (future_for_get_promise_marker{});
14101412 using pr_type = decltype (fut.get_promise ());
@@ -1419,13 +1421,13 @@ private:
14191421 return internal::future_invoke (func, std::move (state).get_value ());
14201422 });
14211423 }
1422- });
1424+ }, sl );
14231425 return fut;
14241426 }
14251427
14261428 template <typename Func, typename Result = futurize_t <internal::future_result_t <Func, T>>>
14271429 Result
1428- then_impl (Func&& func) noexcept {
1430+ then_impl (Func&& func, std::source_location sl ) noexcept {
14291431#ifndef SEASTAR_DEBUG
14301432 using futurator = futurize<internal::future_result_t <Func, T>>;
14311433 if (failed ()) {
@@ -1434,7 +1436,7 @@ private:
14341436 return futurator::invoke (std::forward<Func>(func), get_available_state_ref ().take_value ());
14351437 }
14361438#endif
1437- return then_impl_nrvo<Func, Result>(std::forward<Func>(func));
1439+ return then_impl_nrvo<Func, Result>(std::forward<Func>(func), sl );
14381440 }
14391441
14401442public:
@@ -1455,23 +1457,23 @@ public:
14551457 // / to the eventual value of this future.
14561458 template <std::invocable<future> Func, typename FuncResult = std::invoke_result_t <Func, future>>
14571459 futurize_t <FuncResult>
1458- then_wrapped (Func&& func) & noexcept {
1459- return then_wrapped_maybe_erase<false , FuncResult>(std::forward<Func>(func));
1460+ then_wrapped (Func&& func, std::source_location sl = std::source_location::current () ) & noexcept {
1461+ return then_wrapped_maybe_erase<false , FuncResult>(std::forward<Func>(func), sl );
14601462 }
14611463
14621464 template <std::invocable<future&&> Func, typename FuncResult = std::invoke_result_t <Func, future&&>>
14631465 futurize_t <FuncResult>
1464- then_wrapped (Func&& func) && noexcept {
1465- return then_wrapped_maybe_erase<true , FuncResult>(std::forward<Func>(func));
1466+ then_wrapped (Func&& func, std::source_location sl = std::source_location::current () ) && noexcept {
1467+ return then_wrapped_maybe_erase<true , FuncResult>(std::forward<Func>(func), sl );
14661468 }
14671469
14681470private:
14691471
14701472 template <bool AsSelf, typename FuncResult, typename Func>
14711473 futurize_t <FuncResult>
1472- then_wrapped_maybe_erase (Func&& func) noexcept {
1474+ then_wrapped_maybe_erase (Func&& func, std::source_location sl ) noexcept {
14731475#ifndef SEASTAR_TYPE_ERASE_MORE
1474- return then_wrapped_common<AsSelf, FuncResult>(std::forward<Func>(func));
1476+ return then_wrapped_common<AsSelf, FuncResult>(std::forward<Func>(func), sl );
14751477#else
14761478 using futurator = futurize<FuncResult>;
14771479 using WrapFuncResult = typename futurator::type;
@@ -1482,29 +1484,29 @@ private:
14821484 return futurator::invoke (func, std::move (f));
14831485 });
14841486 }
1485- return then_wrapped_common<AsSelf, WrapFuncResult>(std::move (ncf));
1487+ return then_wrapped_common<AsSelf, WrapFuncResult>(std::move (ncf), sl );
14861488#endif
14871489 }
14881490
14891491 // Keep this simple so that Named Return Value Optimization is used.
14901492 template <typename FuncResult, typename Func>
14911493 futurize_t <FuncResult>
1492- then_wrapped_nrvo (Func&& func) noexcept {
1494+ then_wrapped_nrvo (Func&& func, std::source_location sl ) noexcept {
14931495 using futurator = futurize<FuncResult>;
14941496 typename futurator::type fut (future_for_get_promise_marker{});
14951497 using pr_type = decltype (fut.get_promise ());
14961498 schedule (fut.get_promise (), std::move (func), [](pr_type&& pr, Func& func, future_state&& state) {
14971499 futurator::satisfy_with_result_of (std::move (pr), [&func, &state] {
14981500 return func (future (std::move (state)));
14991501 });
1500- });
1502+ }, sl );
15011503 return fut;
15021504 }
15031505
15041506
15051507 template <bool AsSelf, typename FuncResult, typename Func>
15061508 futurize_t <FuncResult>
1507- then_wrapped_common (Func&& func) noexcept {
1509+ then_wrapped_common (Func&& func, std::source_location sl ) noexcept {
15081510#ifndef SEASTAR_DEBUG
15091511 using futurator = futurize<FuncResult>;
15101512 if (available ()) {
@@ -1518,7 +1520,7 @@ private:
15181520 }
15191521 }
15201522#endif
1521- return then_wrapped_nrvo<FuncResult, Func>(std::forward<Func>(func));
1523+ return then_wrapped_nrvo<FuncResult, Func>(std::forward<Func>(func), sl );
15221524 }
15231525
15241526 void forward_to (internal::promise_base_with_type<T>&& pr) noexcept {
@@ -1570,8 +1572,8 @@ public:
15701572 * nested will be propagated.
15711573 */
15721574 template <std::invocable Func>
1573- future<T> finally (Func&& func) noexcept {
1574- return then_wrapped (finally_body<Func, is_future<std::invoke_result_t <Func>>::value>(std::forward<Func>(func)));
1575+ future<T> finally (Func&& func, std::source_location sl = std::source_location::current () ) noexcept {
1576+ return then_wrapped (finally_body<Func, is_future<std::invoke_result_t <Func>>::value>(std::forward<Func>(func)), sl );
15751577 }
15761578
15771579
@@ -1617,24 +1619,24 @@ public:
16171619 // /
16181620 // / Terminates the entire program is this future resolves
16191621 // / to an exception. Use with caution.
1620- future<> or_terminate () noexcept {
1622+ future<> or_terminate (std::source_location sl = std::source_location::current () ) noexcept {
16211623 return then_wrapped ([] (auto && f) {
16221624 try {
16231625 f.get ();
16241626 } catch (...) {
16251627 engine_exit (std::current_exception ());
16261628 }
1627- });
1629+ }, sl );
16281630 }
16291631
16301632 // / \brief Discards the value carried by this future.
16311633 // /
16321634 // / Converts the future into a no-value \c future<>, by
16331635 // / ignoring any result. Exceptions are propagated unchanged.
1634- future<> discard_result () noexcept {
1636+ future<> discard_result (std::source_location sl = std::source_location::current () ) noexcept {
16351637 // We need the generic variadic lambda, below, because then() behaves differently
16361638 // when value_type is when_all_succeed_tuple
1637- return then ([] (auto &&...) {});
1639+ return then ([] (auto &&...) {}, sl );
16381640 }
16391641
16401642 // / \brief Handle the exception carried by this future.
@@ -1655,15 +1657,15 @@ public:
16551657 || (std::tuple_size_v<tuple_type> == 0 && std::is_invocable_r_v<void , Func, std::exception_ptr>)
16561658 || (std::tuple_size_v<tuple_type> == 1 && std::is_invocable_r_v<T, Func, std::exception_ptr>)
16571659 || (std::tuple_size_v<tuple_type> > 1 && std::is_invocable_r_v<tuple_type ,Func, std::exception_ptr>)
1658- future<T> handle_exception (Func&& func) noexcept {
1660+ future<T> handle_exception (Func&& func, std::source_location sl = std::source_location::current () ) noexcept {
16591661 return then_wrapped ([func = std::forward<Func>(func)]
16601662 (auto && fut) mutable -> future<T> {
16611663 if (!fut.failed ()) {
16621664 return make_ready_future<T>(fut.get ());
16631665 } else {
16641666 return futurize_invoke (func, fut.get_exception ());
16651667 }
1666- });
1668+ }, sl );
16671669 }
16681670
16691671 // / \brief Handle the exception of a certain type carried by this future.
@@ -1677,7 +1679,7 @@ public:
16771679 // / If exception, that future holds, does not match func parameter type
16781680 // / it is propagated as is.
16791681 template <typename Func>
1680- future<T> handle_exception_type (Func&& func) noexcept {
1682+ future<T> handle_exception_type (Func&& func, std::source_location sl = std::source_location::current () ) noexcept {
16811683 using trait = function_traits<Func>;
16821684 static_assert (trait::arity == 1 , " func can take only one parameter" );
16831685 using ex_type = typename trait::template arg<0 >::type;
@@ -1688,7 +1690,7 @@ public:
16881690 } catch (ex_type& ex) {
16891691 return futurize_invoke (func, ex);
16901692 }
1691- });
1693+ }, sl );
16921694 }
16931695
16941696 // / \brief Ignore any result hold by this future
0 commit comments