changeset 14446:172c73eb036d

Merge
author andrew
date Wed, 12 May 2021 16:21:59 +0100
parents d29bb160b027 (current diff) d648900019b6 (diff)
children 0056610eefad
files
diffstat 6 files changed, 232 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Mon May 10 03:15:44 2021 +0100
+++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Wed May 12 16:21:59 2021 +0100
@@ -540,7 +540,7 @@
     // locks may be deadlocked.
     @Override
     public void close() throws IOException {
-        if (tlsIsClosed) {
+        if (isClosed()) {
             return;
         }
 
@@ -549,19 +549,16 @@
         }
 
         try {
-            // shutdown output bound, which may have been closed previously.
-            if (!isOutputShutdown()) {
-                duplexCloseOutput();
-            }
+            if (isConnected()) {
+                // shutdown output bound, which may have been closed previously.
+                if (!isOutputShutdown()) {
+                    duplexCloseOutput();
+                }
 
-            // shutdown input bound, which may have been closed previously.
-            if (!isInputShutdown()) {
-                duplexCloseInput();
-            }
-
-            if (!isClosed()) {
-                // close the connection directly
-                closeSocket(false);
+                // shutdown input bound, which may have been closed previously.
+                if (!isInputShutdown()) {
+                    duplexCloseInput();
+                }
             }
         } catch (IOException ioe) {
             // ignore the exception
@@ -569,7 +566,19 @@
                 SSLLogger.warning("SSLSocket duplex close failed", ioe);
             }
         } finally {
-            tlsIsClosed = true;
+            if (!isClosed()) {
+                // close the connection directly
+                try {
+                    closeSocket(false);
+                } catch (IOException ioe) {
+                    // ignore the exception
+                    if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
+                        SSLLogger.warning("SSLSocket close failed", ioe);
+                    }
+                } finally {
+                    tlsIsClosed = true;
+                }
+            }
         }
     }
 
--- a/src/windows/classes/sun/print/PrintServiceLookupProvider.java	Mon May 10 03:15:44 2021 +0100
+++ b/src/windows/classes/sun/print/PrintServiceLookupProvider.java	Wed May 12 16:21:59 2021 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, 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
@@ -25,10 +25,10 @@
 
 package sun.print;
 
-import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
+
 import javax.print.DocFlavor;
 import javax.print.MultiDocPrintService;
 import javax.print.PrintService;
@@ -120,13 +120,6 @@
         if (win32PrintLUS == null) {
             win32PrintLUS = this;
 
-            String osName = AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("os.name"));
-            // There's no capability for Win98 to refresh printers.
-            // See "OpenPrinter" for more info.
-            if (osName != null && osName.startsWith("Windows 98")) {
-                return;
-            }
             // start the local printer listener thread
             Thread thr = new PrinterChangeListener();
             thr.setDaemon(true);
@@ -353,28 +346,9 @@
         return defaultPrintService;
     }
 
-    class PrinterChangeListener extends Thread {
-        long chgObj;
-        PrinterChangeListener() {
-            chgObj = notifyFirstPrinterChange(null);
-        }
-
+    private final class PrinterChangeListener extends Thread {
         public void run() {
-            if (chgObj != -1) {
-                while (true) {
-                    // wait for configuration to change
-                    if (notifyPrinterChange(chgObj) != 0) {
-                        try {
-                            refreshServices();
-                        } catch (SecurityException se) {
-                            break;
-                        }
-                    } else {
-                        notifyClosePrinterChange(chgObj);
-                        break;
-                    }
-                }
-            }
+            notifyLocalPrinterChange(); // busy loop in the native code
         }
     }
 
@@ -441,8 +415,6 @@
 
     private native String getDefaultPrinterName();
     private native String[] getAllPrinterNames();
-    private native long notifyFirstPrinterChange(String printer);
-    private native void notifyClosePrinterChange(long chgObj);
-    private native int notifyPrinterChange(long chgObj);
+    private native void notifyLocalPrinterChange();
     private native String[] getRemotePrintersNames();
 }
