forked from mia/Aegisub
Fix thread warnings on shutdown on unix
Originally committed to SVN as r4766.
This commit is contained in:
parent
071ada7487
commit
f37e1bf87a
5 changed files with 19 additions and 20 deletions
|
@ -285,6 +285,7 @@ bool AegisubApp::OnInit() {
|
||||||
///
|
///
|
||||||
int AegisubApp::OnExit() {
|
int AegisubApp::OnExit() {
|
||||||
SubtitleFormat::DestroyFormats();
|
SubtitleFormat::DestroyFormats();
|
||||||
|
VideoContext::OnExit();
|
||||||
delete plugins;
|
delete plugins;
|
||||||
delete config::opt;
|
delete config::opt;
|
||||||
delete config::mru;
|
delete config::mru;
|
||||||
|
|
|
@ -150,7 +150,7 @@ void *ThreadedFrameSource::Entry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadedFrameSource::ThreadedFrameSource(wxString videoFileName, wxEvtHandler *parent)
|
ThreadedFrameSource::ThreadedFrameSource(wxString videoFileName, wxEvtHandler *parent)
|
||||||
: wxThread()
|
: wxThread(wxTHREAD_JOINABLE)
|
||||||
, provider(SubtitlesProviderFactory::GetProvider())
|
, provider(SubtitlesProviderFactory::GetProvider())
|
||||||
, videoProvider(VideoProviderFactory::GetProvider(videoFileName))
|
, videoProvider(VideoProviderFactory::GetProvider(videoFileName))
|
||||||
, parent(parent)
|
, parent(parent)
|
||||||
|
@ -162,6 +162,13 @@ ThreadedFrameSource::ThreadedFrameSource(wxString videoFileName, wxEvtHandler *p
|
||||||
Create();
|
Create();
|
||||||
Run();
|
Run();
|
||||||
}
|
}
|
||||||
|
ThreadedFrameSource::~ThreadedFrameSource() {
|
||||||
|
run = false;
|
||||||
|
jobReady.Signal();
|
||||||
|
Wait();
|
||||||
|
frameBuffer[0].Clear();
|
||||||
|
frameBuffer[1].Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ThreadedFrameSource::LoadSubtitles(AssFile *subs) throw() {
|
void ThreadedFrameSource::LoadSubtitles(AssFile *subs) throw() {
|
||||||
AssExporter exporter(subs);
|
AssExporter exporter(subs);
|
||||||
|
@ -185,16 +192,6 @@ AegiVideoFrame const& ThreadedFrameSource::GetFrame(int frame, double time, bool
|
||||||
return ProcFrame(frame, time, raw);
|
return ProcFrame(frame, time, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadedFrameSource::End() {
|
|
||||||
run = false;
|
|
||||||
jobReady.Signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadedFrameSource::~ThreadedFrameSource() {
|
|
||||||
frameBuffer[0].Clear();
|
|
||||||
frameBuffer[1].Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxDEFINE_EVENT(EVT_FRAME_READY, FrameReadyEvent);
|
wxDEFINE_EVENT(EVT_FRAME_READY, FrameReadyEvent);
|
||||||
wxDEFINE_EVENT(EVT_VIDEO_ERROR, VideoProviderErrorEvent);
|
wxDEFINE_EVENT(EVT_VIDEO_ERROR, VideoProviderErrorEvent);
|
||||||
wxDEFINE_EVENT(EVT_SUBTITLES_ERROR, SubtitlesProviderErrorEvent);
|
wxDEFINE_EVENT(EVT_SUBTITLES_ERROR, SubtitlesProviderErrorEvent);
|
||||||
|
|
|
@ -109,13 +109,6 @@ public:
|
||||||
/// @brief raw Get raw frame without subtitles
|
/// @brief raw Get raw frame without subtitles
|
||||||
AegiVideoFrame const& GetFrame(int frame, double time, bool raw = false);
|
AegiVideoFrame const& GetFrame(int frame, double time, bool raw = false);
|
||||||
|
|
||||||
/// @brief Non-blocking Delete
|
|
||||||
///
|
|
||||||
/// Needed due to that calling Delete while the thread is waiting on
|
|
||||||
/// jobReady results in a deadlock; as such this is the only safe way to
|
|
||||||
/// destroy a ThreadedFrameSource
|
|
||||||
void End();
|
|
||||||
|
|
||||||
std::tr1::shared_ptr<VideoProvider> GetVideoProvider() const { return videoProvider; }
|
std::tr1::shared_ptr<VideoProvider> GetVideoProvider() const { return videoProvider; }
|
||||||
|
|
||||||
/// @brief Constructor
|
/// @brief Constructor
|
||||||
|
|
|
@ -172,7 +172,7 @@ void VideoContext::SetVideo(const wxString &filename) {
|
||||||
try {
|
try {
|
||||||
grid->CommitChanges(true);
|
grid->CommitChanges(true);
|
||||||
|
|
||||||
provider.reset(new ThreadedFrameSource(filename, this), std::mem_fun(&ThreadedFrameSource::End));
|
provider.reset(new ThreadedFrameSource(filename, this));
|
||||||
videoProvider = provider->GetVideoProvider();
|
videoProvider = provider->GetVideoProvider();
|
||||||
videoFile = filename;
|
videoFile = filename;
|
||||||
|
|
||||||
|
@ -581,3 +581,10 @@ void VideoContext::OnSubtitlesError(SubtitlesProviderErrorEvent const& err) {
|
||||||
L"Failed rendering subtitles. Error message reported: %s",
|
L"Failed rendering subtitles. Error message reported: %s",
|
||||||
lagi_wxString(err.GetMessage()).c_str());
|
lagi_wxString(err.GetMessage()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoContext::OnExit() {
|
||||||
|
// On unix wxThreadModule will shut down any still-running threads (and
|
||||||
|
// display a warning that it's doing so) before the destructor for
|
||||||
|
// VideoContext runs, so manually kill the thread
|
||||||
|
Get()->provider.reset();
|
||||||
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ private:
|
||||||
std::tr1::shared_ptr<VideoProvider> videoProvider;
|
std::tr1::shared_ptr<VideoProvider> videoProvider;
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
std::tr1::shared_ptr<ThreadedFrameSource> provider;
|
std::auto_ptr<ThreadedFrameSource> provider;
|
||||||
|
|
||||||
/// Filename of currently open video
|
/// Filename of currently open video
|
||||||
wxString videoFile;
|
wxString videoFile;
|
||||||
|
@ -279,6 +279,7 @@ public:
|
||||||
int FrameAtTime(int time, agi::vfr::Time type = agi::vfr::EXACT) const;
|
int FrameAtTime(int time, agi::vfr::Time type = agi::vfr::EXACT) const;
|
||||||
|
|
||||||
static VideoContext *Get();
|
static VideoContext *Get();
|
||||||
|
static void OnExit();
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue