@@ -531,12 +531,12 @@ class FutureImpl : public FutureImplBase {
531531 state_.callback = new ContinuationWithValue<Func, PromiseType, T...>(std::forward<Func>(func),
532532 std::forward<PromiseType>(promise));
533533 if (executor) state_.callback ->SetExecutor (executor);
534- state_.has_callback = true ;
535534
536- std::lock_guard<std::mutex> lock (state_.mtx );
535+ std::unique_lock<std::mutex> lock (state_.mtx );
536+ state_.has_callback = true ;
537537 // Got immediately executed.
538538 if (HasResult ()) {
539- TrySchedule ();
539+ TrySchedule (lock );
540540 }
541541 }
542542
@@ -549,12 +549,12 @@ class FutureImpl : public FutureImplBase {
549549 void SetTerminalCallback (Func&& func, Executor* executor) {
550550 state_.callback = new TerminalWithValue<Func, T...>(std::forward<Func>(func));
551551 if (executor) state_.callback ->SetExecutor (executor);
552- state_.has_callback = true ;
553552
554- std::lock_guard<std::mutex> lock (state_.mtx );
553+ std::unique_lock<std::mutex> lock (state_.mtx );
554+ state_.has_callback = true ;
555555 // Got immediately executed.
556556 if (HasResult ()) {
557- TrySchedule ();
557+ TrySchedule (lock );
558558 }
559559 }
560560
@@ -571,12 +571,12 @@ class FutureImpl : public FutureImplBase {
571571 state_.callback = new ContinuationWithFuture<Func, PromiseType, T...>(std::forward<Func>(func),
572572 std::forward<PromiseType>(promise));
573573 if (executor) state_.callback ->SetExecutor (executor);
574- state_.has_callback = true ;
575574
576- std::lock_guard<std::mutex> lock (state_.mtx );
575+ std::unique_lock<std::mutex> lock (state_.mtx );
576+ state_.has_callback = true ;
577577 // Got immediately executed.
578578 if (HasResult ()) {
579- TrySchedule ();
579+ TrySchedule (lock );
580580 }
581581 }
582582
@@ -589,12 +589,12 @@ class FutureImpl : public FutureImplBase {
589589 void SetTerminalCallbackWrapped (Func&& func, Executor* executor) {
590590 state_.callback = new TerminalWithFuture<Func, T...>(std::forward<Func>(func));
591591 if (executor) state_.callback ->SetExecutor (executor);
592- state_.has_callback = true ;
593592
594- std::lock_guard<std::mutex> lock (state_.mtx );
593+ std::unique_lock<std::mutex> lock (state_.mtx );
594+ state_.has_callback = true ;
595595 // Got immediately executed.
596596 if (HasResult ()) {
597- TrySchedule ();
597+ TrySchedule (lock );
598598 }
599599 }
600600
@@ -603,41 +603,36 @@ class FutureImpl : public FutureImplBase {
603603 state_.value = std::move (value);
604604 state_.ready = true ;
605605 // Result state may be looped by another thread.
606- {
607- std::lock_guard<std::mutex> lock (state_.mtx );
608- state_.has_result = true ;
609- }
610- TrySchedule ();
606+ std::unique_lock<std::mutex> lock (state_.mtx );
607+ state_.has_result = true ;
608+ TrySchedule (lock);
611609 }
612610
613611 // / @brief Exceptional value set through promise.
614612 void SetException (const Exception& e) {
615613 state_.exception = e;
616614 state_.failed = true ;
617615 // Result state may be looped by another thread.
618- {
619- std::lock_guard<std::mutex> lock (state_.mtx );
620- state_.has_result = true ;
621- }
622- TrySchedule ();
616+ std::unique_lock<std::mutex> lock (state_.mtx );
617+ state_.has_result = true ;
618+ TrySchedule (lock);
623619 }
624620
625621 // / @brief Support non const parameter.
626622 void SetException (Exception&& e) {
627623 state_.exception = std::move (e);
628624 state_.failed = true ;
629- {
630- std::lock_guard<std::mutex> lock (state_.mtx );
631- state_.has_result = true ;
632- }
633- TrySchedule ();
625+ std::unique_lock<std::mutex> lock (state_.mtx );
626+ state_.has_result = true ;
627+ TrySchedule (lock);
634628 }
635629
636630 private:
637631 // / @brief Future may or may not registered callback yet, check to inspire callback.
638632 // / @note Callback can only inspired once.
639- void TrySchedule () {
633+ void TrySchedule (std::unique_lock<std::mutex>& lock ) {
640634 if (state_.has_callback ) {
635+ lock.unlock ();
641636 if (IsReady ()) {
642637 if (state_.schedule_flag .test_and_set () == false ) {
643638 state_.callback ->SetValue (GetValue ());
@@ -704,11 +699,11 @@ class FutureImpl<T> : public FutureImplBase {
704699 state_.callback =
705700 new ContinuationWithValue<Func, PromiseType, T>(std::forward<Func>(func), std::forward<PromiseType>(promise));
706701 if (executor) state_.callback ->SetExecutor (executor);
707- state_.has_callback = true ;
708702
709- std::lock_guard<std::mutex> lock (state_.mtx );
703+ std::unique_lock<std::mutex> lock (state_.mtx );
704+ state_.has_callback = true ;
710705 if (HasResult ()) {
711- TrySchedule ();
706+ TrySchedule (lock );
712707 }
713708 }
714709
@@ -717,11 +712,11 @@ class FutureImpl<T> : public FutureImplBase {
717712 void SetTerminalCallback (Func&& func, Executor* executor) {
718713 state_.callback = new TerminalWithValue<Func, T>(std::forward<Func>(func));
719714 if (executor) state_.callback ->SetExecutor (executor);
720- state_.has_callback = true ;
721715
722- std::lock_guard<std::mutex> lock (state_.mtx );
716+ std::unique_lock<std::mutex> lock (state_.mtx );
717+ state_.has_callback = true ;
723718 if (HasResult ()) {
724- TrySchedule ();
719+ TrySchedule (lock );
725720 }
726721 }
727722
@@ -732,11 +727,11 @@ class FutureImpl<T> : public FutureImplBase {
732727 state_.callback =
733728 new ContinuationWithFuture<Func, PromiseType, T>(std::forward<Func>(func), std::forward<PromiseType>(promise));
734729 if (executor) state_.callback ->SetExecutor (executor);
735- state_.has_callback = true ;
736730
737- std::lock_guard<std::mutex> lock (state_.mtx );
731+ std::unique_lock<std::mutex> lock (state_.mtx );
732+ state_.has_callback = true ;
738733 if (HasResult ()) {
739- TrySchedule ();
734+ TrySchedule (lock );
740735 }
741736 }
742737
@@ -745,51 +740,46 @@ class FutureImpl<T> : public FutureImplBase {
745740 void SetTerminalCallbackWrapped (Func&& func, Executor* executor) {
746741 state_.callback = new TerminalWithFuture<Func, T>(std::forward<Func>(func));
747742 if (executor) state_.callback ->SetExecutor (executor);
748- state_.has_callback = true ;
749743
750- std::lock_guard<std::mutex> lock (state_.mtx );
744+ std::unique_lock<std::mutex> lock (state_.mtx );
745+ state_.has_callback = true ;
751746 if (HasResult ()) {
752- TrySchedule ();
747+ TrySchedule (lock );
753748 }
754749 }
755750
756751 // / @brief Same as multiple version.
757752 void SetValue (T&& value) {
758753 state_.value = std::move (value);
759754 state_.ready = true ;
760- {
761- std::lock_guard<std::mutex> lock (state_.mtx );
762- state_.has_result = true ;
763- }
764- TrySchedule ();
755+ std::unique_lock<std::mutex> lock (state_.mtx );
756+ state_.has_result = true ;
757+ TrySchedule (lock);
765758 }
766759
767760 // / @brief Same as multiple version.
768761 void SetException (const Exception& e) {
769762 state_.exception = e;
770763 state_.failed = true ;
771- {
772- std::lock_guard<std::mutex> lock (state_.mtx );
773- state_.has_result = true ;
774- }
775- TrySchedule ();
764+ std::unique_lock<std::mutex> lock (state_.mtx );
765+ state_.has_result = true ;
766+ TrySchedule (lock);
776767 }
777768
778769 // / @brief Same as multiple version.
779770 void SetException (Exception&& e) {
780771 state_.exception = std::move (e);
781772 state_.failed = true ;
782- {
783- std::lock_guard<std::mutex> lock (state_.mtx );
784- state_.has_result = true ;
785- }
786- TrySchedule ();
773+ std::unique_lock<std::mutex> lock (state_.mtx );
774+ state_.has_result = true ;
775+ TrySchedule (lock);
787776 }
788777
789778 private:
790779 // / @brief Same as multiple version.
791- void TrySchedule () {
780+ void TrySchedule (std::unique_lock<std::mutex>& lock ) {
792781 if (state_.has_callback ) {
782+ lock.unlock ();
793783 if (IsReady ()) {
794784 if (state_.schedule_flag .test_and_set () == false ) {
795785 state_.callback ->SetValue (GetValue ());
0 commit comments