X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=src%2Fbackgroundsupr.cpp;h=c4720770bdc310051a4cd6da8fa4e212881d5d2a;hp=a647c44b9382bb88510ccd26ddf9f638ee0d8cb6;hb=f7ee98f7d964ed361068179f0e7ea4475ed1abdf;hpb=f1e69bf8888b1462007c93c8d6bf3ae1e0ecec20 diff --git a/src/backgroundsupr.cpp b/src/backgroundsupr.cpp index a647c44..c472077 100644 --- a/src/backgroundsupr.cpp +++ b/src/backgroundsupr.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: backgroundsupr.cpp,v 1.8 2001/02/26 17:36:56 kevin Exp $ +** $Id$ ** ** 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 @@ -31,6 +31,9 @@ #include "wx/wx.h" #endif +// pragma line required for Fedora 4 and wxWin 2.4.2 +#pragma implementation "timer.h" + #include "ct.h" #include "ctsim.h" #include "docs.h" @@ -38,10 +41,9 @@ #include "backgroundsupr.h" #include "backgroundmgr.h" -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif +#ifdef HAVE_WXTHREADS +#define USE_BKGMGR 1 //////////////////////////////////////////////////////////////////////////// // @@ -51,32 +53,19 @@ IMPLEMENT_DYNAMIC_CLASS(BackgroundSupervisor, wxEvtHandler) BEGIN_EVENT_TABLE(BackgroundSupervisor, BackgroundSupervisor) -EVT_MENU(MSG_BACKGROUND_SUPERVISOR_CANCEL, BackgroundSupervisor::OnCancel) -EVT_MENU(MSG_WORKER_THREAD_FAIL, BackgroundSupervisor::OnWorkerFail) -EVT_MENU(MSG_WORKER_THREAD_DONE, BackgroundSupervisor::OnWorkerDone) -EVT_MENU(MSG_WORKER_THREAD_UNIT_TICK, BackgroundSupervisor::OnWorkerUnitTick) -EVT_MENU(MSG_DOCUMENT_ACK_REMOVE, BackgroundSupervisor::OnAckDocumentRemove) END_EVENT_TABLE() -// Static function -void -BackgroundSupervisor::cancelSupervisor (BackgroundSupervisor* pSupervisor) -{ - wxCommandEvent cancelEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_CANCEL); - wxPostEvent (pSupervisor, cancelEvent); -} -BackgroundSupervisor::BackgroundSupervisor (SupervisorThread* pMyThread, wxFrame* pParentFrame, wxDocument* pDocument, const char* const pszProcessTitle, int iTotalUnits) - : m_pMyThread(pMyThread), m_pParentFrame(pParentFrame), m_pDocument(pDocument), m_pDialogProgress(NULL), m_strProcessTitle(pszProcessTitle), - m_iTotalUnits(iTotalUnits), m_iNumThreads(0), m_bDone(false), m_bFail(false), m_bCancelled(false), - m_pTimer(NULL), m_bBackgroundTaskAdded(false), m_bWorkersDeleted(false), - wxEvtHandler() +BackgroundSupervisor::BackgroundSupervisor (SupervisorThread* pMyThread, wxWindow* pParentFrame, BackgroundProcessingDocument* pDocument, wxChar const* pszProcessTitle, int iTotalUnits) + : wxEvtHandler(), m_pMyThread(pMyThread), m_pParentFrame(pParentFrame), m_pDocument(pDocument), m_strProcessTitle(pszProcessTitle), + m_iTotalUnits(iTotalUnits), m_iNumThreads(0), m_bDone(false), m_bFail(false), m_bCancelled(false), m_iRunning(0), + m_pTimer(NULL), m_bWorkersDeleted(false), m_bBackgroundManagerAdded(false) { m_iNumThreads = theApp->getNumberCPU(); -// ++m_iNumThreads; + // ++m_iNumThreads; - m_vecpThreads.reserve (m_iNumThreads); + m_vecpThreads.resize (m_iNumThreads); for (int iThread = 0; iThread < m_iNumThreads; iThread++) m_vecpThreads[iThread] = NULL; @@ -84,20 +73,9 @@ BackgroundSupervisor::BackgroundSupervisor (SupervisorThread* pMyThread, wxFrame BackgroundSupervisor::~BackgroundSupervisor() { - if (m_bBackgroundTaskAdded) { - wxCommandEvent doneEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_REMOVE); - doneEvent.SetClientData (this); - wxPostEvent (theApp->getBackgroundManager(), doneEvent); - wxPostEvent (m_pDocument, doneEvent); - } - - while (m_bBackgroundTaskAdded) { - m_pMyThread->Sleep(50); - ProcessPendingEvents(); - } + m_pDocument->removeBackgroundSupervisor (this); delete m_pTimer; - delete m_pDialogProgress; } void @@ -107,139 +85,132 @@ BackgroundSupervisor::deleteWorkers() if (m_bWorkersDeleted) return; - for (int i = 0; i < m_iNumThreads; i++) - if (m_vecpThreads[i]) { - m_vecpThreads[i]->Delete(); // sends Destroy message to workers - } + for (int i = 0; i < m_iNumThreads; i++) + if (m_vecpThreads[i]) + m_vecpThreads[i]->Delete(); // send Destroy message to workers - while (m_iRunning > 0) { +#ifdef USE_BKGMGR + wxCommandEvent doneEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_REMOVE); + doneEvent.SetClientData (this); + wxPostEvent (theApp->getBackgroundManager(), doneEvent); +#endif + + while (m_iRunning > 0 || m_bBackgroundManagerAdded) m_pMyThread->Sleep(50); - ProcessPendingEvents(); - } - m_iRunning = 0; + m_bWorkersDeleted = true; } +void +BackgroundSupervisor::ackRemoveBackgroundManager() +{ + m_bBackgroundManagerAdded = false; +} + bool BackgroundSupervisor::start() { int iBaseUnits = m_iTotalUnits / m_iNumThreads; int iExtraUnits = m_iTotalUnits % m_iNumThreads; + int iStartUnit = 0; for (int iThread = 0; iThread < m_iNumThreads; iThread++) { - int iStartUnit = iThread * iBaseUnits; int iNumUnits = iBaseUnits; if (iThread < iExtraUnits) ++iNumUnits; m_vecpThreads[iThread] = createWorker (iThread, iStartUnit, iNumUnits); if (! m_vecpThreads[iThread]) { m_bFail = true; - m_strFailMessage = "createWorker returned NULL [BackgroundSupervisor]"; + m_strFailMessage = _T("createWorker returned NULL [BackgroundSupervisor]"); break; } if (m_vecpThreads[iThread]->Create () != wxTHREAD_NO_ERROR) { m_bFail = true; - m_strFailMessage = "Thread creation failed [BackgroundSupervisor]"; + m_strFailMessage = _T("Thread creation failed [BackgroundSupervisor]"); break; } - m_vecpThreads[iThread]->SetPriority (40); + m_vecpThreads[iThread]->SetPriority (40); + iStartUnit += iNumUnits; } if (m_bFail) return false; m_pTimer = new Timer; - - if (! theApp->getUseBackgroundTasks()) - m_pDialogProgress = new wxProgressDialog (_T("Filtered Backprojection"), _T("Reconstruction Progress"), - m_iTotalUnits, m_pParentFrame, wxPD_CAN_ABORT | wxPD_AUTO_HIDE); - else { - std::string strLabel (m_strProcessTitle); - strLabel += " "; - strLabel += m_pParentFrame->GetTitle(); - wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_ADD); - addTaskEvent.SetString (strLabel.c_str()); - addTaskEvent.SetInt (m_iTotalUnits); - addTaskEvent.SetClientData (this); - wxPostEvent (theApp->getBackgroundManager(), addTaskEvent); - wxPostEvent (m_pDocument, addTaskEvent); - m_bBackgroundTaskAdded = true; - } - + + wxString strLabel (m_strProcessTitle); + strLabel += _T(" "); + strLabel += dynamic_cast(m_pParentFrame)->GetTitle(); + +#ifdef USE_BKGMGR + wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_ADD); + addTaskEvent.SetString (strLabel); + addTaskEvent.SetInt (m_iTotalUnits); + addTaskEvent.SetClientData (this); + wxPostEvent (theApp->getBackgroundManager(), addTaskEvent); +#endif + + m_pDocument->addBackgroundSupervisor (this); + m_bBackgroundManagerAdded = true; + m_iRunning = m_iNumThreads; m_iUnitsDone = 0; for (int i = 0; i < m_iNumThreads; i++) m_vecpThreads[i]->Run(); - + return true; } void -BackgroundSupervisor::OnCancel(wxCommandEvent& event) +BackgroundSupervisor::onCancel() { m_bCancelled = true; m_bDone = true; - deleteWorkers(); } -void -BackgroundSupervisor::OnAckDocumentRemove(wxCommandEvent& event) -{ - m_bBackgroundTaskAdded = false; -} void -BackgroundSupervisor::OnWorkerUnitTick (wxCommandEvent& event) +BackgroundSupervisor::onWorkerUnitTick () { ++m_iUnitsDone; - -#ifdef DEBUG - if (theApp->getVerboseLogging()) - *theApp->getLog() << "Units done: " << static_cast(m_iUnitsDone) <<"\n"; + +#ifdef USE_BKGMGR + wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_UNIT_TICK); + addTaskEvent.SetInt (m_iUnitsDone - 1); + addTaskEvent.SetClientData (this); + wxPostEvent (theApp->getBackgroundManager(), addTaskEvent); #endif - - if (m_pDialogProgress) { - if (! m_pDialogProgress->Update (m_iUnitsDone - 1)) { - wxCommandEvent dummy; - OnCancel (dummy); - } - } else { - wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_UNIT_TICK); - addTaskEvent.SetInt (m_iUnitsDone - 1); - addTaskEvent.SetClientData (this); - wxPostEvent (theApp->getBackgroundManager(), addTaskEvent); - } } void -BackgroundSupervisor::OnWorkerDone (wxCommandEvent& event) +BackgroundSupervisor::onWorkerDone (int iThread) { + wxCriticalSection critsectDone; + critsectDone.Enter(); + m_iRunning--; - wxASSERT (m_iRunning >= 0); #ifdef DEBUG if (theApp->getVerboseLogging()) { wxString msg; - msg.Printf("Background Supervisor: Thread finished. Remaining threads: %d\n", m_iRunning); + msg.Printf(_T("Background 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 } #endif - if (m_iRunning <= 0 && ! m_bCancelled) { - deleteWorkers(); - onDone(); - } + + critsectDone.Leave(); } void -BackgroundSupervisor::OnWorkerFail (wxCommandEvent& event) +BackgroundSupervisor::onWorkerFail (int iThread, const wxString& strFailMessage) { m_iRunning--; wxCommandEvent eventLog( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT ); - eventLog.SetString( event.GetString() ); + eventLog.SetString( strFailMessage ); wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event - wxCommandEvent dummy; - OnCancel(dummy); + onCancel(); } +#endif // HAVE_WXTHREADS