2 * copyright (c) 2010 Sveriges Television AB <info@casparcg.com>
\r
4 * This file is part of CasparCG.
\r
6 * CasparCG is free software: you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation, either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * CasparCG is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
\r
21 #include "..\stdafx.h"
\r
23 #include "AMCPCommandQueue.h"
\r
25 namespace caspar { namespace protocol { namespace amcp {
\r
27 AMCPCommandQueue::AMCPCommandQueue() : newCommandEvent_(FALSE, FALSE)
\r
30 AMCPCommandQueue::~AMCPCommandQueue()
\r
35 bool AMCPCommandQueue::Start()
\r
37 if(commandPump_.IsRunning())
\r
40 return commandPump_.Start(this);
\r
43 void AMCPCommandQueue::Stop()
\r
45 commandPump_.Stop();
\r
48 void AMCPCommandQueue::AddCommand(AMCPCommandPtr pNewCommand)
\r
51 tbb::mutex::scoped_lock lock(mutex_);
\r
53 if(pNewCommand->GetScheduling() == ImmediatelyAndClear) {
\r
54 //Clears the queue, objects are deleted automatically
\r
57 commands_.push_back(pNewCommand);
\r
58 CASPAR_LOG(info) << "Cleared queue and added command";
\r
61 commands_.push_back(pNewCommand);
\r
62 CASPAR_LOG(info) << "Added command to end of queue";
\r
66 SetEvent(newCommandEvent_);
\r
69 void AMCPCommandQueue::Run(HANDLE stopEvent)
\r
71 bool logTemporarilyBadState = true;
\r
72 AMCPCommandPtr pCurrentCommand;
\r
74 CASPAR_LOG(info) << "AMCP CommandPump started";
\r
76 while(WaitForSingleObject(stopEvent, 0) != WAIT_OBJECT_0)
\r
78 DWORD waitResult = WaitForSingleObject(newCommandEvent_, 50);
\r
79 if(waitResult == WAIT_OBJECT_0)
\r
81 tbb::mutex::scoped_lock lock(mutex_);
\r
83 if(commands_.size() > 0)
\r
85 CASPAR_LOG(debug) << "Found " << commands_.size() << " commands in queue";
\r
87 AMCPCommandPtr pNextCommand = commands_.front();
\r
89 if(pCurrentCommand == 0 || pNextCommand->GetScheduling() == ImmediatelyAndClear) {
\r
90 pCurrentCommand = pNextCommand;
\r
91 commands_.pop_front();
\r
96 if(pCurrentCommand != 0)
\r
100 if(pCurrentCommand->Execute())
\r
101 CASPAR_LOG(info) << "Executed command: " << pCurrentCommand->print();
\r
103 CASPAR_LOG(info) << "Failed to execute command: " << pCurrentCommand->print();
\r
107 CASPAR_LOG_CURRENT_EXCEPTION();
\r
108 CASPAR_LOG(info) << "Failed to execute command:" << pCurrentCommand->print();
\r
111 pCurrentCommand->SendReply();
\r
112 pCurrentCommand.reset();
\r
114 newCommandEvent_.Set();
\r
115 logTemporarilyBadState = true;
\r
117 CASPAR_LOG(info) << "Ready for a new command";
\r
121 CASPAR_LOG(info) << "CommandPump ended";
\r
124 bool AMCPCommandQueue::OnUnhandledException(const std::exception& ex) throw()
\r
126 bool bDoRestart = true;
\r
130 CASPAR_LOG(fatal) << "UNHANDLED EXCEPTION in commandqueue. Message: " << ex.what();
\r
134 bDoRestart = false;
\r