@@ -1224,8 +1224,8 @@ private static int getInvokeLaterMode() {
1224
1224
final String invokeLaterArg = System .getProperty (invokeLaterKey );
1225
1225
final int result ;
1226
1226
if (invokeLaterArg == null ) {
1227
- // default = 'enabled' to avoid any potential freeze (safe) until better solution :
1228
- result = INVOKE_LATER_ENABLED ;
1227
+ // default = 'false' :
1228
+ result = INVOKE_LATER_DISABLED ;
1229
1229
} else {
1230
1230
switch (invokeLaterArg .toLowerCase ()) {
1231
1231
default :
@@ -1247,51 +1247,46 @@ private static int getInvokeLaterMode() {
1247
1247
return result ;
1248
1248
}
1249
1249
1250
- @ SuppressWarnings ("removal" )
1251
- private final static boolean INVOKE_LATER_USE_PWM = getInvokeLaterUsePWM ();
1252
-
1253
- private static boolean getInvokeLaterUsePWM () {
1254
- final String usePwmKey = "awt.mac.flushBuffers.pwm" ;
1255
- final String usePwmArg = System .getProperty (usePwmKey );
1256
- final boolean result ;
1257
- if (usePwmArg == null ) {
1258
- // default = 'false':
1259
- result = false ;
1260
- } else {
1261
- result = "true" .equalsIgnoreCase (usePwmArg );
1262
- logger .info ("CPlatformWindow: property \" {0}={1}\" , using usePWM={2}." ,
1263
- usePwmKey , usePwmArg , result );
1264
- }
1265
- return result ;
1266
- }
1267
-
1250
+ private final static long NANOS_PER_SEC = 1000000000L ;
1268
1251
/* 10s period arround reference times (sleep/wake-up...)
1269
1252
* to ensure all displays are awaken properly */
1270
- private final static long NANOS_PER_SEC = 1000000000L ;
1271
1253
private final static long STATE_CHANGE_PERIOD = 10L * NANOS_PER_SEC ;
1272
1254
1273
1255
private final AtomicBoolean mirroringState = new AtomicBoolean (false );
1274
1256
/** per window timestamp of disabling mirroring */
1275
1257
private final AtomicLong mirroringDisablingTime = new AtomicLong (0L );
1276
1258
1277
1259
// Specific class needed to get obvious stack traces:
1278
- private final class EmptyRunnable implements Runnable {
1260
+ private final static class EmptyRunnable implements Runnable {
1261
+
1262
+ private final String identifier ;
1263
+
1264
+ EmptyRunnable (final String identifier ) {
1265
+ this .identifier = identifier ;
1266
+ }
1267
+
1279
1268
@ Override
1280
1269
public void run () {
1281
1270
// Posting an empty to flush the EventQueue without blocking the main thread
1282
1271
if (logger .isLoggable (PlatformLogger .Level .FINE )) {
1283
- logger .fine ("CPlatformWindow.flushBuffers: run() invoked on {0}" ,
1284
- getIdentifier (target ));
1272
+ logger .fine ("CPlatformWindow.flushBuffers: run() invoked on target: {0}" , identifier );
1285
1273
}
1286
1274
}
1287
1275
};
1288
- private final EmptyRunnable emptyTask = new EmptyRunnable ();
1289
1276
1290
1277
void flushBuffers () {
1291
1278
// Only 1 usage by deliverMoveResizeEvent():
1292
1279
// System-dependent appearance optimization.
1293
1280
// May be blocking so postpone this event processing:
1294
1281
1282
+ // Test only to validate LWCToolkit self-defense against freezes:
1283
+ final boolean checkLWCToolkitBlockingMainGuard = false ;
1284
+
1285
+ if (!checkLWCToolkitBlockingMainGuard && LWCToolkit .isBlockingMainThread ()) {
1286
+ logger .fine ("Blocked main thread, skip flushBuffers()." );
1287
+ return ;
1288
+ }
1289
+
1295
1290
if (isVisible () && !nativeBounds .isEmpty () && !isFullScreenMode ) {
1296
1291
// use the system property 'awt.mac.flushBuffers.invokeLater' to true/auto (default: auto)
1297
1292
// to avoid deadlocks caused by the LWCToolkit.invokeAndWait() call below:
@@ -1307,7 +1302,6 @@ void flushBuffers() {
1307
1302
1308
1303
// JBR-5497: force using invokeLater() when computer returns from sleep or displayChanged()
1309
1304
// (mirroring case especially) to avoid deadlocks until solved definitely:
1310
-
1311
1305
boolean mirroring = false ;
1312
1306
if (peer != null ) {
1313
1307
final GraphicsDevice device = peer .getGraphicsConfiguration ().getDevice ();
@@ -1357,39 +1351,30 @@ void flushBuffers() {
1357
1351
useInvokeLater = true ;
1358
1352
break ;
1359
1353
}
1360
- if (!useInvokeLater && INVOKE_LATER_USE_PWM ) {
1361
- // If the system property 'awt.mac.flushBuffers.pwm' is true,
1362
- // invokeLater is enforced during power transitions.
1363
- final boolean inTransition = LWCToolkit .isWithinPowerTransition ();
1364
- if (inTransition ) {
1365
- logger .fine ("CPlatformWindow.flushBuffers[pwm]: inTransition = true" );
1366
- useInvokeLater = true ;
1367
- }
1368
- }
1369
1354
try {
1355
+ final String identifier = logger .isLoggable (PlatformLogger .Level .FINE ) ? getIdentifier (target ) : null ;
1356
+ final EmptyRunnable emptyTask = new EmptyRunnable (identifier );
1357
+
1370
1358
// check invokeAndWait: KO (operations require AWTLock and main thread)
1371
- // => use invokeLater as it is an empty event to force refresh ASAP
1359
+ // => use invokeLater as it is an empty event to force refresh
1372
1360
if (useInvokeLater ) {
1373
1361
LWCToolkit .invokeLater (emptyTask , target );
1374
1362
} else {
1363
+ /* Ensure >3000ms = 3.666ms timeout to avoid any deadlock among
1364
+ * appkit, EDT, Flusher & a11y threads, locks
1365
+ * and various synchronization patterns... */
1366
+ final double timeoutSeconds = 3.666 ; // seconds
1367
+
1375
1368
if (logger .isLoggable (PlatformLogger .Level .FINE )) {
1376
1369
logger .fine ("CPlatformWindow.flushBuffers: enter " +
1377
- "LWCToolkit.invokeAndWait(emptyTask) on target = {0}" ,
1378
- getIdentifier (target ));
1370
+ "LWCToolkit.invokeAndWait(emptyTask) on target = {0}" , identifier );
1379
1371
}
1380
1372
1381
- /* Ensure >500ms = 666ms timeout to avoid any deadlock among
1382
- * appkit, EDT, Flusher & a11y threads, locks
1383
- * and various synchronization patterns... */
1384
- final double timeoutSeconds = 0.666 ; // seconds
1385
-
1386
- // FUCK: appKit is calling this method !
1387
1373
LWCToolkit .invokeAndWait (emptyTask , target , timeoutSeconds );
1388
1374
1389
1375
if (logger .isLoggable (PlatformLogger .Level .FINE )) {
1390
1376
logger .fine ("CPlatformWindow.flushBuffers: exit " +
1391
- "LWCToolkit.invokeAndWait(emptyTask) on target = {0}" ,
1392
- getIdentifier (target ));
1377
+ "LWCToolkit.invokeAndWait(emptyTask) on target = {0}" , identifier );
1393
1378
}
1394
1379
}
1395
1380
} catch (InvocationTargetException ite ) {
@@ -1442,6 +1427,10 @@ public void doDeliverMoveResizeEvent() {
1442
1427
/* native call by AWTWindow._deliverMoveResizeEvent() */
1443
1428
protected void deliverMoveResizeEvent (int x , int y , int width , int height ,
1444
1429
boolean byUser ) {
1430
+
1431
+ /* Test only to generate more appkit freezes */
1432
+ final boolean bypassToHaveMoreFreezes = false ;
1433
+
1445
1434
AtomicBoolean ref = new AtomicBoolean ();
1446
1435
execute (ptr -> {
1447
1436
ref .set (CWrapper .NSWindow .isZoomed (ptr ));
@@ -1460,10 +1449,9 @@ protected void deliverMoveResizeEvent(int x, int y, int width, int height,
1460
1449
}
1461
1450
1462
1451
// System-dependent appearance optimization.
1463
- if ((byUser && !oldB .getSize ().equals (nativeBounds .getSize ()))
1452
+ if (bypassToHaveMoreFreezes
1453
+ || (byUser && !oldB .getSize ().equals (nativeBounds .getSize ()))
1464
1454
|| isFullScreenAnimationOn ) {
1465
-
1466
- // May be blocking so postpone this event processing:
1467
1455
flushBuffers ();
1468
1456
}
1469
1457
}
0 commit comments