void AMCPCommandQueue::Run(HANDLE stopEvent) { bool logTemporarilyBadState = true; AMCPCommandPtr pCurrentCommand; CASPAR_LOG(info) << "AMCP CommandPump started"; while(WaitForSingleObject(stopEvent, 0) != WAIT_OBJECT_0) { DWORD waitResult = WaitForSingleObject(newCommandEvent_, 50); if(waitResult == WAIT_OBJECT_0) { tbb::mutex::scoped_lock lock(mutex_); if(commands_.size() > 0) { CASPAR_LOG(debug) << "Found " << commands_.size() << " commands in queue"; AMCPCommandPtr pNextCommand = commands_.front(); if(pCurrentCommand == 0 || pNextCommand->GetScheduling() == ImmediatelyAndClear) { pCurrentCommand = pNextCommand; commands_.pop_front(); } } } if(pCurrentCommand != 0) { try { if(pCurrentCommand->Execute()) CASPAR_LOG(info) << "Executed command: " << pCurrentCommand->print(); else CASPAR_LOG(info) << "Failed to execute command: " << pCurrentCommand->print(); } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); CASPAR_LOG(info) << "Failed to execute command:" << pCurrentCommand->print(); } pCurrentCommand->SendReply(); pCurrentCommand.reset(); newCommandEvent_.Set(); logTemporarilyBadState = true; CASPAR_LOG(info) << "Ready for a new command"; } } CASPAR_LOG(info) << "CommandPump ended"; }
void AMCPCommandQueue::AddCommand(AMCPCommandPtr pCurrentCommand) { if(!pCurrentCommand) return; if(pCurrentCommand->GetScheduling() == ImmediatelyAndClear) executor_.clear(); if(executor_.size() > 64) { try { CASPAR_LOG(error) << "AMCP Command Queue Overflow."; CASPAR_LOG(error) << "Failed to execute command:" << pCurrentCommand->print(); pCurrentCommand->SetReplyString(L"500 FAILED\r\n"); pCurrentCommand->SendReply(); } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); } } executor_.begin_invoke([=] { try { try { if(pCurrentCommand->Execute()) CASPAR_LOG(debug) << "Executed command: " << pCurrentCommand->print(); else CASPAR_LOG(warning) << "Failed to execute command: " << pCurrentCommand->print(); } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); CASPAR_LOG(error) << "Failed to execute command:" << pCurrentCommand->print(); pCurrentCommand->SetReplyString(L"500 FAILED\r\n"); } pCurrentCommand->SendReply(); CASPAR_LOG(trace) << "Ready for a new command"; } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); } }); }
void AMCPCommandQueue::AddCommand(AMCPCommandPtr pNewCommand) { { Lock lock(*this); if(pNewCommand->GetScheduling() == ImmediatelyAndClear) { //Clears the queue, objects are deleted automatically commands_.clear(); commands_.push_back(pNewCommand); LOG << LogLevel::Verbose << TEXT("Cleared queue and added command: ") << pNewCommand->print(); } else { commands_.push_back(pNewCommand); LOG << LogLevel::Verbose << TEXT("Added command to end of queue: ") << pNewCommand->print(); } } SetEvent(newCommandEvent_); }
void AMCPCommandQueue::Run(HANDLE stopEvent) { bool logTemporarilyBadState = true; AMCPCommandPtr pCurrentCommand; LOG << LogLevel::Verbose << TEXT("CommandPump started"); while(WaitForSingleObject(stopEvent, 0) != WAIT_OBJECT_0) { DWORD waitResult = WaitForSingleObject(newCommandEvent_, 50); if(waitResult == WAIT_OBJECT_0) { Lock lock(*this); if(commands_.size() > 0) { LOG << LogLevel::Debug << TEXT("Found ") << commands_.size() << TEXT(" commands in queue"); AMCPCommandPtr pNextCommand = commands_.front(); if(pCurrentCommand == 0 || pNextCommand->GetScheduling() == ImmediatelyAndClear) { pCurrentCommand = pNextCommand; commands_.pop_front(); } } } if(pCurrentCommand != 0) { AMCPCommandCondition condition = pCurrentCommand->CheckConditions(); if(condition == ConditionTemporarilyBad) { if(logTemporarilyBadState) { LOG << LogLevel::Debug << TEXT("Cound not execute command right now, waiting a sec"); logTemporarilyBadState = false; } //don't fail, just wait for a while and then try again continue; } else if(condition == ConditionGood) { bool success = false; try { success = pCurrentCommand->Execute(); } catch(std::exception& ex) { LOG << LogLevel::Critical << TEXT("UNEXPECTED EXCEPTION: In command execution. Message: ") << ex.what(); } catch(...) { LOG << LogLevel::Critical << TEXT("UNEXPECTED EXCEPTION: In command execution. Message: Unknown"); } if(success) LOG << LogLevel::Verbose << TEXT("Executed command: ") << pCurrentCommand->print(); else LOG << LogLevel::Verbose << TEXT("Failed to execute command: ") << pCurrentCommand->print(); } else { //condition == ConditionPermanentlyBad LOG << TEXT("Invalid commandobject"); } pCurrentCommand->SendReply(); pCurrentCommand.reset(); newCommandEvent_.Set(); logTemporarilyBadState = true; LOG << LogLevel::Debug << TEXT("Ready for a new command"); } } LOG << LogLevel::Verbose << TEXT("CommandPump ended"); }