]> git.sesse.net Git - casparcg/commitdiff
Manually merged 44adc50 from master
authorniklaspandersson <niklas.p.andersson@svt.se>
Fri, 30 Aug 2013 08:17:45 +0000 (10:17 +0200)
committerniklaspandersson <niklas.p.andersson@svt.se>
Fri, 30 Aug 2013 08:17:45 +0000 (10:17 +0200)
protocol/amcp/AMCPCommandsImpl.cpp
protocol/amcp/AMCPCommandsImpl.h
protocol/amcp/AMCPProtocolStrategy.cpp
protocol/amcp/AMCPProtocolStrategy.h
shell/main.cpp
shell/server.cpp
shell/server.h

index 13f0d581d78e3cc8a3ae5f3f5e1d8886795e3e8a..014267a6bbb1b9f060a25f4de8c3b88bc14f0853 100644 (file)
@@ -1969,5 +1969,12 @@ bool ThumbnailCommand::DoExecuteGenerateAll()
        }
 }
 
+bool KillCommand::DoExecute()
+{
+       shutdown_server_now_->set_value(false); //false for not waiting for keypress
+       SetReplyString(TEXT("202 KILL OK\r\n"));
+       return true;
+}
+
 }      //namespace amcp
 }}     //namespace caspar
\ No newline at end of file
index d0ec2fb8728647e8d2e86f999ab29e05f592c6df..8fca23c89ca73be26b5ec388ba627ae11f725f75 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "AMCPCommand.h"
 
+#include <boost/thread/future.hpp>
 #include <core/thumbnail_generator.h>
 
 namespace caspar { namespace protocol {
@@ -310,6 +311,17 @@ private:
        std::shared_ptr<core::thumbnail_generator> thumb_gen_;
 };
 
+class KillCommand : public AMCPCommandBase<0> 
+{
+public:
+       KillCommand(IO::ClientInfoPtr client, boost::promise<bool>& shutdown_server_now) : AMCPCommandBase(client), shutdown_server_now_(&shutdown_server_now) {}
+       std::wstring print() const { return L"KillCommand";}
+       bool DoExecute();
+
+private:
+       boost::promise<bool>* shutdown_server_now_;
+};
+
 //class KillCommand : public AMCPCommand
 //{
 //public:
index d72516a369b7632a79f5bc412a475bb854205c34..c461fe17bc32d7fc139a3116e10c35932f8b3020 100644 (file)
@@ -53,9 +53,10 @@ private:
        std::vector<channel_context>                            channels_;
        std::vector<AMCPCommandQueue::ptr_type>         commandQueues_;
        std::shared_ptr<core::thumbnail_generator>      thumb_gen_;
+       boost::promise<bool>&                                           shutdown_server_now_;
 
 public:
-       impl(const std::vector<spl::shared_ptr<core::video_channel>>& channels, const std::shared_ptr<core::thumbnail_generator>& thumb_gen) : thumb_gen_(thumb_gen)
+       impl(const std::vector<spl::shared_ptr<core::video_channel>>& channels, const std::shared_ptr<core::thumbnail_generator>& thumb_gen, boost::promise<bool>& shutdown_server_now) : thumb_gen_(thumb_gen), shutdown_server_now_(shutdown_server_now)
        {
                commandQueues_.push_back(std::make_shared<AMCPCommandQueue>());
 
@@ -357,10 +358,7 @@ private:
                else if(s == TEXT("LOCK"))                      return std::make_shared<LockCommand>(client, channels_);
                else if(s == TEXT("LOG"))                       return std::make_shared<LogCommand>(client);
                else if(s == TEXT("THUMBNAIL"))         return std::make_shared<ThumbnailCommand>(client, thumb_gen_);
-               //else if(s == TEXT("KILL"))
-               //{
-               //      result = AMCPCommandPtr(new KillCommand());
-               //}
+               else if(s == TEXT("KILL"))                      return std::make_shared<KillCommand>(client, shutdown_server_now_);
 
                return nullptr;
        }
@@ -389,7 +387,7 @@ private:
 };
 
 
