@@ -55,21 +55,13 @@ class FDv1AdapterSynchronizer final
5555
5656 private:
5757 /* *
58- * Holds the lifecycle, result queue, and pending Next() promise; shared
59- * with the FDv1 source's IDestination via the inner ConvertingDestination.
58+ * Holds the result queue and pending Next() promise; shared with the
59+ * FDv1 source's IDestination via the inner ConvertingDestination.
6060 * All methods are thread-safe.
6161 */
6262 class State {
6363 public:
64- // Returns true if this call transitioned Initial → Started; false if
65- // already started or already closed. Used to gate the one-time
66- // StartAsync call on the wrapped FDv1 source.
67- bool TryStart ();
68-
69- // Marks the state closed and returns whether the source was started
70- // before the transition (so the caller knows whether ShutdownAsync
71- // needs to be called).
72- bool MarkClosed ();
64+ explicit State (async::Future<std::monostate> closed_future);
7365
7466 async::Future<data_interfaces::FDv2SourceResult> GetNext ();
7567
@@ -81,10 +73,12 @@ class FDv1AdapterSynchronizer final
8173 void Notify (data_interfaces::FDv2SourceResult result);
8274
8375 private:
84- // Protected by mutex_.
76+ // Finished once the owning FDv1AdapterSynchronizer's close_promise_
77+ // is resolved. Read in Notify to drop late results.
78+ async::Future<std::monostate> const closed_future_;
79+
8580 mutable std::mutex mutex_;
86- bool started_ = false ;
87- bool closed_ = false ;
81+ // Protected by mutex_.
8882 std::optional<async::Promise<data_interfaces::FDv2SourceResult>>
8983 pending_promise_;
9084 std::deque<data_interfaces::FDv2SourceResult> result_queue_;
@@ -108,6 +102,10 @@ class FDv1AdapterSynchronizer final
108102 std::weak_ptr<State> state_;
109103 };
110104
105+ // Thread-safe primitive. Declared before state_ so state_'s constructor
106+ // can take a future from it.
107+ async::Promise<std::monostate> close_promise_;
108+
111109 // shared_ptr so async callbacks that may fire after this is destroyed
112110 // can hold their own reference.
113111 std::shared_ptr<State> const state_;
@@ -121,8 +119,13 @@ class FDv1AdapterSynchronizer final
121119
122120 std::unique_ptr<data_interfaces::IDataSynchronizer> const fdv1_source_;
123121
124- // Thread-safe primitive.
125- async::Promise<std::monostate> close_promise_;
122+ // Serializes StartAsync and ShutdownAsync on fdv1_source_ across
123+ // concurrent Next() and Close() calls.
124+ std::mutex lifecycle_mutex_;
125+ // Protected by lifecycle_mutex_. Set when Next() calls StartAsync, or
126+ // when Close() runs without a prior start (to gate any later Next()
127+ // from calling StartAsync after Close).
128+ bool started_ = false ;
126129};
127130
128131} // namespace launchdarkly::server_side::data_systems
0 commit comments