C++ TinyThread and OpenGL with FreeGLUT - c++

The problem I've encountered is generated by the probable misuse of threading within a simplistic FreeGLUT C++ application.
Since exiting the glutMainLoop() cannot be done elegantly, I rely on glutLeaveMainLoop() to do some of the work, but this one doesn't really give the control back to the program's main function. I have a global pointer that will be set in the main function, prior to the GL calls, to an object instance created on the heap. Without using the atexit callback, nobody will call the delete operator on this instance, although I placed such an operation after the glutMainLoop call (now commented because of its futility).
Here's a pseudocode for what I'm doing (I won't post the actual code since it's too long to filter):
CWorld* g_world;
AtExit()
{
delete g_world;
}
void main()
{
atexit(AtExit);
// create an instance of an object that creates a thread in its constructor
// via the new operator and joins this thread in its destructor
// calling the delete operator on that pointer to the thread instance
CWidget thisObjectCreatesATinyThread;
g_world = new CWorld();
...
glutMainLoop();
// delete g_world;
}
Note that in the main function, I also included a widget instance that does some work via a thread created in its constructor. This thread is joined in its destructor, then the memory is deallocated via a delete.
The wrong behaviour: without setting the atexit callback, I get a resource leak, since the destructor of the CWorld object won't get called. If I set this callback, then the delete operator gets called twice for some reason, even though the AtExit function is called only once.
What is the place to look for the source of this odd behaviour?
Even if I disable the CWidget instantiation, I still get the peculiar behaviuor.

I assume you're not using the original GLUT library (since it's ancient) but rather FreeGLUT, which is the most wide-spread GLUT implementation. In order to have glutMainLoop() return, you would do:
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
before calling glutMainLoop(). This will cause it to return if there are no more active top-level windows left when you call glutLeaveMainLoop(). If you don't care about still active windows, instead do:
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
You probably have to include <GL/freeglut.h> instead of <GL/glut.h> in order to get the definitions.

Related

GLFW how to ensure glfwTerminate is called when the program exits?

In GLFW documentation it is written that glfwTerminate will
This will destroy any remaining window, monitor and cursor objects, restore any modified gamma ramps, re-enable the screensaver if it had been disabled and free any other resources allocated by GLFW.
and that one should call it before terminating the program. From my understanding that means, that if this function is not called the operating system doesn't have to re-enable the screensaver or restore modified gamma ramps, which is bad. How do I ensure that it is called regardless of how the program ends?
It's possible to use std::atexit to ensure it is called at the end if the program is exited via the exit command or by returning from the main function. It is also possible to do that making an object with a destructor in the main function that terminates when it is destroyed. The problem is what to do when the program ends with a signal. It's not possible to just register a function using std::signal, because glfwTerminate calls standard library functions other than the ones listed in https://en.cppreference.com/w/cpp/utility/program/signal which the site says is undefined behavior.
How do I ensure the program calls glfwTerminate? Or is it just not possible? And do I understand it correctly that without it the program can leave a modified gamma ramp after getting a signal? And are there any other ways the program can stop without calling the function?
There is no guarantee that the program will call glfwTerminate in case of segfaults or other undefined errors, so it is better to handle all errors before you decide to close it. So, recommendation is calling before the program terminates to restore the modified gamma ramps and re-enable the screensave.

What happens when a library is initialized?

I'm using GLFW and am getting confused by the logic of using libraries. According to my understanding of functions, when a function is called, the code within is executed and any memory allocated by said function is deallocated at the end of it. Although when calling glfwInit() for example, this allows for the subsequent use of other GLFW functions. My intuition is that this function call would have no effect on the code after it, so how is this happening?

Can destruction order be controlled across dynamic libraries?

