// $Id: JGServiceManager.cpp,v 1.2 2003/03/16 14:51:01 fukasawa Exp $

//=============================================================================
/**
 *  @file    JGManager.cpp
 *
 *  @author  Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2001-2003 BEE Co.,Ltd. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
//=============================================================================

#define BEE_BUILD_DLL

#include "JGServiceManager.h"
#include "JGEquipment.h"
#include "BS2ErrorMessage.h"
#include "BS2DeclAtoms.h"

static MUTEX_UInt _opid = 1;

//-----------------------------------------------------------------------------
// Timer
//-----------------------------------------------------------------------------
class BEE_Export OpeTimerHandler : public ACE_Handler
{
public:
    OpeTimerHandler() : ACE_Handler() {}

    virtual void handle_time_out(const ACE_Time_Value &tv,
                                 const void * arg)
    {
        TRACE_FUNCTION(TRL_LOW, "OpeTimerHandler::handle_time_out@JGManager");
        ACE_UNUSED_ARG(tv);

        JGOperationInfo * ope = (JGOperationInfo *)arg;

        // lock map table
        ope->m_manager->findOperation(ope->m_opid);

        ope->timeout();         // Send error responce

        ope->m_manager->removeOperation(ope->m_opid);

    }
};


//-----------------------------------------------------------------------------
// Constructor/Destructor
//-----------------------------------------------------------------------------
JGServiceManager::JGServiceManager(const string& name) : JGManager(name),
                                                         m_assistant(NULL)
{
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGServiceManager::JGServiceManager");
}

//-----------------------------------------------------------------------------
//  Set/Get Operation ID
//-----------------------------------------------------------------------------
void JGServiceManager::opid(UINT id)
{
    _opid = id;
}
//-----------------------------------------------------------------------------
UINT JGServiceManager::opid()
{
    return _opid++;
}

//-----------------------------------------------------------------------------
//  Atatch/Detach Observer (same JGTask)
//-----------------------------------------------------------------------------
int JGServiceManager::attach(JGObserver * observer)
{
    TRACE_FUNCTION(TRL_LOW, "JGManager::attach");
    m_observer = observer;
    return 0;
}

int JGServiceManager::detach(JGObserver * observer)
{
    TRACE_FUNCTION(TRL_LOW, "JGManager::detach");
    ACE_UNUSED_ARG(observer);
    m_observer = NULL;
    return 0;
}

//-----------------------------------------------------------------------------
//  Entry/Remove Opearation Info.
//-----------------------------------------------------------------------------
static OpeTimerHandler timer;

int JGServiceManager::entryOperation(JGOperationInfo * ope)
{
    TRACE_FUNCTION(TRL_LOW, "JGManager::entryOperation");

    ACE_Guard<ACE_Thread_Mutex > mon(this->m_lock);
    while (mon.locked() == 0)
    {
        ;
    }

    m_opes.insert(JGOperationPair(ope->m_opid, ope));

    ACE_Time_Value tv(20);  // 20 seconds
    long tmid = ACE_Proactor::instance()->schedule_timer(timer, ope, tv);
    if (tmid == -1)
    {
        TRACE_ERROR((_TX("%p\n"), ACE_TEXT("schedule_timer")));
        return BEE_ERROR;
    }

    ope->m_tmid = tmid;
    return 0;
}

//-----------------------------------------------------------------------------
int JGServiceManager::removeOperation(UINT opid)
{
    TRACE_FUNCTION(TRL_LOW, "JGManager::removeOperation");

    ACE_Guard<ACE_Thread_Mutex > mon(this->m_lock);
    while (mon.locked() == 0)
    {
        ;
    }

    JGOperationTable::iterator iter = m_opes.find(opid);
    if (iter == m_opes.end())
    {
        return 0;
    }
    JGOperationInfo * ope = (*iter).second;

    // remove from map
    m_opes.erase(iter);
    delete ope;
    return 0;
}

//-----------------------------------------------------------------------------
JGOperationInfo * JGServiceManager::findOperation(UINT opid)
{
    TRACE_FUNCTION(TRL_LOW, "JGManager::findOperation");

    ACE_Guard<ACE_Thread_Mutex > mon(this->m_lock);
    while (mon.locked() == 0)
    {
        ;
    }

    JGOperationTable::iterator iter = m_opes.find(opid);
    if (iter == m_opes.end())
    {
        return NULL;
    }
    JGOperationInfo * ope = (*iter).second;
    return ope;
}

