#233 VBO deletion happening in another thread than Main thread

v3.0.0
open
GL (74)
5
2010-12-04
2010-12-04
Anonymous
No

Hi pyopengl dudes,

I got a bug with VBO. It seem that the deletion of VBO (the one that involve glDeleteBuffers) is happening sometimes inside another thread than Main thread, and lead to a segfault.

I've added a call to threading.currentThread() + traceback.print_stack() just before the call of glDeleteBuffers() in arrays/vbo.py.
And normal case, i got: glDeleteBuffers() <_MainThread(MainThread, started 140737353901824)> + a traceback with last line very weird (like gc call...)
And the segfault case: glDeleteBuffers() <Thread(Thread-6, started daemon 140736902752016)>

Here is both traceback that look different : http://paste.pocoo.org/show/300045/ and http://paste.pocoo.org/show/300047/

It look like the callback of weakref.ref() is called when the object is deleted and finalized... but not in main thread.

Do you confirm this case ? Do you have any tips about how to do ?
I was thinking to use a Queue, and if the deletion happen outside the main thread, queuing the deletion for the next call. (tricky, but since pyopengl don't have clokc of callback from main thread...)

Discussion

  • The appropriate way to delete a VBO in a multi-threaded situation is to call .delete() on it in the rendering thread *before* you delete the VBO in another thread. The VBO's cleanup will then *not* delete the VBO. Anything I do to try to work around this will constrain the design of all pyopengl applications.

    That said, your approach would work fine (moving the deletions to the main thread) for your application:

    # non-render thread
    for obj in objs_to_delete:
    remove_from_tree(obj)
    to_delete_queue.push( obj ) # no garbage collection here because of this reference

    # render thread
    while: to_delete_queue:
    to_delete_queue.pop() # garbage collected and deleted here...

     

  • Anonymous
    2010-12-05

    Just to ensure you've understand me, i don't do any deletion of VBO in another thread than main thread. I've a reference to the VBO in a class, and when the class is gone, the vbo is gone too. All theses operations are always executed in a main thread.

    That's why i think this bug can happen as soon as you use thread in python no ? And that's problematic :/

     
  • ?? boggle ?? Okay, *that* is surprising. AFAIK the weakref code is just hooked into the DECREF counting so that iff count goes to < 1 then the weakrefs are called, then the __del__ method. I suppose somehow one of the callbacks might allow a thread context switch... but that still seems pretty exotic. Don't suppose you have a small test-case that shows this?

     
  • Tracker.. Bang-up :)