Use of mutex in destructors
Rene Zwanenburg
renezwanenburg at gmail.com
Fri Apr 27 04:15:03 PDT 2012
Since an OpenGL context is owned by one thread, any OpenGL calls
made from other threads will fail. I've wrapped OpenGL 'objects'
in D classes to automate destruction of the underlying object:
this() {
// Init texture
}
~this() {
glDeleteTextures(1, &_handle);
}
This will blow up if the GC runs in it's own thread. As a
solution, I was planning for each wrapper instance to have a
reference to an OpenGL command queue unique to the context which
owns the object. This queue will be emptied once per frame. The
texture wrapper will change to
this(CommandQueue comQueue) {
this.comQueue = comQueue;
comQueue ~= { /* Init texture */ }
}
~this() {
this.comQueue ~= { /* Delete texture */ }
}
Putting the initialization in a command allows for asynchronous
loading of resources, which is a nice bonus. However, access to
this queue should be synchronized. I haven't used synchronized in
D yet so I'd like to know what happens in the following situation:
One thread is processing the command queue. Due to some
allocation by code in a command or on another thread, the GC
runs. The processing thread still holds the lock on the queue
mutex when the GC blocks all threads. The GC runs the destructor
of a resource, so it waits for the lock on the queue to be
released and we have a deadlock.
Does the GC somehow avoid this? If not, what's the best solution
to this problem?
More information about the Digitalmars-d-learn
mailing list