Troubleshooting
Problem
This technote describes how to create a Rose RealTime C++ application that responds to UNIX signals in a user defined manner. The information below assumes you have some knowledge of the RTCustomController. Please read the online help about the Custom Peer Controller. For more information on this subject can be found in the online help regarding the SocketInterfaceExample and the IsrExample models that are located in $ROSERT_HOME/Models/C++. You should also be familiar with Unix signals for your OS.
Resolving The Problem
An example model is attached to this Solution. In this example model, the requirement is for the Rose RealTime model to respond in a predetermined way when a user sends a SIGUSR2 signal to the process (i.e. kill -USR2 <process_id>). The following steps were taken to ensure this requirement is met.
- Create a physical and logical thread.
- Examine the EventDetector capsule. This capsule will block waiting for a SIGUSR1 (will be used for RoseRT messages) or a SIGUSR2 signal. This is achieved by placing it on a thread that uses the RTCustomController as it's implementation class. The RTCustomController allows us to override the following controller methods in a capsule class. The following methods must be registered using the REGISTER_LAYER macro:
- waitForEvents() - override this function to wait for a SIGUSR1 or a SIGUSR2 signal. This function sets up the thread to respond to wait for either signal. When one of the signals is received, it unblocks and sets a flag to be used in the processEvents() method.
- processEvents() - When the controller unblocks from waitForEvents(), this method determines which signal caused it to unblock. There are two possibilities.
- SIGUSR1 - This signal is used for RoseRT messaging. Either a message was placed on this controller's inbound queue and its wakeup() funtion was called or a user typed kill -USR1
. In either case, do nothing in this function and let RoseRT process any RoseRT messages that may exist. - SIGUSR2 - A user typed kill -USR2
. Send a message into the model. - SIGUSR2 - A user typed kill -USR2
- SIGUSR1 - This signal is used for RoseRT messaging. Either a message was placed on this controller's inbound queue and its wakeup() funtion was called or a user typed kill -USR1
- wakeup() - When another controller places a message on this controller's inqueue, it calls this wakeup() function. This function sends a SIGUSR1 to it's own process id. This will unblock the waitForEvents() method.
NOTE: Use of the RTCustomController will allow the thread to block on user specified signals, but will also allow the thread to receive normal RoseRT messages. This strategy allows for other capsules to run on the same thread as the EventDetector, Target Observability will work with the EventDetector, and the system will be able to shutdown properly. - Override the RTCustomController's targetStartup() method - only the thread in which the EventDetector runs should respond to the signals SIGUSR1 or a SIGUSR2. All the other threads in the process need to be setup to ignore these signals. Otherwise there is no guarantee that another thread will not respond to them (i.e. debug, main, timer threads). The targetStartup() function is used to configure the process to ignore these signals. All threads forked from the main process will also ignore these signals then. The thread we are interested in is then setup to wait for the signals of interest in the EventDetector's waitForEvents() method.
To see the overridden method, look in the EventDetector's specification under the C++ tab in the implementation preface. NOTE: When overriding the targetStartup() method, make sure you include any target specific code that may be present in the original method. For SUN5 the method used is the default method in $ROSERT_HOME/C++/TargetRTS/src/RTMain and is empty. Other targets such as have overridden this method and have target specific code located in ROSERT_HOME/C++/TargetRTS/src/target//RTMain.
Running the example model from the shell prompt -
- Build the model
- Run it from an xterm
./Container -URTS_DEBUG=quit - From another xterm,
ps -uf username | grep Container
will provide you with the process # - From the same xterm that you typed ps..., type
kill -USR1 [prosess #] // should have no visual effect on the model
kill -USR2 [prosess #] // should cause the EventDetector to send a message to the
// Container.
Running the example model from Rose RealTime -
- Build the model
- Run it from Rose RealTime
- Open a state monitor on the Container
- From an xterm type,
ps -uf username | grep Container - From the same xterm that you typed ps..., type
kill -USR1 [prosess #] // should have no visual effect on the model
kill -USR2 [prosess #] // should cause the EventDetector to send a message to the
// Container. should also see activity in the Container state
// monitor
NOTE: The example associated with this technical note works on Solaris. To run it on another UNIX system, the procedures to follow will be the same. You will have to know how signals work for your operating system and make the appropriate changes to the model.
Related Information
Historical Number
17558
Was this topic helpful?
Document Information
Modified date:
16 June 2018
UID
swg21124578