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...)
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...
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
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 :)