@@ -24,6 +24,7 @@ limitations under the License.
2424#include < iostream>
2525#include < list>
2626#include < string>
27+ #include < utility>
2728#include < vector>
2829
2930namespace sysdig
@@ -142,6 +143,7 @@ void async_key_value_source<key_type, value_type>::run()
142143
143144 if (!m_terminate)
144145 {
146+
145147 run_impl ();
146148 }
147149 }
@@ -163,14 +165,27 @@ bool async_key_value_source<key_type, value_type>::lookup_delayed(
163165 m_thread = std::thread (&async_key_value_source::run, this );
164166 }
165167
166- typename value_map::const_iterator itr = m_value_map.find (key);
168+ typename value_map::iterator itr = m_value_map.find (key);
167169 bool request_complete;
168170
169171 if (itr == m_value_map.end ())
170172 {
171- // Haven't made the request yet
172- m_value_map[key].m_available = false ;
173- m_value_map[key].m_value = value;
173+ // Haven't made the request yet. Be explicit and validate insertion.
174+ auto insert_result = m_value_map.emplace (key, lookup_request ());
175+
176+ if (!insert_result.second )
177+ {
178+ g_logger.log (" async_key_value_source: Failed to insert an empty item "
179+ " into the container cache." , sinsp_logger::SEV_ERROR);
180+ return false ;
181+ }
182+
183+ // Replace the itr with the mapped value
184+ itr = insert_result.first ;
185+
186+ // Not sure why setting the value is needed, but being consistent with
187+ // previous implementation.
188+ itr->second .m_value = value;
174189
175190 // Make request to API and let the async thread know about it
176191 if (std::find (m_request_set.begin (),
@@ -200,22 +215,25 @@ bool async_key_value_source<key_type, value_type>::lookup_delayed(
200215 // and the async thread will continue handling the request so
201216 // that it'll be available on the next call.
202217 //
203- m_value_map[key] .m_available_condition .wait_for (
218+ itr-> second .m_available_condition .wait_for (
204219 guard,
205220 std::chrono::milliseconds (m_max_wait_ms));
206221
222+ // Replace the iterator in case something changed
207223 itr = m_value_map.find (key);
208224 request_complete = (itr != m_value_map.end ()) && itr->second .m_available ;
209225 }
210226
211227 if (request_complete)
212228 {
229+ // Pass the value back the caller and erase from the list.
213230 value = itr->second .m_value ;
214- m_value_map.erase (key );
231+ m_value_map.erase (itr );
215232 }
216233 else
217234 {
218- m_value_map[key].m_callback = handler;
235+ // Set the callback to fill the value later
236+ itr->second .m_callback = handler;
219237 }
220238
221239 return request_complete;
@@ -267,16 +285,26 @@ void async_key_value_source<key_type, value_type>::store_value(
267285{
268286 std::lock_guard<std::mutex> guard (m_mutex);
269287
270- if (m_value_map[key].m_callback )
288+ typename value_map::iterator itr = m_value_map.find (key);
289+ if (itr == m_value_map.end ())
271290 {
272- m_value_map[key].m_callback (key, value);
273- m_value_map.erase (key);
291+ g_logger.log (" async_key_value_source: Container not found when committing "
292+ " to container cache. Either the container no longer exists or "
293+ " the container lookup took longer than the timeout." ,
294+ sinsp_logger::SEV_WARNING);
295+ return ;
296+ }
297+
298+ if (itr->second .m_callback )
299+ {
300+ itr->second .m_callback (key, value);
301+ m_value_map.erase (itr);
274302 }
275303 else
276304 {
277- m_value_map[key] .m_value = value;
278- m_value_map[key] .m_available = true ;
279- m_value_map[key] .m_available_condition .notify_one ();
305+ itr-> second .m_value = value;
306+ itr-> second .m_available = true ;
307+ itr-> second .m_available_condition .notify_one ();
280308 }
281309}
282310
@@ -357,3 +385,4 @@ std::chrono::steady_clock::time_point async_key_value_source<key_type, value_typ
357385}
358386
359387} // end namespace sysdig
388+
0 commit comments