From 1ef49f39828474ed05fe69aff68d400e3b7d4044 Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Fri, 23 Feb 2001 18:56:56 +0000 Subject: [PATCH] r576: no message --- msvc/ctsim/ctsim.plg | 28 +++---- src/backgroundmgr.cpp | 8 +- src/backgroundmgr.h | 10 +-- src/docs.cpp | 48 ++++++++---- src/docs.h | 16 +++- src/threadrecon.cpp | 170 +++++++++++++++++++++++++----------------- src/threadrecon.h | 91 +++++++++++++++------- src/views.cpp | 4 +- 8 files changed, 234 insertions(+), 141 deletions(-) diff --git a/msvc/ctsim/ctsim.plg b/msvc/ctsim/ctsim.plg index c89a669..e4d6f21 100644 --- a/msvc/ctsim/ctsim.plg +++ b/msvc/ctsim/ctsim.plg @@ -6,15 +6,7 @@ --------------------Configuration: ctsim - Win32 Debug--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP8D.tmp" with contents -[ -/nologo /G6 /MTd /W3 /Gm /Gi /GR /GX /Zi /Od /Gy /I "\wx2.2.5\include" /I "..\..\..\fftw-2.1.3\fftw" /I "\wx2.2.5\src\png" /I "\wx2.2.5\src\zlib" /I "..\..\include" /I "..\..\getopt" /I "..\..\..\fftw-2.1.3\rfftw" /D VERSION=\"3.0.0beta1\" /D "_DEBUG" /D "__WXMSW__" /D "HAVE_SGP" /D "HAVE_PNG" /D "HAVE_WXWINDOWS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "HAVE_STRING_H" /D "HAVE_FFTW" /D "HAVE_RFFTW" /D "HAVE_GETOPT_H" /D "MSVC" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D CTSIMVERSION=\"3.0.4\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c -"C:\ctsim\src\backgroundmgr.cpp" -"C:\ctsim\src\graph3dview.cpp" -"C:\ctsim\src\threadrecon.cpp" -] -Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP8D.tmp" -Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP8E.tmp" with contents +Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP119.tmp" with contents [ /nologo /G6 /MTd /W3 /Gm /Gi /GR /GX /Zi /Od /Gy /I "\wx2.2.5\include" /I "..\..\..\fftw-2.1.3\fftw" /I "\wx2.2.5\src\png" /I "\wx2.2.5\src\zlib" /I "..\..\include" /I "..\..\getopt" /I "..\..\..\fftw-2.1.3\rfftw" /D VERSION=\"3.0.0beta1\" /D "_DEBUG" /D "__WXMSW__" /D "HAVE_SGP" /D "HAVE_PNG" /D "HAVE_WXWINDOWS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "HAVE_STRING_H" /D "HAVE_FFTW" /D "HAVE_RFFTW" /D "HAVE_GETOPT_H" /D "MSVC" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D CTSIMVERSION=\"3.0.4\" /D CTSIMVERSION=\"3.0.0alpha5\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c "C:\ctsim\src\ctsim.cpp" @@ -22,8 +14,14 @@ Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP8E.tmp" with content "C:\ctsim\src\docs.cpp" "C:\ctsim\src\views.cpp" ] -Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP8E.tmp" -Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP8F.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP119.tmp" +Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP11A.tmp" with contents +[ +/nologo /G6 /MTd /W3 /Gm /Gi /GR /GX /Zi /Od /Gy /I "\wx2.2.5\include" /I "..\..\..\fftw-2.1.3\fftw" /I "\wx2.2.5\src\png" /I "\wx2.2.5\src\zlib" /I "..\..\include" /I "..\..\getopt" /I "..\..\..\fftw-2.1.3\rfftw" /D VERSION=\"3.0.0beta1\" /D "_DEBUG" /D "__WXMSW__" /D "HAVE_SGP" /D "HAVE_PNG" /D "HAVE_WXWINDOWS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "HAVE_STRING_H" /D "HAVE_FFTW" /D "HAVE_RFFTW" /D "HAVE_GETOPT_H" /D "MSVC" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D CTSIMVERSION=\"3.0.4\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c +"C:\ctsim\src\threadrecon.cpp" +] +Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP11A.tmp" +Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP11B.tmp" with contents [ winmm.lib rpcrt4.lib ws2_32.lib ../libctsim/Debug/libctsim.lib libcmtd.lib ..\..\..\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib ..\..\..\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib wxd.lib xpmd.lib tiffd.lib zlibd.lib pngd.lib comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib htmlhelp.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"\wx2.2.5\lib" .\Debug\backgroundmgr.obj @@ -47,17 +45,15 @@ winmm.lib rpcrt4.lib ws2_32.lib ../libctsim/Debug/libctsim.lib libcmtd.lib ..\.. \wx2.2.5\lib\zlibd.lib \wx2.2.5\lib\tiffd.lib ] -Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP8F.tmp" +Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP11B.tmp"

