Hi Martin,

If you want to optimize for without-security-manager case, then it would be better this way:

    private static void privilegedInterrupt(Thread t) {
        if (System.getSecurityManager() == null) {
            t.interrupt();
        } else {
            PrivilegedAction<Void> doInterrupt =
                () -> { t.interrupt(); return null; };
           AccessController.doPrivileged(doInterrupt);
        }
    }


...and no security exception catching. This way you don't trigger double security checks for case with-security-manager and not enough permission...

Regards, Peter

On 10/02/2013 06:29 PM, Martin Buchholz wrote:
FutureTask.cancel(true) invokes thread.interrupt on the thread (if any)
currently running the task.
This should succeed even if modifyThread permission is denied by the
security manager.

Here's a proposed fix for jdk8+:

--- src/main/java/util/concurrent/FutureTask.java 15 May 2013 02:39:59 -0000
1.103
+++ src/main/java/util/concurrent/FutureTask.java 2 Oct 2013 16:25:23 -0000
@@ -132,6 +132,12 @@
          return state != NEW;
      }

+    private static void privilegedInterrupt(Thread t) {
+        java.security.PrivilegedAction<Void> doInterrupt =
+            () -> { t.interrupt(); return null; };
+        java.security.AccessController.doPrivileged(doInterrupt);
+    }
+
      public boolean cancel(boolean mayInterruptIfRunning) {
          if (!(state == NEW &&
                UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
@@ -142,7 +148,11 @@
                  try {
                      Thread t = runner;
                      if (t != null)
-                        t.interrupt();
+                        try {
+                            t.interrupt();
+                        } catch (SecurityException e) {
+                            privilegedInterrupt(t);
+                        }
                  } finally { // final state
                      UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                  }

Reply via email to