@@ -44,6 +44,48 @@ namespace cloud_firestore_windows {
4444
4545static std::string kLibraryName = " flutter-fire-fst" ;
4646
47+ void TransactionResponse::Reset () {
48+ std::lock_guard<std::mutex> lock (mutex_);
49+ response_received_ = false ;
50+ commands_.clear ();
51+ }
52+
53+ void TransactionResponse::Complete (
54+ InternalTransactionResult result,
55+ std::vector<InternalTransactionCommand> commands) {
56+ {
57+ std::lock_guard<std::mutex> lock (mutex_);
58+ result_ = result;
59+ commands_ = std::move (commands);
60+ response_received_ = true ;
61+ }
62+ condition_.notify_one ();
63+ }
64+
65+ TransactionResponseStatus TransactionResponse::WaitFor (
66+ std::chrono::milliseconds timeout, InternalTransactionResult& result,
67+ std::vector<InternalTransactionCommand>& commands) {
68+ std::unique_lock<std::mutex> lock (mutex_);
69+ if (!condition_.wait_for (
70+ lock, timeout, [this ] { return response_received_ || cancelled_; })) {
71+ return TransactionResponseStatus::kTimedOut ;
72+ }
73+ if (cancelled_) {
74+ return TransactionResponseStatus::kCancelled ;
75+ }
76+ result = result_;
77+ commands = std::move (commands_);
78+ return TransactionResponseStatus::kReceived ;
79+ }
80+
81+ void TransactionResponse::Cancel () {
82+ {
83+ std::lock_guard<std::mutex> lock (mutex_);
84+ cancelled_ = true ;
85+ }
86+ condition_.notify_one ();
87+ }
88+
4789namespace {
4890
4991constexpr wchar_t kTaskRunnerWindowClassName [] =
@@ -996,10 +1038,7 @@ class TransactionStreamHandler
9961038 void ReceiveTransactionResponse (
9971039 InternalTransactionResult resultType,
9981040 std::vector<InternalTransactionCommand> commands) {
999- std::lock_guard<std::mutex> lock (commands_mutex_);
1000- resultType_ = resultType;
1001- commands_ = commands;
1002- cv_.notify_one ();
1041+ response_.Complete (resultType, std::move (commands));
10031042 }
10041043
10051044 std::unique_ptr<flutter::StreamHandlerError<flutter::EncodableValue>>
@@ -1024,25 +1063,31 @@ class TransactionStreamHandler
10241063
10251064 flutter::EncodableMap map;
10261065 map.emplace (" appName" , firestore_->app ()->name ());
1066+ response_.Reset ();
10271067 SendSuccessOnPlatformThread (events_state_,
10281068 flutter::EncodableValue (map));
10291069
1030- std::unique_lock<std::mutex> lock (mtx_);
1031- if (cv_.wait_for (lock, std::chrono::milliseconds (timeout_)) ==
1032- std::cv_status::timeout) {
1033- SendErrorOnPlatformThread (events_state_, " Timeout" ,
1034- " Transaction timed out." ,
1035- flutter::EncodableValue (), true );
1036- return Error::kErrorDeadlineExceeded ;
1070+ InternalTransactionResult resultType;
1071+ std::vector<InternalTransactionCommand> commands;
1072+ switch (response_.WaitFor (std::chrono::milliseconds (timeout_),
1073+ resultType, commands)) {
1074+ case TransactionResponseStatus::kTimedOut :
1075+ SendErrorOnPlatformThread (events_state_, " Timeout" ,
1076+ " Transaction timed out." ,
1077+ flutter::EncodableValue (), true );
1078+ return Error::kErrorDeadlineExceeded ;
1079+ case TransactionResponseStatus::kCancelled :
1080+ return Error::kErrorCancelled ;
1081+ case TransactionResponseStatus::kReceived :
1082+ break ;
10371083 }
10381084
1039- std::lock_guard<std::mutex> command_lock (commands_mutex_);
1040- if (resultType_ == InternalTransactionResult::kFailure ) {
1085+ if (resultType == InternalTransactionResult::kFailure ) {
10411086 return Error::kErrorAborted ;
10421087 }
1043- if (commands_ .empty ()) return Error::kErrorOk ;
1088+ if (commands .empty ()) return Error::kErrorOk ;
10441089
1045- for (InternalTransactionCommand& command : commands_ ) {
1090+ for (InternalTransactionCommand& command : commands ) {
10461091 std::string path = command.path ();
10471092 InternalTransactionType type = command.type ();
10481093 if (path.empty () /* or some other invalid condition */ ) {
@@ -1114,8 +1159,7 @@ class TransactionStreamHandler
11141159
11151160 std::unique_ptr<flutter::StreamHandlerError<flutter::EncodableValue>>
11161161 OnCancelInternal (const flutter::EncodableValue* arguments) override {
1117- std::unique_lock<std::mutex> lock (mtx_);
1118- cv_.notify_one ();
1162+ response_.Cancel ();
11191163 EndStreamOnPlatformThread (events_state_);
11201164 return nullptr ;
11211165 }
@@ -1125,11 +1169,7 @@ class TransactionStreamHandler
11251169 long timeout_;
11261170 int maxAttempts_;
11271171 std::string transactionId_;
1128- std::vector<InternalTransactionCommand> commands_;
1129- InternalTransactionResult resultType_ = InternalTransactionResult::kSuccess ;
1130- std::mutex mtx_;
1131- std::mutex commands_mutex_;
1132- std::condition_variable cv_;
1172+ TransactionResponse response_;
11331173 std::shared_ptr<EventSinkState> events_state_;
11341174};
11351175
0 commit comments