Skip to content
Snippets Groups Projects
cmd_thread.cpp 8.73 KiB
Newer Older
/*
 * cmd_thread.cpp
 *
 * $Author: claudio $
 *
 * $Revision: 1.3 $
 *
 * $Log: cmd_thread.cpp,v $
 * Revision 1.3  2015-07-21 13:40:59  claudio
 * minor cleanups
 *
 * Revision 1.2  2008-11-17 13:13:21  graziano
 * command action can be: without arguments or with string argument
 *
 * Revision 1.1  2008/11/10 10:53:31  graziano
 * thread for execution of commands
 *
 *
 *
 *
 *
 * copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
 *           Strada Statale 14 - km 163,5 in AREA Science Park
 *           34012 Basovizza, Trieste ITALY
 */

#include "cmd_thread.h"
static const char __FILE__rev[] = __FILE__ " $Revision: 1.3 $";

/*
 * cmd_thread::cmd_thread()
 */
cmd_thread::cmd_thread() 
{
	cout << __FILE__rev << endl;
	cout << gettime().tv_sec << " cmd_thread::cmd_thread(): constructor... !" << endl;	
	//mutex_dp = new omni_mutex::omni_mutex();
}

/*
 * cmd_thread::~cmd_thread()
 */
cmd_thread::~cmd_thread()
{
	cout << gettime().tv_sec << " cmd_thread::~cmd_thread(): delete device entering..." << endl;
	//delete mutex_dp;	
}

/*
 * cmd_thread::run()
 */
void cmd_thread::run(void *)
{
	long call_id;
	while (true) {
		/*
		 * pop_front() will wait() on condition variable
		 */
		try
		{
			cmd_t cmd = list.pop_front();
			switch(cmd.cmd_id)
			{
				case CMD_THREAD_EXIT:
					cout << gettime().tv_sec << " cmd_thread::run(): received command THREAD_EXIT -> exiting..." << endl;				
				return;
				
				case CMD_COMMAND:
				{
					try {
						cout << gettime().tv_sec << " cmd_thread::run(): COMMAND ... action=" << cmd.arg_s3 << endl;
						dp = (Tango::DeviceProxy *)cmd.dp_add;
						if(cmd.arg_b)
						{
							Tango::DevString str = CORBA::string_dup(cmd.arg_s1.c_str());
							Tango::DeviceData Din;
							Din << str;
							CORBA::string_free(str);
							//found->second.dp_a->ping();
							//call_id = dp->command_inout_asynch(cmd.arg_s2, Din, true);		//true -> "fire and forget" mode: client do not care at all about the server answer
							call_id = dp->command_inout_asynch(cmd.arg_s2, Din);		//true -> "fire and forget" mode: client do not care at all about the server answer
						}
						else
							call_id = dp->command_inout_asynch(cmd.arg_s2);
						cout << gettime().tv_sec <<  " cmd_thread::run() executed action: " << cmd.arg_s3 << " !!! call_id=" << call_id << endl;
						/*cmd_t arg;
						arg.cmd_id = CMD_RESPONSE;
						arg.call_id = call_id;
						arg.dp_add = cmd.dp_add;
						arg.arg_s1 = cmd.arg_s1;
						arg.arg_s2 = cmd.arg_s2;
						arg.arg_s3 = cmd.arg_s3;	
						cmdloop->list.push_back(arg);*/
						cmd.cmd_id = CMD_RESPONSE;			//if no exception till now push in list request of response
						cmd.call_id = call_id;				//if no exception till now push in list request of response
						list.push_back(cmd);		//if no exception till now push in list request of response
Graziano Scalamera's avatar
Graziano Scalamera committed
					} catch(Tango::DevFailed &e)
					{
						TangoSys_MemStream out_stream;
						string err(e.errors[0].desc);
						if(err.find("is not yet arrived") == string::npos)			//TODO: change this!!
						{
							out_stream << "Failed to execute action " << cmd.arg_s3 << ", err=" << e.errors[0].desc << ends;
							cout << gettime().tv_sec <<  " cmd_thread::run() ERROR: " << out_stream.str() << endl;
						}
						else
						{
							cout << gettime().tv_sec <<  " cmd_thread::run() exception 'is not yet arrived': pushing request of response, call_id=" << call_id << endl;
							cmd.cmd_id = CMD_RESPONSE;			//if no exception till now push in list request of response
							cmd.call_id = call_id;				//if no exception till now push in list request of response
							list.push_back(cmd);		//if no exception till now push in list request of response						
						}
						
					}					
				}	
				break;
				
				case CMD_RESPONSE:
				{
					//cout << gettime().tv_sec << " cmd_thread::run(): RESPONSE WAKE UP... action=" << cmd.arg_s3 << " call_id=" << cmd.call_id << endl;
					Tango::DeviceData resp;
					dp = (Tango::DeviceProxy *)cmd.dp_add;
					try {
						resp = dp->command_inout_reply(cmd.call_id);
						cout << gettime().tv_sec << " cmd_thread::run() RECEIVED response to action " << cmd.arg_s3 << endl;
Graziano Scalamera's avatar
Graziano Scalamera committed
					} catch(Tango::DevFailed &e)
					{
						TangoSys_MemStream out_stream;
						out_stream << "EXCEPTION executing action " << cmd.arg_s3 << ", err=" << e.errors[0].desc << ends;
						
						if(out_stream.str().find("is not yet arrived") != string::npos)			//TODO: change this!!
						{
							
							list.push_back(cmd);				//if exception "not yet arrived" push in list another request of response		
							omni_thread::sleep(0,300000000);	//0.3 s
						}
						else
						{
							cout << gettime().tv_sec << " cmd_thread::run() " <<  out_stream.str() << endl;
							Tango::Except::print_exception(e);
						}
					}				
				}
				break;		
			}
/*			if(cmd.arg_s == CMD_THREAD_EXIT)
			{
				cout << gettime().tv_sec << " cmd_thread::run(): received command THREAD_EXIT -> exiting..." << endl;				
				return;
			}
			else
			{
				cout << gettime().tv_sec << " cmd_thread::run(): WAKE UP... action=" << cmd.arg_s << endl;
				Tango::DeviceData resp;
				dp = (Tango::DeviceProxy *)cmd.dp_add;
				try {
					mutex_dp->lock();
					resp = dp->command_inout_reply(cmd.cmd_id);
					mutex_dp->unlock();
					cout << gettime().tv_sec << " cmd_thread::run() received response to action " << cmd.arg_s << endl;
Graziano Scalamera's avatar
Graziano Scalamera committed
				} catch(Tango::DevFailed &e)
				{
					TangoSys_MemStream out_stream;
					out_stream << "EXCEPTION executing action " << cmd.arg_s << ", err=" << e.errors[0].desc << ends;
					
					if(out_stream.str().find("is not yet arrived") != string::npos)			//TODO: change this!!
					{
						
						list.push_back(cmd);
						omni_thread::sleep(0,300000000);	//0.2 s
					}
					else
						cout << gettime().tv_sec << " cmd_thread::run() " <<  out_stream.str() << endl;
				}
			}*/
			
		}
		catch(omni_thread_fatal& ex)
		{
			ostringstream err;
			err << "omni_thread_fatal exception running command thread, err=" << ex.error << ends;
			//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;	
			printf("cmd_thread::run(): %s", err.str().c_str());			
		}			
		catch(Tango::DevFailed& ex)
		{
			ostringstream err;
			err << "exception running command thread: '" << ex.errors[0].desc << "'" << ends;
			//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;	
			printf("cmd_thread::run(): %s", err.str().c_str());			
			Tango::Except::print_exception(ex);
		}		
		catch(...)
		{
			//WARN_STREAM << "alarm_thread::run(): catched unknown exception!!" << endl;
			printf("cmd_thread::run(): catched unknown exception!!");
		}		
	}
	//cout << "alarm_thread::run(): returning" << endl;
}  /* cmd_thread::run() */