I am encountering an issue where my library is crashing due to executable that loads me calling my function after main exits. I'm wondering - can I control the lifecycle of my globals to not be destroyed until (and if) my library gets unloaded? I understand what I'm asking.
Basically, the executable looks something like this (roughly):
struct MyLibController
{
void *libhandle;
void (*function)() myLibFunction;
~MyLibController()
{
myLibFunction(); // Call to my library's exported function
dlclose(libhandle);
}
};
std::shared_ptr<MyLibController> globalPtr;
int main(int argc, const char **argv)
{
globalPtr = std::make_shared<MyLibController>();
// initializing globalPtr to dlopen my library, map function ptrs, etc.
// do some work with my library
return 0;
}
I have absolutely no control over the code in this executable.
My library code look something like this:
SomeType globalObject;
// Exported function via c interface in my library
void myLibFunction()
{
// crash occurs globalObject is used after executable's main function exits
globalObject.someFunction();
// do some work
}
I have a lot of control over the library code - but this is a simple example. The Sometype globalObject is very necessary (suppose that it's a mutex, used to sync myLibFunction and a bunch of others).
I'd like to ensure that my globalObject is valid even after executable's main function exits. Is this possible? If so, how?
P.S. I am aware that I can dynamically allocate the globalObject and leak it, which resolves the crash. It feels wrong though, and I don't want to sign off on it.
You can register for a callback when the main() returns using std::atexit(): http://en.cppreference.com/w/cpp/utility/program/atexit
For example, when your library is loaded, use atexit() to register, then when that callback fires, set a flag for yourself that you check before trying to do anything else. If the flag is set, ignore any other actions from the caller, because the program is shutting down.
Your best bet is to make your global object a reference counted singleton of some sort. Then update your interface to instantiate an object from your loaded library. This object can then grab a reference to the global object during construction, and thus only releases it after it has been destroyed. The global variable itself would also merely have a reference, thus during the dlclose() process the global reference would be released, but your object would still have a reference until it is destroyed.
#o11c's comment provided a working solution:
Using attribute((constructor)) and attribute((destructor))
allows you to specify a priority
In other words, I can have the control over lifecycle of my variables despite binary's main function exiting (I just have to dynamically allocate them and free them).

Does exit(0) pose any issues in MFC?

I want to immediately exit my MFC app in C++. Is exit(0) the best solution? eg. does it prevent destructors from being called, is it threadsafe? etc. Is there a better solution? Thanks.
Yes, exit(0) is the best solution. It will cause the destructors of global objects (and static objects within functions) to run, however it will not cause destructors of stack-allocated or heap-allocated objects to run:
// At global scope
ClassWithDestruct globalObject;
void SomeFunction()
{
static ClassWithDestructor staticObject;
ClassWithDestructor stackObject;
ClassWithDestructor *heapObject = new ClassWithDestructor;
// On the following call to exit(), the destructors of 'globalObject' and
// 'staticObject' will run, but those of 'stackObject' and 'heapObject' will
// NOT run
exit(0);
}
As to whether or not it's thread-safe, that's a hard question to answer: you should not be calling exit simultaneously from multiple threads, you should only call it once. If any destructors run as a result of exit, or any if any functions registered with atexit run, then obviously those functions should be thread-safe if they deal with data that could potentially be being used by other threads.
If your program is exiting normally (say, as a result of the user requesting an exit), you should either call exit or return from main/WinMain, which is equivalent to calling exit. If your program is exiting abnormally (say, as a result of an access violation or failed assertion), you should call either _exit or abort, which do not call any destructors.
If you want to exit immediately, ensuring against running any destructors and such beforehand, then you probably want to call abort(). If you do want destructors to execute, then you probably want to use PostQuitMessage(0);. Either way, exit() is probably the wrong choice.
when a win32 process exits any resource associated with it is cleaned up by the OS, so in order to me it is perfectly ok.
exit(0) exits the process. All memory is cleaned up. On the other hand explicitly managed resources may not be closed. Of course file handles would be closed and stuff in windows buffers will be flushed. However stuff that the application manages will not.
No, it's not a safe way to end your program. Static-storage data and non-local automatic objects will destruct, but local automatic objects will not.
From 18.3/8 in the C++ standard:
The function exit() has additional
behavior in this International
Standard:
First, objects with static storage
duration are destroyed and functions
registered by calling atexit are
called. Non-local objects with static
storage duration are destroyed […].
(Automatic objects are not destroyed
as a result of calling
exit().)[207]) […] A local static
object obj3 is destroyed at the same
time it would be if a function calling
the obj3 destructor were registered
with atexit at the completion of the
obj3 constructor.
Next, all open C streams (as
mediated by the function signatures
declared in <cstdio>) with unwritten
buffered data are flushed, all open C
streams are closed, and all files
created by calling tmpfile() are
removed.[209])
[207]: Objects with automatic storage
duration are all destroyed in a
program whose function main()
contains no automatic objects and
executes the call to exit(). Control
can be transferred directly to such a
main() by throwing an exception that
is caught in main().
[209]: Any C streams associated with
cin, cout, etc (27.3) are flushed
and closed when static objects are
destroyed in the previous phase. The
function tmpfile() is declared in
<cstdio>.
On a related note, std::exit(EXIT_SUCCESS) is disturbingly misleading.

