diff --git a/ui/qt/rtp_analysis_dialog.cpp b/ui/qt/rtp_analysis_dialog.cpp index f66dc33d7e..cd1e7b1747 100644 --- a/ui/qt/rtp_analysis_dialog.cpp +++ b/ui/qt/rtp_analysis_dialog.cpp @@ -240,11 +240,12 @@ enum { }; RtpAnalysisDialog *RtpAnalysisDialog::pinstance_{nullptr}; -std::mutex RtpAnalysisDialog::mutex_; +std::mutex RtpAnalysisDialog::init_mutex_; +std::mutex RtpAnalysisDialog::run_mutex_; RtpAnalysisDialog *RtpAnalysisDialog::openRtpAnalysisDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list) { - std::lock_guard lock(mutex_); + std::lock_guard lock(init_mutex_); if (pinstance_ == nullptr) { pinstance_ = new RtpAnalysisDialog(parent, cf); @@ -316,13 +317,15 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf) : RtpAnalysisDialog::~RtpAnalysisDialog() { - std::lock_guard lock(mutex_); - delete ui; - for(int i=0; i lock(init_mutex_); + if (pinstance_ != nullptr) { + delete ui; + for(int i=0; i stream_ids) { - std::lock_guard lock(mutex_); - // Delete existing tabs (from last to first) - if (tabs_.count() > 0) { - for(int i = static_cast(tabs_.count()); i>0; i--) { - closeTab(i-1); + std::unique_lock lock(run_mutex_, std::try_to_lock); + if (lock.owns_lock()) { + // Delete existing tabs (from last to first) + if (tabs_.count() > 0) { + for(int i = static_cast(tabs_.count()); i>0; i--) { + closeTab(i-1); + } } + addRtpStreamsPrivate(stream_ids); + } else { + ws_warning("replaceRtpStreams was called while other thread locked it. Current call is ignored, try it later."); } - addRtpStreamsPrivate(stream_ids); } void RtpAnalysisDialog::addRtpStreams(QVector stream_ids) { - std::lock_guard lock(mutex_); - addRtpStreamsPrivate(stream_ids); + std::unique_lock lock(run_mutex_, std::try_to_lock); + if (lock.owns_lock()) { + addRtpStreamsPrivate(stream_ids); + } else { + ws_warning("addRtpStreams was called while other thread locked it. Current call is ignored, try it later."); + } } void RtpAnalysisDialog::addRtpStreamsPrivate(QVector stream_ids) @@ -1089,20 +1100,24 @@ void RtpAnalysisDialog::addRtpStreamsPrivate(QVector stream_id void RtpAnalysisDialog::removeRtpStreams(QVector stream_ids) { - std::lock_guard lock(mutex_); - setUpdatesEnabled(false); - foreach(rtpstream_id_t *id, stream_ids) { - QList tabs = tab_hash_.values(rtpstream_id_to_hash(id)); - for (int i = 0; i < tabs.size(); i++) { - tab_info_t *tab = tabs.at(i); - if (rtpstream_id_equal(&tab->stream.id, id, RTPSTREAM_ID_EQUAL_SSRC)) { - closeTab(static_cast(tabs_.indexOf(tab))); + std::unique_lock lock(run_mutex_, std::try_to_lock); + if (lock.owns_lock()) { + setUpdatesEnabled(false); + foreach(rtpstream_id_t *id, stream_ids) { + QList tabs = tab_hash_.values(rtpstream_id_to_hash(id)); + for (int i = 0; i < tabs.size(); i++) { + tab_info_t *tab = tabs.at(i); + if (rtpstream_id_equal(&tab->stream.id, id, RTPSTREAM_ID_EQUAL_SSRC)) { + closeTab(static_cast(tabs_.indexOf(tab))); + } } } - } - setUpdatesEnabled(true); + setUpdatesEnabled(true); - updateGraph(); + updateGraph(); + } else { + ws_warning("removeRtpStreams was called while other thread locked it. Current call is ignored, try it later."); + } } tab_info_t *RtpAnalysisDialog::getTabInfoForCurrentTab() diff --git a/ui/qt/rtp_analysis_dialog.h b/ui/qt/rtp_analysis_dialog.h index a6b29876e5..b04b7ba66a 100644 --- a/ui/qt/rtp_analysis_dialog.h +++ b/ui/qt/rtp_analysis_dialog.h @@ -127,7 +127,8 @@ private slots: private: static RtpAnalysisDialog *pinstance_; - static std::mutex mutex_; + static std::mutex init_mutex_; + static std::mutex run_mutex_; Ui::RtpAnalysisDialog *ui; enum StreamDirection { dir_all_, dir_one_ }; diff --git a/ui/qt/rtp_player_dialog.cpp b/ui/qt/rtp_player_dialog.cpp index 7aa37c5157..7b119ff3b9 100644 --- a/ui/qt/rtp_player_dialog.cpp +++ b/ui/qt/rtp_player_dialog.cpp @@ -134,11 +134,12 @@ public: }; RtpPlayerDialog *RtpPlayerDialog::pinstance_{nullptr}; -std::mutex RtpPlayerDialog::mutex_; +std::mutex RtpPlayerDialog::init_mutex_; +std::mutex RtpPlayerDialog::run_mutex_; RtpPlayerDialog *RtpPlayerDialog::openRtpPlayerDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list, bool capture_running) { - std::lock_guard lock(mutex_); + std::lock_guard lock(init_mutex_); if (pinstance_ == nullptr) { pinstance_ = new RtpPlayerDialog(parent, cf, capture_running); @@ -377,16 +378,18 @@ QToolButton *RtpPlayerDialog::addPlayerButton(QDialogButtonBox *button_box, QDia #ifdef QT_MULTIMEDIA_LIB RtpPlayerDialog::~RtpPlayerDialog() { - std::lock_guard lock(mutex_); - cleanupMarkerStream(); - for (int row = 0; row < ui->streamTreeWidget->topLevelItemCount(); row++) { - QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); - RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value(); - if (audio_stream) - delete audio_stream; + std::lock_guard lock(init_mutex_); + if (pinstance_ != nullptr) { + cleanupMarkerStream(); + for (int row = 0; row < ui->streamTreeWidget->topLevelItemCount(); row++) { + QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); + RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value(); + if (audio_stream) + delete audio_stream; + } + delete ui; + pinstance_ = nullptr; } - delete ui; - pinstance_ = nullptr; } void RtpPlayerDialog::accept() @@ -773,75 +776,87 @@ void RtpPlayerDialog::unlockUI() void RtpPlayerDialog::replaceRtpStreams(QVector stream_ids) { - std::lock_guard lock(mutex_); - lockUI(); + std::unique_lock lock(run_mutex_, std::try_to_lock); + if (lock.owns_lock()) { + lockUI(); - // Delete all existing rows - if (last_ti_) { - highlightItem(last_ti_, false); - last_ti_ = NULL; - } + // Delete all existing rows + if (last_ti_) { + highlightItem(last_ti_, false); + last_ti_ = NULL; + } - for (int row = ui->streamTreeWidget->topLevelItemCount() - 1; row >= 0; row--) { - QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); - removeRow(ti); - } + for (int row = ui->streamTreeWidget->topLevelItemCount() - 1; row >= 0; row--) { + QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); + removeRow(ti); + } - // Add all new streams - for (int i=0; i < stream_ids.size(); i++) { - addSingleRtpStream(stream_ids[i]); - } - setMarkers(); + // Add all new streams + for (int i=0; i < stream_ids.size(); i++) { + addSingleRtpStream(stream_ids[i]); + } + setMarkers(); - unlockUI(); + unlockUI(); #ifdef QT_MULTIMEDIA_LIB - QTimer::singleShot(0, this, SLOT(retapPackets())); + QTimer::singleShot(0, this, SLOT(retapPackets())); #endif + } else { + ws_warning("replaceRtpStreams was called while other thread locked it. Current call is ignored, try it later."); + } } void RtpPlayerDialog::addRtpStreams(QVector stream_ids) { - std::lock_guard lock(mutex_); - lockUI(); + std::unique_lock lock(run_mutex_, std::try_to_lock); + if (lock.owns_lock()) { + lockUI(); - int tli_count = ui->streamTreeWidget->topLevelItemCount(); + int tli_count = ui->streamTreeWidget->topLevelItemCount(); - // Add new streams - for (int i=0; i < stream_ids.size(); i++) { - addSingleRtpStream(stream_ids[i]); - } + // Add new streams + for (int i=0; i < stream_ids.size(); i++) { + addSingleRtpStream(stream_ids[i]); + } - if (tli_count == 0) { - setMarkers(); - } + if (tli_count == 0) { + setMarkers(); + } - unlockUI(); + unlockUI(); #ifdef QT_MULTIMEDIA_LIB - QTimer::singleShot(0, this, SLOT(retapPackets())); + QTimer::singleShot(0, this, SLOT(retapPackets())); #endif + } else { + ws_warning("addRtpStreams was called while other thread locked it. Current call is ignored, try it later."); + } } void RtpPlayerDialog::removeRtpStreams(QVector stream_ids) { - std::lock_guard lock(mutex_); - lockUI(); - int tli_count = ui->streamTreeWidget->topLevelItemCount(); + std::unique_lock lock(run_mutex_, std::try_to_lock); + if (lock.owns_lock()) { + lockUI(); + int tli_count = ui->streamTreeWidget->topLevelItemCount(); - for (int i=0; i < stream_ids.size(); i++) { - for (int row = 0; row < tli_count; row++) { - QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); - RtpAudioStream *row_stream = ti->data(stream_data_col_, Qt::UserRole).value(); - if (row_stream->isMatch(stream_ids[i])) { - removeRow(ti); - tli_count--; - break; + for (int i=0; i < stream_ids.size(); i++) { + for (int row = 0; row < tli_count; row++) { + QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); + RtpAudioStream *row_stream = ti->data(stream_data_col_, Qt::UserRole).value(); + if (row_stream->isMatch(stream_ids[i])) { + removeRow(ti); + tli_count--; + break; + } } } - } - updateGraphs(); + updateGraphs(); - updateWidgets(); - unlockUI(); + updateWidgets(); + unlockUI(); + } else { + ws_warning("removeRtpStreams was called while other thread locked it. Current call is ignored, try it later."); + } } void RtpPlayerDialog::setMarkers() diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h index 7faa6e0551..e4632c17c8 100644 --- a/ui/qt/rtp_player_dialog.h +++ b/ui/qt/rtp_player_dialog.h @@ -202,7 +202,8 @@ private slots: #endif private: static RtpPlayerDialog *pinstance_; - static std::mutex mutex_; + static std::mutex init_mutex_; + static std::mutex run_mutex_; #ifdef QT_MULTIMEDIA_LIB Ui::RtpPlayerDialog *ui; diff --git a/ui/qt/voip_calls_dialog.cpp b/ui/qt/voip_calls_dialog.cpp index 9d492e6bab..6d3caae833 100644 --- a/ui/qt/voip_calls_dialog.cpp +++ b/ui/qt/voip_calls_dialog.cpp @@ -44,11 +44,11 @@ enum { voip_calls_type_ = 1000 }; VoipCallsDialog *VoipCallsDialog::pinstance_voip_{nullptr}; VoipCallsDialog *VoipCallsDialog::pinstance_sip_{nullptr}; -std::mutex VoipCallsDialog::mutex_; +std::mutex VoipCallsDialog::init_mutex_; VoipCallsDialog *VoipCallsDialog::openVoipCallsDialogVoip(QWidget &parent, CaptureFile &cf, QObject *packet_list) { - std::lock_guard lock(mutex_); + std::lock_guard lock(init_mutex_); if (pinstance_voip_ == nullptr) { pinstance_voip_ = new VoipCallsDialog(parent, cf, false); @@ -60,7 +60,7 @@ VoipCallsDialog *VoipCallsDialog::openVoipCallsDialogVoip(QWidget &parent, Captu VoipCallsDialog *VoipCallsDialog::openVoipCallsDialogSip(QWidget &parent, CaptureFile &cf, QObject *packet_list) { - std::lock_guard lock(mutex_); + std::lock_guard lock(init_mutex_); if (pinstance_sip_ == nullptr) { pinstance_sip_ = new VoipCallsDialog(parent, cf, true); @@ -195,24 +195,28 @@ bool VoipCallsDialog::eventFilter(QObject *, QEvent *event) VoipCallsDialog::~VoipCallsDialog() { - std::lock_guard lock(mutex_); - delete ui; + std::lock_guard lock(init_mutex_); + if ((all_flows_ && (pinstance_sip_ != nullptr)) + || (!all_flows_ && (pinstance_voip_ != nullptr)) + ) { + delete ui; - voip_calls_reset_all_taps(&tapinfo_); - if (!voip_calls_tap_listeners_removed_) { - voip_calls_remove_all_tap_listeners(&tapinfo_); - voip_calls_tap_listeners_removed_ = true; - } - sequence_info_->unref(); - g_queue_free(tapinfo_.callsinfos); - // We don't need to clear shown_callsinfos_ data, it was shared - // with tapinfo_.callsinfos and was cleared - // during voip_calls_reset_all_taps - g_queue_free(shown_callsinfos_); - if (all_flows_) { - pinstance_sip_ = nullptr; - } else { - pinstance_voip_ = nullptr; + voip_calls_reset_all_taps(&tapinfo_); + if (!voip_calls_tap_listeners_removed_) { + voip_calls_remove_all_tap_listeners(&tapinfo_); + voip_calls_tap_listeners_removed_ = true; + } + sequence_info_->unref(); + g_queue_free(tapinfo_.callsinfos); + // We don't need to clear shown_callsinfos_ data, it was shared + // with tapinfo_.callsinfos and was cleared + // during voip_calls_reset_all_taps + g_queue_free(shown_callsinfos_); + if (all_flows_) { + pinstance_sip_ = nullptr; + } else { + pinstance_voip_ = nullptr; + } } } diff --git a/ui/qt/voip_calls_dialog.h b/ui/qt/voip_calls_dialog.h index e7ca37c418..c3567ba644 100644 --- a/ui/qt/voip_calls_dialog.h +++ b/ui/qt/voip_calls_dialog.h @@ -89,7 +89,7 @@ private: static VoipCallsDialog *pinstance_voip_; static VoipCallsDialog *pinstance_sip_; bool all_flows_; - static std::mutex mutex_; + static std::mutex init_mutex_; Ui::VoipCallsDialog *ui; VoipCallsInfoModel *call_infos_model_;