@@ -230,67 +230,49 @@ namespace pcpp
230
230
}
231
231
}
232
232
233
- PcapLiveDevice::StatisticsUpdateWorker::StatisticsUpdateWorker (PcapLiveDevice const & pcapDevice,
234
- OnStatsUpdateCallback onStatsUpdateCallback,
235
- void * onStatsUpdateUserCookie,
236
- unsigned int updateIntervalMs)
237
- {
238
- // Setup thread data
239
- m_SharedThreadData = std::make_shared<SharedThreadData>();
240
-
241
- ThreadData threadData;
242
- threadData.pcapDevice = &pcapDevice;
243
- threadData.cbOnStatsUpdate = onStatsUpdateCallback;
244
- threadData.cbOnStatsUpdateUserCookie = onStatsUpdateUserCookie;
245
- threadData.updateIntervalMs = updateIntervalMs;
246
-
247
- // Start the thread
248
- m_WorkerThread = std::thread (&StatisticsUpdateWorker::workerMain, m_SharedThreadData, std::move (threadData));
249
- }
250
-
251
- void PcapLiveDevice::StatisticsUpdateWorker::stopWorker ()
252
- {
253
- m_SharedThreadData->stopRequested = true ;
254
- if (m_WorkerThread.joinable ())
255
- {
256
- m_WorkerThread.join ();
257
- }
258
- }
259
-
260
- void PcapLiveDevice::StatisticsUpdateWorker::workerMain (std::shared_ptr<SharedThreadData> sharedThreadData,
261
- ThreadData threadData)
233
+ namespace
262
234
{
263
- if (sharedThreadData == nullptr )
264
- {
265
- PCPP_LOG_ERROR (" Shared thread data is null" );
266
- return ;
267
- }
268
-
269
- if (threadData.pcapDevice == nullptr )
235
+ struct StatisticsUpdateContext
270
236
{
271
- PCPP_LOG_ERROR (" Pcap device is null" );
272
- return ;
273
- }
237
+ OnStatsUpdateCallback cbOnStatsUpdate;
238
+ void * cbOnStatsUpdateUserCookie = nullptr ;
239
+ std::chrono::milliseconds updateInterval = std::chrono::seconds(1 );
240
+ };
274
241
275
- if (threadData.cbOnStatsUpdate == nullptr )
242
+ void statsThreadMain (std::atomic<bool >& stopFlag, internal::PcapHandle const & pcapDescriptor,
243
+ StatisticsUpdateContext context)
276
244
{
277
- PCPP_LOG_ERROR (" Statistics Callback is null" );
278
- return ;
279
- }
245
+ if (context.cbOnStatsUpdate == nullptr )
246
+ {
247
+ PCPP_LOG_ERROR (" No callback provided for statistics updates" );
248
+ return ;
249
+ }
280
250
281
- PCPP_LOG_DEBUG (" Started statistics thread " );
251
+ PCPP_LOG_DEBUG (" Begin periodic statistics update procedure " );
282
252
283
- PcapStats stats;
284
- auto sleepDuration = std::chrono::milliseconds (threadData.updateIntervalMs );
285
- while (!sharedThreadData->stopRequested )
286
- {
287
- threadData.pcapDevice ->getStatistics (stats);
288
- threadData.cbOnStatsUpdate (stats, threadData.cbOnStatsUpdateUserCookie );
289
- std::this_thread::sleep_for (sleepDuration);
253
+ IPcapDevice::PcapStats stats;
254
+ while (!stopFlag.load ())
255
+ {
256
+ try
257
+ {
258
+ pcapDescriptor.getStatistics (stats);
259
+ context.cbOnStatsUpdate (stats, context.cbOnStatsUpdateUserCookie );
260
+ }
261
+ catch (const std::exception& ex)
262
+ {
263
+ PCPP_LOG_ERROR (" Exception occurred while invoking statistics update callback: " << ex.what ());
264
+ break ;
265
+ }
266
+ catch (...)
267
+ {
268
+ PCPP_LOG_ERROR (" Unknown exception occurred while invoking statistics update callback" );
269
+ break ;
270
+ }
271
+ std::this_thread::sleep_for (context.updateInterval );
272
+ }
273
+ PCPP_LOG_DEBUG (" Ended periodic statistics update procedure" );
290
274
}
291
-
292
- PCPP_LOG_DEBUG (" Stopped statistics thread" );
293
- }
275
+ } // namespace
294
276
295
277
PcapLiveDevice::PcapLiveDevice (DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress,
296
278
bool calculateDefaultGateway)
@@ -686,10 +668,14 @@ namespace pcpp
686
668
687
669
if (onStatsUpdate != nullptr && intervalInSecondsToUpdateStats > 0 )
688
670
{
689
- // Due to passing a 'this' pointer, the current device object shouldn't be relocated, while the worker is
690
- // active.
691
- m_StatisticsUpdateWorker = std::make_unique<StatisticsUpdateWorker>(
692
- *this , std::move (onStatsUpdate), onStatsUpdateUserCookie, intervalInSecondsToUpdateStats * 1000 );
671
+ StatisticsUpdateContext statsContext;
672
+
673
+ statsContext.cbOnStatsUpdate = std::move (onStatsUpdate);
674
+ statsContext.cbOnStatsUpdateUserCookie = onStatsUpdateUserCookie;
675
+ statsContext.updateInterval = std::chrono::seconds (intervalInSecondsToUpdateStats);
676
+
677
+ m_StatsThread = std::thread (statsThreadMain, std::ref (m_StopThread), std::ref (m_PcapDescriptor),
678
+ std::move (statsContext));
693
679
694
680
PCPP_LOG_DEBUG (" Successfully created stats thread for device '" << m_InterfaceDetails.name << " '." );
695
681
}
@@ -890,11 +876,10 @@ namespace pcpp
890
876
}
891
877
PCPP_LOG_DEBUG (" Capture thread stopped for device '" << m_InterfaceDetails.name << " '" );
892
878
893
- if (m_StatisticsUpdateWorker != nullptr )
879
+ if (m_StatsThread. joinable () )
894
880
{
895
881
PCPP_LOG_DEBUG (" Stopping stats thread, waiting for it to join..." );
896
- m_StatisticsUpdateWorker->stopWorker ();
897
- m_StatisticsUpdateWorker.reset ();
882
+ m_StatsThread.join ();
898
883
PCPP_LOG_DEBUG (" Stats thread stopped for device '" << m_InterfaceDetails.name << " '" );
899
884
}
900
885
0 commit comments