# HG changeset patch # User michaelm # Date 1409062718 -3600 # Node ID 07d27e04533518ba78a5a6b23f16ce3e252b2c49 # Parent 56c6ac1ad45ef6d7adff1d1fae11ca6f218d9b59# Parent f7860e8501d820f0ef1afd914d86fe5d6c1068e0 Merge diff -r 56c6ac1ad45e -r 07d27e045335 jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c --- a/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Tue Aug 26 15:08:42 2014 +0100 +++ b/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Tue Aug 26 15:18:38 2014 +0100 @@ -333,7 +333,7 @@ int res = -1; RESTARTABLE(dup((int)fd), res); - if (fd == -1) { + if (res == -1) { throwUnixException(env, errno); } return (jint)res; @@ -361,13 +361,14 @@ JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream) { - int res; FILE* fp = jlong_to_ptr(stream); - do { - res = fclose(fp); - } while (res == EOF && errno == EINTR); - if (res == EOF) { + /* NOTE: fclose() wrapper is only used with read-only streams. + * If it ever is used with write streams, it might be better to add + * RESTARTABLE(fflush(fp)) before closing, to make sure the stream + * is completely written even if fclose() failed. + */ + if (fclose(fp) == EOF && errno != EINTR) { throwUnixException(env, errno); } } @@ -675,11 +676,9 @@ JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) { - int err; DIR* dirp = jlong_to_ptr(dir); - RESTARTABLE(closedir(dirp), err); - if (errno == -1) { + if (closedir(dirp) == -1 && errno != EINTR) { throwUnixException(env, errno); } } diff -r 56c6ac1ad45e -r 07d27e045335 jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java --- a/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java Tue Aug 26 15:08:42 2014 +0100 +++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java Tue Aug 26 15:18:38 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Semaphore; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; import javax.management.MBeanServerFactory; @@ -56,10 +58,12 @@ public class NotificationAccessControllerTest { public class NAC implements NotificationAccessController { - private boolean throwException; + private final boolean throwException; public NAC(boolean throwException) { this.throwException = throwException; } + + @Override public void addNotificationListener( String connectionId, ObjectName name, @@ -73,9 +77,13 @@ if (throwException) if (name.getCanonicalName().equals("domain:name=1,type=NB") && + subject != null + && subject.getPrincipals().contains(new JMXPrincipal("role"))) throw new SecurityException(); } + + @Override public void removeNotificationListener( String connectionId, ObjectName name, @@ -89,9 +97,13 @@ if (throwException) if (name.getCanonicalName().equals("domain:name=2,type=NB") && + subject != null + && subject.getPrincipals().contains(new JMXPrincipal("role"))) throw new SecurityException(); } + + @Override public void fetchNotification( String connectionId, ObjectName name, @@ -105,13 +117,17 @@ echo("\tsubject: " + (subject == null ? null : subject.getPrincipals())); if (!throwException) - if (name.getCanonicalName().equals("domain:name=2,type=NB") && + if (name.getCanonicalName().equals("domain:name=2,type=NB") + && + subject != null + && subject.getPrincipals().contains(new JMXPrincipal("role"))) throw new SecurityException(); } } public class CustomJMXAuthenticator implements JMXAuthenticator { + @Override public Subject authenticate(Object credentials) { String role = ((String[]) credentials)[0]; echo("\nCreate principal with name = " + role); @@ -129,6 +145,7 @@ public static class NB extends NotificationBroadcasterSupport implements NBMBean { + @Override public void emitNotification(int seqnum, ObjectName name) { if (name == null) { sendNotification(new Notification("nb", this, seqnum)); @@ -139,13 +156,20 @@ } public class Listener implements NotificationListener { - public List notifs = new ArrayList(); + public final List notifs = new CopyOnWriteArrayList<>(); + + private final Semaphore s; + public Listener(Semaphore s) { + this.s = s; + } + @Override public void handleNotification(Notification n, Object h) { echo("handleNotification:"); echo("\tNotification = " + n); echo("\tNotification.SeqNum = " + n.getSequenceNumber()); echo("\tHandback = " + h); notifs.add(n); + s.release(); } } @@ -192,6 +216,17 @@ JMXConnectorServer server = null; JMXConnector client = null; + /* + * (!enableChecks) + * - List must contain three notifs from sources nb1, nb2 and nb3 + * (enableChecks && !throwException) + * - List must contain one notif from source nb1 + * (enableChecks && throwException) + * - List must contain two notifs from sources nb2 and nb3 + */ + final int expected_notifs = + (!enableChecks ? 3 : (throwException ? 2 : 1)); + // Create a new MBeanServer // final MBeanServer mbs = MBeanServerFactory.createMBeanServer(); @@ -199,7 +234,7 @@ try { // Create server environment map // - final Map env = new HashMap(); + final Map env = new HashMap<>(); env.put("jmx.remote.authenticator", new CustomJMXAuthenticator()); if (enableChecks) { env.put("com.sun.jmx.remote.notification.access.controller", @@ -222,7 +257,7 @@ // Create server environment map // - final Map cenv = new HashMap(); + final Map cenv = new HashMap<>(); String[] credentials = new String[] { "role" , "password" }; cenv.put("jmx.remote.credentials", credentials); @@ -246,7 +281,9 @@ // Add notification listener // - Listener li = new Listener(); + Semaphore s = new Semaphore(0); + + Listener li = new Listener(s); try { mbsc.addNotificationListener(nb1, li, null, null); if (enableChecks && throwException) { @@ -263,6 +300,9 @@ } mbsc.addNotificationListener(nb2, li, null, null); + System.out.println("\n+++ Expecting to receive " + expected_notifs + + " notification" + (expected_notifs > 1 ? "s" : "") + + " +++"); // Invoke the "sendNotification" method // mbsc.invoke(nb1, "emitNotification", @@ -277,7 +317,7 @@ // Wait for notifications to be emitted // - Thread.sleep(2000); + s.acquire(expected_notifs); // Remove notification listener // @@ -303,21 +343,7 @@ sources.add(nb1); sources.add(nb2); sources.add(nb3); - if (!enableChecks) { - // List must contain three notifs from sources nb1, nb2 and nb3 - // - result = checkNotifs(3, li.notifs, sources); - } - if (enableChecks && !throwException) { - // List must contain one notif from source nb1 - // - result = checkNotifs(1, li.notifs, sources); - } - if (enableChecks && throwException) { - // List must contain two notifs from sources nb2 and nb3 - // - result = checkNotifs(2, li.notifs, sources); - } + result = checkNotifs(expected_notifs, li.notifs, sources); if (result > 0) { return result; }