/*
 * cmd_list class methods
 */
void cmd_list::push_back(cmd_t& cmd)
{
	this->lock();

	//cout << "cmd_list::push_back: cmd_id=" << cmd.cmd_id << " call_id=" << cmd.call_id << endl;
	try{
		l_cmd.push_back(cmd);		
		empty.signal();
	}
	catch(omni_thread_fatal& ex)
	{
		ostringstream err;
		err << "omni_thread_fatal exception signaling omni_condition, err=" << ex.error << ends;
		//WARN_STREAM << "event_list::push_back(): " << err.str() << endl;	
		printf("cmd_list::push_back(): %s", err.str().c_str());
	}			
	catch(Tango::DevFailed& ex)
	{
		ostringstream err;
		err << "exception  signaling omni_condition: '" << ex.errors[0].desc << "'" << ends;
		//WARN_STREAM << "cmd_list::push_back(): " << err.str() << endl;
		printf("cmd_list::push_back: %s", err.str().c_str());
		Tango::Except::print_exception(ex);	
	}		
	catch(...)
	{
		printf("cmd_list::push_back(): catched unknown exception  signaling omni_condition!!");	
	}	
	this->unlock();
}

const cmd_t cmd_list::pop_front(void)
{
	this->lock();
	//omni_mutex_lock l((omni_mutex)this);	//call automatically unlock on destructor and on exception
	try{
		while (l_cmd.empty() == true)
			empty.wait();					//wait release mutex while is waiting, then reacquire when signaled
	}
	catch(omni_thread_fatal& ex)
	{
		ostringstream err;
		err << "omni_thread_fatal exception waiting on omni_condition, err=" << ex.error << ends;
		printf("cmd_list::pop_front(): %s", err.str().c_str());
		this->unlock();
		sleep(1);
		cmd_t c;
		return c;
	}			
	catch(Tango::DevFailed& ex)
	{
		ostringstream err;
		err << "exception  waiting on omni_condition: '" << ex.errors[0].desc << "'" << ends;	
		printf("cmd_list::pop_front: %s", err.str().c_str());
		Tango::Except::print_exception(ex);
		this->unlock();
		sleep(1);
		cmd_t c;
		return c;		
	}		
	catch(...)
	{
		printf("cmd_list::pop_front(): catched unknown exception  waiting on omni_condition!!");
		this->unlock();
		sleep(1);
		cmd_t c;
		return c;		
	}			
	/*const*/ cmd_t cmd;

	cmd = *(l_cmd.begin());
	//cout << "cmd_list::pop_front: " << e.name << " value=" << e.value[0] << endl;
	l_cmd.pop_front();

	this->unlock();
	return cmd;
}

void cmd_list::clear(void)
{
	//this->lock();
	l_cmd.clear();
	//this->unlock();
}