Explicitly calling a destructor in a signal handler

I have a destructor that performs some necessary cleanup (it kills processes). It needs to run even when SIGINT is sent to the program. My code currently looks like:
typedef boost::shared_ptr<PidManager> PidManagerPtr
void PidManager::handler(int sig)
{
std::cout << "Caught SIGINT\n";
instance_.~PidManagerPtr(); //PidManager is a singleton
exit(1);
}
//handler registered in the PidManager constructor
This works, but there seem to be numerous warnings against explicitly calling a destructor. Is this the right thing to do in this situation, or is there a "more correct" way to do it?
If that object is a singleton, you don't need to use a shared-pointer. (There's only one!)
If you switch it to auto_ptr you can call release() on it. Or perhaps scoped_ptr, calling reset().
This all said, I'm 99% certain that exit() will destruct statically constructed objects. (Which singletons tend to be.) What I do know is that exit() calls the registered atexit() functions.
If your singleton is not destructed automatically by exit, the proper thing to do in your case is to make an atexit hook:
void release_singleton(void)
{
//instance_.release();
instance_.reset();
}
// in main, probably
atexit(release_singleton);
Never explicitly call destructor unless object was constructed with placement new.
Move cleanup code into separate function and call it instead. The same function is to be called from the destructor.
Turns out that doing this was a very bad idea. The amount of weird stuff going on is tremendous.
What was happening
The shared_ptr had a use_count of two going into the handler. One reference was in PidManager itself, the other was in the client of PidManager. Calling the destructor of the shared_ptr (~PidManager() ) reduced the use_count by one. Then, as GMan hinted at, when exit() was called, the destructor for the statically initialized PidManagerPtr instance_ was called, reducing the use_count to 0 and causing the PidManager destructor to be called. Obviously, if PidManager had more than one client, the use_count would not have dropped to 0, and this wouldn't have worked at all.
This also gives some hints as to why calling instance_.reset() didn't work. The call does indeed reduce the reference count by 1. But the remaining reference is the shared_ptr in the client of PidManager. That shared_ptr is an automatic variable, so its destructor is not called at exit(). The instance_ destructor is called, but since it was reset(), it no longer points to the PidManager instance.
The Solution
I completely abandoned the use of shared_ptrs and decided to go with the Meyers Singleton instead. Now my code looks like this:
void handler(int sig)
{
exit(1);
}
typedef PidManager * PidManagerPtr
PidManagerPtr PidManager::instance()
{
static PidManager instance_;
static bool handler_registered = false;
if(!handler_registered)
{
signal(SIGINT,handler);
handler_registered = true;
}
return &instance_;
}
Explicitly calling exit allows the destructor of the statically initialized PidManager instance_ to run, so no other clean up code need be placed in the handler. This neatly avoids any issues with the handler being called while PidManager is in an inconsistent state.
You really don't want to do much of anything in a signal handler. The safest the thing to do is just set a flag (e.g. a global volatile bool), and then have your program's regular event loop check that flag every so often, and if it has become true, call the cleanup/shutdown routine from there.
Because the signal handler runs asynchronously with the rest of the application, doing much more than that from inside the signal handler is unsafe -- whatever data you might want to interact with might be in an inconsistent state. (and you're not allowed to use mutexes or other synchronization from a signal handler, either -- signals are pretty evil that way)
However, if you don't like the idea of having to poll a boolean all the time, one other thing you can do from within a signal handler (at least on most OS's) is send a byte on a socket. So you could set up a socketpair() in advance, and have your normal event loop select() (or whatever) on the other end of the socket pair; when it receives a byte on that socket, it knows your signal handler must have sent that byte, and therefore it's time to clean up.
One other way could be to have the singleton dynamically allocated (on first use or in main), and delete it for cleanup.
Eh. I guess your PidManagerPtr actually points to a dynamically allocated object ... But doesn't boost::shared_ptr actually clean up on reallocation? So it should be enough to:
instance_ = 0;
?
Just call reset() on the shared_ptr and it'll remove your instance for you.