yiguolei commented on code in PR #39470: URL: https://github.com/apache/doris/pull/39470#discussion_r1720872532
########## be/src/util/once.h: ########## @@ -42,95 +48,67 @@ namespace doris { // } // // bool is_inited() const { -// return _init_once.has_called() && _init_once.stored_result().ok(); +// return _init_once.is_called() && _init_once.stored_result().ok(); // } // private: // Status _do_init() { /* init logic here */ } // DorisCallOnce<Status> _init_once; // }; -template <typename ReturnType> + +template <typename R> class DorisCallOnce { public: - DorisCallOnce() : _has_called(false) {} - - // this method is not exception safe, it will core when exception occurs in - // callback method. I have tested the code https://en.cppreference.com/w/cpp/thread/call_once. - // If the underlying `once_flag` has yet to be invoked, invokes the provided - // lambda and stores its return value. Otherwise, returns the stored Status. - // template <typename Fn> - // ReturnType call(Fn fn) { - // std::call_once(_once_flag, [this, fn] { - // _status = fn(); - // _has_called.store(true, std::memory_order_release); - // }); - // return _status; - // } + DorisCallOnce() : _eptr(nullptr), _is_exception_thrown(false), _ret_val(std::nullopt) {} - // If exception occurs in the function, the call flag is set, if user call - // it again, the same exception will be thrown. - // It is different from std::call_once. This is because if a method is called once - // some internal state is changed, it maybe not called again although exception - // occurred. template <typename Fn> - ReturnType call(Fn fn) { - // Avoid lock to improve performance - if (has_called()) { - if (_eptr) { - std::rethrow_exception(_eptr); + requires std::is_invocable_r_v<R, Fn> + R call(Fn fn) { + std::call_once(_once_flag, [&] { Review Comment: In the past, we use std call once, but there are 2 main reasons that we implement our own call once: 1. std call once could not deal with exception logic correctly. 2. when it is core during std call once, it's callstack will include another thread, it is not very clear. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org