2011-06-14 05:41:02 +02:00
|
|
|
/*
|
|
|
|
|
OutputDirector - handling all the real external output connections
|
|
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2011, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
|
|
* *****************************************************/
|
|
|
|
|
|
|
|
|
|
|
2016-11-03 18:22:31 +01:00
|
|
|
/** @file output-director.cpp
|
2016-11-09 23:40:46 +01:00
|
|
|
** Implementation of global output connection management
|
2016-11-03 18:20:10 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2018-11-15 23:42:43 +01:00
|
|
|
#include "steam/play/play-service.hpp"
|
|
|
|
|
#include "steam/play/output-manager.hpp"
|
|
|
|
|
#include "steam/play/output-director.hpp"
|
|
|
|
|
#include "vault/thread-wrapper.hpp"
|
2011-06-14 05:41:02 +02:00
|
|
|
|
2018-11-15 23:59:23 +01:00
|
|
|
using vault::Thread;
|
2011-06-14 05:41:02 +02:00
|
|
|
|
|
|
|
|
|
2018-11-15 23:55:13 +01:00
|
|
|
namespace steam {
|
2011-06-14 05:41:02 +02:00
|
|
|
namespace play {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace { // hidden local details of the service implementation....
|
|
|
|
|
|
|
|
|
|
} // (End) hidden service impl details
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** storage for the single application wide OutputDirector instance */
|
2013-10-20 03:19:36 +02:00
|
|
|
lib::Depend<OutputDirector> OutputDirector::instance;
|
2011-06-14 05:41:02 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/** bring up the framework for handling input/output connections.
|
|
|
|
|
* Creating this object happens on first access and shouldn't be
|
|
|
|
|
* confused with actually booting up / shutting down this subsystem.
|
|
|
|
|
* Rather, the purpose of the OutputDirector is actively to conduct
|
|
|
|
|
* the Lifecycle of booting, connecting, operating, disconnecting.
|
|
|
|
|
*/
|
|
|
|
|
OutputDirector::OutputDirector()
|
2018-04-03 05:14:39 +02:00
|
|
|
: player_{PlayServiceHandle::NOT_YET_STARTED}
|
|
|
|
|
, shutdown_initiated_{false}
|
2011-06-14 05:41:02 +02:00
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
OutputDirector::~OutputDirector() { }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** connect and bring up the external input/output connections,
|
|
|
|
|
* handlers and interface services and the render/playback service.
|
|
|
|
|
* @return true if the output subsystem can be considered operational
|
|
|
|
|
*/
|
|
|
|
|
bool
|
|
|
|
|
OutputDirector::connectUp()
|
|
|
|
|
{
|
|
|
|
|
Lock sync(this);
|
2017-01-05 00:56:46 +01:00
|
|
|
REQUIRE (not shutdown_initiated_);
|
2011-06-14 05:41:02 +02:00
|
|
|
|
2018-04-03 02:14:45 +02:00
|
|
|
player_.createInstance();
|
2011-06-14 05:41:02 +02:00
|
|
|
return this->isOperational();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-10-14 04:10:54 +02:00
|
|
|
/** @todo WIP-WIP-WIP 6/2011 */
|
2011-06-14 05:41:02 +02:00
|
|
|
bool
|
|
|
|
|
OutputDirector::isOperational() const
|
|
|
|
|
{
|
|
|
|
|
return bool(player_); ////////////TODO more to check here....
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** initiate shutdown of all ongoing render/playback processes
|
|
|
|
|
* and closing of all external input/output interfaces.
|
|
|
|
|
* Works as an asynchronous operation; the given callback signal
|
|
|
|
|
* will be invoked when the shutdown is complete.
|
|
|
|
|
* @note starting a new thread, which might fail.
|
|
|
|
|
* When this happens, the raised exception will cause
|
|
|
|
|
* immediate unconditional termination of the application.
|
|
|
|
|
*/
|
|
|
|
|
void
|
2017-01-05 00:56:46 +01:00
|
|
|
OutputDirector::triggerDisconnect (SigTerm completedSignal) noexcept
|
2011-06-14 05:41:02 +02:00
|
|
|
{
|
2017-01-05 00:56:46 +01:00
|
|
|
if (not shutdown_initiated_)
|
2014-10-14 04:10:54 +02:00
|
|
|
{
|
|
|
|
|
shutdown_initiated_ = true;
|
2018-03-26 04:40:54 +02:00
|
|
|
Thread ("Output shutdown supervisor",
|
|
|
|
|
[=]{
|
|
|
|
|
bringDown (completedSignal);
|
|
|
|
|
});
|
2014-10-14 04:10:54 +02:00
|
|
|
}
|
2011-06-14 05:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @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;
|
2017-01-05 00:56:46 +01:00
|
|
|
if (not isOperational())
|
2014-10-14 03:46:12 +02:00
|
|
|
{
|
|
|
|
|
WARN (play, "Attempt to OutputDirector::bringDown() -- "
|
|
|
|
|
"which it is not in running state. Invocation ignored. "
|
|
|
|
|
"This indicates an error in Lifecycle logic.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2011-06-14 05:41:02 +02:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
TODO ("actually bring down the output generation");
|
2018-04-03 02:14:45 +02:00
|
|
|
player_.shutdown();
|
2011-06-14 05:41:02 +02:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-15 23:55:13 +01:00
|
|
|
}} // namespace steam::play
|