44#include < functional>
55#include < list>
66#include < mutex>
7+ #include < optional>
78#include < shared_mutex>
89#include < thread>
910
@@ -39,6 +40,8 @@ class AsyncRunner : public NonCopyable
3940 void wait (Id id) const ;
4041 void wait_all () const ;
4142 Status status (Id id) const ;
43+ std::optional<Item> get (Id id) const ;
44+ std::optional<Item> get_running () const ;
4245
4346 void clear ();
4447 bool running () const ;
@@ -49,10 +52,13 @@ class AsyncRunner : public NonCopyable
4952 ProcessFunc process_;
5053
5154 std::list<std::pair<Id, Item>> queue_;
52- std::mutex queue_mutex_;
55+ mutable std::mutex queue_mutex_;
5356 std::condition_variable queue_cond_;
5457 std::atomic_bool running_ = false ;
5558
59+ Id running_id_ = 0 ;
60+ Item running_item_ {};
61+
5662 mutable std::shared_mutex status_mutex_;
5763 std::map<Id, Status> status_map_;
5864
@@ -128,6 +134,9 @@ inline void AsyncRunner<Item>::working()
128134
129135 auto [id, item] = std::move (queue_.front ());
130136 queue_.pop_front ();
137+
138+ running_id_ = id;
139+ running_item_ = item;
131140 queue_lock.unlock ();
132141
133142 std::unique_lock status_lock (status_mutex_);
@@ -136,6 +145,12 @@ inline void AsyncRunner<Item>::working()
136145
137146 bool ret = process_ (id, std::move (item));
138147
148+ {
149+ std::unique_lock clear_lock (queue_mutex_);
150+ running_id_ = 0 ;
151+ running_item_ = {};
152+ }
153+
139154 status_lock.lock ();
140155 status_map_[id] = ret ? Status::succeeded : Status::failed;
141156 status_lock.unlock ();
@@ -219,6 +234,36 @@ inline AsyncRunner<Item>::Status AsyncRunner<Item>::status(Id id) const
219234 return iter->second ;
220235}
221236
237+ template <typename Item>
238+ inline std::optional<Item> AsyncRunner<Item>::get(Id id) const
239+ {
240+ std::unique_lock queue_lock (queue_mutex_);
241+
242+ if (running_id_ == id) {
243+ return running_item_;
244+ }
245+
246+ for (const auto & [item_id, item] : queue_) {
247+ if (item_id == id) {
248+ return item;
249+ }
250+ }
251+
252+ return std::nullopt ;
253+ }
254+
255+ template <typename Item>
256+ inline std::optional<Item> AsyncRunner<Item>::get_running() const
257+ {
258+ std::unique_lock queue_lock (queue_mutex_);
259+
260+ if (running_id_ != 0 ) {
261+ return running_item_;
262+ }
263+
264+ return std::nullopt ;
265+ }
266+
222267template <typename Item>
223268inline void AsyncRunner<Item>::clear()
224269{
0 commit comments