// --------------------------------------------------------------
//
// Copyright (C) 2008 - All Rights Reserved.
//
// Author: LiuYin
// File: TaskProtocol
// Version: 1.0
// Date: 2008-4-22
//
// Purpose:
// Warning:
// --------------------------------------------------------------
#ifndef TaskProtocol_H
#define TaskProtocol_H
//////////////////////////////////////////////////////////////////////////
#include <ACE/Synch.h>
#include <ACE/Task_T.h>
#include <ACE/Thread_Semaphore.h>
//////////////////////////////////////////////////////////////////////////
class CTaskProtocol : public ACE_Task<ACE_MT_SYNCH>
{
public:
CTaskProtocol()
: active_object_(false),
thread_semaphore_(0)
{
ACE_TRACE(ACE_TEXT("CTaskProtocol()"));
}
int open(void *arg)
{
ACE_TRACE(ACE_TEXT("open(void *)"));
int ret = 0;
if (!active_object_) {
ret = this->activate();
thread_semaphore_.acquire();
}
return ret;
}
int close(u_long flags)
{
ACE_TRACE(ACE_TEXT("close(u_long)"));
int ret = 0;
if (active_object_) {
ACE_Message_Block *message_block = 0;
ACE_NEW_RETURN(message_block, ACE_Message_Block(0, ACE_Message_Block::MB_HANGUP), -1);
ret = this->putq(message_block);
if (ret == -1) {
message_block->release();
message_block = 0;
}
else {
while (active_object_) {
ACE_OS::sleep(ACE_Time_Value(0, 4000));
}
}
}
return ret;
}
void destroy()
{
close(0);
delete this;
}
int put(ACE_Message_Block *message_block, ACE_Time_Value *timeout)
{
ACE_TRACE(ACE_TEXT("put(ACE_Message_Block *, ACE_Time_Value *)"));
int ret = -1;
if (active_object_) {
ret = this->putq(message_block, timeout);
if (ret == -1) {
message_block->release();
message_block = 0;
}
}
else {
ret = process_ex(message_block);
}
return ret;
}
int svc()
{
ACE_TRACE(ACE_TEXT("svc()"));
active_object_ = true;
thread_semaphore_.release(1);
int ret = -1;
while (true) {
ret = -1;
ACE_Message_Block *message_block = 0;
if (this->getq(message_block) == -1 || message_block == 0) {
goto Exit;
}
if (message_block->msg_type() == ACE_Message_Block::MB_HANGUP) {
message_block->release();
message_block = 0;
break;
}
ret = process_ex(message_block);
}
ret = 0;
Exit:
active_object_ = false;
return ret;
}
protected:
~CTaskProtocol()
{
ACE_TRACE(ACE_TEXT("~CTaskProtocol()"));
}
int process_ex(ACE_Message_Block *&message_block)
{
ACE_TRACE(ACE_TEXT("process_ex(ACE_Message_Block *&)"));
ACE_Message_Block *message_block_process = 0;
int ret = process(message_block, message_block_process);
if (message_block) {
message_block->release();
message_block = 0;
}
if (ret == 0 && next()) {
ret = put_next(message_block_process);
message_block_process = 0;
}
if (message_block_process) {
message_block_process->release();
message_block_process = 0;
}
return ret;
}
virtual int process(ACE_Message_Block *&message_block, ACE_Message_Block *&message_block_process) = 0;
private:
bool active_object_;
ACE_Thread_Semaphore thread_semaphore_;
};
//////////////////////////////////////////////////////////////////////////
#endif