void Do_Cooperate( int level ) { if ( level != 1 ) { do { } while ( POVMS_ProcessMessages( POVMS_Render_Context, 0 ) - 1 ); do { } while ( POVMS_ProcessMessages( POVMS_Output_Context, 0 ) - 1 ); } return; }
void vfeSession::WorkerThread() { WorkerThreadStartup(); if (POVMS_Init() == false) m_LastError = vfePOVMSInitFailed ; else if (POVMS_OpenContext (const_cast<void **>(&pov::POVMS_GUI_Context)) != kNoError) m_LastError = vfeOpenContextFailed ; else if (POVMS_GetContextAddress (pov::POVMS_GUI_Context, const_cast<void **>(&pov::GUIThreadAddr)) != kNoErr) m_LastError = vfeConnectFailed ; if (m_LastError != vfeNoError) { m_InitializeEvent.notify_all (); return; } m_BackendThread = povray_init (boost::bind(&vfeSession::BackendThreadNotify, this), const_cast<void **>(&pov::RenderThreadAddr)) ; POVMS_Output_Context = pov::POVMS_GUI_Context ; m_Console = shared_ptr<vfeConsole> (new vfeConsole(this, m_ConsoleWidth)) ; POVMS_Object obj ; m_Frontend = new VirtualFrontEnd (*this, POVMS_Output_Context, (POVMSAddress) pov::RenderThreadAddr, obj, NULL, m_Console) ; if (m_Frontend == NULL) throw POV_EXCEPTION_STRING ("Worker thread failed to create frontend"); m_BackendState = m_Frontend->GetState(); m_InitializeEvent.notify_all (); try { while (m_WorkerThreadShutdownRequest == false) { if (m_BackendThreadExited) { // the main thread (created by pov_init()) has exited. this is not good. // we could re-start it, but given it's only supposed to exit under critical // circumstances, we won't risk it and instead will alert the user. note that // if we are implementing a detached frontend and are not attached, this may // not be possible, but there's not a lot we can do about that. throw vfeCriticalError("Backend worker thread shut down prematurely: please re-start POV-Ray."); } try { while (POVMS_ProcessMessages (pov::POVMS_GUI_Context, true, true) == kFalseErr) { m_MessageCount++ ; ProcessFrontend () ; if (m_RenderCancelRequested == true || m_RequestFlag != rqNoRequest || m_WorkerThreadShutdownRequest == true) break ; } ProcessFrontend () ; if (m_RenderCancelRequested) { POV_LONG ts = GetTimestamp() + 2500; m_RenderCancelled = true; while (POVMS_ProcessMessages (pov::POVMS_GUI_Context, false, false) == kFalseErr) { ProcessFrontend () ; // don't allow it to take more than 2.5 seconds to process remaining messages // (this should not happen unless our thread priority is too low) if (GetTimestamp() > ts) break; } ProcessFrontend () ; if (ProcessCancelRender() == true) m_RenderCancelRequested = false; } if (m_RequestFlag != rqNoRequest) { int rq = m_RequestFlag; m_RequestFlag = rqNoRequest; switch (rq) { case rqPauseRequest: m_RequestResult = m_Frontend->Pause() ? 1 : 0; break; case rqResumeRequest: m_RequestResult = m_Frontend->Resume() ? 1 : 0; break; } m_RequestEvent.notify_all (); } boost::thread::yield(); } catch (pov_base::Exception& e) { SetFailed(); if (StopRender(e.what()) == false) m_RenderCancelRequested = true; } catch (vfeException& e) { SetFailed(); if (StopRender(e.what()) == false) m_RenderCancelRequested = true; } catch (std::exception& e) { SetFailed(); if (StopRender(e.what()) == false) m_RenderCancelRequested = true; } } } catch (vfeCriticalError& e) { m_HadCriticalError = true; m_Failed = true; m_LastError = vfeCaughtCriticalError; NotifyCriticalError (e.what(), e.Filename().c_str(), e.Line()) ; } catch (vfeException&) { m_Failed = true; m_LastError = vfeCaughtException; } catch (std::exception&) { m_Failed = true; m_LastError = vfeCaughtException; } if (m_LastError == vfeCaughtException || m_LastError == vfeCaughtCriticalError) { while (POVMS_ProcessMessages (pov::POVMS_GUI_Context, false, false) == kFalseErr) ProcessFrontend () ; ProcessFrontend () ; ProcessCancelRender() ; } if (m_LastError == vfeCaughtException || m_LastError == vfeCaughtCriticalError) NotifyEvent(stCriticalError|stRenderShutdown); try { delete m_Frontend; m_Frontend = NULL; WorkerThreadShutdown(); m_Initialized = false; m_BackendThread = NULL; povray_terminate(); POVMS_CloseContext (POVMS_Output_Context); m_CurrentSessionTemporaryHack = NULL; m_WorkerThreadExited = true; m_ShutdownEvent.notify_all (); } catch (std::runtime_error) { // typical cause of an exception here (at least if it is a POVException) is if the destruction // of m_Frontend takes too long. this can happen if there's a lot of memory blocks to free. } }