OSDN Git Service

Let unchecked exceptions thrown in a Runnable kill the app do not just
authorPat <pat@bitiotic.com>
Sat, 26 Jan 2013 00:28:44 +0000 (16:28 -0800)
committerPat <pat@bitiotic.com>
Sat, 26 Jan 2013 00:28:44 +0000 (16:28 -0800)
eat them.

Do not hold the lock on runnables across invocation of the callbacks.
Its fine to add more runnables while the executed runnables list is
being run through.

Add a test case too.

backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglApplication.java
tests/gdx-tests/src/com/badlogic/gdx/tests/RunnablePostTest.java [new file with mode: 0644]
tests/gdx-tests/src/com/badlogic/gdx/tests/utils/GdxTests.java

index 5050cc8..588cd09 100644 (file)
@@ -168,18 +168,14 @@ public class LwjglApplication implements Application {
                                executedRunnables.clear();\r
                                executedRunnables.addAll(runnables);\r
                                runnables.clear();\r
+                       }\r
 \r
-                               for (int i = 0; i < executedRunnables.size; i++) {\r
-                                       shouldRender = true;\r
-                                       try {\r
-                                               executedRunnables.get(i).run();\r
-                                       } catch (Throwable t) {\r
-                                               t.printStackTrace();\r
-                                       }\r
-                               }\r
+                       for (int i = 0; i < executedRunnables.size; i++) {\r
+                               shouldRender = true;\r
+                               executedRunnables.get(i).run(); // calls out to random app code that could do anything ...\r
                        }\r
 \r
-                       // If one of the runnables set running in false, for example after an exit().\r
+                       // If one of the runnables set running to false, for example after an exit().\r
                        if (!running) break;\r
 \r
                        input.update();\r
diff --git a/tests/gdx-tests/src/com/badlogic/gdx/tests/RunnablePostTest.java b/tests/gdx-tests/src/com/badlogic/gdx/tests/RunnablePostTest.java
new file mode 100644 (file)
index 0000000..55d9117
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\r
+ * Copyright 2011 See AUTHORS file.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *   http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ ******************************************************************************/\r
+                       \r
+package com.badlogic.gdx.tests;\r
+\r
+import com.badlogic.gdx.Gdx;\r
+import com.badlogic.gdx.tests.utils.GdxTest;\r
+\r
+/** Test that unchecked exceptions thrown from a runnable get posted and terminate the app. */\r
+public class RunnablePostTest extends GdxTest {\r
+       \r
+       private static final String TAG = "RunnablePostTest";\r
+       static boolean expectIt = false;\r
+       \r
+       static private Thread.UncaughtExceptionHandler exHandler = new Thread.UncaughtExceptionHandler() {\r
+               @Override\r
+               public void uncaughtException(Thread t, Throwable e) {\r
+                       if (expectIt) {\r
+                               Gdx.app.log(TAG, "PASSED: " + e.getMessage());\r
+                       } else {\r
+                               Gdx.app.log(TAG, "FAILED!  Unexpected exception received.");                            \r
+                               e.printStackTrace(System.err);\r
+                       }\r
+               }\r
+       };\r
+       \r
+       @Override\r
+       public boolean needsGL20 () {\r
+               return false;\r
+       }\r
+       \r
+       public void create () {\r
+               Thread.setDefaultUncaughtExceptionHandler(exHandler);           \r
+       }\r
+\r
+       @Override\r
+       public void render () {\r
+               if (Gdx.input.justTouched()) {\r
+                       expectIt = true;\r
+                       Gdx.app.postRunnable(new Runnable() {\r
+                               @Override\r
+                               public void run () {\r
+                                       throw new RuntimeException("This is a test of the uncaught exception handler.");\r
+                               }\r
+                       });\r
+               }\r
+       }\r
+}\r
index b4e61bb..cb21e73 100644 (file)
@@ -75,7 +75,8 @@ public class GdxTests {
                // InternationalFontsTest.class, VorbisTest.class\r
                TextButtonTest.class, TextButtonTestGL2.class, TextureBindTest.class, SortedSpriteTest.class,\r
                ExternalMusicTest.class, SoftKeyboardTest.class, DirtyRenderingTest.class, YDownTest.class,\r
-               ScreenCaptureTest.class, BitmapFontTest.class, LabelScaleTest.class, GLEEDTest.class, GamepadTest.class, NetAPITest.class));\r
+               ScreenCaptureTest.class, BitmapFontTest.class, LabelScaleTest.class, GLEEDTest.class, GamepadTest.class, NetAPITest.class,\r
+               RunnablePostTest.class));\r
        \r
        public static List<String> getNames () {\r
                List<String> names = new ArrayList<String>(tests.size());\r