Re: Error passing function in signal( ... )
On Dec 30, 2:17 am, Ian Collins <ian-n...@hotmail.com> wrote:
On 12/30/10 12:48 PM, Dudebot wrote:
Whoa. This seems like choosing between two bad design options, almost
a philosophical question.
Pavel points me to making a wrapper in
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2,
where the number of caveats is too numerous to count ;)
Ian tells me to make it extern... meaning, try to match the objects
perfectly in the compile, and hope for the best.
Hope for the best?
Are these really the only two good ways to proceed?
Well your options are limited by the C interface you are working with.
You simply can't pass a C++ member function (the signature is wrong)
some compilers will let you get away with a static member function , but
the linkage is still wrong.
The handler function signature means neither a static member or a friend
function can be passed a pointer to a class instance. Using the int
parameter to pass some form of index might be your only option.
It's not really an option either; you're very, very limited with
regards to what you can do in a signal handler: you *can't* call
exit (which he apparently wants to do), you can't even access
anything C++. According to the C standard, all you can do is
write (but not read) to a variable with type sig_atomic_t.
Posix (and presumably Windows) allows a little bit more, but
nothing which involves C++: you can't do stream IO (FILE* or
iostream), you can't call a destructor, and you can't throw an
exception. (You can call _exit or abort, but this won't flush
any stream buffers.)
More generally, you probably don't want to, at least if the goal
is to trigger a clean shutdown. You normally can't start
a clean shutdown at just anytime, and signals arrive
asynchronously. The usual solution depends on the application:
for anything multithreaded under Unix, you can create a special
signal handler thread; signals will generate an event which
unblocks the thread, and the thread can start the clean shutdown
(running as a normal thread, and not as a signal handler). For
single threaded processes, the usual solution is just to have
a global sig_atomic_t initialized to zero, set it to one in the
signal handler, and poll it at appropriate moments.
--
James Kanze