Bug 1076 - Fix race conditions in GLDrawableHelper glRunnable and Animator* for unhandled exceptions
Summary: Fix race conditions in GLDrawableHelper glRunnable and Animator* for unhandle...
Status: RESOLVED FIXED
Alias: None
Product: Jogl
Classification: JogAmp
Component: core (show other bugs)
Version: 2.3.0
Hardware: All all
: --- major
Assignee: Sven Gothel
URL:
Depends on:
Blocks:
 
Reported: 2014-09-22 23:36 CEST by Sven Gothel
Modified: 2019-03-29 17:54 CET (History)
1 user (show)

See Also:
Type: DEFECT
SCM Refs:
c298b4317a30cc453a2350ebeb5ab3570a4c107d cef7ba607ad7e8eb1ff2a438d77710a29aa0bda6 66ecb6c386d5c3d87d8be2600a0c7dd7d71a4329
Workaround: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sven Gothel 2014-09-22 23:36:10 CEST
commit c298b4317a30cc453a2350ebeb5ab3570a4c107d:

GLDrawable.invoke(..) regression of 
commit c77b8f586cb2553582a42f5b90aeee5ef85f1efe:
  'wait' was not set to false, if 'deferredHere' was forced to 'false'.
  This could lead to the situation where GLRunnableTask
  will catch the exception and supresses it.

Animator/FPSAnimator post exception propagation code
   animThread = null; notifyAll();
must be complete to finalize animator state in case of an exception.
Decorate 'handleUncaughtException(..)' w/ try { } finally { }
where the latter ensures the mentioned 'closure'.

+++

commit cef7ba607ad7e8eb1ff2a438d77710a29aa0bda6:

Fix synchronization issues in GLDrawableHelper.flushGLRunnables():
  - Querying 'glRunnables.size()' is not synchronized, only its reference is volatile,
    not the instance's own states.

  - 'flushGLRunnable()' must operates while acquired the 'glRunnable' lock.

  - 'glRunnables' are no more volatile

  - introduced volatile 'glRunnableCount', allowing 'display(..)' method
    to pre-query whether blocking 'execGLRunnables(..)' must be called.
    This is risk (deadlock) free.

Also fixes rare deadlock in animator display-exception / GLAD.invoke(wait=true, ..) case:
  - 'GLDrawableHelper.invoke(.., GLRunnable)' acquires the 'glRunnable' lock.
  - Then it queries animator state, which is blocking.
  - Hence animator's 'flushGLRunnable()' call must happen outside the animator lock
Comment 1 Sven Gothel 2014-09-23 04:00:17 CEST
commit 66ecb6c386d5c3d87d8be2600a0c7dd7d71a4329:

Fix synchronization issues in Animator* Exception case

Refines commit cef7ba607ad7e8eb1ff2a438d77710a29aa0bda6

- The animator monitor-lock was still hold in the post finally block
  issuing flushGLRunnables(), due to intrinsic monitor release (in finally):
   - <http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.11.10>
   - <http://stackoverflow.com/questions/10743285/behavior-of-a-synchronized-method-with-try-and-finally>

- Further: AnimatorBase.flushGLRunnables() acquired the lock itself (duh!)

This commit removes the requirement for finally altogether
by simply return a boolean from handleUncaughtException(caughtException),
where false denotes the caller to propagate the exception itself (no handler).

Post synchronized block then issues flushGLRunnables() and
exceptation propagation as required.

AnimatorBase.flushGLRunnables() 'synchronized' modifier is removed.

Further, ThreadDeath is being propagated if caught.
Here the finally block is also removed - redundant.