exec_thread.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "exec_thread.h"
00024
00025 #include <core/exceptions/software.h>
00026 #include <core/exceptions/system.h>
00027 #include <core/threading/mutex.h>
00028 #include <utils/logging/component.h>
00029
00030 #include <lua/context.h>
00031 #include <lua/interface_importer.h>
00032
00033 #include <interfaces/SkillerInterface.h>
00034 #include <interfaces/SkillerDebugInterface.h>
00035
00036 #include <string>
00037 #include <cstring>
00038
00039 using namespace std;
00040 using namespace fawkes;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 LuaAgentExecutionThread::LuaAgentExecutionThread()
00052 : Thread("LuaAgentExecutionThread", Thread::OPMODE_WAITFORWAKEUP),
00053 BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_THINK)
00054 {
00055 __lua = NULL;
00056 }
00057
00058
00059
00060 LuaAgentExecutionThread::~LuaAgentExecutionThread()
00061 {
00062 }
00063
00064
00065
00066
00067
00068
00069 void
00070 LuaAgentExecutionThread::init_failure_cleanup()
00071 {
00072 try {
00073 if ( __skiller_if ) blackboard->close(__skiller_if);
00074 if ( __agdbg_if ) blackboard->close(__agdbg_if);
00075
00076 delete __lua_ifi;
00077
00078 } catch (...) {
00079
00080
00081
00082 logger->log_error(name(), "Really screwed up while finalizing, aborting cleanup. "
00083 "Fawkes is no longer in a clean state. Restart!");
00084 }
00085 }
00086
00087
00088 void
00089 LuaAgentExecutionThread::init()
00090 {
00091 try {
00092 __cfg_agent = config->get_string("/luaagent/agent");
00093 __cfg_watch_files = config->get_bool("/luaagent/watch_files");
00094 } catch (Exception &e) {
00095 e.append("Insufficient configuration for LuaAgent");
00096 throw;
00097 }
00098
00099 logger->log_debug("LuaAgentExecutionThread", "Agent: %s", __cfg_agent.c_str());
00100
00101 __clog = new ComponentLogger(logger, "LuaAgentLua");
00102
00103 __lua = NULL;
00104 __lua_ifi = NULL;
00105 __skiller_if = NULL;
00106 __agdbg_if = NULL;
00107
00108 std::string reading_prefix = "/luaagent/interfaces/" + __cfg_agent + "/reading/";
00109 std::string writing_prefix = "/luaagent/interfaces/" + __cfg_agent + "/writing/";
00110
00111 __skiller_if = blackboard->open_for_reading<SkillerInterface>("Skiller");
00112
00113 __skiller_if->read();
00114 if (__skiller_if->exclusive_controller() != 0) {
00115 throw Exception("Skiller already has an exclusive controller");
00116 }
00117
00118 __skiller_if->msgq_enqueue(new SkillerInterface::AcquireControlMessage());
00119 __agdbg_if = blackboard->open_for_writing<SkillerDebugInterface>("LuaAgent");
00120
00121 try {
00122 __lua = new LuaContext(__cfg_watch_files);
00123
00124 __lua_ifi = new LuaInterfaceImporter(__lua, blackboard, config, logger);
00125 __lua_ifi->open_reading_interfaces(reading_prefix);
00126 __lua_ifi->open_writing_interfaces(writing_prefix);
00127
00128 __lua->add_package_dir(LUADIR);
00129 __lua->add_cpackage_dir(LUALIBDIR);
00130
00131 __lua->add_package("fawkesutils");
00132 __lua->add_package("fawkesconfig");
00133 __lua->add_package("fawkesinterface");
00134
00135 __lua->set_string("AGENT", __cfg_agent.c_str());
00136 __lua->set_usertype("config", config, "Configuration", "fawkes");
00137 __lua->set_usertype("logger", __clog, "ComponentLogger", "fawkes");
00138 __lua->set_usertype("clock", clock, "Clock", "fawkes");
00139
00140 __lua_ifi->add_interface("skiller", __skiller_if);
00141 __lua_ifi->add_interface("agdbg", __agdbg_if);
00142
00143 __lua_ifi->push_interfaces();
00144
00145 __lua->set_start_script(LUADIR"/luaagent/start.lua");
00146 } catch (Exception &e) {
00147 init_failure_cleanup();
00148 throw;
00149 }
00150
00151 __agdbg_if->set_graph("");
00152 __agdbg_if->set_graph_fsm(__cfg_agent.c_str());
00153
00154 }
00155
00156
00157 void
00158 LuaAgentExecutionThread::finalize()
00159 {
00160 if (__skiller_if->has_writer() ) {
00161 __skiller_if->msgq_enqueue(new SkillerInterface::ReleaseControlMessage());
00162 }
00163
00164 blackboard->close(__skiller_if);
00165 blackboard->close(__agdbg_if);
00166
00167 delete __lua_ifi;
00168 delete __lua;
00169 delete __clog;
00170 }
00171
00172 void
00173 LuaAgentExecutionThread::process_agdbg_messages()
00174 {
00175 while ( ! __agdbg_if->msgq_empty() ) {
00176 if (__agdbg_if->msgq_first_is<SkillerDebugInterface::SetGraphDirectionMessage>() ) {
00177 SkillerDebugInterface::SetGraphDirectionMessage *m = __agdbg_if->msgq_first<SkillerDebugInterface::SetGraphDirectionMessage>();
00178 try {
00179 std::string graphdir = "TB";
00180 switch (m->graph_dir()) {
00181 case SkillerDebugInterface::GD_BOTTOM_TOP: graphdir = "BT"; break;
00182 case SkillerDebugInterface::GD_LEFT_RIGHT: graphdir = "LR"; break;
00183 case SkillerDebugInterface::GD_RIGHT_LEFT: graphdir = "RL"; break;
00184 default: break;
00185 }
00186 __lua->do_string("agentenv.set_graphdir(\"%s\")", graphdir.c_str());
00187 } catch (Exception &e) {
00188 logger->log_warn("LuaAgentExecutionThread", "Failed to set graph direction, exception follows");
00189 logger->log_warn("LuaAgentExecutionThread", e);
00190 }
00191 } else if (__agdbg_if->msgq_first_is<SkillerDebugInterface::SetGraphColoredMessage>() ) {
00192 SkillerDebugInterface::SetGraphColoredMessage *m = __agdbg_if->msgq_first<SkillerDebugInterface::SetGraphColoredMessage>();
00193 try {
00194 __lua->do_string("agentenv.set_graph_colored(%s)", m->is_graph_colored() ? "true" : "false");
00195 } catch (Exception &e) {
00196 logger->log_warn("LuaAgentExecutionThread", "Failed to set graph direction, exception follows");
00197 logger->log_warn("LuaAgentExecutionThread", e);
00198 }
00199 }
00200
00201 __agdbg_if->msgq_pop();
00202 }
00203 }
00204
00205
00206 void
00207 LuaAgentExecutionThread::loop()
00208 {
00209 #ifdef HAVE_INOTIFY
00210 __lua->process_fam_events();
00211 #endif
00212
00213 process_agdbg_messages();
00214
00215 __lua_ifi->read();
00216 __skiller_if->read();
00217
00218 try {
00219
00220 __lua->do_string("agentenv.execute()");
00221 } catch (Exception &e) {
00222 logger->log_error("LuaAgentExecutionThread", "Execution of %s.execute() failed, exception follows",
00223 __cfg_agent.c_str());
00224 logger->log_error("LuaAgentExecutionThread", e);
00225 }
00226
00227 __lua_ifi->write();
00228 }