Currently race-conditions are possible on the following high level utility method: - GLDrawableUtil.swapGLContextAndAllGLEventListener( GLAutoDrawable a, GLAutoDrawable b); - GLEventListenerState.moveFrom(GLAutoDrawable src) - GLEventListenerState.moveTo(GLAutoDrawable dest) Their implementation lacks locking of [1] the GLAutoDrawable's NativeSurface, as well as of [2] the GLAutoDrawable's implementation own 'upstream' lock. Locking of the NativeSurface is mandatory to hinder other threads of acquiring the OpenGL context (lock). Since GLAutoDrawable implementations also employ their own 'high-level' lock, e.g. for modifying their surface/drawable, it is important to acquire a lock on such beforehand. Actual locking order of GLAutoDrawable is: 1) GLAutoDrawable Lock 2) NativeSurface Lock (Note: GLContext.makeCurrent() acquires the NativeSurface Lock 1st.) Allowing proper locking requires our API to expose the GLAutoDrawable 'upstream' lock! Note: While holding the GLAutoDrawable locks, GLAutoDrawable.invoke(..) cannot be issued, since it may be performed off-thread.
c77b8f586cb2553582a42f5b90aeee5ef85f1efe GLAutoDrawable (API CHANGE) allowing atomic operations: - Add class API-doc chapter about 'GLAutoDrawable Locking' - Add method invoke(..) API-doc description about throwing IllegalStateException in case of a detected deadlock situation ahead (Note: Implemented in GLDrawableHelper.invoke(..) for all implementations) - Add new methods for proper multithread handling: - public RecursiveLock getUpstreamLock(); - public boolean isThreadGLCapable(); +++ GLEventListenerState/GLDrawableUtil: - Perform operation in a atomic fashion, i.e. lock GLAutoDrawable during whole operations: - GLDrawableUtil.swapGLContext(..) - GLDrawableUtil.swapGLContextAndAllGLEventListener(..) - GLEventListenerState.moveFrom(..) - GLEventListenerState.moveTo(..) - ReshapeGLEventListener: - Moved from GLEventListenerState.ReshapeGLEventListener -> GLDrawableUtil.ReshapeGLEventListener - Takes 'displayAfterReshape' case into account. +++ javax.media.opengl.Threading Clarifications: - Public 'enum Mode', i.e. Threading.Mode - Public getMode() - Clarified 'isOpenGLThread()': - Take 'singleThreaded' into account directly, i.e. always return 'true' if singleThreaded == false