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