#ifndef OPERATION_D8F2BC78_108D_4219_9D6E_F1728D1B8C95_H__
#define OPERATION_D8F2BC78_108D_4219_9D6E_F1728D1B8C95_H__
#include
class Operation
{
enum OperationState
{
OPERATION_IDLE = 0,
OPERATION_STARTING,
OPERATION_RUNNING,
OPERATION_CANCELLING,
OPERATION_FINISHED
};
public:
Operation();
Operation(const std::string& name);
virtual ~Operation();
public:
virtual void processOpertion() = 0;
public:
virtual void process();
virtual void release();
inline std::string name() const { return m_name; }
inline void set_name(__in std::string name){ m_name = name; }
private:
OperationState m_state;
std::string m_name;
};
#endif
#ifndef OPERATIONMANAGER_7EEF3272_2557_4A76_9C25_67D4639F40DB_H__
#define OPERATIONMANAGER_7EEF3272_2557_4A76_9C25_67D4639F40DB_H__
#include
#include
#include
#include
#include
class Operation;
class OperationManager
{
public:
OperationManager() = default;
~OperationManager();
OperationManager(OperationManager&) = delete;
OperationManager(OperationManager&&) = delete;
OperationManager& operator= (OperationManager&) = delete;
OperationManager& operator= (OperationManager&&) = delete;
public:
uint32_t startup();
void shutdown( int seconds = 2000);
uint32_t startOperation( Operation* pOperation, int delay);
uint32_t startOperationWithLambda(std::function operationRun
, int delay
, std::string oper_name);
uint32_t clearOperationByName(std::string oper_name);
private:
std::list m_vecDelayOperations;
std::list m_vecRealtimeOperations;
std::mutex m_cvMutex; // 互斥锁.
std::condition_variable m_CV; // 条件变量
std::mutex m_mutexOperation;
bool m_bContinue = true;
std::thread m_operationThread;
};
OperationManager* getOperationManager();
#endif// OPERATIONMANAGER_7EEF3272_2557_4A76_9C25_67D4639F40DB_H__
#include "Operation.h"
#include
const std::string OPERATION_NAME_COMMON = "operation_name_common";
Operation::Operation()
:m_state(OPERATION_IDLE)
, m_name(OPERATION_NAME_COMMON)
{
}
Operation::Operation(const std::string& name)
:m_state(OPERATION_IDLE)
,m_name(name)
{
}
Operation::~Operation()
{
}
void Operation::process()
{
try
{
m_state = OPERATION_RUNNING;
processOpertion();
}
catch (std::exception& exc)
{
assert(false);
}
catch (...)
{
assert(false);
}
m_state = OPERATION_FINISHED;
}
void Operation::release()
{
delete this;
}
/******************************************************************************/
#include "Operation.h"
#include "OperationManager.h"
#include
#include
namespace
{
class LambdaOperation : public Operation
{
public:
LambdaOperation(std::function operationRun)
:m_operationRun(operationRun)
{
}
virtual void processOpertion()
{
m_operationRun();
}
virtual void release()
{
delete this;
}
private:
std::function m_operationRun;
};
}
uint32_t OperationManager::startup()
{
m_operationThread = std::thread([&]
{
std::unique_lock lck(m_cvMutex);
Operation* pOperation = nullptr;
while (m_bContinue)
{
if (!m_bContinue)
break;
if (m_vecRealtimeOperations.empty())
m_CV.wait(lck);
if (!m_bContinue)
break;
{
std::lock_guard lock(m_mutexOperation);
if (m_vecRealtimeOperations.empty())
continue;
pOperation = m_vecRealtimeOperations.front();
m_vecRealtimeOperations.pop_front();
}
if (!m_bContinue)
break;
if (pOperation)
{
pOperation->process();
pOperation->release();
}
}
});
return 1;
}
void OperationManager::shutdown( int seconds /*= 2000*/)
{
m_bContinue = false;
m_CV.notify_one();
if (m_operationThread.joinable())
m_operationThread.join();
{
std::lock_guard locker(m_mutexOperation);
for (Operation* pOper : m_vecRealtimeOperations)
{
try
{
pOper->release();
}
catch (...)
{
}
}
m_vecRealtimeOperations.clear();
}
for (Operation* pOper : m_vecDelayOperations)
{
delete pOper;
pOper = 0;
}
m_vecDelayOperations.clear();
}
uint32_t OperationManager::startOperation( Operation* pOperation, int delay)
{
assert(pOperation);
if (0 == pOperation)
{
return 0;
}
if (delay > 0)
{
}
else
{
std::lock_guard locker(m_mutexOperation);
m_vecRealtimeOperations.push_back(pOperation);
m_CV.notify_one();
}
return 1;
}
uint32_t OperationManager::startOperationWithLambda(std::function operationRun
, int delay
, std::string oper_name)
{
LambdaOperation* pLambdaOper = new LambdaOperation(operationRun);
pLambdaOper->set_name(oper_name);
return startOperation(pLambdaOper, delay);
}
uint32_t OperationManager::clearOperationByName(std::string oper_name)
{
std::lock_guard locker(m_mutexOperation);
auto iter = std::remove_if(m_vecRealtimeOperations.begin(), m_vecRealtimeOperations.end(),
[=](Operation* pOper)
{
if (pOper->name() == oper_name)
{
pOper->release();
return 1;
}
return 0;
});
if (iter != m_vecRealtimeOperations.end())
{
m_vecRealtimeOperations.erase(iter, m_vecRealtimeOperations.end());
}
return 1;
}
OperationManager::~OperationManager()
{
try
{
shutdown();
}
catch (...)
{
assert(0);
}
}
OperationManager* getOperationManager()
{
static OperationManager manager;
return &manager;
}
teamtalk 在线程操作闭包