-AMCPProtocolStrategy::AMCPProtocolStrategy(const std::vector<spl::shared_ptr<core::video_channel>>& channels, const std::shared_ptr<core::thumbnail_generator>& thumb_gen) : impl_(spl::make_unique<impl>(channels, thumb_gen)) {}
+AMCPProtocolStrategy::AMCPProtocolStrategy(const std::vector<spl::shared_ptr<core::video_channel>>& channels, const std::shared_ptr<core::thumbnail_generator>& thumb_gen, boost::promise<bool>& shutdown_server_now) : impl_(spl::make_unique<impl>(channels, thumb_gen, shutdown_server_now)) {}
 AMCPProtocolStrategy::~AMCPProtocolStrategy() {}
 void AMCPProtocolStrategy::Parse(const std::wstring& msg, IO::ClientInfoPtr pClientInfo) { impl_->Parse(msg, pClientInfo); }
 
index d0d59d80959cddc768bbc2b599844f7df034e039..e647473c1a687c47f576a60c32375046c3f95c94 100644 (file)
@@ -29,6 +29,7 @@
 #include <common/memory.h>
 
 #include <boost/noncopyable.hpp>
+#include <boost/thread/future.hpp>
 
 #include <string>
 
@@ -37,7 +38,11 @@ namespace caspar { namespace protocol { namespace amcp {
 class AMCPProtocolStrategy : public IO::IProtocolStrategy, boost::noncopyable
 {
 public:
-       AMCPProtocolStrategy(const std::vector<spl::shared_ptr<core::video_channel>>& channels, const std::shared_ptr<core::thumbnail_generator>& thumb_gen);
+       AMCPProtocolStrategy(
+               const std::vector<spl::shared_ptr<core::video_channel>>& channels, 
+               const std::shared_ptr<core::thumbnail_generator>& thumb_gen,
+               boost::promise<bool>& shutdown_server_now);
+
        virtual ~AMCPProtocolStrategy();
 
        virtual void Parse(const std::wstring& msg, IO::ClientInfoPtr pClientInfo);
index 875ae4aca19b01205d612b6a25e79cbefee23358..c10c2a6f719a48442dcddee7c8ffa01da914daa8 100644 (file)
@@ -54,7 +54,6 @@
 
 #include <common/env.h>
 #include <common/except.h>
-#include <common/except.h>
 #include <common/log.h>
 #include <common/gl/gl_check.h>
 #include <common/os/windows/current_version.h>
@@ -68,6 +67,9 @@
 #include <boost/foreach.hpp>
 #include <boost/locale.hpp>
 #include <boost/algorithm/string/predicate.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
 
 #include <signal.h>
 
@@ -179,29 +181,14 @@ LONG WINAPI UserUnhandledExceptionFilter(EXCEPTION_POINTERS* info)
        return EXCEPTION_CONTINUE_EXECUTION;
 }
 
-void run()
+void do_run(server& caspar_server, boost::promise<bool>& shutdown_server_now)
 {
-       // Create server object which initializes channels, protocols and controllers.
-       server caspar_server;
-                               
-       auto server = spl::make_shared<protocol::osc::server>(5253);
-       caspar_server.subscribe(server);
-                                               
-       //auto console_obs = reactive::make_observer([](const monitor::event& e)
-       //{
-       //      std::stringstream str;
-       //      str << e;
-       //      CASPAR_LOG(trace) << str.str().c_str();
-       //});
-
-       //caspar_server.subscribe(console_obs);
-                                               
        // Create a dummy client which prints amcp responses to console.
        auto console_client = spl::make_shared<IO::ConsoleClientInfo>();
        
        // Create a amcp parser for console commands.
        //protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.channels());
-       auto amcp = spl::make_shared<caspar::IO::delimiter_based_chunking_strategy_factory<wchar_t>>(L"\r\n", spl::make_shared<caspar::IO::legacy_strategy_adapter_factory>(spl::make_shared<protocol::amcp::AMCPProtocolStrategy>(caspar_server.channels(), caspar_server.get_thumbnail_generator())))->create(console_client);
+       auto amcp = spl::make_shared<caspar::IO::delimiter_based_chunking_strategy_factory<wchar_t>>(L"\r\n", spl::make_shared<caspar::IO::legacy_strategy_adapter_factory>(spl::make_shared<protocol::amcp::AMCPProtocolStrategy>(caspar_server.channels(), caspar_server.get_thumbnail_generator(), shutdown_server_now)))->create(console_client);
 
        std::wstring wcmd;
        while(true)
@@ -211,7 +198,10 @@ void run()
                //boost::to_upper(wcmd);
 
                if(boost::iequals(wcmd, L"EXIT") || boost::iequals(wcmd, L"Q") || boost::iequals(wcmd, L"QUIT") || boost::iequals(wcmd, L"BYE"))
+               {
+                       shutdown_server_now.set_value(true);    //true to wait for keypress
                        break;
+               }
 
                try
                {
@@ -288,8 +278,35 @@ void run()
 
                wcmd += L"\r\n";
                amcp->parse(wcmd);
-       }       
-       CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";
+       }
+};
+
+bool run()
+{
+       boost::promise<bool> shutdown_server_now;
+       boost::unique_future<bool> shutdown_server = shutdown_server_now.get_future();
+
+       // Create server object which initializes channels, protocols and controllers.
+       server caspar_server(shutdown_server_now);
+                               
+       auto server = spl::make_shared<protocol::osc::server>(5253);
+       caspar_server.subscribe(server);
+                                               
+       //auto console_obs = reactive::make_observer([](const monitor::event& e)
+       //{
+       //      std::stringstream str;
+       //      str << e;
+       //      CASPAR_LOG(trace) << str.str().c_str();
+       //});
+
+       //caspar_server.subscribe(console_obs);
+
+
+       // Use separate thread for the blocking console input, will be terminated 
+       // anyway when the main thread terminates.
+       boost::thread stdin_thread(std::bind(do_run, std::ref(caspar_server), std::ref(shutdown_server_now)));  //compiler didn't like lambda here...
+       stdin_thread.detach();
+       return shutdown_server.get();
 }
 
 void on_abort(int)
@@ -374,9 +391,12 @@ int main(int argc, wchar_t* argv[])
                boost::property_tree::write_xml(str, env::properties(), w);
                CASPAR_LOG(info) << L"casparcg.config:\n-----------------------------------------\n" << str.str().c_str() << L"-----------------------------------------";
                
-               run();
+               auto wait = run();
                
-               system("pause");        
+               Sleep(500);
+               CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";
+
+               if(wait) system("pause");       
        }
        catch(boost::property_tree::file_parser_error&)
        {
index fd1e62b7a0d85b3b8a713febc61d6ed570040b5f..b569bf555e19f5d554d1209e0d21df19352b7797 100644 (file)
@@ -81,9 +81,10 @@ struct server::impl : boost::noncopyable
        std::vector<spl::shared_ptr<IO::AsyncEventServer>>      async_servers_; 
        std::vector<spl::shared_ptr<video_channel>>                     channels_;
        std::shared_ptr<thumbnail_generator>                            thumbnail_generator_;
+       boost::promise<bool>&                                                           shutdown_server_now_;
 
-       impl()          
-               : accelerator_(env::properties().get(L"configuration.accelerator", L"auto"))
+       explicit impl(boost::promise<bool>& shutdown_server_now)                
+               : accelerator_(env::properties().get(L"configuration.accelerator", L"auto")), shutdown_server_now_(shutdown_server_now)
        {       
 
                ffmpeg::init();
@@ -240,7 +241,7 @@ struct server::impl : boost::noncopyable
                using namespace IO;
 
                if(boost::iequals(name, L"AMCP"))
-                       return wrap_legacy_protocol("\r\n", spl::make_shared<amcp::AMCPProtocolStrategy>(channels_, thumbnail_generator_));
+                       return wrap_legacy_protocol("\r\n", spl::make_shared<amcp::AMCPProtocolStrategy>(channels_, thumbnail_generator_, shutdown_server_now_));
                else if(boost::iequals(name, L"CII"))
                        return wrap_legacy_protocol("\r\n", spl::make_shared<cii::CIIProtocolStrategy>(channels_));
                else if(boost::iequals(name, L"CLOCK"))
@@ -253,7 +254,7 @@ struct server::impl : boost::noncopyable
 
 };
 
-server::server() : impl_(new impl()){}
+server::server(boost::promise<bool>& shutdown_server_now) : impl_(new impl(shutdown_server_now)){}
 
 const std::vector<spl::shared_ptr<video_channel>> server::channels() const
 {
index 987043c4a93b5ac1f09437b3ad37667b2b3d1ab5..9c701f8102c101c9baf98104b3df996584cbf6dc 100644 (file)
@@ -26,6 +26,7 @@
 #include <core/monitor/monitor.h>
 
 #include <boost/noncopyable.hpp>
+#include <boost/thread/future.hpp>
 
 #include <vector>
 
@@ -40,7 +41,7 @@ class server sealed : public monitor::observable
                                        , boost::noncopyable
 {
 public:
-       server();
+       explicit server(boost::promise<bool>& shutdown_server_now);
        const std::vector<spl::shared_ptr<core::video_channel>> channels() const;
        std::shared_ptr<core::thumbnail_generator> get_thumbnail_generator() const;
        // monitor::observable