Output Window

Compiling... -threadrecon.cpp -backgroundmgr.cpp -graph3dview.cpp -Compiling... ctsim.cpp dialogs.cpp docs.cpp views.cpp +Compiling... +threadrecon.cpp Linking... diff --git a/src/backgroundmgr.cpp b/src/backgroundmgr.cpp index e915624..c835b7b 100644 --- a/src/backgroundmgr.cpp +++ b/src/backgroundmgr.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: backgroundmgr.cpp,v 1.3 2001/02/23 02:06:02 kevin Exp $ +** $Id: backgroundmgr.cpp,v 1.4 2001/02/23 18:56:56 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -76,7 +76,7 @@ BackgroundManager::OnCloseWindow (wxCloseEvent& event) wxGauge* -BackgroundManager::addTask (BackgroundTask* pTask, int iNumUnits, const char* const pszTaskName) +BackgroundManager::addTask (BackgroundSupervisor* pTask, int iNumUnits, const char* const pszTaskName) { wxCriticalSectionLocker locker (m_criticalSection); int iNumTasks = m_vecpBackgroundTasks.size(); @@ -117,7 +117,7 @@ BackgroundManager::addTask (BackgroundTask* pTask, int iNumUnits, const char* co void -BackgroundManager::taskDone (BackgroundTask* pTask) +BackgroundManager::taskDone (BackgroundSupervisor* pTask) { wxCriticalSectionLocker locker (m_criticalSection); @@ -166,7 +166,7 @@ BackgroundManager::resizeWindow() bool -BackgroundManager::isCancelling (BackgroundTask* pTask) +BackgroundManager::isCancelling (BackgroundSupervisor* pTask) { return false; } diff --git a/src/backgroundmgr.h b/src/backgroundmgr.h index d3f49a1..90bbf14 100644 --- a/src/backgroundmgr.h +++ b/src/backgroundmgr.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: backgroundmgr.h,v 1.3 2001/02/23 02:06:02 kevin Exp $ +** $Id: backgroundmgr.h,v 1.4 2001/02/23 18:56:56 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -63,7 +63,7 @@ private: BackgroundManagerCanvas* m_pCanvas; int m_iNumTasks; - typedef std::vector TaskContainer; + typedef std::vector TaskContainer; typedef std::vector GaugeContainer; typedef std::vector StringContainer; typedef std::vector PositionContainer; @@ -83,9 +83,9 @@ private: public: BackgroundManager (); - wxGauge* addTask (BackgroundTask* pTask, int iNumUnits, const char* const pszTaskName); - void taskDone (BackgroundTask* pTask); - bool isCancelling (BackgroundTask* pTask); + wxGauge* addTask (BackgroundSupervisor* pTask, int iNumUnits, const char* const pszTaskName); + void taskDone (BackgroundSupervisor* pTask); + bool isCancelling (BackgroundSupervisor* pTask); TaskContainer& getTasks() { return m_vecpBackgroundTasks;} GaugeContainer& getGauges() { return m_vecpGauges;} diff --git a/src/docs.cpp b/src/docs.cpp index 460082a..b356033 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: docs.cpp,v 1.25 2001/02/22 11:05:38 kevin Exp $ +** $Id: docs.cpp,v 1.26 2001/02/23 18:56:56 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -129,6 +129,10 @@ ImageFileDocument::Revert () // ProjectionFileDocument IMPLEMENT_DYNAMIC_CLASS(ProjectionFileDocument, wxDocument) +BEGIN_EVENT_TABLE(ProjectionFileDocument, wxDocument) +EVT_MENU(BackgroundSupervisor::MSG_BACKGROUND_SUPERVISOR_ADD, ProjectionFileDocument::OnAddBackground) +EVT_MENU(BackgroundSupervisor::MSG_BACKGROUND_SUPERVISOR_REMOVE, ProjectionFileDocument::OnRemoveBackground) +END_EVENT_TABLE() bool ProjectionFileDocument::OnSaveDocument(const wxString& filename) @@ -145,31 +149,47 @@ ProjectionFileDocument::OnSaveDocument(const wxString& filename) ProjectionFileDocument::~ProjectionFileDocument() { - for (int i = 0; i < m_vecpActiveReconstructors.size(); i++) { - ThreadedReconstructor* pThreadedReconstructor = m_vecpActiveReconstructors[i]; - if (pThreadedReconstructor) { - pThreadedReconstructor->cancel(); + for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin(); + i != m_vecpBackgroundSupervisors.end(); i++) { + (*i)->cancel(); } - } + + m_vecpBackgroundSupervisors.clear(); + delete m_pProjectionFile; +} + +void +ProjectionFileDocument::OnAddBackground (wxCommandEvent& event) +{ +} - delete m_pProjectionFile; +void +ProjectionFileDocument::OnRemoveBackground (wxCommandEvent& event) +{ } void -ProjectionFileDocument::addReconstructor (ThreadedReconstructor* pRecon) +ProjectionFileDocument::addReconstructor (BackgroundSupervisor* pRecon) { wxCriticalSectionLocker locker (m_criticalSection); - m_vecpActiveReconstructors.push_back (pRecon); + m_vecpBackgroundSupervisors.push_back (pRecon); } void -ProjectionFileDocument::removeReconstructor (ThreadedReconstructor* pRecon) +ProjectionFileDocument::removeReconstructor (BackgroundSupervisor* pRecon) { wxCriticalSectionLocker locker (m_criticalSection); - for (int i = 0; i < m_vecpActiveReconstructors.size(); i++) { - if (m_vecpActiveReconstructors[i] == pRecon) - m_vecpActiveReconstructors[i] = NULL; - } + bool bFound = false; + for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin(); + i != m_vecpBackgroundSupervisors.end(); + i++) + if (*i == pRecon) { + m_vecpBackgroundSupervisors.erase(i); + bFound = true; + break; + } + if (! bFound) + sys_error (ERR_SEVERE, "Could not find background task [ProjectionFileDocument::removeBackgroundTask"); } bool diff --git a/src/docs.h b/src/docs.h index 88e362e..71ce6e3 100644 --- a/src/docs.h +++ b/src/docs.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: docs.h,v 1.22 2001/02/22 11:05:38 kevin Exp $ +** $Id: docs.h,v 1.23 2001/02/23 18:56:56 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -93,7 +93,9 @@ private: DECLARE_DYNAMIC_CLASS(ProjectionFileDocument) Projections* m_pProjectionFile; bool m_bBadFileOpen; - std::vector m_vecpActiveReconstructors; + typedef BackgroundSupervisor BackgroundObject; + typedef std::vector BackgroundContainer ; + BackgroundContainer m_vecpBackgroundSupervisors; wxCriticalSection m_criticalSection; public: @@ -121,8 +123,14 @@ public: ProjectionFileView* getView() const; bool getBadFileOpen() const { return m_bBadFileOpen; } void setBadFileOpen() { m_bBadFileOpen = true; } - void addReconstructor (ThreadedReconstructor* pRecon); - void removeReconstructor (ThreadedReconstructor* pRecon); + + void OnAddBackground (wxCommandEvent& event); + void OnRemoveBackground (wxCommandEvent& event); + + void addReconstructor (BackgroundSupervisor* pRecon); + void removeReconstructor (BackgroundSupervisor* pRecon); + + DECLARE_EVENT_TABLE() }; diff --git a/src/threadrecon.cpp b/src/threadrecon.cpp index 159e9d4..03d4d39 100644 --- a/src/threadrecon.cpp +++ b/src/threadrecon.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: threadrecon.cpp,v 1.5 2001/02/23 03:28:26 kevin Exp $ +** $Id: threadrecon.cpp,v 1.6 2001/02/23 18:56:56 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -43,25 +43,22 @@ #endif -IMPLEMENT_DYNAMIC_CLASS(ThreadedReconstructor, BackgroundTask) -BEGIN_EVENT_TABLE(ThreadedReconstructor, BackgroundTask) -EVT_MENU(RECONSTRUCTION_THREAD_EVENT, ThreadedReconstructor::OnThreadEvent) +IMPLEMENT_DYNAMIC_CLASS(ReconstructorSupervisor, BackgroundSupervisor) +BEGIN_EVENT_TABLE(ReconstructorSupervisor, BackgroundSupervisor) +EVT_MENU(RECONSTRUCTION_THREAD_EVENT, ReconstructorSupervisor::OnThreadEvent) +EVT_MENU(MSG_WORKER_THREAD_FAIL, ReconstructorSupervisor::OnWorkerFail) +EVT_MENU(MSG_WORKER_THREAD_DONE, ReconstructorSupervisor::OnWorkerDone) +EVT_MENU(MSG_WORKER_THREAD_UNIT_TICK, ReconstructorSupervisor::OnWorkerUnitTick) END_EVENT_TABLE() -enum { - RTHREAD_UNIT_COMPLETE = -1, - RTHREAD_THREAD_DONE = -2, - RTHREAD_THREAD_CANCELLED = -3, -}; - -ThreadedReconstructor::ThreadedReconstructor (ProjectionFileView* pProjView, +ReconstructorSupervisor::ReconstructorSupervisor (ProjectionFileView* pProjView, int iImageNX, int iImageNY, const char* pszFilterName, double dFilterParam, const char* pszFilterMethod, int iZeropad, const char* pszFilterGenerationName, const char* pszInterpName, int iInterpParam, const char* pszBackprojectName, const char* const pszLabel) : m_pProjView(pProjView), m_pDialogProgress(NULL), m_pGauge(NULL), m_bFail(false), m_iNumThreads(0), m_iImageNX(iImageNX), m_iImageNY(iImageNY), m_strLabel(pszLabel), m_pTimer(NULL), m_bCancelled(false), m_bCancelling(false), - BackgroundTask() + BackgroundSupervisor() { m_iNumThreads = theApp->getNumberCPU(); // ++m_iNumThreads; @@ -79,7 +76,7 @@ ThreadedReconstructor::ThreadedReconstructor (ProjectionFileView* pProjView, int iNumViews = iBaseViews; if (iProc < iExtraViews) ++iNumViews; - m_vecpThread[iProc] = new ReconstructionThread (this, pProjView, m_vecpChildImageFile[iProc], iProc, iStartView, iNumViews, + m_vecpThread[iProc] = new ReconstructorWorker (this, pProjView, m_vecpChildImageFile[iProc], iProc, iStartView, iNumViews, pszFilterName, dFilterParam, pszFilterMethod, iZeropad, pszFilterGenerationName, pszInterpName, iInterpParam, pszBackprojectName); if (m_vecpThread[iProc]->Create () != wxTHREAD_NO_ERROR) { m_bFail = true; @@ -91,7 +88,7 @@ ThreadedReconstructor::ThreadedReconstructor (ProjectionFileView* pProjView, bool -ThreadedReconstructor::start() +ReconstructorSupervisor::start() { if (m_bFail) return false; @@ -120,7 +117,7 @@ ThreadedReconstructor::start() } void -ThreadedReconstructor::cancel() +ReconstructorSupervisor::cancel() { if (isDone() || m_bCancelled) return; @@ -130,18 +127,20 @@ ThreadedReconstructor::cancel() } void -ThreadedReconstructor::cleanUp() +ReconstructorSupervisor::cleanUp() { wxCriticalSection cleanSection; cleanSection.Enter(); + m_critsectThreadContainer.Enter(); for (int i = 0; i < m_iNumThreads; i++) if (m_vecpThread[i] && m_vecpThread[i]->IsRunning()) { m_vecpThread[i]->Pause(); m_vecpThread[i]->Delete(); } + m_critsectThreadContainer.Leave(); - for (i = 0; i < m_iNumThreads; i++) { + for (i = 0; i < m_iNumThreads; i++) { delete m_vecpChildImageFile[i]; m_vecpChildImageFile[i] = NULL; } @@ -160,7 +159,7 @@ ThreadedReconstructor::cleanUp() } void -ThreadedReconstructor::onDone() +ReconstructorSupervisor::onDone() { wxCriticalSection doneSection; doneSection.Enter(); @@ -191,21 +190,9 @@ ThreadedReconstructor::onDone() cleanUp(); } - void -ThreadedReconstructor::OnThreadEvent (wxCommandEvent& event) +ReconstructorSupervisor::OnWorkerUnitTick (wxCommandEvent& event) { - if (isDone()) - return; - wxCriticalSection eventSection; - eventSection.Enter(); - if (isDone()) { - eventSection.Leave(); - return; - } - - int iEventId = event.GetInt(); - if (iEventId == RTHREAD_UNIT_COMPLETE) { ++m_iViewsDone; #ifdef DEBUG @@ -217,33 +204,66 @@ ThreadedReconstructor::OnThreadEvent (wxCommandEvent& event) m_bCancelling = ! m_pDialogProgress->Update (m_iViewsDone - 1); else if (m_pGauge) { m_pGauge->SetValue (m_iViewsDone - 1); - eventSection.Leave(); m_bCancelling = theApp->getBackgroundManager()->isCancelling(this); } if (! isDone() && m_bCancelling) { - eventSection.Leave(); cancel(); return; } - } - else if (event.GetInt() >= 0) { - m_iRunning--; - m_vecpThread[event.GetInt()] = NULL; - *theApp->getLog() << "Thread finished. Remaining threads: " << m_iRunning << "\n"; - if (m_iRunning <= 0) { - eventSection.Leave(); - onDone(); - return; - } +} + +void +ReconstructorSupervisor::OnWorkerDone (wxCommandEvent& event) +{ + if (isDone()) + return; + + m_iRunning--; + m_critsectThreadContainer.Enter(); + m_vecpThread[event.GetInt()] = NULL; + m_critsectThreadContainer.Leave(); + wxString msg; + msg.Printf("Reconstructor Supervisor: Thread finished. Remaining threads: %d\n", m_iRunning); + wxCommandEvent eventLog (wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT ); + eventLog.SetString( msg ); + wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event + + if (m_iRunning <= 0) { + onDone(); + return; } - else - *theApp->getLog() << "Got event #" << iEventId << "\n"; - - eventSection.Leave(); +} + +void +ReconstructorSupervisor::OnWorkerFail (wxCommandEvent& event) +{ + if (isDone()) + return; + + m_iRunning--; + m_critsectThreadContainer.Enter(); + m_vecpThread[event.GetInt()] = NULL; + m_critsectThreadContainer.Leave(); + wxCommandEvent eventLog( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT ); + eventLog.SetString( event.GetString() ); + wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event + + onDone(); +} + + +void +ReconstructorSupervisor::OnThreadEvent (wxCommandEvent& event) +{ + wxString msg; + msg.Printf("Reconstructor Supervisor: Received event #%d\n", event.GetInt()); + wxCommandEvent eventLog( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT ); + eventLog.SetString( msg ); + wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event } ImageFile* -ThreadedReconstructor::getImageFile() +ReconstructorSupervisor::getImageFile() { ImageFile* pImageFile = new ImageFile (m_iImageNX, m_iImageNY); pImageFile->arrayDataClear(); @@ -261,59 +281,73 @@ ThreadedReconstructor::getImageFile() } bool -ThreadedReconstructor::testDone() +ReconstructorSupervisor::testDone() { return (m_iRunning <= 0 ? true : false); } -ThreadedReconstructor::~ThreadedReconstructor() +ReconstructorSupervisor::~ReconstructorSupervisor() { } -ReconstructionThread::ReconstructionThread -(ThreadedReconstructor* pSupervisor, ProjectionFileView* pProjView, ImageFile* pImageFile, int iThread, int iStartView, int iNumViews, +ReconstructorWorker::ReconstructorWorker +(ReconstructorSupervisor* pSupervisor, ProjectionFileView* pProjView, ImageFile* pImageFile, int iThread, int iStartView, int iNumViews, const char* pszFilterName, double dFilterParam, const char* pszFilterMethod, int iZeropad, const char* pszFilterGenerationName, const char* pszInterpName, int iInterpParam, const char* pszBackprojectName) - : m_pSupervisor(pSupervisor), - m_iStartView(iStartView), m_iNumViews(iNumViews), m_iThread(iThread), - wxThread(wxTHREAD_DETACHED) + : m_pSupervisor(pSupervisor), m_iStartView(iStartView), m_iNumViews(iNumViews), m_iThread(iThread), + m_pProjView(pProjView), m_pImageFile(pImageFile), m_strFilterName(pszFilterName), m_dFilterParam(dFilterParam), m_strFilterMethod(pszFilterMethod), + m_iZeropad(iZeropad), m_strFilterGenerationName(pszFilterGenerationName), m_strInterpName(pszInterpName), + m_iInterpParam(iInterpParam), m_strBackprojectName(pszBackprojectName), + wxThread(wxTHREAD_DETACHED) { - m_pReconstructor = new Reconstructor (pProjView->GetDocument()->getProjections(), - *pImageFile, pszFilterName, dFilterParam, pszFilterMethod, iZeropad, pszFilterGenerationName, - pszInterpName, iInterpParam, pszBackprojectName, Trace::TRACE_NONE); } wxThread::ExitCode -ReconstructionThread::Entry () +ReconstructorWorker::Entry () { - wxCommandEvent eventProgress (wxEVT_COMMAND_MENU_SELECTED, RECONSTRUCTION_THREAD_EVENT); + Reconstructor* pReconstructor = new Reconstructor (m_pProjView->GetDocument()->getProjections(), + *m_pImageFile, m_strFilterName.c_str(), m_dFilterParam, m_strFilterMethod.c_str(), m_iZeropad, + m_strFilterGenerationName.c_str(), m_strInterpName.c_str(), m_iInterpParam, m_strBackprojectName.c_str(), Trace::TRACE_NONE); + if (pReconstructor->fail()) { + wxString msg; + msg.Printf("Unable to make reconstructor: %s", pReconstructor->failMessage()); + wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_FAIL ); + event.SetString( msg ); + wxPostEvent( theApp->getMainFrame(), event ); // send in a thread-safe way + return reinterpret_cast(-1); + } + + wxCommandEvent eventProgress (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_UNIT_TICK); for (int iView = 0; iView < m_iNumViews; iView++) { if (TestDestroy()) { +#ifdef DEBUG wxString msg; - msg.Printf("TestDestroy TRUE at view #%d\n", iView); + msg.Printf("Received destroy message view #%d\n", iView); wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT ); event.SetString( msg ); wxPostEvent( theApp->getMainFrame(), event ); // send in a thread-safe way - return reinterpret_cast(RTHREAD_THREAD_CANCELLED); +#endif + delete pReconstructor; + return reinterpret_cast(-1); } - m_pReconstructor->reconstructView (iView + m_iStartView, 1); - eventProgress.SetInt (RTHREAD_UNIT_COMPLETE); + pReconstructor->reconstructView (iView + m_iStartView, 1); wxPostEvent (m_pSupervisor, eventProgress); } - m_pReconstructor->postProcessing(); + pReconstructor->postProcessing(); + wxCommandEvent eventDone (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_DONE); eventProgress.SetInt (m_iThread); // Send back thread# that has finished - wxPostEvent (m_pSupervisor, eventProgress); + wxPostEvent (m_pSupervisor, eventDone); + delete pReconstructor; return reinterpret_cast(0); } void -ReconstructionThread::OnExit () +ReconstructorWorker::OnExit () { - delete m_pReconstructor; } diff --git a/src/threadrecon.h b/src/threadrecon.h index 0daa621..9c1e5e2 100644 --- a/src/threadrecon.h +++ b/src/threadrecon.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: threadrecon.h,v 1.5 2001/02/23 03:28:26 kevin Exp $ +** $Id: threadrecon.h,v 1.6 2001/02/23 18:56:56 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -33,39 +33,60 @@ #include #include "timer.h" -// This thread creates a BackgroundTask event handler object -// The thread is detached and terminates when BackgroundTask terminates -class BackgroundTaskThread : public wxThread { +// This thread creates a SupervisorTask event handler object +// The thread is detached and terminates when SupervisorTask terminates +class SupervisorTaskThread : public wxThread { private: public: - BackgroundTaskThread(); + SupervisorTaskThread(); - virtual wxThread::ExitCode Entry(); + virtual wxThread::ExitCode Entry() = 0; // called when the thread exits - whether it terminates normally or is stopped with Delete() virtual void OnExit(); }; -// Pure virtual class for BackgroundTasks that can communication -// with BackgroundManager +class ReconstructorSupervisorThread : public SupervisorTaskThread { +private: +public: +}; -class BackgroundTask : public wxEvtHandler { + +// Pure virtual class for BackgroundSupervisor that can communication +// with BackgroundManager via messages + +class BackgroundSupervisor : public wxEvtHandler { private: bool m_bDone; public: - BackgroundTask() + + enum { + MSG_BACKGROUND_SUPERVISOR_ADD = 7500, // sends to BackgroundManager and Document + MSG_BACKGROUND_SUPERVISOR_REMOVE = 7501, // sends to BackgroundManager and Document + MSG_BACKGROUND_SUPERVISOR_UNIT_TICK = 7502, // sends to BackgroundManager for progress bars + MSG_BACKGROUND_SUPERVISOR_CANCEL = 7503, // *sent* to Supervisor to cancel process + + MSG_WORKER_THREAD_UNIT_TICK = 7504, + MSG_WORKER_THREAD_DONE = 7505, + MSG_WORKER_THREAD_FAIL = 7506, // sent by workers when they fail + }; + + BackgroundSupervisor() : m_bDone(false), wxEvtHandler() {} - virtual ~BackgroundTask() + virtual ~BackgroundSupervisor() {} virtual void cancel() = 0; virtual bool start() = 0; virtual bool testDone() = 0; + virtual void OnWorkerFail(wxCommandEvent& event) = 0; + virtual void OnWorkerUnitTick(wxCommandEvent& event) = 0; + virtual void OnWorkerDone(wxCommandEvent& event) = 0; bool isDone() const {return m_bDone;} void setDone() { m_bDone = true; } @@ -74,20 +95,22 @@ public: class Reconstructor; class ImageFile; class ProjectionFileDocument; -class ReconstructionThread; +class ReconstructorWorker; class ProjectionFileView; -class ThreadedReconstructor : public BackgroundTask { +class ReconstructorSupervisor : public BackgroundSupervisor { private: - DECLARE_DYNAMIC_CLASS(ThreadedReconstructor) + DECLARE_DYNAMIC_CLASS(ReconstructorSupervisor) + wxCriticalSection m_critsectThreadContainer; std::vector m_vecpChildImageFile; - std::vector m_vecpThread; + typedef std::vector ThreadContainer; + ThreadContainer m_vecpThread; ProjectionFileView* m_pProjView; wxProgressDialog* m_pDialogProgress; wxGauge* m_pGauge; - + volatile bool m_bFail; int m_iNumThreads; const int m_iImageNX; @@ -95,23 +118,23 @@ private: volatile int m_iRunning; volatile unsigned int m_iViewsDone; volatile unsigned int m_iTotalViews; - //wxCriticalSection m_criticalSection; wxString m_strLabel; Timer* m_pTimer; bool m_bCancelled; bool m_bCancelling; public: - ThreadedReconstructor (ProjectionFileView* pProjView, + ReconstructorSupervisor (ProjectionFileView* pProjView, int iNX, int iNY, const char* pszFilterName, double dFilterParam, const char* pszFilterMethod, int iZeropad, const char* pszFilterGenerationName, const char* pszInterpName, int iInterpParam, const char* pszBackprojectName, const char* const pszLabel); - ThreadedReconstructor () - : m_bFail(true), m_iNumThreads(0), m_iImageNX(0), m_iImageNY(0), m_iTotalViews(0), BackgroundTask() + ReconstructorSupervisor () + : m_bFail(true), m_iNumThreads(0), m_iImageNX(0), m_iImageNY(0), m_iTotalViews(0), + BackgroundSupervisor() {} - ~ThreadedReconstructor (); + ~ReconstructorSupervisor (); void OnThreadEvent (wxCommandEvent& event); void cancel(); @@ -121,6 +144,9 @@ public: bool fail() const {return m_bFail;} bool testDone(); void cleanUp(); + virtual void OnWorkerFail(wxCommandEvent& event); + virtual void OnWorkerUnitTick(wxCommandEvent& event); + virtual void OnWorkerDone(wxCommandEvent& event); ImageFile* getImageFile(); @@ -129,20 +155,29 @@ public: -class ReconstructionThread : public wxThread { +class ReconstructorWorker : public wxThread { private: - ThreadedReconstructor* m_pSupervisor; - Reconstructor* m_pReconstructor; + ReconstructorSupervisor* m_pSupervisor; int m_iStartView; int m_iNumViews; int m_iThread; + ProjectionFileView* m_pProjView; + ImageFile* m_pImageFile; + const std::string m_strFilterName; + const double m_dFilterParam; + const std::string m_strFilterMethod; + const int m_iZeropad; + const std::string m_strFilterGenerationName; + const std::string m_strInterpName; + const int m_iInterpParam; + const std::string m_strBackprojectName; public: - ReconstructionThread (ThreadedReconstructor* pSupervisor, + ReconstructorWorker (ReconstructorSupervisor* pSupervisor, ProjectionFileView* pProjFile, ImageFile* pImageFile, int iThread, int iStartView, int iNumViews, - const char* pszFilterName, double dFilterParam, const char* pszFilterMethod, - int iZeropad, const char* pszFilterGenerationName, const char* pszInterpName, int iInterpParam, + const char* const pszFilterName, double dFilterParam, const char* const pszFilterMethod, + int iZeropad, const char* const pszFilterGenerationName, const char* const pszInterpName, int iInterpParam, const char* pszBackprojectName); virtual wxThread::ExitCode Entry(); // thread execution starts here @@ -153,4 +188,4 @@ public: #endif - \ No newline at end of file + diff --git a/src/views.cpp b/src/views.cpp index d8c0984..888b9b4 100644 --- a/src/views.cpp +++ b/src/views.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: views.cpp,v 1.114 2001/02/23 02:06:02 kevin Exp $ +** $Id: views.cpp,v 1.115 2001/02/23 18:56:56 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -2434,7 +2434,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event) } else { if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) { - ThreadedReconstructor* pReconstructor = new ThreadedReconstructor (this, + ReconstructorSupervisor* pReconstructor = new ReconstructorSupervisor (this, m_iDefaultNX, m_iDefaultNY, optFilterName.c_str(), m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), os.str().c_str()); -- 2.34.1