On Thursday, September 26, 2019 at 10:57:17 AM UTC+1, Paavo Helde wrote:
> exit() is not among the functions you can legally call from a signal
> handler; see "
http://man7.org/linux/man-pages/man7/signal-safety.7.html"
>
> This is easy to understand: consider what happens when the signal
> handler is invoked at the moment when the program is in a malloc() call
> and actively modifying the global memory manager data structures, and
> there is an installed atexit() function which wants to call free() at
> the same time.
Ok I'm really starting to think that this should be done from scratch all by ourselves. Maybe we should abandon the use of "atexit".
How about we change the "minimalistic C++ program" to the following?
#include <exception> /* exception */
#include <functional> /* function */
#include <stack> /* stack : Note that this is Last In First Out */
#include <cstdlib> /* EXIT_FAILURE */
inline void Perimortem_Run(std::function<void()> const &f, int const hidden_param = 0)
{
static std::stack< std::function<void()> > stuff_to_do;
if ( 42 != hidden_param )
{
stuff_to_do.push(f);
return;
}
for ( ; !stuff_to_do.empty(); stuff_to_do.pop() )
{
stuff_to_do.top()();
}
}
int GetHandle(void) { return 42; }
void ReleaseHandle(int) { /* Whatever */ }
void SomeFunc(void)
{
int h = GetHandle();
Perimortem_Run( [h](){ReleaseHandle(h);} );
/* Re-use 'h' again, maybe even get another handle */
}
int real_main()
{
/* Your program goes here */
SomeFunc();
return 0;
}
int main()
{
int retval = EXIT_FAILURE;
try
{
retval = real_main();
}
catch(std::exception const &e)
{
/* Do something with e.what() */
}
catch(...)
{
}
Perimortem_Run( std::function<void()>(), 42 ); /* Passing the hidden 42 makes it do its thing */
return retval;
}
How does that look?