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 #ifndef _COMMANDQUEUE_H__
\r
22 #define _COMMANDQUEUE_H__
\r
28 #include "Lockable.h"
\r
33 //TODO: Add idle-processing. preferably as a functor suplied at construction-time
\r
35 //CommandQueue is a
\r
36 template<typename T>
\r
39 template<typename U>
\r
40 class WorkerThread : public utils::IRunnable, private utils::LockableObject
\r
43 WorkerThread() : commandAvailibleEvent_(TRUE, FALSE)
\r
46 void AddCommand(U pCommand);
\r
47 virtual void Run(HANDLE stopEvent);
\r
48 virtual bool OnUnhandledException(const std::exception& ex) throw();
\r
51 utils::Event commandAvailibleEvent_;
\r
53 //Needs synro-protection
\r
54 std::list<U> commands_;
\r
57 CommandQueue(const CommandQueue&);
\r
58 CommandQueue& operator=(const CommandQueue&);
\r
60 CommandQueue() : pWorker_(new WorkerThread<T>())
\r
67 void AddCommand(T pCommand);
\r
70 utils::Thread commandPump_;
\r
71 std::tr1::shared_ptr<WorkerThread<T> > pWorker_;
\r
75 template<typename T>
\r
76 bool CommandQueue<T>::Start() {
\r
77 return commandPump_.Start(pWorker_.get());
\r
80 template<typename T>
\r
81 void CommandQueue<T>::Stop() {
\r
82 commandPump_.Stop();
\r
85 template<typename T>
\r
86 void CommandQueue<T>::AddCommand(T pCommand) {
\r
87 pWorker_->AddCommand(pCommand);
\r
90 template<typename T>
\r
91 template<typename U>
\r
92 void CommandQueue<T>::WorkerThread<U>::AddCommand(U pCommand) {
\r
95 commands_.push_back(pCommand);
\r
96 commandAvailibleEvent_.Set();
\r
99 template<typename T>
\r
100 template<typename U>
\r
101 void CommandQueue<T>::WorkerThread<U>::Run(HANDLE stopEvent)
\r
103 HANDLE events[2] = {commandAvailibleEvent_, stopEvent};
\r
107 DWORD waitResult = WaitForMultipleObjects(2, events, FALSE, 1000);
\r
108 int result = waitResult - WAIT_OBJECT_0;
\r
113 else if(result == 0) {
\r
116 if(commands_.size() > 0) {
\r
117 pCommand = commands_.front();
\r
118 commands_.pop_front();
\r
120 if(commands_.size() == 0)
\r
121 commandAvailibleEvent_.Reset();
\r
125 if(pCommand != 0) {
\r
126 pCommand->Execute();
\r
132 template<typename T>
\r
133 template<typename U>
\r
134 bool CommandQueue<T>::WorkerThread<U>::OnUnhandledException(const std::exception& ex) throw() {
\r
135 bool bDoRestart = true;
\r
139 LOG << LogLevel::Critical << TEXT("UNHANDLED EXCEPTION in commandqueue. Message: ") << ex.what() << LogStream::Flush;
\r
143 bDoRestart = false;
\r
149 } //namespace utils
\r
150 } //namespace caspar
\r
152 #endif //_COMMANDQUEUE_H__