mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
BugFix: correctly wait for Mixer to save file on exit
On the way, also improved Connection Manager ending properly.
This commit is contained in:
@@ -35,16 +35,12 @@
|
||||
#endif
|
||||
|
||||
|
||||
Connection::Connection() : receiver_(nullptr)
|
||||
Connection::Connection() : asking_(false), receiver_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Connection::~Connection()
|
||||
{
|
||||
if (receiver_!=nullptr) {
|
||||
receiver_->Break();
|
||||
delete receiver_;
|
||||
}
|
||||
}
|
||||
|
||||
bool Connection::init()
|
||||
@@ -52,6 +48,7 @@ bool Connection::init()
|
||||
// add default info for myself
|
||||
connections_.push_back(ConnectionInfo());
|
||||
|
||||
if (receiver_ == nullptr) {
|
||||
// try to open a socket at base handshake port
|
||||
int trial = 0;
|
||||
while (trial < MAX_HANDSHAKE) {
|
||||
@@ -79,12 +76,15 @@ bool Connection::init()
|
||||
// try again
|
||||
trial++;
|
||||
}
|
||||
}
|
||||
|
||||
// perfect, we could initialize the receiver
|
||||
if (receiver_!=nullptr) {
|
||||
// listen for answers
|
||||
std::thread(listen).detach();
|
||||
|
||||
// regularly check for available streaming hosts
|
||||
asking_ = true;
|
||||
std::thread(ask).detach();
|
||||
|
||||
// inform the application settings of our id
|
||||
@@ -104,10 +104,31 @@ bool Connection::init()
|
||||
|
||||
void Connection::terminate()
|
||||
{
|
||||
if (receiver_!=nullptr)
|
||||
// end ask loop
|
||||
std::mutex mtx;
|
||||
std::unique_lock<std::mutex> lck(mtx);
|
||||
asking_ = false;
|
||||
if ( ask_end_.wait_for(lck,std::chrono::seconds(2)) == std::cv_status::timeout)
|
||||
g_printerr("Failed to terminate Connection manager (asker).");
|
||||
|
||||
// end receiver
|
||||
if (receiver_!=nullptr) {
|
||||
|
||||
// request termination of receiver
|
||||
receiver_->AsynchronousBreak();
|
||||
|
||||
// restore state of Streamer
|
||||
// wait for the listenner end notification
|
||||
std::mutex mtx;
|
||||
std::unique_lock<std::mutex> lck(mtx);
|
||||
if ( listen_end_.wait_for(lck,std::chrono::seconds(2)) == std::cv_status::timeout)
|
||||
g_printerr("Failed to terminate Connection manager (listener).");
|
||||
|
||||
// delete receiver and ready to initialize
|
||||
delete receiver_;
|
||||
receiver_ = nullptr;
|
||||
}
|
||||
|
||||
// end Streamers
|
||||
Streaming::manager().enable( false );
|
||||
}
|
||||
|
||||
@@ -175,6 +196,8 @@ void Connection::listen()
|
||||
#endif
|
||||
if (Connection::manager().receiver_)
|
||||
Connection::manager().receiver_->Run();
|
||||
|
||||
Connection::manager().listen_end_.notify_all();
|
||||
}
|
||||
|
||||
void Connection::ask()
|
||||
@@ -191,7 +214,7 @@ void Connection::ask()
|
||||
socket.SetEnableBroadcast(true);
|
||||
|
||||
// loop infinitely
|
||||
while(true)
|
||||
while(Connection::manager().asking_)
|
||||
{
|
||||
// broadcast on several ports
|
||||
for(int i=HANDSHAKE_PORT; i<HANDSHAKE_PORT+MAX_HANDSHAKE; i++)
|
||||
@@ -222,6 +245,7 @@ void Connection::ask()
|
||||
}
|
||||
}
|
||||
|
||||
Connection::manager().ask_end_.notify_all();
|
||||
}
|
||||
|
||||
void Connection::RequestListener::ProcessMessage( const osc::ReceivedMessage& m,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "NetworkToolkit.h"
|
||||
|
||||
@@ -86,8 +87,11 @@ protected:
|
||||
private:
|
||||
|
||||
static void ask();
|
||||
std::atomic<bool> asking_;
|
||||
std::condition_variable ask_end_;
|
||||
static void listen();
|
||||
RequestListener listener_;
|
||||
std::condition_variable listen_end_;
|
||||
UdpListeningReceiveSocket *receiver_;
|
||||
|
||||
std::vector< ConnectionInfo > connections_;
|
||||
|
||||
@@ -105,11 +105,11 @@ void Mixer::update()
|
||||
// get the session loaded by this loader
|
||||
merge( sessionImporters_.back().get() );
|
||||
// FIXME: shouldn't we delete the imported session?
|
||||
}
|
||||
// done with this session loader
|
||||
sessionImporters_.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there is a session loader pending
|
||||
if (!sessionLoaders_.empty()) {
|
||||
@@ -119,9 +119,9 @@ void Mixer::update()
|
||||
if (sessionLoaders_.back().valid()) {
|
||||
// get the session loaded by this loader
|
||||
set( sessionLoaders_.back().get() );
|
||||
}
|
||||
// done with this session loader
|
||||
sessionLoaders_.pop_back();
|
||||
}
|
||||
busy_ = false;
|
||||
}
|
||||
}
|
||||
@@ -135,9 +135,9 @@ void Mixer::update()
|
||||
// did we get a filename in return?
|
||||
if (sessionSavers_.back().valid()) {
|
||||
filename = sessionSavers_.back().get();
|
||||
}
|
||||
// done with this session saver
|
||||
sessionSavers_.pop_back();
|
||||
}
|
||||
if (filename.empty())
|
||||
Log::Warning("Failed to save Session.");
|
||||
// all ok
|
||||
|
||||
@@ -118,11 +118,12 @@ bool Streaming::busy()
|
||||
{
|
||||
bool b = false;
|
||||
|
||||
streamers_lock_.lock();
|
||||
if (streamers_lock_.try_lock()) {
|
||||
std::vector<VideoStreamer *>::const_iterator sit = streamers_.begin();
|
||||
for (; sit != streamers_.end() && !b; ++sit)
|
||||
b = (*sit)->busy() ;
|
||||
streamers_lock_.unlock();
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
@@ -132,11 +133,12 @@ std::vector<std::string> Streaming::listStreams()
|
||||
{
|
||||
std::vector<std::string> ls;
|
||||
|
||||
streamers_lock_.lock();
|
||||
if (streamers_lock_.try_lock()) {
|
||||
std::vector<VideoStreamer *>::const_iterator sit = streamers_.begin();
|
||||
for (; sit != streamers_.end(); ++sit)
|
||||
ls.push_back( (*sit)->info() );
|
||||
streamers_lock_.unlock();
|
||||
}
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,6 @@ UserInterface::UserInterface()
|
||||
currentTextEdit.clear();
|
||||
screenshot_step = 0;
|
||||
pending_save_on_exit = false;
|
||||
close_and_exit = false;
|
||||
|
||||
sessionopendialog = nullptr;
|
||||
sessionimportdialog = nullptr;
|
||||
@@ -154,7 +153,6 @@ bool UserInterface::Init()
|
||||
return false;
|
||||
|
||||
pending_save_on_exit = false;
|
||||
close_and_exit = false;
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
@@ -685,28 +683,24 @@ bool UserInterface::TryClose()
|
||||
if (DialogToolkit::FileDialog::busy())
|
||||
return false;
|
||||
|
||||
// force close if trying to close again although it is already pending for save
|
||||
if (pending_save_on_exit) {
|
||||
close_and_exit = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// determine if a pending save of session is required
|
||||
pending_save_on_exit = ( Settings::application.recentSessions.save_on_exit
|
||||
&& !Mixer::manager().session()->empty()
|
||||
&& Mixer::manager().session()->filename().empty() );
|
||||
|
||||
// if no pending save of session is needed, close
|
||||
if (!pending_save_on_exit)
|
||||
{
|
||||
// stop all recordings
|
||||
// always stop all recordings
|
||||
FrameGrabbing::manager().stopAll();
|
||||
|
||||
// save on exit
|
||||
if (Settings::application.recentSessions.save_on_exit)
|
||||
Mixer::manager().save(false);
|
||||
// force close if trying to close again although it is already pending for save
|
||||
if (pending_save_on_exit)
|
||||
return true;
|
||||
|
||||
close_and_exit = true;
|
||||
// save on exit
|
||||
pending_save_on_exit = false;
|
||||
if (Settings::application.recentSessions.save_on_exit && !Mixer::manager().session()->empty())
|
||||
{
|
||||
// determine if a pending save of session is required
|
||||
if (Mixer::manager().session()->filename().empty())
|
||||
// need to wait for user to give a filename
|
||||
pending_save_on_exit = true;
|
||||
else
|
||||
// ok to save the session
|
||||
Mixer::manager().save(false);
|
||||
}
|
||||
|
||||
// say we can close if no pending save of session is needed
|
||||
@@ -784,8 +778,7 @@ void UserInterface::NewFrame()
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (ImGui::Button(MENU_QUIT, ImVec2(ImGui::GetWindowContentRegionWidth(), 0))) {
|
||||
pending_save_on_exit = false;
|
||||
close_and_exit = true;
|
||||
Rendering::manager().close();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
@@ -793,21 +786,6 @@ void UserInterface::NewFrame()
|
||||
}
|
||||
}
|
||||
|
||||
// Asked to close_and_exit
|
||||
if (close_and_exit){
|
||||
if (!ImGui::IsPopupOpen("Closing"))
|
||||
ImGui::OpenPopup("Closing");
|
||||
if (ImGui::BeginPopupModal("Closing", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::Text("Please wait...");
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// exit only after everything is closed
|
||||
if (!FrameGrabbing::manager().busy() && !Mixer::manager().busy()) {
|
||||
Rendering::manager().close();
|
||||
}
|
||||
}
|
||||
|
||||
// navigator bar first
|
||||
navigator.Render();
|
||||
}
|
||||
|
||||
@@ -405,7 +405,6 @@ protected:
|
||||
int target_view_navigator;
|
||||
unsigned int screenshot_step;
|
||||
bool pending_save_on_exit;
|
||||
bool close_and_exit;
|
||||
|
||||
// Dialogs
|
||||
DialogToolkit::OpenSessionDialog *sessionopendialog;
|
||||
|
||||
Reference in New Issue
Block a user