39 bool attachedTerminal;
53 attachedToPort(false),
54 attachedTerminal(false)
61 yCInfo(RFMODULE,
"Listening to terminal (type \"quit\" to stop module).");
63 while (!(isEof || isStopping() || owner.
isStopping())) {
73 for (
size_t i = 0; i < reply.
size(); i++) {
80 yCInfo(RFMODULE,
"Command not understood -- %s.", str.c_str());
84 yCDebug(RFMODULE,
"terminal shutting down\n");
91 attachedToPort =
true;
99 attachedToPort =
true;
107 attachedTerminal =
true;
116 return attachedTerminal;
122 yCWarning(RFMODULE,
"Critical: stopping thread, this might hang.");
133 if (!cmd.
read(connection)) {
138 bool result = owner.safeRespond(cmd, response);
139 if (response.
size() >= 1) {
141 if (writer !=
nullptr) {
143 for (
size_t i = 1; i < response.
size(); i++) {
154 response.
write(*writer);
185 bool singleton_run_module;
193 singleton_run_module(false),
194 respond_handler(nullptr),
195 threaded_handler(nullptr)
202 delete respond_handler;
203 delete threaded_handler;
210 return threaded_handler !=
nullptr;
215 delete threaded_handler;
216 threaded_handler =
nullptr;
222 return singleton_run_module;
226 singleton_run_module =
true;
235 if (mPriv->threaded_handler !=
nullptr) {
236 return mPriv->threaded_handler->getKey();
248 yCInfo(RFMODULE,
"Aborting (calling abort())...");
251 yCInfo(RFMODULE,
"[try %d of 3] Trying to shut down.", ct);
279 static void handler_sigbreak(
int sig)
281 yarp::os::impl::raise(SIGINT);
298 yCInfo(RFMODULE,
"RFModule::RFModule() signal handling currently only good for one module.");
302 yarp::os::impl::signal(SIGBREAK, handler_sigbreak);
305 yarp::os::impl::signal(SIGINT,
handler);
306 yarp::os::impl::signal(SIGTERM,
handler);
325 if (mPriv->getSingletonRunModule()) {
328 mPriv->setSingletonRunModule();
356 if (sleepPeriod > 1) {
365 yCInfo(RFMODULE,
"RFModule closing.");
366 if (mPriv->respond_handler->isTerminalAttached()) {
367 yCWarning(RFMODULE,
"Module attached to terminal calling exit() to quit.");
368 yCWarning(RFMODULE,
"You should be aware that this is not a good way to stop a module. Effects will be:");
369 yCWarning(RFMODULE,
"- class destructors will NOT be called");
370 yCWarning(RFMODULE,
"- code in the main after runModule() will NOT be executed");
371 yCWarning(RFMODULE,
"This happens because in your module you called attachTerminal() and we don't have a portable way to quit a module that is listening to the terminal.");
372 yCWarning(RFMODULE,
"At the moment the only way to have the module quit correctly is to avoid listening to terminal (i.e. do not call attachTerminal()).");
373 yCWarning(RFMODULE,
"This will also make this annoying message go away.");
384 yCInfo(RFMODULE,
"RFModule finished.");
391 if (mPriv->getSingletonRunModule()) {
396 yCInfo(RFMODULE,
"RFModule failed to open.");
405 if (mPriv->getSingletonRunModule()) {
409 if (!mPriv->newThreadHandler()) {
410 yCError(RFMODULE,
"RFModule handling thread failed to allocate.");
414 if (!mPriv->threaded_handler->start()) {
415 yCError(RFMODULE,
"RFModule handling thread failed to start.");
425 if (mPriv->getSingletonRunModule()) {
430 yCError(RFMODULE,
"RFModule failed to open.");
447 return basicRespond(command, reply);
458 mPriv->respond_handler->attach(source);
465 mPriv->respond_handler->attach(source);
472 mPriv->respond_handler->attachTerminal();
479 mPriv->respond_handler->detachTerminal();
501 yCError(RFMODULE,
"interruptModule() returned an error there could be problems shutting down the module.");
518 if (mPriv->threaded_handler !=
nullptr) {
519 if (mPriv->threaded_handler->join(seconds)) {
520 mPriv->deleteThreadHandler();
523 yCWarning(RFMODULE,
"RFModule joinModule() timed out.");
526 yCWarning(RFMODULE,
"Cannot call join: RFModule runModule() is not currently threaded.");
533 if (subName.empty()) {
537 std::string base = name;
541 if (subName[0] !=
'/') {
542 yCWarning(RFMODULE,
"SubName in getName() does not begin with \"/\" this suggest you expect getName() to follow a deprecated behavior.");
543 yCWarning(RFMODULE,
"I am now adding \"/\" between %s and %s but you should not rely on this.", name.c_str(), subName.c_str());
561 bool ok =
respond(command, reply);
564 ok = basicRespond(command, reply);
570 bool RFModule::basicRespond(
const Bottle& command,
Bottle& reply)
576 reply.addVocab32(
"bye");
580 reply.
addString(
"command not recognized");
static void handler(int sig)
bool attach(yarp::os::RpcServer &source)
bool attach(yarp::os::Port &source)
void run() override
Main body of the new thread.
RFModuleRespondHandler(RFModule &owner)
bool isTerminalAttached()
bool read(yarp::os::ConnectionReader &connection) override
Handler for reading messages from the network, and passing them on to the respond() method.
void run() override
Main body of the new thread.
RFModuleThreadedHandler(RFModule &owner)
bool getSingletonRunModule()
RFModuleThreadedHandler * threaded_handler
void setSingletonRunModule()
void deleteThreadHandler()
RFModuleRespondHandler * respond_handler
A simple collection of objects that can be described and transmitted in a portable way.
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
size_type size() const
Gets the number of elements in the bottle.
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
An interface for reading from a network connection.
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
An interface for writing to a network connection.
virtual bool isTextMode() const =0
Check if the connection is text mode.
static void initMinimum()
Basic system initialization, not including plugins.
static void finiMinimum()
Deinitialization, excluding plugins.
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
A mini-server for network communication.
void setReader(PortReader &reader) override
Set an external reader for port data.
A base-class for standard YARP modules that supports ResourceFinder.
virtual ~RFModule()
Destructor.
virtual int runModule()
Calls updateModule() until that returns false.
bool attachTerminal()
Make any input from standard input (usually the keyboard) go to the respond() method.
virtual bool updateModule()=0
Override this to do whatever your module needs to do.
bool joinModule(double seconds=-1)
The function returns when the thread execution has completed.
virtual bool close()
Close function.
void setName(const char *name)
Set the name of the module.
virtual bool respond(const Bottle &command, Bottle &reply)
Respond to a message.
virtual bool attach(yarp::os::Port &source)
Make any input from a Port object go to the respond() method.
virtual bool configure(yarp::os::ResourceFinder &rf)
Configure the module, pass a ResourceFinder object to the module.
virtual int getThreadKey()
return the Thread unique identifier
virtual bool interruptModule()
Try to halt any ongoing operations by threads managed by the module.
bool safeRespond(const Bottle &command, Bottle &reply)
Wrapper around respond() that is guaranteed to process system messages.
bool detachTerminal()
Detach terminal.
void stopModule(bool wait=false)
Ask the module to stop.
virtual int runModuleThreaded()
Calls updateModule() on a separate thread until that returns false.
bool isStopping()
Check if the module should stop.
virtual double getPeriod()
You can override this to control the approximate periodicity at which updateModule() is called by run...
std::string getName(const std::string &subName="")
Return name of module, as set with setName().
Helper class for finding config files and other external resources.
A port that is specialized as an RPC server.
An abstraction for a thread of execution.
static long int getKeyOfCaller()
Get a unique identifier for the calling thread.
bool stop()
Stop the thread.
bool start()
Start the new thread running.
A single value (typically within a Bottle).
virtual yarp::conf::vocab32_t asVocab32() const
Get vocabulary identifier as an integer.
virtual bool isList() const
Checks if value is a list.
virtual Bottle * asList() const
Get list value.
std::string toString() const override
Return a standard text representation of the content of the object.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_OS_LOG_COMPONENT(name, name_string)
void useSystemClock()
Configure YARP to use system time (this is the default).
void yield()
The calling thread releases its remaining quantum upon calling this function.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
void delay(double seconds)
Wait for a certain number of seconds.
std::string readString(bool *eof)
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.
constexpr yarp::conf::vocab32_t createVocab32(char a, char b=0, char c=0, char d=0)
Create a vocab from chars.
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
The main, catch-all namespace for YARP.