--- a/src/windows/native/sun/windows/WPrinterJob.cpp	Mon May 10 03:15:44 2021 +0100
+++ b/src/windows/native/sun/windows/WPrinterJob.cpp	Wed May 12 16:21:59 2021 +0100
@@ -185,28 +185,20 @@
     return getPrinterNames(env, PRINTER_ENUM_CONNECTIONS);
 }
 
-
-JNIEXPORT jlong JNICALL
-Java_sun_print_PrintServiceLookupProvider_notifyFirstPrinterChange(JNIEnv *env,
-                                                                jobject peer,
-                                                                jstring printer) {
-    HANDLE hPrinter;
+JNIEXPORT void JNICALL
+Java_sun_print_PrintServiceLookupProvider_notifyLocalPrinterChange(JNIEnv *env,
+                                                                   jobject peer)
+{
+    jclass cls = env->GetObjectClass(peer);
+    CHECK_NULL(cls);
+    jmethodID refresh = env->GetMethodID(cls, "refreshServices", "()V");
+    CHECK_NULL(refresh);
 
-    LPTSTR printerName = NULL;
-    if (printer != NULL) {
-        printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
-                                                         printer,
-                                                         NULL);
-        JNU_ReleaseStringPlatformChars(env, printer, printerName);
+    HANDLE hPrinter;
+    LPTSTR printerName = NULL; // NULL indicates the local printer server
+    if (!::OpenPrinter(printerName, &hPrinter, NULL)) {
+        return;
     }
-
-    // printerName - "Win NT/2K/XP: If NULL, it indicates the local printer
-    // server" - MSDN.   Win9x : OpenPrinter returns 0.
-    BOOL ret = OpenPrinter(printerName, &hPrinter, NULL);
-    if (!ret) {
-      return (jlong)-1;
-    }
-
     // PRINTER_CHANGE_PRINTER = PRINTER_CHANGE_ADD_PRINTER |
     //                          PRINTER_CHANGE_SET_PRINTER |
     //                          PRINTER_CHANGE_DELETE_PRINTER |
@@ -215,32 +207,23 @@
                                                        PRINTER_CHANGE_PRINTER,
                                                        0,
                                                        NULL);
-    return (chgObj == INVALID_HANDLE_VALUE) ? (jlong)-1 : (jlong)chgObj;
-}
-
-
-
-JNIEXPORT void JNICALL
-Java_sun_print_PrintServiceLookupProvider_notifyClosePrinterChange(JNIEnv *env,
-                                                                jobject peer,
-                                                                jlong chgObject) {
-    FindClosePrinterChangeNotification((HANDLE)chgObject);
-}
-
+    if (chgObj != INVALID_HANDLE_VALUE) {
+        BOOL keepMonitoring;
+        do {
+            keepMonitoring = FALSE;
+            if (WaitForSingleObject(chgObj, INFINITE) == WAIT_OBJECT_0) {
+                DWORD dwChange;
+                keepMonitoring = FindNextPrinterChangeNotification(
+                                                 chgObj, &dwChange, NULL, NULL);
+            }
+            if (keepMonitoring) {
+                env->CallVoidMethod(peer, refresh);
+            }
+        } while (keepMonitoring && !env->ExceptionCheck());
 
-JNIEXPORT jint JNICALL
-Java_sun_print_PrintServiceLookupProvider_notifyPrinterChange(JNIEnv *env,
-                                                           jobject peer,
-                                                           jlong chgObject) {
-    DWORD dwChange;
-
-    DWORD ret = WaitForSingleObject((HANDLE)chgObject, INFINITE);
-    if (ret == WAIT_OBJECT_0) {
-        return(FindNextPrinterChangeNotification((HANDLE)chgObject,
-                                                  &dwChange, NULL, NULL));
-    } else {
-        return 0;
+        FindClosePrinterChangeNotification(chgObj);
     }
+    ::ClosePrinter(hPrinter);
 }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/print/PrintServicesSecurityManager.java	Wed May 12 16:21:59 2021 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+
+import javax.print.PrintServiceLookup;
+
+/*
+ * @test
+ * @bug 8241829
+ */
+public final class PrintServicesSecurityManager {
+
+    public static void main(String[] args) throws InterruptedException {
+        System.setSecurityManager(new SecurityManager());
+        test();
+        Thread.sleep(3000); // to be sure the pooling thread started
+        test();
+    }
+
+    private static void test() {
+        Object[] services = PrintServiceLookup.lookupPrintServices(null, null);
+        if (services.length != 0) {
+            System.err.println("services = " + Arrays.toString(services));
+            throw new RuntimeException("The array of Services must be empty");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/SSLSocketImpl/SSLSocketLeak.java	Wed May 12 16:21:59 2021 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020 SAP SE. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+import com.sun.management.UnixOperatingSystemMXBean;
+
+/*
+ * @test
+ * @bug 8256818 8257670 8257884 8257997
+ * @summary Test that creating and closing SSL Sockets without bind/connect
+ *          will not leave leaking socket file descriptors
+ * @run main/native/manual/othervm SSLSocketLeak
+ * @comment native library is required only on Windows, use the following commands:
+ *          "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
+ *          cl ^
+ *              /LD ^
+ *              <path/to/jdksrc>\jdk\test\sun\security\ssl\SSLSocketImpl\libFileUtils.c ^
+ *              /I<path/to/jdkbin>\include ^
+ *              /I<path/to/jdkbin>\include\win32 ^
+ *              /FeFileUtils.dll
+ *          jtreg <...> -nativepath:. <path/to/jdk8u>\jdk\test\sun\security\ssl\SSLSocketImpl\SSLSocketLeak.java
+ */
+public class SSLSocketLeak {
+
+    // number of sockets to open/close
+    private static final int NUM_TEST_SOCK = 500;
+    private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows");
+    private static volatile boolean nativeLibLoaded;
+
+    // percentage of accepted growth of open handles
+    private static final int OPEN_HANDLE_GROWTH_THRESHOLD_PERCENTAGE = IS_WINDOWS ? 25 : 10;
+
+    public static void main(String[] args) throws IOException {
+        long fds_start = getProcessHandleCount();
+        System.out.println("FDs at the beginning: " + fds_start);
+
+        SocketFactory f = SSLSocketFactory.getDefault();
+        for (int i = 0; i < NUM_TEST_SOCK; i++) {
+            f.createSocket().close();
+        }
+
+        long fds_end = getProcessHandleCount();
+        System.out.println("FDs in the end: " + fds_end);
+
+        if ((fds_end - fds_start) > ((NUM_TEST_SOCK * OPEN_HANDLE_GROWTH_THRESHOLD_PERCENTAGE)) / 100) {
+            throw new RuntimeException("Too many open file descriptors. Looks leaky.");
+        }
+    }
+
+    // Return the current process handle count
+    private static long getProcessHandleCount() {
+        if (IS_WINDOWS) {
+            if (!nativeLibLoaded) {
+                System.loadLibrary("FileUtils");
+                nativeLibLoaded = true;
+            }
+            return getWinProcessHandleCount();
+        } else {
+            return ((UnixOperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount();
+        }
+    }
+
+    private static native long getWinProcessHandleCount();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/SSLSocketImpl/libFileUtils.c	Wed May 12 16:21:59 2021 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifdef _WIN32
+
+#include "jni.h"
+#include <windows.h>
+
+JNIEXPORT jlong JNICALL Java_SSLSocketLeak_getWinProcessHandleCount(JNIEnv *env)
+{
+    DWORD handleCount;
+    HANDLE handle = GetCurrentProcess();
+    if (GetProcessHandleCount(handle, &handleCount)) {
+        return (jlong)handleCount;
+    } else {
+        return -1L;
+    }
+}
+
+#endif  /*  _WIN32 */