1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-24 21:34:01 +03:00
one/include/ActionManager.h

225 lines
5.6 KiB
C
Raw Normal View History

/* -------------------------------------------------------------------------- */
2016-05-04 13:33:23 +03:00
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef ACTION_MANAGER_H_
#define ACTION_MANAGER_H_
#include <queue>
#include <pthread.h>
#include <ctime>
#include <string>
/**
* Represents a generic request, pending actions are stored in a queue.
* Each element stores the base action type, additional data is added by each
* ActionListener implementation.
*/
class ActionRequest
{
public:
/**
* Base Action types
*/
enum Type
{
FINALIZE,
TIMER,
USER
};
Type type() const
{
return _type;
}
ActionRequest(Type __type): _type(__type){};
virtual ~ActionRequest(){};
virtual ActionRequest * clone() const
{
return new ActionRequest(_type);
}
protected:
Type _type;
};
/**
* ActionListener class. Interface to be implemented by any class that need to
* handle actions.
*/
class ActionListener
{
protected:
ActionListener(){};
2015-07-01 22:15:40 +03:00
virtual ~ActionListener(){};
/**
* the user_action() function is executed upon action arrival.
* This function should check the action type, and perform the
* corresponding action.
* @param ar the ActionRequest
*/
virtual void user_action(const ActionRequest& ar){};
/**
* Periodic timer action, executed each time the time_out expires. Listener
* needs to re-implement the default timer action if needed.
* @param ar the ActionRequest
*/
virtual void timer_action(const ActionRequest& ar){};
/**
* Action executed when the Manager finlizes. Listener needs to re-implement
* the default action if needed.
* @param ar the ActionRequest
*/
virtual void finalize_action(const ActionRequest& ar){};
private:
friend class ActionManager;
/**
* Invoke the action handler
*/
void _do_action(const ActionRequest& ar)
{
switch(ar.type())
{
case ActionRequest::FINALIZE:
finalize_action(ar);
break;
case ActionRequest::TIMER:
timer_action(ar);
break;
case ActionRequest::USER:
user_action(ar);
break;
}
}
};
/**
* ActionManager. Provides action support for a class implementing
* the ActionListener interface.
*/
class ActionManager
{
public:
ActionManager();
virtual ~ActionManager();
/**
* Function to trigger an action to this manager.
* @param action the action name
* @param args arguments for the action
*/
void trigger(const ActionRequest& ar);
/**
* Trigger the FINALIZE event
*/
void finalize()
{
ActionRequest frequest(ActionRequest::FINALIZE);
2015-07-01 22:15:40 +03:00
trigger(frequest);
}
/**
* The calling thread will be suspended until an action is triggered.
* @param timeout for the periodic action.
* @param timer_args arguments for the timer action
*/
void loop(time_t timeout, const ActionRequest& trequest);
/**
* The calling thread will be suspended until an action is triggered.
* @param timeout for the periodic action, the timer action will recieve
* an "empty" ActionRequest.
*/
void loop(time_t timeout)
{
ActionRequest trequest(ActionRequest::TIMER);
loop(timeout, trequest);
}
/**
* The calling thread will be suspended until an action is triggered. No
* periodic action is defined.
*/
void loop()
{
ActionRequest trequest(ActionRequest::TIMER);
loop(0, trequest);
}
/**
* Register the calling object in this action manager.
* @param listener a pointer to the action listner
*/
void addListener(ActionListener * listener)
{
this->listener = listener;
};
private:
/**
* Queue of pending actions, processed in a FIFO manner
*/
std::queue<ActionRequest *> actions;
/**
* Action synchronization is implemented using the pthread library,
* with condition variable and its associated mutex
*/
pthread_mutex_t mutex;
pthread_cond_t cond;
/**
* The listener notified by this manager
*/
ActionListener * listener;
/**
* Function to lock the Manager mutex
*/
void lock()
{
pthread_mutex_lock(&mutex);
};
/**
* Function to unlock the Manager mutex
*/
void unlock()
{
pthread_mutex_unlock(&mutex);
};
};
#endif /*ACTION_MANAGER_H_*/