I have written a code where two independent programs (say 1 & 2) are communicating via message queues. Each programs sends a message of a specific mtype
and waits for response of specific mtype
. Based on the mtype
functions are invoked. program 2 initially waits on select()
on the message queue waiting for message chain initiation from program 1 and after each successfull communication chain via message queues comes back to select()
waiting for program 1’s initiation of next communication chain.
I want that program 2 must return to select()
by stopping execution wherever it was in between a communication chain on receiving a specific signal (say SIGUUSR1
) from program 1 in case program 1 finds an error in current chain and wants a reset and later would initiate a new communication chain.
On receiving this signal program 2 returns from all functions it is in and straight jumps to select()
.
I regret for not sharing a code snippet, but I hope I have made my point.
Thanks…
Advertisement
Answer
How about:
- When Program 2 starts up, it performs most of the initialization, and then forks a copy of itself.
- The child process creates the socket and connects to it, then selects, and runs as normal.
- When the child process receives
SIGUSR1
it exits with an exit status that indicates a restart is required. - The parent process just sits waiting for the child to exit, and if the exit status indicates a restart is required, forks another child. (Any other exit status causes the parent to exit with the same status).
Discussion:
- Restart will be quite slow (need to create sockets etc).
- Process 1 will need to be aware that the message queue will get disconnected when it sends
SIGUSR1
- This should be very reliable, and portable across Posix.
- The
fork
bit is really only an optimization. You could make the parent process be some sort of script – in which case the model could even be ported to Windows (obviously the script would be different, but the source of program 2 would be portable).
The only other alternative is to have some sort of flag which Process 2 polls “frequently”. If the flag is set, the process throws an exception (C++), or longjmp
s (C) back to the select
call. The flag is set in the signal handler.
The issue with that approach is that a) it breaks if something happens to stop you polling the flag; b) it is quite hard to write code that is exception safe or which doesn’t leak resources if you longjmp
through it.