/** @internal actually bring down any calculation processes * and finally disconnect any external input/output interfaces. * This shutdown and cleanup operation is executed in a separate * "Output shutdown supervisor" thread and has the liability to * bring down the relevant facilities within a certain timespan. * When done, the last operation within this thread will be to * invoke the callback signal given as parameter. * @note locks the OutputDirector */ void OutputDirector::bringDown (SigTerm completedSignal) { Lock sync(this); string problemLog; if (not isOperational()) { WARN (play, "Attempt to OutputDirector::bringDown() -- " "which it is not in running state. Invocation ignored. " "This indicates an error in Lifecycle logic."); return; } try { TODO ("actually bring down the output generation"); player_.shutdown(); completedSignal(0); } catch (lumiera::Error& problem) { problemLog = problem.what(); lumiera_error(); // reset error state completedSignal (&problemLog); } catch (...) { problemLog = "Unknown error while disconnecting output. " "Lumiera error flag is = "+string(lumiera_error()); completedSignal (&problemLog); } }
/** @param name to use in log and error messages * @note does error handling, but delegates the actual * execution to the protected (subclass) member */ ExecResult HandlingPattern::invoke (CommandImpl& command, Symbol name) const { TRACE (proc_dbg, "invoking %s...", name.c()); static format err_pre ("Error state detected, %s *NOT* invoked."); static format err_post ("Error state after %s invocation."); static format err_fatal ("Execution of %s raised unknown error."); try { Symbol errID_pre = lumiera_error(); if (errID_pre) return ExecResult (error::Logic (str (err_pre % command), errID_pre)); // execute or undo it... perform (command); Symbol errID = lumiera_error(); if (errID) return ExecResult (error::State (str (err_post % command),errID)); else return ExecResult(); } catch (lumiera::Error& problem) { Symbol errID = lumiera_error(); WARN (command, "Invocation of %s failed: %s", name.c(), problem.what()); TRACE (proc_dbg, "Error flag was: %s", errID.c()); return ExecResult (problem); } catch (std::exception& library_problem) { Symbol errID = lumiera_error(); WARN (command, "Invocation of %s failed: %s", name.c(), library_problem.what()); TRACE (proc_dbg, "Error flag was: %s", errID.c()); return ExecResult (error::External (library_problem)); } catch (...) { Symbol errID = lumiera_error(); ERROR (command, "Invocation of %s failed with unknown exception; error flag is: %s", name.c(), errID.c()); throw error::Fatal (str (err_fatal % command), errID); } }
/** @note as an optimisation we hand out a direct reference * to the implementing process object. While this ref could * still be passed as handle to the C Language interface, using * it directly within the client (=GUI) bypasses the C interface * and thus leaves us only with one level of indirection, * irrespective if using the C or C++ interface. * @note in hindsight this turned out as a very bad idea, * since it complicated the definition of the facade proxy * and created quite involved library dependency problems. */ Process start(LumieraDisplaySlot viewerHandle) { ProcessImplementationLink* pP = static_cast<ProcessImplementationLink*> (_i_.startPlay (viewerHandle)); if (!pP) throw lumiera::error::State("failed to start DummyPlayer", lumiera_error()); return pP->createHandle(); }