diff --git a/.hgtags b/.hgtags
index 0d24ad7e1a5..254ea2ed37a 100644
--- a/.hgtags
+++ b/.hgtags
@@ -476,3 +476,4 @@ dfa46cfe56346884a61efdc30dc50f7505d66761 jdk-11+1
1fd4d6068f54561cfc67d54fc9ca84af7212c4f8 jdk-11+3
e59941f7247d451fa7df9eaef3fce0f492f8420c jdk-11+4
d5c43e9f08fb9a7c74aae0d48daf17f2ad2afaef jdk-11+5
+3acb379b86725c47e7f33358cb22efa8752ae532 jdk-11+6
diff --git a/doc/testing.html b/doc/testing.html
index be4c23302bd..1963b3bd636 100644
--- a/doc/testing.html
+++ b/doc/testing.html
@@ -40,7 +40,7 @@
$ make run-test-jdk_lang JTREG="JOBS=8"
$ make run-test TEST=jdk_lang
$ make run-test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1"
-$ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug"
+$ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
$ make run-test TEST="jtreg:hotspot/test:hotspot_gc hotspot/test/native_sanity/JniVersion.java"
$ make exploded-run-test TEST=hotspot_tier1
Configuration
@@ -77,8 +77,8 @@ TEST FAILURE
Test suite control
It is possible to control various aspects of the test suites using make control variables.
These variables use a keyword=value approach to allow multiple values to be set. So, for instance, JTREG="JOBS=1;TIMEOUT=8" will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting JTREG_JOBS=1 JTREG_TIMEOUT=8, but using the keyword format means that the JTREG variable is parsed and verified for correctness, so JTREG="TMIEOUT=8" would give an error, while JTREG_TMIEOUT=8 would just pass unnoticed.
-
To separate multiple keyword=value pairs, use ; (semicolon). Since the shell normally eats ;, the recommended usage is to write the assignment inside qoutes, e.g. JTREG="...;...". This will also make sure spaces are preserved, as in JTREG="VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug".
-
(Other ways are possible, e.g. using backslash: JTREG=JOBS=1\;TIMEOUT=8. Also, as a special technique, the string %20 will be replaced with space for certain options, e.g. JTREG=VM_OTIONS=-XshowSettings%20-Xlog:gc+ref=debug. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)
+
To separate multiple keyword=value pairs, use ; (semicolon). Since the shell normally eats ;, the recommended usage is to write the assignment inside qoutes, e.g. JTREG="...;...". This will also make sure spaces are preserved, as in JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug".
+
(Other ways are possible, e.g. using backslash: JTREG=JOBS=1\;TIMEOUT=8. Also, as a special technique, the string %20 will be replaced with space for certain options, e.g. JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)
As far as possible, the names of the keywords have been standardized between test suites.
JTReg keywords
JOBS
diff --git a/doc/testing.md b/doc/testing.md
index da9b8ca7624..6e5aa8dfc4f 100644
--- a/doc/testing.md
+++ b/doc/testing.md
@@ -18,7 +18,7 @@ Some example command-lines:
$ make run-test-jdk_lang JTREG="JOBS=8"
$ make run-test TEST=jdk_lang
$ make run-test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1"
- $ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug"
+ $ make run-test TEST="hotspot/test:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
$ make run-test TEST="jtreg:hotspot/test:hotspot_gc hotspot/test/native_sanity/JniVersion.java"
$ make exploded-run-test TEST=hotspot_tier1
@@ -140,11 +140,11 @@ pass unnoticed.
To separate multiple keyword=value pairs, use `;` (semicolon). Since the shell
normally eats `;`, the recommended usage is to write the assignment inside
qoutes, e.g. `JTREG="...;..."`. This will also make sure spaces are preserved,
-as in `JTREG="VM_OTIONS=-XshowSettings -Xlog:gc+ref=debug"`.
+as in `JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"`.
(Other ways are possible, e.g. using backslash: `JTREG=JOBS=1\;TIMEOUT=8`.
Also, as a special technique, the string `%20` will be replaced with space for
-certain options, e.g. `JTREG=VM_OTIONS=-XshowSettings%20-Xlog:gc+ref=debug`.
+certain options, e.g. `JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug`.
This can be useful if you have layers of scripts and have trouble getting
proper quoting of command line arguments through.)
diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk
index 00dec731379..3fd9314c97e 100644
--- a/make/lib/SoundLibraries.gmk
+++ b/make/lib/SoundLibraries.gmk
@@ -23,101 +23,50 @@
# questions.
#
-LIBJSOUND_SRC_DIRS := \
+LIBJSOUND_SRC_DIRS := $(wildcard \
$(TOPDIR)/src/java.desktop/share/native/libjsound \
- $(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libjsound \
- #
+ $(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS)/native/libjsound \
+ )
+
LIBJSOUND_CFLAGS := \
-I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \
$(LIBJAVA_HEADER_FLAGS) \
$(foreach dir, $(LIBJSOUND_SRC_DIRS), -I$(dir)) \
+ -DUSE_PORTS=TRUE \
+ -DUSE_DAUDIO=TRUE \
#
-LIBJSOUND_SRC_FILES := Utilities.c Platform.c
-
-EXTRA_SOUND_JNI_LIBS :=
-
-LIBJSOUND_MIDIFILES := \
- MidiInDevice.c \
- MidiInDeviceProvider.c \
- MidiOutDevice.c \
- MidiOutDeviceProvider.c \
- PlatformMidi.c
-
-# files needed for ports
-LIBJSOUND_PORTFILES := \
- PortMixerProvider.c \
- PortMixer.c
-
-# files needed for direct audio
-LIBJSOUND_DAUDIOFILES := \
- DirectAudioDeviceProvider.c \
- DirectAudioDevice.c
-
-ifeq ($(OPENJDK_TARGET_OS), windows)
- EXTRA_SOUND_JNI_LIBS += jsoundds
- LIBJSOUND_CFLAGS += -DX_PLATFORM=X_WINDOWS \
+ifneq ($(OPENJDK_TARGET_OS), solaris)
+ LIBJSOUND_CFLAGS += \
-DUSE_PLATFORM_MIDI_OUT=TRUE \
-DUSE_PLATFORM_MIDI_IN=TRUE \
- -DUSE_PORTS=TRUE
- LIBJSOUND_SRC_FILES += \
- PLATFORM_API_WinOS_Charset_Util.cpp \
- PLATFORM_API_WinOS_MidiIn.cpp \
- PLATFORM_API_WinOS_MidiOut.c \
- PLATFORM_API_WinOS_Util.c \
- PLATFORM_API_WinOS_Ports.c
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES)
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES)
-endif # OPENJDK_TARGET_OS windows
+ #
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ LIBJSOUND_CFLAGS += -DX_PLATFORM=X_WINDOWS
+endif
ifeq ($(OPENJDK_TARGET_OS), linux)
- EXTRA_SOUND_JNI_LIBS += jsoundalsa
LIBJSOUND_CFLAGS += -DX_PLATFORM=X_LINUX
-endif # OPENJDK_TARGET_OS linux
+endif
ifeq ($(OPENJDK_TARGET_OS), aix)
LIBJSOUND_CFLAGS += -DX_PLATFORM=X_AIX
-endif # OPENJDK_TARGET_OS aix
+endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBJSOUND_TOOLCHAIN := TOOLCHAIN_LINK_CXX
- LIBJSOUND_CFLAGS += -DX_PLATFORM=X_MACOSX \
- -DUSE_PORTS=TRUE \
- -DUSE_DAUDIO=TRUE \
- -DUSE_PLATFORM_MIDI_OUT=TRUE \
- -DUSE_PLATFORM_MIDI_IN=TRUE
- LIBJSOUND_SRC_DIRS += $(TOPDIR)/src/java.desktop/macosx/native/libjsound
- LIBJSOUND_SRC_FILES += \
- PLATFORM_API_MacOSX_Utils.cpp \
- PLATFORM_API_MacOSX_PCM.cpp \
- PLATFORM_API_MacOSX_Ports.cpp \
- PLATFORM_API_MacOSX_MidiIn.c \
- PLATFORM_API_MacOSX_MidiOut.c \
- PLATFORM_API_MacOSX_MidiUtils.c
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES)
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES)
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES)
-endif # OPENJDK_TARGET_OS macosx
+ LIBJSOUND_CFLAGS += -DX_PLATFORM=X_MACOSX
+endif
ifeq ($(OPENJDK_TARGET_OS), solaris)
- LIBJSOUND_CFLAGS += -DX_PLATFORM=X_SOLARIS \
- -DUSE_PORTS=TRUE \
- -DUSE_DAUDIO=TRUE
- LIBJSOUND_SRC_FILES += \
- PLATFORM_API_SolarisOS_Utils.c \
- PLATFORM_API_SolarisOS_Ports.c \
- PLATFORM_API_SolarisOS_PCM.c
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_MIDIFILES)
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_PORTFILES)
- LIBJSOUND_SRC_FILES += $(LIBJSOUND_DAUDIOFILES)
-endif # OPENJDK_TARGET_OS solaris
-
-LIBJSOUND_CFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"'
+ LIBJSOUND_CFLAGS += -DX_PLATFORM=X_SOLARIS
+endif
$(eval $(call SetupJdkLibrary, BUILD_LIBJSOUND, \
NAME := jsound, \
SRC := $(LIBJSOUND_SRC_DIRS), \
- INCLUDE_FILES := $(LIBJSOUND_SRC_FILES), \
TOOLCHAIN := $(LIBJSOUND_TOOLCHAIN), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -127,10 +76,11 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUND, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS_unix := -ljava -ljvm, \
+ LIBS_linux := $(ALSA_LIBS), \
LIBS_macosx := -framework CoreAudio -framework CoreFoundation \
- -framework CoreServices -framework AudioUnit $(LIBCXX) \
- -framework CoreMIDI -framework AudioToolbox, \
- LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib winmm.lib, \
+ -framework CoreServices -framework AudioUnit \
+ -framework CoreMIDI -framework AudioToolbox $(LIBCXX), \
+ LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib dsound.lib winmm.lib user32.lib ole32.lib, \
))
$(BUILD_LIBJSOUND): $(call FindLib, java.base, java)
@@ -138,61 +88,3 @@ $(BUILD_LIBJSOUND): $(call FindLib, java.base, java)
TARGETS += $(BUILD_LIBJSOUND)
##########################################################################################
-
-ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), )
-
- $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUNDALSA, \
- NAME := jsoundalsa, \
- SRC := $(LIBJSOUND_SRC_DIRS), \
- INCLUDE_FILES := Utilities.c $(LIBJSOUND_MIDIFILES) $(LIBJSOUND_PORTFILES) \
- $(LIBJSOUND_DAUDIOFILES) \
- PLATFORM_API_LinuxOS_ALSA_CommonUtils.c \
- PLATFORM_API_LinuxOS_ALSA_PCM.c \
- PLATFORM_API_LinuxOS_ALSA_PCMUtils.c \
- PLATFORM_API_LinuxOS_ALSA_MidiIn.c \
- PLATFORM_API_LinuxOS_ALSA_MidiOut.c \
- PLATFORM_API_LinuxOS_ALSA_MidiUtils.c \
- PLATFORM_API_LinuxOS_ALSA_Ports.c, \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) $(ALSA_CFLAGS) \
- $(LIBJSOUND_CFLAGS) \
- -DUSE_DAUDIO=TRUE \
- -DUSE_PORTS=TRUE \
- -DUSE_PLATFORM_MIDI_OUT=TRUE \
- -DUSE_PLATFORM_MIDI_IN=TRUE, \
- MAPFILE := $(TOPDIR)/make/mapfiles/libjsoundalsa/mapfile-vers, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- $(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := $(ALSA_LIBS) -ljava -ljvm, \
- ))
-
- $(BUILD_LIBJSOUNDALSA): $(call FindLib, java.base, java)
-
- TARGETS += $(BUILD_LIBJSOUNDALSA)
-
-endif
-
-##########################################################################################
-
-ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), )
-
- $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUNDDS, \
- NAME := jsoundds, \
- SRC := $(LIBJSOUND_SRC_DIRS), \
- INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \
- PLATFORM_API_WinOS_Charset_Util.cpp \
- PLATFORM_API_WinOS_DirectSound.cpp, \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) \
- $(LIBJSOUND_CFLAGS) \
- -DUSE_DAUDIO=TRUE, \
- LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
- $(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := $(JDKLIB_LIBS) dsound.lib winmm.lib user32.lib ole32.lib, \
- ))
-
- $(BUILD_LIBJSOUNDDS): $(call FindLib, java.base, java)
-
- TARGETS += $(BUILD_LIBJSOUNDDS)
-
-endif
diff --git a/make/mapfiles/libjsound/mapfile-vers b/make/mapfiles/libjsound/mapfile-vers
index 4cd03a758b1..97e3d793e3a 100644
--- a/make/mapfiles/libjsound/mapfile-vers
+++ b/make/mapfiles/libjsound/mapfile-vers
@@ -65,8 +65,6 @@ SUNWprivate_1.1 {
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetNumDevices;
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVendor;
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVersion;
- Java_com_sun_media_sound_Platform_nGetExtraLibraries;
- Java_com_sun_media_sound_Platform_nGetLibraryForFeature;
Java_com_sun_media_sound_Platform_nIsBigEndian;
Java_com_sun_media_sound_PortMixer_nClose;
Java_com_sun_media_sound_PortMixer_nControlGetFloatValue;
diff --git a/make/mapfiles/libjsoundalsa/mapfile-vers b/make/mapfiles/libjsoundalsa/mapfile-vers
deleted file mode 100644
index 6228f8ad23e..00000000000
--- a/make/mapfiles/libjsoundalsa/mapfile-vers
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Copyright (c) 2005, 2013, 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. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# 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.
-#
-
-# Define library interface.
-
-SUNWprivate_1.1 {
- global:
- Java_com_sun_media_sound_DirectAudioDeviceProvider_nGetNumDevices;
- Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo;
- Java_com_sun_media_sound_DirectAudioDevice_nAvailable;
- Java_com_sun_media_sound_DirectAudioDevice_nClose;
- Java_com_sun_media_sound_DirectAudioDevice_nFlush;
- Java_com_sun_media_sound_DirectAudioDevice_nGetBufferSize;
- Java_com_sun_media_sound_DirectAudioDevice_nGetBytePosition;
- Java_com_sun_media_sound_DirectAudioDevice_nGetFormats;
- Java_com_sun_media_sound_DirectAudioDevice_nIsStillDraining;
- Java_com_sun_media_sound_DirectAudioDevice_nOpen;
- Java_com_sun_media_sound_DirectAudioDevice_nRead;
- Java_com_sun_media_sound_DirectAudioDevice_nRequiresServicing;
- Java_com_sun_media_sound_DirectAudioDevice_nService;
- Java_com_sun_media_sound_DirectAudioDevice_nSetBytePosition;
- Java_com_sun_media_sound_DirectAudioDevice_nStart;
- Java_com_sun_media_sound_DirectAudioDevice_nStop;
- Java_com_sun_media_sound_DirectAudioDevice_nWrite;
- Java_com_sun_media_sound_MidiInDeviceProvider_nGetDescription;
- Java_com_sun_media_sound_MidiInDeviceProvider_nGetName;
- Java_com_sun_media_sound_MidiInDeviceProvider_nGetNumDevices;
- Java_com_sun_media_sound_MidiInDeviceProvider_nGetVendor;
- Java_com_sun_media_sound_MidiInDeviceProvider_nGetVersion;
- Java_com_sun_media_sound_MidiInDevice_nClose;
- Java_com_sun_media_sound_MidiInDevice_nGetMessages;
- Java_com_sun_media_sound_MidiInDevice_nGetTimeStamp;
- Java_com_sun_media_sound_MidiInDevice_nOpen;
- Java_com_sun_media_sound_MidiInDevice_nStart;
- Java_com_sun_media_sound_MidiInDevice_nStop;
- Java_com_sun_media_sound_MidiOutDeviceProvider_nGetDescription;
- Java_com_sun_media_sound_MidiOutDeviceProvider_nGetName;
- Java_com_sun_media_sound_MidiOutDeviceProvider_nGetNumDevices;
- Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVendor;
- Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVersion;
- Java_com_sun_media_sound_MidiOutDevice_nClose;
- Java_com_sun_media_sound_MidiOutDevice_nGetTimeStamp;
- Java_com_sun_media_sound_MidiOutDevice_nOpen;
- Java_com_sun_media_sound_MidiOutDevice_nSendLongMessage;
- Java_com_sun_media_sound_MidiOutDevice_nSendShortMessage;
- Java_com_sun_media_sound_PortMixerProvider_nGetNumDevices;
- Java_com_sun_media_sound_PortMixerProvider_nNewPortMixerInfo;
- Java_com_sun_media_sound_PortMixer_nClose;
- Java_com_sun_media_sound_PortMixer_nControlGetFloatValue;
- Java_com_sun_media_sound_PortMixer_nControlGetIntValue;
- Java_com_sun_media_sound_PortMixer_nControlSetFloatValue;
- Java_com_sun_media_sound_PortMixer_nControlSetIntValue;
- Java_com_sun_media_sound_PortMixer_nGetControls;
- Java_com_sun_media_sound_PortMixer_nGetPortCount;
- Java_com_sun_media_sound_PortMixer_nGetPortName;
- Java_com_sun_media_sound_PortMixer_nGetPortType;
- Java_com_sun_media_sound_PortMixer_nOpen;
- local:
- *;
-};
diff --git a/make/mapfiles/libnio/mapfile-linux b/make/mapfiles/libnio/mapfile-linux
index 7d14da12e80..e3d02592e19 100644
--- a/make/mapfiles/libnio/mapfile-linux
+++ b/make/mapfiles/libnio/mapfile-linux
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2018, 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,23 +37,12 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_DatagramDispatcher_readv0;
Java_sun_nio_ch_DatagramDispatcher_write0;
Java_sun_nio_ch_DatagramDispatcher_writev0;
- Java_sun_nio_ch_EPollArrayWrapper_epollCreate;
- Java_sun_nio_ch_EPollArrayWrapper_epollCtl;
- Java_sun_nio_ch_EPollArrayWrapper_epollWait;
- Java_sun_nio_ch_EPollArrayWrapper_init;
- Java_sun_nio_ch_EPollArrayWrapper_interrupt;
- Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
- Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent;
Java_sun_nio_ch_EPoll_eventSize;
Java_sun_nio_ch_EPoll_eventsOffset;
Java_sun_nio_ch_EPoll_dataOffset;
- Java_sun_nio_ch_EPoll_epollCreate;
- Java_sun_nio_ch_EPoll_epollCtl;
- Java_sun_nio_ch_EPoll_epollWait;
- Java_sun_nio_ch_EPollPort_close0;
- Java_sun_nio_ch_EPollPort_drain1;
- Java_sun_nio_ch_EPollPort_interrupt;
- Java_sun_nio_ch_EPollPort_socketpair;
+ Java_sun_nio_ch_EPoll_create;
+ Java_sun_nio_ch_EPoll_ctl;
+ Java_sun_nio_ch_EPoll_wait;
Java_sun_nio_ch_FileChannelImpl_initIDs;
Java_sun_nio_ch_FileChannelImpl_map0;
Java_sun_nio_ch_FileChannelImpl_position0;
@@ -95,6 +84,7 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_IOUtil_makePipe;
Java_sun_nio_ch_IOUtil_randomBytes;
Java_sun_nio_ch_IOUtil_setfdVal;
+ Java_sun_nio_ch_IOUtil_write1;
Java_sun_nio_ch_NativeThread_current;
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal;
diff --git a/make/mapfiles/libnio/mapfile-macosx b/make/mapfiles/libnio/mapfile-macosx
index c58b5635fa4..08f59083793 100644
--- a/make/mapfiles/libnio/mapfile-macosx
+++ b/make/mapfiles/libnio/mapfile-macosx
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2018, 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
@@ -42,7 +42,7 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_FileChannelImpl_position0;
Java_sun_nio_ch_FileChannelImpl_transferTo0;
Java_sun_nio_ch_FileChannelImpl_unmap0;
- Java_sun_nio_ch_FileDispatcherImpl_allocate0;
+ Java_sun_nio_ch_FileDispatcherImpl_allocate0;
Java_sun_nio_ch_FileDispatcherImpl_close0;
Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
Java_sun_nio_ch_FileDispatcherImpl_force0;
@@ -71,117 +71,115 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_IOUtil_configureBlocking;
Java_sun_nio_ch_IOUtil_drain;
Java_sun_nio_ch_IOUtil_fdVal;
+ Java_sun_nio_ch_IOUtil_fdLimit;
Java_sun_nio_ch_IOUtil_initIDs;
+ Java_sun_nio_ch_IOUtil_iovMax;
Java_sun_nio_ch_IOUtil_makePipe;
Java_sun_nio_ch_IOUtil_randomBytes;
Java_sun_nio_ch_IOUtil_setfdVal;
- Java_sun_nio_ch_IOUtil_iovMax;
- Java_sun_nio_ch_KQueue_kqueue;
- Java_sun_nio_ch_KQueue_keventRegister;
- Java_sun_nio_ch_KQueue_keventPoll;
- Java_sun_nio_ch_KQueue_keventSize;
- Java_sun_nio_ch_KQueue_identOffset;
- Java_sun_nio_ch_KQueue_filterOffset;
- Java_sun_nio_ch_KQueue_flagsOffset;
- Java_sun_nio_ch_KQueuePort_socketpair;
- Java_sun_nio_ch_KQueuePort_interrupt;
- Java_sun_nio_ch_KQueuePort_drain1;
- Java_sun_nio_ch_KQueuePort_close0;
- Java_sun_nio_ch_NativeThread_current;
- Java_sun_nio_ch_NativeThread_init;
- Java_sun_nio_ch_NativeThread_signal;
- Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0;
- Java_sun_nio_ch_Net_canJoin6WithIPv4Group0;
- Java_sun_nio_ch_Net_socket0;
- Java_sun_nio_ch_Net_bind0;
- Java_sun_nio_ch_Net_connect0;
- Java_sun_nio_ch_Net_listen;
- Java_sun_nio_ch_Net_localPort;
- Java_sun_nio_ch_Net_localInetAddress;
- Java_sun_nio_ch_Net_getIntOption0;
- Java_sun_nio_ch_Net_setIntOption0;
+ Java_sun_nio_ch_IOUtil_write1;
+ Java_sun_nio_ch_KQueue_create;
+ Java_sun_nio_ch_KQueue_register;
+ Java_sun_nio_ch_KQueue_poll;
+ Java_sun_nio_ch_KQueue_keventSize;
+ Java_sun_nio_ch_KQueue_identOffset;
+ Java_sun_nio_ch_KQueue_filterOffset;
+ Java_sun_nio_ch_KQueue_flagsOffset;
+ Java_sun_nio_ch_NativeThread_current;
+ Java_sun_nio_ch_NativeThread_init;
+ Java_sun_nio_ch_NativeThread_signal;
+ Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0;
+ Java_sun_nio_ch_Net_canJoin6WithIPv4Group0;
+ Java_sun_nio_ch_Net_socket0;
+ Java_sun_nio_ch_Net_bind0;
+ Java_sun_nio_ch_Net_connect0;
+ Java_sun_nio_ch_Net_listen;
+ Java_sun_nio_ch_Net_localPort;
+ Java_sun_nio_ch_Net_localInetAddress;
+ Java_sun_nio_ch_Net_getIntOption0;
+ Java_sun_nio_ch_Net_setIntOption0;
Java_sun_nio_ch_Net_initIDs;
Java_sun_nio_ch_Net_isIPv6Available0;
Java_sun_nio_ch_Net_isReusePortAvailable0;
- Java_sun_nio_ch_Net_joinOrDrop4;
- Java_sun_nio_ch_Net_blockOrUnblock4;
- Java_sun_nio_ch_Net_joinOrDrop6;
- Java_sun_nio_ch_Net_blockOrUnblock6;
- Java_sun_nio_ch_Net_setInterface4;
- Java_sun_nio_ch_Net_getInterface4;
- Java_sun_nio_ch_Net_setInterface6;
- Java_sun_nio_ch_Net_getInterface6;
- Java_sun_nio_ch_Net_shutdown;
- Java_sun_nio_ch_Net_poll;
- Java_sun_nio_ch_Net_pollinValue;
- Java_sun_nio_ch_Net_polloutValue;
- Java_sun_nio_ch_Net_pollerrValue;
- Java_sun_nio_ch_Net_pollhupValue;
- Java_sun_nio_ch_Net_pollnvalValue;
- Java_sun_nio_ch_Net_pollconnValue;
+ Java_sun_nio_ch_Net_joinOrDrop4;
+ Java_sun_nio_ch_Net_blockOrUnblock4;
+ Java_sun_nio_ch_Net_joinOrDrop6;
+ Java_sun_nio_ch_Net_blockOrUnblock6;
+ Java_sun_nio_ch_Net_setInterface4;
+ Java_sun_nio_ch_Net_getInterface4;
+ Java_sun_nio_ch_Net_setInterface6;
+ Java_sun_nio_ch_Net_getInterface6;
+ Java_sun_nio_ch_Net_shutdown;
+ Java_sun_nio_ch_Net_poll;
+ Java_sun_nio_ch_Net_pollinValue;
+ Java_sun_nio_ch_Net_polloutValue;
+ Java_sun_nio_ch_Net_pollerrValue;
+ Java_sun_nio_ch_Net_pollhupValue;
+ Java_sun_nio_ch_Net_pollnvalValue;
+ Java_sun_nio_ch_Net_pollconnValue;
Java_sun_nio_ch_Net_isExclusiveBindAvailable;
Java_sun_nio_ch_PollArrayWrapper_interrupt;
Java_sun_nio_ch_PollArrayWrapper_poll0;
Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_SocketChannelImpl_checkConnect;
- Java_sun_nio_ch_SocketChannelImpl_sendOutOfBandData;
- Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0;
- Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs;
- Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect;
- Java_sun_nio_fs_BsdNativeDispatcher_initIDs;
- Java_sun_nio_fs_BsdNativeDispatcher_getfsstat;
- Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry;
- Java_sun_nio_fs_BsdNativeDispatcher_endfsstat;
- Java_sun_nio_fs_UnixNativeDispatcher_init;
- Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
- Java_sun_nio_fs_UnixNativeDispatcher_strerror;
- Java_sun_nio_fs_UnixNativeDispatcher_dup;
- Java_sun_nio_fs_UnixNativeDispatcher_access0;
- Java_sun_nio_fs_UnixNativeDispatcher_exists0;
- Java_sun_nio_fs_UnixNativeDispatcher_stat0;
+ Java_sun_nio_ch_SocketChannelImpl_sendOutOfBandData;
+ Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0;
+ Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs;
+ Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect;
+ Java_sun_nio_fs_BsdNativeDispatcher_initIDs;
+ Java_sun_nio_fs_BsdNativeDispatcher_getfsstat;
+ Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry;
+ Java_sun_nio_fs_BsdNativeDispatcher_endfsstat;
+ Java_sun_nio_fs_UnixNativeDispatcher_init;
+ Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
+ Java_sun_nio_fs_UnixNativeDispatcher_strerror;
+ Java_sun_nio_fs_UnixNativeDispatcher_dup;
+ Java_sun_nio_fs_UnixNativeDispatcher_access0;
+ Java_sun_nio_fs_UnixNativeDispatcher_exists0;
+ Java_sun_nio_fs_UnixNativeDispatcher_stat0;
Java_sun_nio_fs_UnixNativeDispatcher_stat1;
- Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
- Java_sun_nio_fs_UnixNativeDispatcher_fstat;
- Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;
- Java_sun_nio_fs_UnixNativeDispatcher_chmod0;
- Java_sun_nio_fs_UnixNativeDispatcher_fchmod;
- Java_sun_nio_fs_UnixNativeDispatcher_chown0;
- Java_sun_nio_fs_UnixNativeDispatcher_lchown0;
- Java_sun_nio_fs_UnixNativeDispatcher_fchown;
- Java_sun_nio_fs_UnixNativeDispatcher_utimes0;
- Java_sun_nio_fs_UnixNativeDispatcher_futimes;
- Java_sun_nio_fs_UnixNativeDispatcher_open0;
- Java_sun_nio_fs_UnixNativeDispatcher_openat0;
- Java_sun_nio_fs_UnixNativeDispatcher_close0;
- Java_sun_nio_fs_UnixNativeDispatcher_read;
- Java_sun_nio_fs_UnixNativeDispatcher_write;
- Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
- Java_sun_nio_fs_UnixNativeDispatcher_fclose;
- Java_sun_nio_fs_UnixNativeDispatcher_opendir0;
- Java_sun_nio_fs_UnixNativeDispatcher_fdopendir;
- Java_sun_nio_fs_UnixNativeDispatcher_readdir;
- Java_sun_nio_fs_UnixNativeDispatcher_closedir;
- Java_sun_nio_fs_UnixNativeDispatcher_link0;
- Java_sun_nio_fs_UnixNativeDispatcher_unlink0;
- Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0;
- Java_sun_nio_fs_UnixNativeDispatcher_rename0;
- Java_sun_nio_fs_UnixNativeDispatcher_renameat0;
- Java_sun_nio_fs_UnixNativeDispatcher_mkdir0;
- Java_sun_nio_fs_UnixNativeDispatcher_rmdir0;
- Java_sun_nio_fs_UnixNativeDispatcher_symlink0;
- Java_sun_nio_fs_UnixNativeDispatcher_readlink0;
- Java_sun_nio_fs_UnixNativeDispatcher_realpath0;
- Java_sun_nio_fs_UnixNativeDispatcher_statvfs0;
- Java_sun_nio_fs_UnixNativeDispatcher_pathconf0;
- Java_sun_nio_fs_UnixNativeDispatcher_fpathconf;
- Java_sun_nio_fs_UnixNativeDispatcher_mknod0;
- Java_sun_nio_fs_UnixNativeDispatcher_getpwuid;
- Java_sun_nio_fs_UnixNativeDispatcher_getgrgid;
- Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0;
- Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0;
- Java_sun_nio_fs_UnixCopyFile_transfer;
- handleSocketError;
+ Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
+ Java_sun_nio_fs_UnixNativeDispatcher_fstat;
+ Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;
+ Java_sun_nio_fs_UnixNativeDispatcher_chmod0;
+ Java_sun_nio_fs_UnixNativeDispatcher_fchmod;
+ Java_sun_nio_fs_UnixNativeDispatcher_chown0;
+ Java_sun_nio_fs_UnixNativeDispatcher_lchown0;
+ Java_sun_nio_fs_UnixNativeDispatcher_fchown;
+ Java_sun_nio_fs_UnixNativeDispatcher_utimes0;
+ Java_sun_nio_fs_UnixNativeDispatcher_futimes;
+ Java_sun_nio_fs_UnixNativeDispatcher_open0;
+ Java_sun_nio_fs_UnixNativeDispatcher_openat0;
+ Java_sun_nio_fs_UnixNativeDispatcher_close0;
+ Java_sun_nio_fs_UnixNativeDispatcher_read;
+ Java_sun_nio_fs_UnixNativeDispatcher_write;
+ Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
+ Java_sun_nio_fs_UnixNativeDispatcher_fclose;
+ Java_sun_nio_fs_UnixNativeDispatcher_opendir0;
+ Java_sun_nio_fs_UnixNativeDispatcher_fdopendir;
+ Java_sun_nio_fs_UnixNativeDispatcher_readdir;
+ Java_sun_nio_fs_UnixNativeDispatcher_closedir;
+ Java_sun_nio_fs_UnixNativeDispatcher_link0;
+ Java_sun_nio_fs_UnixNativeDispatcher_unlink0;
+ Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0;
+ Java_sun_nio_fs_UnixNativeDispatcher_rename0;
+ Java_sun_nio_fs_UnixNativeDispatcher_renameat0;
+ Java_sun_nio_fs_UnixNativeDispatcher_mkdir0;
+ Java_sun_nio_fs_UnixNativeDispatcher_rmdir0;
+ Java_sun_nio_fs_UnixNativeDispatcher_symlink0;
+ Java_sun_nio_fs_UnixNativeDispatcher_readlink0;
+ Java_sun_nio_fs_UnixNativeDispatcher_realpath0;
+ Java_sun_nio_fs_UnixNativeDispatcher_statvfs0;
+ Java_sun_nio_fs_UnixNativeDispatcher_pathconf0;
+ Java_sun_nio_fs_UnixNativeDispatcher_fpathconf;
+ Java_sun_nio_fs_UnixNativeDispatcher_mknod0;
+ Java_sun_nio_fs_UnixNativeDispatcher_getpwuid;
+ Java_sun_nio_fs_UnixNativeDispatcher_getgrgid;
+ Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0;
+ Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0;
+ Java_sun_nio_fs_UnixCopyFile_transfer;
+ handleSocketError;
local:
*;
diff --git a/make/mapfiles/libnio/mapfile-solaris b/make/mapfiles/libnio/mapfile-solaris
index 8764e06dfde..dc53024cf3d 100644
--- a/make/mapfiles/libnio/mapfile-solaris
+++ b/make/mapfiles/libnio/mapfile-solaris
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2018, 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
@@ -38,7 +38,6 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_DatagramDispatcher_write0;
Java_sun_nio_ch_DatagramDispatcher_writev0;
Java_sun_nio_ch_DevPollArrayWrapper_init;
- Java_sun_nio_ch_DevPollArrayWrapper_interrupt;
Java_sun_nio_ch_DevPollArrayWrapper_poll0;
Java_sun_nio_ch_DevPollArrayWrapper_register;
Java_sun_nio_ch_DevPollArrayWrapper_registerMultiple;
@@ -83,6 +82,7 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_IOUtil_makePipe;
Java_sun_nio_ch_IOUtil_randomBytes;
Java_sun_nio_ch_IOUtil_setfdVal;
+ Java_sun_nio_ch_IOUtil_write1;
Java_sun_nio_ch_NativeThread_current;
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal;
diff --git a/make/scripts/compare.sh b/make/scripts/compare.sh
index 8f7c47b7bef..d0ad63f5a7f 100644
--- a/make/scripts/compare.sh
+++ b/make/scripts/compare.sh
@@ -1298,22 +1298,37 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
# Find the common images to compare, prioritizing later build stages
if [ -d "$THIS/install/jdk" ] && [ -d "$OTHER/install/jdk" ]; then
THIS_JDK="$THIS/install/jdk"
- THIS_JRE="$THIS/install/jre"
OTHER_JDK="$OTHER/install/jdk"
- OTHER_JRE="$OTHER/install/jre"
- echo "Selecting install images for compare"
+ echo "Selecting install images for JDK compare"
+ if [ -d "$THIS/install/jre" ] && [ -d "$OTHER/install/jre" ]; then
+ THIS_JRE="$THIS/install/jre"
+ OTHER_JRE="$OTHER/install/jre"
+ echo "Also selecting install images for JRE compare"
+ else
+ echo "No install JRE image found"
+ fi
elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/deploy/images/jdk" ]; then
THIS_JDK="$THIS/images/jdk"
- THIS_JRE="$THIS/images/jre"
OTHER_JDK="$OTHER/deploy/images/jdk"
- OTHER_JRE="$OTHER/deploy/images/jre"
- echo "Selecting deploy images for compare"
+ echo "Selecting deploy images for JDK compare"
+ if [ -d "$THIS/images/jre" ] && [ -d "$OTHER/deploy/images/jre" ]; then
+ THIS_JRE="$THIS/images/jre"
+ OTHER_JRE="$OTHER/deploy/images/jre"
+ echo "Selecting deploy images for JRE compare"
+ else
+ echo "No deploy JRE image found"
+ fi
elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/images/jdk" ]; then
THIS_JDK="$THIS/images/jdk"
- THIS_JRE="$THIS/images/jre"
OTHER_JDK="$OTHER/images/jdk"
- OTHER_JRE="$OTHER/images/jre"
- echo "Selecting jdk images for compare"
+ echo "Selecting normal images for JDK compare"
+ if [ -d "$THIS/images/jre" ] && [ -d "$OTHER/images/jre" ]; then
+ THIS_JRE="$THIS/images/jre"
+ OTHER_JRE="$OTHER/images/jre"
+ echo "Selecting normal images for JRE compare"
+ else
+ echo "No normal JRE image found"
+ fi
elif [ -d "$(ls -d $THIS/licensee-src/build/*/images/jdk 2> /dev/null)" ] \
&& [ -d "$(ls -d $OTHER/licensee-src/build/*/images/jdk 2> /dev/null)" ]
then
@@ -1406,9 +1421,11 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
else
OTHER_SEC_DIR="$OTHER/tmp"
fi
- OTHER_SEC_BIN="$OTHER_SEC_DIR/sec-bin.zip"
- THIS_SEC_DIR="$THIS/images"
- THIS_SEC_BIN="$THIS_SEC_DIR/sec-bin.zip"
+ if [ -f "$THIS_SEC_DIR/sec-bin.zip" ]; then
+ OTHER_SEC_BIN="$OTHER_SEC_DIR/sec-bin.zip"
+ THIS_SEC_DIR="$THIS/images"
+ THIS_SEC_BIN="$THIS_SEC_DIR/sec-bin.zip"
+ fi
if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
if [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; then
JGSS_WINDOWS_BIN="jgss-windows-x64-bin.zip"
@@ -1437,11 +1454,12 @@ if [ "$CMP_NAMES" = "true" ]; then
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
compare_dirs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
- echo -n "JRE "
- compare_dirs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
-
echo -n "JDK "
compare_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
+ fi
+ if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
+ echo -n "JRE "
+ compare_dirs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
echo -n "JRE "
compare_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
@@ -1480,49 +1498,38 @@ if [ "$CMP_NAMES" = "true" ]; then
fi
fi
-if [ "$CMP_PERMS" = "true" ]; then
+if [ "$CMP_LIBS" = "true" ]; then
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
- compare_permissions $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
- echo -n "JRE "
- compare_permissions $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
+ compare_all_libs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
- compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
+ compare_all_libs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
fi
if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then
echo -n "JavaAppletPlugin "
- compare_permissions $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
+ compare_all_libs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
fi
if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then
echo -n "Sparkle.framework "
- compare_permissions $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
+ compare_all_libs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
fi
fi
-if [ "$CMP_TYPES" = "true" ]; then
+if [ "$CMP_EXECS" = "true" ]; then
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
- echo -n "JDK "
- compare_file_types $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
- echo -n "JRE "
- compare_file_types $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- fi
- if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
- echo -n "JDK Bundle "
- compare_file_types $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
- echo -n "JRE Bundle "
- compare_file_types $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
+ compare_all_execs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
- compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
+ compare_all_execs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
fi
if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then
echo -n "JavaAppletPlugin "
- compare_file_types $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
+ compare_all_execs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
fi
if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then
echo -n "Sparkle.framework "
- compare_file_types $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
+ compare_all_execs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
fi
fi
@@ -1530,6 +1537,8 @@ if [ "$CMP_GENERAL" = "true" ]; then
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
compare_general_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
+ fi
+ if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
echo -n "JRE "
compare_general_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
@@ -1601,46 +1610,53 @@ if [ "$CMP_JARS" = "true" ]; then
fi
fi
-if [ "$CMP_LIBS" = "true" ]; then
+if [ "$CMP_PERMS" = "true" ]; then
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
echo -n "JDK "
- compare_all_libs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
- if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
- echo -n "JRE "
- compare_all_libs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- fi
+ compare_permissions $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
+ fi
+ if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
+ echo -n "JRE "
+ compare_permissions $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
- compare_all_libs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
+ compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
fi
if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then
echo -n "JavaAppletPlugin "
- compare_all_libs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
+ compare_permissions $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
fi
if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then
echo -n "Sparkle.framework "
- compare_all_libs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
+ compare_permissions $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
fi
fi
-if [ "$CMP_EXECS" = "true" ]; then
+if [ "$CMP_TYPES" = "true" ]; then
if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
- compare_all_execs $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
- if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
- echo -n "JRE "
- compare_all_execs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- fi
+ echo -n "JDK "
+ compare_file_types $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
+ fi
+ if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
+ echo -n "JRE "
+ compare_file_types $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
+ fi
+ if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
+ echo -n "JDK Bundle "
+ compare_file_types $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
+ echo -n "JRE Bundle "
+ compare_file_types $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
- compare_all_execs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
+ compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
fi
if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then
echo -n "JavaAppletPlugin "
- compare_all_execs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
+ compare_file_types $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin
fi
if [ -n "$THIS_SPARKLE_DIR" ] && [ -n "$OTHER_SPARKLE_DIR" ]; then
echo -n "Sparkle.framework "
- compare_all_execs $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
+ compare_file_types $THIS_SPARKLE_DIR $OTHER_SPARKLE_DIR $COMPARE_ROOT/sparkle
fi
fi
diff --git a/make/scripts/compare_exceptions.sh.incl b/make/scripts/compare_exceptions.sh.incl
index eab85d45541..455c74e987c 100644
--- a/make/scripts/compare_exceptions.sh.incl
+++ b/make/scripts/compare_exceptions.sh.incl
@@ -339,7 +339,7 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
DIS_DIFF_FILTER="$SED \
-e 's/^[0-9a-f]\{16\}/:/' \
- -e 's/^ *[0-9a-f]\{3,8\}:/ :/' \
+ -e 's/^ *[0-9a-f]\{3,12\}:/ :/' \
-e 's/: [0-9a-f][0-9a-f]\( [0-9a-f][0-9a-f]\)\{2,10\}/: /' \
-e 's/\$[a-zA-Z0-9_\$]\{15\}\././' \
-e 's/, [0-9a-fx\-]\{1,8\}/, /g' \
diff --git a/src/java.base/linux/classes/sun/nio/ch/EPoll.java b/src/java.base/linux/classes/sun/nio/ch/EPoll.java
index 123431e4136..6b3387d5728 100644
--- a/src/java.base/linux/classes/sun/nio/ch/EPoll.java
+++ b/src/java.base/linux/classes/sun/nio/ch/EPoll.java
@@ -109,11 +109,11 @@ class EPoll {
private static native int dataOffset();
- static native int epollCreate() throws IOException;
+ static native int create() throws IOException;
- static native int epollCtl(int epfd, int opcode, int fd, int events);
+ static native int ctl(int epfd, int opcode, int fd, int events);
- static native int epollWait(int epfd, long pollAddress, int numfds)
+ static native int wait(int epfd, long pollAddress, int numfds, int timeout)
throws IOException;
static {
diff --git a/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java b/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java
deleted file mode 100644
index ac5bc54634c..00000000000
--- a/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (c) 2005, 2018, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.nio.ch;
-
-import java.io.IOException;
-import java.security.AccessController;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Map;
-import sun.security.action.GetIntegerAction;
-
-/**
- * Manipulates a native array of epoll_event structs on Linux:
- *
- * typedef union epoll_data {
- * void *ptr;
- * int fd;
- * __uint32_t u32;
- * __uint64_t u64;
- * } epoll_data_t;
- *
- * struct epoll_event {
- * __uint32_t events;
- * epoll_data_t data;
- * };
- *
- * The system call to wait for I/O events is epoll_wait(2). It populates an
- * array of epoll_event structures that are passed to the call. The data
- * member of the epoll_event structure contains the same data as was set
- * when the file descriptor was registered to epoll via epoll_ctl(2). In
- * this implementation we set data.fd to be the file descriptor that we
- * register. That way, we have the file descriptor available when we
- * process the events.
- */
-
-class EPollArrayWrapper {
- // EPOLL_EVENTS
- private static final int EPOLLIN = 0x001;
-
- // opcodes
- private static final int EPOLL_CTL_ADD = 1;
- private static final int EPOLL_CTL_DEL = 2;
- private static final int EPOLL_CTL_MOD = 3;
-
- // Miscellaneous constants
- private static final int SIZE_EPOLLEVENT = sizeofEPollEvent();
- private static final int EVENT_OFFSET = 0;
- private static final int DATA_OFFSET = offsetofData();
- private static final int FD_OFFSET = DATA_OFFSET;
- private static final int OPEN_MAX = IOUtil.fdLimit();
- private static final int NUM_EPOLLEVENTS = Math.min(OPEN_MAX, 8192);
-
- // Special value to indicate that an update should be ignored
- private static final byte KILLED = (byte)-1;
-
- // Initial size of arrays for fd registration changes
- private static final int INITIAL_PENDING_UPDATE_SIZE = 64;
-
- // maximum size of updatesLow
- private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged(
- new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024)));
-
- // The fd of the epoll driver
- private final int epfd;
-
- // The epoll_event array for results from epoll_wait
- private final AllocatedNativeObject pollArray;
-
- // Base address of the epoll_event array
- private final long pollArrayAddress;
-
- // The fd of the interrupt line going out
- private final int outgoingInterruptFD;
-
- // Number of updated pollfd entries
- private int updated;
-
- // object to synchronize fd registration changes
- private final Object updateLock = new Object();
-
- // number of file descriptors with registration changes pending
- private int updateCount;
-
- // file descriptors with registration changes pending
- private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE];
-
- // events for file descriptors with registration changes pending, indexed
- // by file descriptor and stored as bytes for efficiency reasons. For
- // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at
- // least) then the update is stored in a map.
- private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE];
- private final Map eventsHigh = new HashMap<>();
-
- // Used by release and updateRegistrations to track whether a file
- // descriptor is registered with epoll.
- private final BitSet registered = new BitSet();
-
-
- EPollArrayWrapper(int fd0, int fd1) throws IOException {
- // creates the epoll file descriptor
- epfd = epollCreate();
-
- // the epoll_event array passed to epoll_wait
- int allocationSize = NUM_EPOLLEVENTS * SIZE_EPOLLEVENT;
- pollArray = new AllocatedNativeObject(allocationSize, true);
- pollArrayAddress = pollArray.address();
-
- outgoingInterruptFD = fd1;
- epollCtl(epfd, EPOLL_CTL_ADD, fd0, EPOLLIN);
- }
-
- void putEventOps(int i, int event) {
- int offset = SIZE_EPOLLEVENT * i + EVENT_OFFSET;
- pollArray.putInt(offset, event);
- }
-
- void putDescriptor(int i, int fd) {
- int offset = SIZE_EPOLLEVENT * i + FD_OFFSET;
- pollArray.putInt(offset, fd);
- }
-
- int getEventOps(int i) {
- int offset = SIZE_EPOLLEVENT * i + EVENT_OFFSET;
- return pollArray.getInt(offset);
- }
-
- int getDescriptor(int i) {
- int offset = SIZE_EPOLLEVENT * i + FD_OFFSET;
- return pollArray.getInt(offset);
- }
-
- /**
- * Returns {@code true} if updates for the given key (file
- * descriptor) are killed.
- */
- private boolean isEventsHighKilled(Integer key) {
- assert key >= MAX_UPDATE_ARRAY_SIZE;
- Byte value = eventsHigh.get(key);
- return (value != null && value == KILLED);
- }
-
- /**
- * Sets the pending update events for the given file descriptor. This
- * method has no effect if the update events is already set to KILLED,
- * unless {@code force} is {@code true}.
- */
- private void setUpdateEvents(int fd, byte events, boolean force) {
- if (fd < MAX_UPDATE_ARRAY_SIZE) {
- if ((eventsLow[fd] != KILLED) || force) {
- eventsLow[fd] = events;
- }
- } else {
- Integer key = Integer.valueOf(fd);
- if (!isEventsHighKilled(key) || force) {
- eventsHigh.put(key, Byte.valueOf(events));
- }
- }
- }
-
- /**
- * Returns the pending update events for the given file descriptor.
- */
- private byte getUpdateEvents(int fd) {
- if (fd < MAX_UPDATE_ARRAY_SIZE) {
- return eventsLow[fd];
- } else {
- Byte result = eventsHigh.get(Integer.valueOf(fd));
- // result should never be null
- return result.byteValue();
- }
- }
-
- /**
- * Update the events for a given file descriptor
- */
- void setInterest(int fd, int mask) {
- synchronized (updateLock) {
- // record the file descriptor and events
- int oldCapacity = updateDescriptors.length;
- if (updateCount == oldCapacity) {
- int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE;
- int[] newDescriptors = new int[newCapacity];
- System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity);
- updateDescriptors = newDescriptors;
- }
- updateDescriptors[updateCount++] = fd;
-
- // events are stored as bytes for efficiency reasons
- byte b = (byte)mask;
- assert (b == mask) && (b != KILLED);
- setUpdateEvents(fd, b, false);
- }
- }
-
- /**
- * Add a file descriptor
- */
- void add(int fd) {
- // force the initial update events to 0 as it may be KILLED by a
- // previous registration.
- synchronized (updateLock) {
- assert !registered.get(fd);
- setUpdateEvents(fd, (byte)0, true);
- }
- }
-
- /**
- * Remove a file descriptor
- */
- void remove(int fd) {
- synchronized (updateLock) {
- // kill pending and future update for this file descriptor
- setUpdateEvents(fd, KILLED, false);
-
- // remove from epoll
- if (registered.get(fd)) {
- epollCtl(epfd, EPOLL_CTL_DEL, fd, 0);
- registered.clear(fd);
- }
- }
- }
-
- /**
- * Close epoll file descriptor and free poll array
- */
- void close() throws IOException {
- FileDispatcherImpl.closeIntFD(epfd);
- pollArray.free();
- }
-
- int poll(long timeout) throws IOException {
- updateRegistrations();
- return epollWait(pollArrayAddress, NUM_EPOLLEVENTS, timeout, epfd);
- }
-
- /**
- * Update the pending registrations.
- */
- private void updateRegistrations() {
- synchronized (updateLock) {
- int j = 0;
- while (j < updateCount) {
- int fd = updateDescriptors[j];
- short events = getUpdateEvents(fd);
- boolean isRegistered = registered.get(fd);
- int opcode = 0;
-
- if (events != KILLED) {
- if (isRegistered) {
- opcode = (events != 0) ? EPOLL_CTL_MOD : EPOLL_CTL_DEL;
- } else {
- opcode = (events != 0) ? EPOLL_CTL_ADD : 0;
- }
- if (opcode != 0) {
- epollCtl(epfd, opcode, fd, events);
- if (opcode == EPOLL_CTL_ADD) {
- registered.set(fd);
- } else if (opcode == EPOLL_CTL_DEL) {
- registered.clear(fd);
- }
- }
- }
- j++;
- }
- updateCount = 0;
- }
- }
-
- public void interrupt() {
- interrupt(outgoingInterruptFD);
- }
-
- static {
- IOUtil.load();
- init();
- }
-
- private native int epollCreate();
- private native void epollCtl(int epfd, int opcode, int fd, int events);
- private native int epollWait(long pollAddress, int numfds, long timeout,
- int epfd) throws IOException;
- private static native int sizeofEPollEvent();
- private static native int offsetofData();
- private static native void interrupt(int fd);
- private static native void init();
-}
diff --git a/src/java.base/linux/classes/sun/nio/ch/EPollPort.java b/src/java.base/linux/classes/sun/nio/ch/EPollPort.java
index 71c9d7ffa7d..059eab3a2c4 100644
--- a/src/java.base/linux/classes/sun/nio/ch/EPollPort.java
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollPort.java
@@ -30,7 +30,13 @@ import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
-import static sun.nio.ch.EPoll.*;
+
+import static sun.nio.ch.EPoll.EPOLLIN;
+import static sun.nio.ch.EPoll.EPOLLONESHOT;
+import static sun.nio.ch.EPoll.EPOLL_CTL_ADD;
+import static sun.nio.ch.EPoll.EPOLL_CTL_DEL;
+import static sun.nio.ch.EPoll.EPOLL_CTL_MOD;
+
/**
* AsynchronousChannelGroup implementation based on the Linux epoll facility.
@@ -48,6 +54,9 @@ final class EPollPort
// epoll file descriptor
private final int epfd;
+ // address of the poll array passed to epoll_wait
+ private final long address;
+
// true if epoll closed
private boolean closed;
@@ -57,9 +66,6 @@ final class EPollPort
// number of wakeups pending
private final AtomicInteger wakeupCount = new AtomicInteger();
- // address of the poll array passed to epoll_wait
- private final long address;
-
// encapsulates an event for a channel
static class Event {
final PollableChannel channel;
@@ -85,23 +91,21 @@ final class EPollPort
{
super(provider, pool);
- // open epoll
- this.epfd = epollCreate();
+ this.epfd = EPoll.create();
+ this.address = EPoll.allocatePollArray(MAX_EPOLL_EVENTS);
// create socket pair for wakeup mechanism
- int[] sv = new int[2];
try {
- socketpair(sv);
- // register one end with epoll
- epollCtl(epfd, EPOLL_CTL_ADD, sv[0], EPOLLIN);
- } catch (IOException x) {
- close0(epfd);
- throw x;
+ long fds = IOUtil.makePipe(true);
+ this.sp = new int[]{(int) (fds >>> 32), (int) fds};
+ } catch (IOException ioe) {
+ EPoll.freePollArray(address);
+ FileDispatcherImpl.closeIntFD(epfd);
+ throw ioe;
}
- this.sp = sv;
- // allocate the poll array
- this.address = allocatePollArray(MAX_EPOLL_EVENTS);
+ // register one end with epoll
+ EPoll.ctl(epfd, EPOLL_CTL_ADD, sp[0], EPOLLIN);
// create the queue and offer the special event to ensure that the first
// threads polls
@@ -123,17 +127,17 @@ final class EPollPort
return;
closed = true;
}
- freePollArray(address);
- close0(sp[0]);
- close0(sp[1]);
- close0(epfd);
+ try { FileDispatcherImpl.closeIntFD(epfd); } catch (IOException ioe) { }
+ try { FileDispatcherImpl.closeIntFD(sp[0]); } catch (IOException ioe) { }
+ try { FileDispatcherImpl.closeIntFD(sp[1]); } catch (IOException ioe) { }
+ EPoll.freePollArray(address);
}
private void wakeup() {
if (wakeupCount.incrementAndGet() == 1) {
// write byte to socketpair to force wakeup
try {
- interrupt(sp[1]);
+ IOUtil.write1(sp[1], (byte)0);
} catch (IOException x) {
throw new AssertionError(x);
}
@@ -171,9 +175,9 @@ final class EPollPort
@Override
void startPoll(int fd, int events) {
// update events (or add to epoll on first usage)
- int err = epollCtl(epfd, EPOLL_CTL_MOD, fd, (events | EPOLLONESHOT));
+ int err = EPoll.ctl(epfd, EPOLL_CTL_MOD, fd, (events | EPOLLONESHOT));
if (err == ENOENT)
- err = epollCtl(epfd, EPOLL_CTL_ADD, fd, (events | EPOLLONESHOT));
+ err = EPoll.ctl(epfd, EPOLL_CTL_ADD, fd, (events | EPOLLONESHOT));
if (err != 0)
throw new AssertionError(); // should not happen
}
@@ -191,7 +195,11 @@ final class EPollPort
private Event poll() throws IOException {
try {
for (;;) {
- int n = epollWait(epfd, address, MAX_EPOLL_EVENTS);
+ int n;
+ do {
+ n = EPoll.wait(epfd, address, MAX_EPOLL_EVENTS, -1);
+ } while (n == IOStatus.INTERRUPTED);
+
/*
* 'n' events have been read. Here we map them to their
* corresponding channel in batch and queue n-1 so that
@@ -201,14 +209,14 @@ final class EPollPort
fdToChannelLock.readLock().lock();
try {
while (n-- > 0) {
- long eventAddress = getEvent(address, n);
- int fd = getDescriptor(eventAddress);
+ long eventAddress = EPoll.getEvent(address, n);
+ int fd = EPoll.getDescriptor(eventAddress);
// wakeup
if (fd == sp[0]) {
if (wakeupCount.decrementAndGet() == 0) {
// no more wakeups so drain pipe
- drain1(sp[0]);
+ IOUtil.drain(sp[0]);
}
// queue special event if there are more events
@@ -222,7 +230,7 @@ final class EPollPort
PollableChannel channel = fdToChannel.get(fd);
if (channel != null) {
- int events = getEvents(eventAddress);
+ int events = EPoll.getEvents(eventAddress);
Event ev = new Event(channel, events);
// n-1 events are queued; This thread handles
@@ -306,18 +314,4 @@ final class EPollPort
}
}
}
-
- // -- Native methods --
-
- private static native void socketpair(int[] sv) throws IOException;
-
- private static native void interrupt(int fd) throws IOException;
-
- private static native void drain1(int fd) throws IOException;
-
- private static native void close0(int fd);
-
- static {
- IOUtil.load();
- }
}
diff --git a/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java b/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
index 1107f4a73ad..d01799a6f65 100644
--- a/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
@@ -26,33 +26,59 @@
package sun.nio.ch;
import java.io.IOException;
-import java.nio.channels.*;
-import java.nio.channels.spi.*;
-import java.util.*;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.ArrayDeque;
+import java.util.BitSet;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import static sun.nio.ch.EPoll.EPOLLIN;
+import static sun.nio.ch.EPoll.EPOLL_CTL_ADD;
+import static sun.nio.ch.EPoll.EPOLL_CTL_DEL;
+import static sun.nio.ch.EPoll.EPOLL_CTL_MOD;
+
/**
- * An implementation of Selector for Linux 2.6+ kernels that uses
- * the epoll event notification facility.
+ * Linux epoll based Selector implementation
*/
-class EPollSelectorImpl
- extends SelectorImpl
-{
- // File descriptors used for interrupt
+
+class EPollSelectorImpl extends SelectorImpl {
+
+ // maximum number of events to poll in one call to epoll_wait
+ private static final int NUM_EPOLLEVENTS = Math.min(IOUtil.fdLimit(), 1024);
+
+ // epoll file descriptor
+ private final int epfd;
+
+ // address of poll array when polling with epoll_wait
+ private final long pollArrayAddress;
+
+ // file descriptors used for interrupt
private final int fd0;
private final int fd1;
- // The poll object
- private final EPollArrayWrapper pollWrapper;
+ // maps file descriptor to selection key, synchronize on selector
+ private final Map fdToKey = new HashMap<>();
- // Maps from file descriptors to keys
- private final Map fdToKey;
+ // file descriptors registered with epoll, synchronize on selector
+ private final BitSet registered = new BitSet();
- // True if this Selector has been closed
- private volatile boolean closed;
+ // pending new registrations/updates, queued by implRegister and putEventOps
+ private final Object updateLock = new Object();
+ private final Deque newKeys = new ArrayDeque<>();
+ private final Deque updateKeys = new ArrayDeque<>();
+ private final Deque updateOps = new ArrayDeque<>();
- // Lock for interrupt triggering and clearing
+ // interrupt triggering and clearing
private final Object interruptLock = new Object();
- private boolean interruptTriggered = false;
+ private boolean interruptTriggered;
/**
* Package private constructor called by factory method in
@@ -60,40 +86,57 @@ class EPollSelectorImpl
*/
EPollSelectorImpl(SelectorProvider sp) throws IOException {
super(sp);
- long pipeFds = IOUtil.makePipe(false);
- fd0 = (int) (pipeFds >>> 32);
- fd1 = (int) pipeFds;
+
+ this.epfd = EPoll.create();
+ this.pollArrayAddress = EPoll.allocatePollArray(NUM_EPOLLEVENTS);
+
try {
- pollWrapper = new EPollArrayWrapper(fd0, fd1);
- fdToKey = new HashMap<>();
- } catch (Throwable t) {
- try {
- FileDispatcherImpl.closeIntFD(fd0);
- } catch (IOException ioe0) {
- t.addSuppressed(ioe0);
- }
- try {
- FileDispatcherImpl.closeIntFD(fd1);
- } catch (IOException ioe1) {
- t.addSuppressed(ioe1);
- }
- throw t;
+ long fds = IOUtil.makePipe(false);
+ this.fd0 = (int) (fds >>> 32);
+ this.fd1 = (int) fds;
+ } catch (IOException ioe) {
+ EPoll.freePollArray(pollArrayAddress);
+ FileDispatcherImpl.closeIntFD(epfd);
+ throw ioe;
}
+
+ // register one end of the socket pair for wakeups
+ EPoll.ctl(epfd, EPOLL_CTL_ADD, fd0, EPOLLIN);
}
private void ensureOpen() {
- if (closed)
+ if (!isOpen())
throw new ClosedSelectorException();
}
@Override
protected int doSelect(long timeout) throws IOException {
- ensureOpen();
+ assert Thread.holdsLock(this);
+
int numEntries;
+ processUpdateQueue();
processDeregisterQueue();
try {
begin();
- numEntries = pollWrapper.poll(timeout);
+
+ // epoll_wait timeout is int
+ int to = (int) Math.min(timeout, Integer.MAX_VALUE);
+ boolean timedPoll = (to > 0);
+ do {
+ long startTime = timedPoll ? System.nanoTime() : 0;
+ numEntries = EPoll.wait(epfd, pollArrayAddress, NUM_EPOLLEVENTS, to);
+ if (numEntries == IOStatus.INTERRUPTED && timedPoll) {
+ // timed poll interrupted so need to adjust timeout
+ long adjust = System.nanoTime() - startTime;
+ to -= TimeUnit.MILLISECONDS.convert(adjust, TimeUnit.NANOSECONDS);
+ if (to <= 0) {
+ // timeout expired so no retry
+ numEntries = 0;
+ }
+ }
+ } while (numEntries == IOStatus.INTERRUPTED);
+ assert IOStatus.check(numEntries);
+
} finally {
end();
}
@@ -101,21 +144,70 @@ class EPollSelectorImpl
return updateSelectedKeys(numEntries);
}
+ /**
+ * Process new registrations and changes to the interest ops.
+ */
+ private void processUpdateQueue() {
+ assert Thread.holdsLock(this);
+
+ synchronized (updateLock) {
+ SelectionKeyImpl ski;
+
+ // new registrations
+ while ((ski = newKeys.pollFirst()) != null) {
+ if (ski.isValid()) {
+ SelChImpl ch = ski.channel;
+ int fd = ch.getFDVal();
+ SelectionKeyImpl previous = fdToKey.put(fd, ski);
+ assert previous == null;
+ assert registered.get(fd) == false;
+ }
+ }
+
+ // changes to interest ops
+ assert updateKeys.size() == updateOps.size();
+ while ((ski = updateKeys.pollFirst()) != null) {
+ int ops = updateOps.pollFirst();
+ int fd = ski.channel.getFDVal();
+ if (ski.isValid() && fdToKey.containsKey(fd)) {
+ if (registered.get(fd)) {
+ if (ops == 0) {
+ // remove from epoll
+ EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0);
+ registered.clear(fd);
+ } else {
+ // modify events
+ EPoll.ctl(epfd, EPOLL_CTL_MOD, fd, ops);
+ }
+ } else if (ops != 0) {
+ // add to epoll
+ EPoll.ctl(epfd, EPOLL_CTL_ADD, fd, ops);
+ registered.set(fd);
+ }
+ }
+ }
+ }
+ }
+
/**
* Update the keys whose fd's have been selected by the epoll.
* Add the ready keys to the ready queue.
*/
private int updateSelectedKeys(int numEntries) throws IOException {
+ assert Thread.holdsLock(this);
+ assert Thread.holdsLock(nioSelectedKeys());
+
boolean interrupted = false;
int numKeysUpdated = 0;
for (int i=0; i= 0);
- SelChImpl ch = ski.channel;
- int fd = ch.getFDVal();
- fdToKey.remove(Integer.valueOf(fd));
- pollWrapper.remove(fd);
- ski.setIndex(-1);
- keys.remove(ski);
+ assert !ski.isValid();
+ assert Thread.holdsLock(this);
+ assert Thread.holdsLock(nioKeys());
+ assert Thread.holdsLock(nioSelectedKeys());
+
+ int fd = ski.channel.getFDVal();
+ fdToKey.remove(fd);
+ if (registered.get(fd)) {
+ EPoll.ctl(epfd, EPOLL_CTL_DEL, fd, 0);
+ registered.clear(fd);
+ }
+
selectedKeys.remove(ski);
+ keys.remove(ski);
+
+ // remove from channel's key set
deregister(ski);
+
SelectableChannel selch = ski.channel();
if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
+ ((SelChImpl) selch).kill();
}
@Override
public void putEventOps(SelectionKeyImpl ski, int ops) {
ensureOpen();
- SelChImpl ch = ski.channel;
- pollWrapper.setInterest(ch.getFDVal(), ops);
+ synchronized (updateLock) {
+ updateOps.addLast(ops); // ops first in case adding the key fails
+ updateKeys.addLast(ski);
+ }
}
@Override
public Selector wakeup() {
synchronized (interruptLock) {
if (!interruptTriggered) {
- pollWrapper.interrupt();
+ try {
+ IOUtil.write1(fd1, (byte)0);
+ } catch (IOException ioe) {
+ throw new InternalError(ioe);
+ }
interruptTriggered = true;
}
}
diff --git a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java
index 1bcb9eef90d..c55e9fbfccd 100644
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -103,8 +103,8 @@ public class LinuxFileSystemProvider extends UnixFileSystemProvider {
@Override
FileTypeDetector getFileTypeDetector() {
String userHome = GetPropertyAction.privilegedGetProperty("user.home");
- Path userMimeTypes = Paths.get(userHome, ".mime.types");
- Path etcMimeTypes = Paths.get("/etc/mime.types");
+ Path userMimeTypes = Path.of(userHome, ".mime.types");
+ Path etcMimeTypes = Path.of("/etc/mime.types");
return chain(new MimeTypesFileTypeDetector(userMimeTypes),
new MimeTypesFileTypeDetector(etcMimeTypes));
diff --git a/src/java.base/linux/native/libnio/ch/EPoll.c b/src/java.base/linux/native/libnio/ch/EPoll.c
index d6526c5d63a..2100de5f215 100644
--- a/src/java.base/linux/native/libnio/ch/EPoll.c
+++ b/src/java.base/linux/native/libnio/ch/EPoll.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -23,53 +23,51 @@
* questions.
*/
+ #include
+ #include
+ #include
+ #include
+
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"
+#include "nio.h"
#include "nio_util.h"
#include "sun_nio_ch_EPoll.h"
-#include
-#include
-#include
-#include
-
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPoll_eventSize(JNIEnv* env, jclass this)
+Java_sun_nio_ch_EPoll_eventSize(JNIEnv* env, jclass clazz)
{
return sizeof(struct epoll_event);
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPoll_eventsOffset(JNIEnv* env, jclass this)
+Java_sun_nio_ch_EPoll_eventsOffset(JNIEnv* env, jclass clazz)
{
return offsetof(struct epoll_event, events);
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPoll_dataOffset(JNIEnv* env, jclass this)
+Java_sun_nio_ch_EPoll_dataOffset(JNIEnv* env, jclass clazz)
{
return offsetof(struct epoll_event, data);
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPoll_epollCreate(JNIEnv *env, jclass c) {
- /*
- * epoll_create expects a size as a hint to the kernel about how to
- * dimension internal structures. We can't predict the size in advance.
- */
+Java_sun_nio_ch_EPoll_create(JNIEnv *env, jclass clazz) {
+ /* size hint not used in modern kernels */
int epfd = epoll_create(256);
if (epfd < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
+ JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
}
return epfd;
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPoll_epollCtl(JNIEnv *env, jclass c, jint epfd,
- jint opcode, jint fd, jint events)
+Java_sun_nio_ch_EPoll_ctl(JNIEnv *env, jclass clazz, jint epfd,
+ jint opcode, jint fd, jint events)
{
struct epoll_event event;
int res;
@@ -77,21 +75,23 @@ Java_sun_nio_ch_EPoll_epollCtl(JNIEnv *env, jclass c, jint epfd,
event.events = events;
event.data.fd = fd;
- RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res);
-
+ res = epoll_ctl(epfd, (int)opcode, (int)fd, &event);
return (res == 0) ? 0 : errno;
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPoll_epollWait(JNIEnv *env, jclass c,
- jint epfd, jlong address, jint numfds)
+Java_sun_nio_ch_EPoll_wait(JNIEnv *env, jclass clazz, jint epfd,
+ jlong address, jint numfds, jint timeout)
{
struct epoll_event *events = jlong_to_ptr(address);
- int res;
-
- RESTARTABLE(epoll_wait(epfd, events, numfds, -1), res);
+ int res = epoll_wait(epfd, events, numfds, timeout);
if (res < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");
+ if (errno == EINTR) {
+ return IOS_INTERRUPTED;
+ } else {
+ JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");
+ return IOS_THROWN;
+ }
}
return res;
}
diff --git a/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c b/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c
deleted file mode 100644
index 12b1c8524bc..00000000000
--- a/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-
-#include "sun_nio_ch_EPollArrayWrapper.h"
-
-#include
-#include
-#include
-
-#define RESTARTABLE(_cmd, _result) do { \
- do { \
- _result = _cmd; \
- } while((_result == -1) && (errno == EINTR)); \
-} while(0)
-
-
-static int
-iepoll(int epfd, struct epoll_event *events, int numfds, jlong timeout)
-{
- jlong start, now;
- int remaining = timeout;
- struct timeval t;
- int diff;
-
- gettimeofday(&t, NULL);
- start = t.tv_sec * 1000 + t.tv_usec / 1000;
-
- for (;;) {
- int res = epoll_wait(epfd, events, numfds, remaining);
- if (res < 0 && errno == EINTR) {
- if (remaining >= 0) {
- gettimeofday(&t, NULL);
- now = t.tv_sec * 1000 + t.tv_usec / 1000;
- diff = now - start;
- remaining -= diff;
- if (diff < 0 || remaining <= 0) {
- return 0;
- }
- start = now;
- }
- } else {
- return res;
- }
- }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_init(JNIEnv *env, jclass this)
-{
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_epollCreate(JNIEnv *env, jobject this)
-{
- /*
- * epoll_create expects a size as a hint to the kernel about how to
- * dimension internal structures. We can't predict the size in advance.
- */
- int epfd = epoll_create(256);
- if (epfd < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
- }
- return epfd;
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent(JNIEnv* env, jclass this)
-{
- return sizeof(struct epoll_event);
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_offsetofData(JNIEnv* env, jclass this)
-{
- return offsetof(struct epoll_event, data);
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_epollCtl(JNIEnv *env, jobject this, jint epfd,
- jint opcode, jint fd, jint events)
-{
- struct epoll_event event;
- int res;
-
- event.events = events;
- event.data.fd = fd;
-
- RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res);
-
- /*
- * A channel may be registered with several Selectors. When each Selector
- * is polled a EPOLL_CTL_DEL op will be inserted into its pending update
- * list to remove the file descriptor from epoll. The "last" Selector will
- * close the file descriptor which automatically unregisters it from each
- * epoll descriptor. To avoid costly synchronization between Selectors we
- * allow pending updates to be processed, ignoring errors. The errors are
- * harmless as the last update for the file descriptor is guaranteed to
- * be EPOLL_CTL_DEL.
- */
- if (res < 0 && errno != EBADF && errno != ENOENT && errno != EPERM) {
- JNU_ThrowIOExceptionWithLastError(env, "epoll_ctl failed");
- }
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_epollWait(JNIEnv *env, jobject this,
- jlong address, jint numfds,
- jlong timeout, jint epfd)
-{
- struct epoll_event *events = jlong_to_ptr(address);
- int res;
-
- if (timeout <= 0) { /* Indefinite or no wait */
- RESTARTABLE(epoll_wait(epfd, events, numfds, timeout), res);
- } else { /* Bounded wait; bounded restarts */
- res = iepoll(epfd, events, numfds, timeout);
- }
-
- if (res < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");
- }
- return res;
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_interrupt(JNIEnv *env, jobject this, jint fd)
-{
- int fakebuf[1];
- fakebuf[0] = 1;
- if (write(fd, fakebuf, 1) < 0) {
- JNU_ThrowIOExceptionWithLastError(env,"write to interrupt fd failed");
- }
-}
diff --git a/src/java.base/linux/native/libnio/ch/EPollPort.c b/src/java.base/linux/native/libnio/ch/EPollPort.c
deleted file mode 100644
index 036b2ea82d4..00000000000
--- a/src/java.base/linux/native/libnio/ch/EPollPort.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-#include "nio_util.h"
-
-#include "sun_nio_ch_EPollPort.h"
-
-#include
-#include
-#include
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPollPort_socketpair(JNIEnv* env, jclass clazz, jintArray sv) {
- int sp[2];
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) {
- JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
- } else {
- jint res[2];
- res[0] = (jint)sp[0];
- res[1] = (jint)sp[1];
- (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]);
- }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPollPort_interrupt(JNIEnv *env, jclass c, jint fd) {
- int res;
- int buf[1];
- buf[0] = 1;
- RESTARTABLE(write(fd, buf, 1), res);
- if (res < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "write failed");
- }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPollPort_drain1(JNIEnv *env, jclass cl, jint fd) {
- int res;
- char buf[1];
- RESTARTABLE(read(fd, buf, 1), res);
- if (res < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "drain1 failed");
- }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPollPort_close0(JNIEnv *env, jclass c, jint fd) {
- int res;
- RESTARTABLE(close(fd), res);
-}
diff --git a/src/java.base/macosx/classes/sun/nio/ch/KQueue.java b/src/java.base/macosx/classes/sun/nio/ch/KQueue.java
index 55785c69875..038df16fd20 100644
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueue.java
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueue.java
@@ -84,17 +84,17 @@ class KQueue {
}
/**
- * Returns the file descriptor from a kevent (assuming to be in ident field)
+ * Returns the file descriptor from a kevent (assuming it is in the ident field)
*/
static int getDescriptor(long address) {
return unsafe.getInt(address + OFFSET_IDENT);
}
- static int getFilter(long address) {
+ static short getFilter(long address) {
return unsafe.getShort(address + OFFSET_FILTER);
}
- static int getFlags(long address) {
+ static short getFlags(long address) {
return unsafe.getShort(address + OFFSET_FLAGS);
}
@@ -108,11 +108,11 @@ class KQueue {
private static native int flagsOffset();
- static native int kqueue() throws IOException;
+ static native int create() throws IOException;
- static native int keventRegister(int kqpfd, int fd, int filter, int flags);
+ static native int register(int kqfd, int fd, int filter, int flags);
- static native int keventPoll(int kqpfd, long pollAddress, int nevents)
+ static native int poll(int kqfd, long pollAddress, int nevents, long timeout)
throws IOException;
static {
diff --git a/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java b/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
deleted file mode 100644
index 8ae844349e9..00000000000
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2011, 2018, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-/*
- * KQueueArrayWrapper.java
- * Implementation of Selector using FreeBSD / Mac OS X kqueues
- * Derived from Sun's DevPollArrayWrapper
- */
-
-package sun.nio.ch;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import sun.security.action.GetPropertyAction;
-
-/*
- * struct kevent { // 32-bit 64-bit
- * uintptr_t ident; // 4 8
- * short filter; // 2 2
- * u_short flags; // 2 2
- * u_int fflags; // 4 4
- * intptr_t data; // 4 8
- * void *udata; // 4 8
- * } // Total: 20 32
- *
- * The implementation works in 32-bit and 64-bit world. We do this by calling a
- * native function that actually sets the sizes and offsets of the fields based
- * on which mode we're in.
- */
-
-class KQueueArrayWrapper {
- // kevent filters
- static short EVFILT_READ;
- static short EVFILT_WRITE;
-
- // kevent struct
- // These fields are now set by initStructSizes in the static initializer.
- static short SIZEOF_KEVENT;
- static short FD_OFFSET;
- static short FILTER_OFFSET;
-
- // kevent array size
- static final int NUM_KEVENTS = 128;
-
- // Are we in a 64-bit VM?
- static boolean is64bit;
-
- // The kevent array (used for outcoming events only)
- private final AllocatedNativeObject keventArray;
- private final long keventArrayAddress;
-
- // The kqueue fd
- private final int kq;
-
- // The fd of the interrupt line going out
- private final int outgoingInterruptFD;
-
-
- static {
- IOUtil.load();
- initStructSizes();
- String datamodel =
- GetPropertyAction.privilegedGetProperty("sun.arch.data.model");
- is64bit = "64".equals(datamodel);
- }
-
- KQueueArrayWrapper(int fd0, int fd1) throws IOException {
- int allocationSize = SIZEOF_KEVENT * NUM_KEVENTS;
- keventArray = new AllocatedNativeObject(allocationSize, true);
- keventArrayAddress = keventArray.address();
- kq = init();
- register0(kq, fd0, 1, 0);
- outgoingInterruptFD = fd1;
- }
-
- // Used to update file description registrations
- private static class Update {
- SelChImpl channel;
- int events;
- Update(SelChImpl channel, int events) {
- this.channel = channel;
- this.events = events;
- }
- }
-
- private LinkedList updateList = new LinkedList();
-
- int getReventOps(int index) {
- int result = 0;
- int offset = SIZEOF_KEVENT*index + FILTER_OFFSET;
- short filter = keventArray.getShort(offset);
-
- // This is all that's necessary based on inspection of usage:
- // SinkChannelImpl, SourceChannelImpl, DatagramChannelImpl,
- // ServerSocketChannelImpl, SocketChannelImpl
- if (filter == EVFILT_READ) {
- result |= Net.POLLIN;
- } else if (filter == EVFILT_WRITE) {
- result |= Net.POLLOUT;
- }
-
- return result;
- }
-
- int getDescriptor(int index) {
- int offset = SIZEOF_KEVENT*index + FD_OFFSET;
- /* The ident field is 8 bytes in 64-bit world, however the API wants us
- * to return an int. Hence read the 8 bytes but return as an int.
- */
- if (is64bit) {
- long fd = keventArray.getLong(offset);
- assert fd <= Integer.MAX_VALUE;
- return (int) fd;
- } else {
- return keventArray.getInt(offset);
- }
- }
-
- void setInterest(SelChImpl channel, int events) {
- synchronized (updateList) {
- // update existing registration
- updateList.add(new Update(channel, events));
- }
- }
-
- void release(SelChImpl channel) {
- synchronized (updateList) {
- // flush any pending updates
- for (Iterator it = updateList.iterator(); it.hasNext();) {
- if (it.next().channel == channel) {
- it.remove();
- }
- }
-
- // remove
- register0(kq, channel.getFDVal(), 0, 0);
- }
- }
-
- void updateRegistrations() {
- synchronized (updateList) {
- Update u;
- while ((u = updateList.poll()) != null) {
- SelChImpl ch = u.channel;
- if (!ch.isOpen())
- continue;
-
- register0(kq, ch.getFDVal(), u.events & Net.POLLIN, u.events & Net.POLLOUT);
- }
- }
- }
-
- void close() throws IOException {
- FileDispatcherImpl.closeIntFD(kq);
- keventArray.free();
- }
-
- int poll(long timeout) {
- updateRegistrations();
- return kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout);
- }
-
- void interrupt() {
- interrupt(outgoingInterruptFD);
- }
-
- private native int init();
- private static native void initStructSizes();
-
- private native void register0(int kq, int fd, int read, int write);
- private native int kevent0(int kq, long keventAddress, int keventCount,
- long timeout);
- private static native void interrupt(int fd);
-}
diff --git a/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java b/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java
index e9177e144e0..91690b0d339 100644
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, 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
@@ -30,7 +30,11 @@ import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
-import static sun.nio.ch.KQueue.*;
+
+import static sun.nio.ch.KQueue.EVFILT_READ;
+import static sun.nio.ch.KQueue.EVFILT_WRITE;
+import static sun.nio.ch.KQueue.EV_ADD;
+import static sun.nio.ch.KQueue.EV_ONESHOT;
/**
* AsynchronousChannelGroup implementation based on the BSD kqueue facility.
@@ -45,6 +49,9 @@ final class KQueuePort
// kqueue file descriptor
private final int kqfd;
+ // address of the poll array passed to kqueue_wait
+ private final long address;
+
// true if kqueue closed
private boolean closed;
@@ -54,9 +61,6 @@ final class KQueuePort
// number of wakeups pending
private final AtomicInteger wakeupCount = new AtomicInteger();
- // address of the poll array passed to kqueue_wait
- private final long address;
-
// encapsulates an event for a channel
static class Event {
final PollableChannel channel;
@@ -82,28 +86,25 @@ final class KQueuePort
{
super(provider, pool);
- // open kqueue
- this.kqfd = kqueue();
+ this.kqfd = KQueue.create();
+ this.address = KQueue.allocatePollArray(MAX_KEVENTS_TO_POLL);
// create socket pair for wakeup mechanism
- int[] sv = new int[2];
try {
- socketpair(sv);
-
- // register one end with kqueue
- keventRegister(kqfd, sv[0], EVFILT_READ, EV_ADD);
- } catch (IOException x) {
- close0(kqfd);
- throw x;
+ long fds = IOUtil.makePipe(true);
+ this.sp = new int[]{(int) (fds >>> 32), (int) fds};
+ } catch (IOException ioe) {
+ KQueue.freePollArray(address);
+ FileDispatcherImpl.closeIntFD(kqfd);
+ throw ioe;
}
- this.sp = sv;
- // allocate the poll array
- this.address = allocatePollArray(MAX_KEVENTS_TO_POLL);
+ // register one end with kqueue
+ KQueue.register(kqfd, sp[0], EVFILT_READ, EV_ADD);
// create the queue and offer the special event to ensure that the first
// threads polls
- this.queue = new ArrayBlockingQueue(MAX_KEVENTS_TO_POLL);
+ this.queue = new ArrayBlockingQueue<>(MAX_KEVENTS_TO_POLL);
this.queue.offer(NEED_TO_POLL);
}
@@ -121,17 +122,18 @@ final class KQueuePort
return;
closed = true;
}
- freePollArray(address);
- close0(sp[0]);
- close0(sp[1]);
- close0(kqfd);
+
+ try { FileDispatcherImpl.closeIntFD(kqfd); } catch (IOException ioe) { }
+ try { FileDispatcherImpl.closeIntFD(sp[0]); } catch (IOException ioe) { }
+ try { FileDispatcherImpl.closeIntFD(sp[1]); } catch (IOException ioe) { }
+ KQueue.freePollArray(address);
}
private void wakeup() {
if (wakeupCount.incrementAndGet() == 1) {
// write byte to socketpair to force wakeup
try {
- interrupt(sp[1]);
+ IOUtil.write1(sp[1], (byte)0);
} catch (IOException x) {
throw new AssertionError(x);
}
@@ -173,9 +175,9 @@ final class KQueuePort
int err = 0;
int flags = (EV_ADD|EV_ONESHOT);
if ((events & Net.POLLIN) > 0)
- err = keventRegister(kqfd, fd, EVFILT_READ, flags);
+ err = KQueue.register(kqfd, fd, EVFILT_READ, flags);
if (err == 0 && (events & Net.POLLOUT) > 0)
- err = keventRegister(kqfd, fd, EVFILT_WRITE, flags);
+ err = KQueue.register(kqfd, fd, EVFILT_WRITE, flags);
if (err != 0)
throw new InternalError("kevent failed: " + err); // should not happen
}
@@ -193,7 +195,11 @@ final class KQueuePort
private Event poll() throws IOException {
try {
for (;;) {
- int n = keventPoll(kqfd, address, MAX_KEVENTS_TO_POLL);
+ int n;
+ do {
+ n = KQueue.poll(kqfd, address, MAX_KEVENTS_TO_POLL, -1L);
+ } while (n == IOStatus.INTERRUPTED);
+
/*
* 'n' events have been read. Here we map them to their
* corresponding channel in batch and queue n-1 so that
@@ -203,14 +209,14 @@ final class KQueuePort
fdToChannelLock.readLock().lock();
try {
while (n-- > 0) {
- long keventAddress = getEvent(address, n);
- int fd = getDescriptor(keventAddress);
+ long keventAddress = KQueue.getEvent(address, n);
+ int fd = KQueue.getDescriptor(keventAddress);
// wakeup
if (fd == sp[0]) {
if (wakeupCount.decrementAndGet() == 0) {
// no more wakeups so drain pipe
- drain1(sp[0]);
+ IOUtil.drain(sp[0]);
}
// queue special event if there are more events
@@ -224,7 +230,7 @@ final class KQueuePort
PollableChannel channel = fdToChannel.get(fd);
if (channel != null) {
- int filter = getFilter(keventAddress);
+ int filter = KQueue.getFilter(keventAddress);
int events = 0;
if (filter == EVFILT_READ)
events = Net.POLLIN;
@@ -314,18 +320,4 @@ final class KQueuePort
}
}
}
-
- // -- Native methods --
-
- private static native void socketpair(int[] sv) throws IOException;
-
- private static native void interrupt(int fd) throws IOException;
-
- private static native void drain1(int fd) throws IOException;
-
- private static native void close0(int fd);
-
- static {
- IOUtil.load();
- }
}
diff --git a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
index 1bd55bd004d..258038e0117 100644
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
@@ -23,11 +23,6 @@
* questions.
*/
-/*
- * KQueueSelectorImpl.java
- * Implementation of Selector using FreeBSD / Mac OS X kqueues
- */
-
package sun.nio.ch;
import java.io.IOException;
@@ -36,85 +31,111 @@ import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
+import java.util.ArrayDeque;
+import java.util.BitSet;
+import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
-class KQueueSelectorImpl
- extends SelectorImpl
-{
- // File descriptors used for interrupt
+import static sun.nio.ch.KQueue.EVFILT_READ;
+import static sun.nio.ch.KQueue.EVFILT_WRITE;
+import static sun.nio.ch.KQueue.EV_ADD;
+import static sun.nio.ch.KQueue.EV_DELETE;
+
+/**
+ * KQueue based Selector implementation for macOS
+ */
+
+class KQueueSelectorImpl extends SelectorImpl {
+
+ // maximum number of events to poll in one call to kqueue
+ private static final int MAX_KEVENTS = 256;
+
+ // kqueue file descriptor
+ private final int kqfd;
+
+ // address of poll array (event list) when polling for pending events
+ private final long pollArrayAddress;
+
+ // file descriptors used for interrupt
private final int fd0;
private final int fd1;
- // The kqueue manipulator
- private final KQueueArrayWrapper kqueueWrapper;
+ // maps file descriptor to selection key, synchronize on selector
+ private final Map fdToKey = new HashMap<>();
- // Map from a file descriptor to an entry containing the selection key
- private final HashMap fdMap;
+ // file descriptors registered with kqueue, synchronize on selector
+ private final BitSet registeredReadFilter = new BitSet();
+ private final BitSet registeredWriteFilter = new BitSet();
- // True if this Selector has been closed
- private boolean closed;
+ // pending new registrations/updates, queued by implRegister and putEventOps
+ private final Object updateLock = new Object();
+ private final Deque newKeys = new ArrayDeque<>();
+ private final Deque updateKeys = new ArrayDeque<>();
+ private final Deque updateOps = new ArrayDeque<>();
- // Lock for interrupt triggering and clearing
+ // interrupt triggering and clearing
private final Object interruptLock = new Object();
private boolean interruptTriggered;
// used by updateSelectedKeys to handle cases where the same file
// descriptor is polled by more than one filter
- private long updateCount;
+ private int pollCount;
- // Used to map file descriptors to a selection key and "update count"
- // (see updateSelectedKeys for usage).
- private static class MapEntry {
- SelectionKeyImpl ski;
- long updateCount;
- MapEntry(SelectionKeyImpl ski) {
- this.ski = ski;
- }
- }
-
- /**
- * Package private constructor called by factory method in
- * the abstract superclass Selector.
- */
KQueueSelectorImpl(SelectorProvider sp) throws IOException {
super(sp);
- long fds = IOUtil.makePipe(false);
- fd0 = (int)(fds >>> 32);
- fd1 = (int)fds;
+
+ this.kqfd = KQueue.create();
+ this.pollArrayAddress = KQueue.allocatePollArray(MAX_KEVENTS);
+
try {
- kqueueWrapper = new KQueueArrayWrapper(fd0, fd1);
- fdMap = new HashMap<>();
- } catch (Throwable t) {
- try {
- FileDispatcherImpl.closeIntFD(fd0);
- } catch (IOException ioe0) {
- t.addSuppressed(ioe0);
- }
- try {
- FileDispatcherImpl.closeIntFD(fd1);
- } catch (IOException ioe1) {
- t.addSuppressed(ioe1);
- }
- throw t;
+ long fds = IOUtil.makePipe(false);
+ this.fd0 = (int) (fds >>> 32);
+ this.fd1 = (int) fds;
+ } catch (IOException ioe) {
+ KQueue.freePollArray(pollArrayAddress);
+ FileDispatcherImpl.closeIntFD(kqfd);
+ throw ioe;
}
+
+ // register one end of the socket pair for wakeups
+ KQueue.register(kqfd, fd0, EVFILT_READ, EV_ADD);
}
private void ensureOpen() {
- if (closed)
+ if (!isOpen())
throw new ClosedSelectorException();
}
@Override
- protected int doSelect(long timeout)
- throws IOException
- {
- ensureOpen();
+ protected int doSelect(long timeout) throws IOException {
+ assert Thread.holdsLock(this);
+
int numEntries;
+ processUpdateQueue();
processDeregisterQueue();
try {
begin();
- numEntries = kqueueWrapper.poll(timeout);
+
+ long to = Math.min(timeout, Integer.MAX_VALUE); // max kqueue timeout
+ boolean timedPoll = (to > 0);
+ do {
+ long startTime = timedPoll ? System.nanoTime() : 0;
+ numEntries = KQueue.poll(kqfd, pollArrayAddress, MAX_KEVENTS, to);
+ if (numEntries == IOStatus.INTERRUPTED && timedPoll) {
+ // timed poll interrupted so need to adjust timeout
+ long adjust = System.nanoTime() - startTime;
+ to -= TimeUnit.MILLISECONDS.convert(adjust, TimeUnit.NANOSECONDS);
+ if (to <= 0) {
+ // timeout expired so no retry
+ numEntries = 0;
+ }
+ }
+ } while (numEntries == IOStatus.INTERRUPTED);
+ assert IOStatus.check(numEntries);
+
} finally {
end();
}
@@ -122,40 +143,101 @@ class KQueueSelectorImpl
return updateSelectedKeys(numEntries);
}
+ /**
+ * Process new registrations and changes to the interest ops.
+ */
+ private void processUpdateQueue() {
+ assert Thread.holdsLock(this);
+
+ synchronized (updateLock) {
+ SelectionKeyImpl ski;
+
+ // new registrations
+ while ((ski = newKeys.pollFirst()) != null) {
+ if (ski.isValid()) {
+ SelChImpl ch = ski.channel;
+ int fd = ch.getFDVal();
+ SelectionKeyImpl previous = fdToKey.put(fd, ski);
+ assert previous == null;
+ assert registeredReadFilter.get(fd) == false;
+ assert registeredWriteFilter.get(fd) == false;
+ }
+ }
+
+ // changes to interest ops
+ assert updateKeys.size() == updateOps.size();
+ while ((ski = updateKeys.pollFirst()) != null) {
+ int ops = updateOps.pollFirst();
+ int fd = ski.channel.getFDVal();
+ if (ski.isValid() && fdToKey.containsKey(fd)) {
+ // add or delete interest in read events
+ if (registeredReadFilter.get(fd)) {
+ if ((ops & Net.POLLIN) == 0) {
+ KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
+ registeredReadFilter.clear(fd);
+ }
+ } else if ((ops & Net.POLLIN) != 0) {
+ KQueue.register(kqfd, fd, EVFILT_READ, EV_ADD);
+ registeredReadFilter.set(fd);
+ }
+
+ // add or delete interest in write events
+ if (registeredWriteFilter.get(fd)) {
+ if ((ops & Net.POLLOUT) == 0) {
+ KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
+ registeredWriteFilter.clear(fd);
+ }
+ } else if ((ops & Net.POLLOUT) != 0) {
+ KQueue.register(kqfd, fd, EVFILT_WRITE, EV_ADD);
+ registeredWriteFilter.set(fd);
+ }
+ }
+ }
+ }
+ }
+
/**
* Update the keys whose fd's have been selected by kqueue.
* Add the ready keys to the selected key set.
* If the interrupt fd has been selected, drain it and clear the interrupt.
*/
- private int updateSelectedKeys(int numEntries)
- throws IOException
- {
+ private int updateSelectedKeys(int numEntries) throws IOException {
+ assert Thread.holdsLock(this);
+ assert Thread.holdsLock(nioSelectedKeys());
+
int numKeysUpdated = 0;
boolean interrupted = false;
// A file descriptor may be registered with kqueue with more than one
- // filter and so there may be more than one event for a fd. The update
- // count in the MapEntry tracks when the fd was last updated and this
- // ensures that the ready ops are updated rather than replaced by a
- // second or subsequent event.
- updateCount++;
+ // filter and so there may be more than one event for a fd. The poll
+ // count is incremented here and compared against the SelectionKey's
+ // "lastPolled" field. This ensures that the ready ops is updated rather
+ // than replaced when a file descriptor is polled by both the read and
+ // write filter.
+ pollCount++;
for (int i = 0; i < numEntries; i++) {
- int nextFD = kqueueWrapper.getDescriptor(i);
- if (nextFD == fd0) {
+ long kevent = KQueue.getEvent(pollArrayAddress, i);
+ int fd = KQueue.getDescriptor(kevent);
+ if (fd == fd0) {
interrupted = true;
} else {
- MapEntry me = fdMap.get(Integer.valueOf(nextFD));
- if (me != null) {
- int rOps = kqueueWrapper.getReventOps(i);
- SelectionKeyImpl ski = me.ski;
+ SelectionKeyImpl ski = fdToKey.get(fd);
+ if (ski != null) {
+ int rOps = 0;
+ short filter = KQueue.getFilter(kevent);
+ if (filter == EVFILT_READ) {
+ rOps |= Net.POLLIN;
+ } else if (filter == EVFILT_WRITE) {
+ rOps |= Net.POLLOUT;
+ }
+
if (selectedKeys.contains(ski)) {
- // first time this file descriptor has been encountered on this
- // update?
- if (me.updateCount != updateCount) {
+ // file descriptor may be polled more than once per poll
+ if (ski.lastPolled != pollCount) {
if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
numKeysUpdated++;
- me.updateCount = updateCount;
+ ski.lastPolled = pollCount;
}
} else {
// ready ops have already been set on this update
@@ -166,7 +248,7 @@ class KQueueSelectorImpl
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
selectedKeys.add(ski);
numKeysUpdated++;
- me.updateCount = updateCount;
+ ski.lastPolled = pollCount;
}
}
}
@@ -181,63 +263,90 @@ class KQueueSelectorImpl
@Override
protected void implClose() throws IOException {
- if (!closed) {
- closed = true;
+ assert !isOpen();
+ assert Thread.holdsLock(this);
+ assert Thread.holdsLock(nioKeys());
- // prevent further wakeup
- synchronized (interruptLock) {
- interruptTriggered = true;
- }
+ // prevent further wakeup
+ synchronized (interruptLock) {
+ interruptTriggered = true;
+ }
- kqueueWrapper.close();
- FileDispatcherImpl.closeIntFD(fd0);
- FileDispatcherImpl.closeIntFD(fd1);
+ FileDispatcherImpl.closeIntFD(kqfd);
+ KQueue.freePollArray(pollArrayAddress);
- // Deregister channels
- Iterator i = keys.iterator();
- while (i.hasNext()) {
- SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
- deregister(ski);
- SelectableChannel selch = ski.channel();
- if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
- i.remove();
- }
+ FileDispatcherImpl.closeIntFD(fd0);
+ FileDispatcherImpl.closeIntFD(fd1);
+
+ // Deregister channels
+ Iterator i = keys.iterator();
+ while (i.hasNext()) {
+ SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
+ deregister(ski);
+ SelectableChannel selch = ski.channel();
+ if (!selch.isOpen() && !selch.isRegistered())
+ ((SelChImpl)selch).kill();
+ i.remove();
}
}
@Override
protected void implRegister(SelectionKeyImpl ski) {
+ assert Thread.holdsLock(nioKeys());
ensureOpen();
- int fd = IOUtil.fdVal(ski.channel.getFD());
- fdMap.put(Integer.valueOf(fd), new MapEntry(ski));
+ synchronized (updateLock) {
+ newKeys.addLast(ski);
+ }
keys.add(ski);
}
@Override
protected void implDereg(SelectionKeyImpl ski) throws IOException {
+ assert !ski.isValid();
+ assert Thread.holdsLock(this);
+ assert Thread.holdsLock(nioKeys());
+ assert Thread.holdsLock(nioSelectedKeys());
+
int fd = ski.channel.getFDVal();
- fdMap.remove(Integer.valueOf(fd));
- kqueueWrapper.release(ski.channel);
- keys.remove(ski);
+ fdToKey.remove(fd);
+ if (registeredReadFilter.get(fd)) {
+ KQueue.register(kqfd, fd, EVFILT_READ, EV_DELETE);
+ registeredReadFilter.clear(fd);
+ }
+ if (registeredWriteFilter.get(fd)) {
+ KQueue.register(kqfd, fd, EVFILT_WRITE, EV_DELETE);
+ registeredWriteFilter.clear(fd);
+ }
+
selectedKeys.remove(ski);
+ keys.remove(ski);
+
+ // remove from channel's key set
deregister(ski);
+
SelectableChannel selch = ski.channel();
if (!selch.isOpen() && !selch.isRegistered())
- ((SelChImpl)selch).kill();
+ ((SelChImpl) selch).kill();
}
@Override
public void putEventOps(SelectionKeyImpl ski, int ops) {
ensureOpen();
- kqueueWrapper.setInterest(ski.channel, ops);
+ synchronized (updateLock) {
+ updateOps.addLast(ops); // ops first in case adding the key fails
+ updateKeys.addLast(ski);
+ }
}
@Override
public Selector wakeup() {
synchronized (interruptLock) {
if (!interruptTriggered) {
- kqueueWrapper.interrupt();
+ try {
+ IOUtil.write1(fd1, (byte)0);
+ } catch (IOException ioe) {
+ throw new InternalError(ioe);
+ }
interruptTriggered = true;
}
}
diff --git a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java
index 5819710f96d..af24b6633ea 100644
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java
@@ -23,17 +23,10 @@
* questions.
*/
-/*
- * KQueueSelectorProvider.java
- * Implementation of Selector using FreeBSD / Mac OS X kqueues
- * Derived from Sun's DevPollSelectorProvider
- */
-
package sun.nio.ch;
import java.io.IOException;
-import java.nio.channels.*;
-import java.nio.channels.spi.*;
+import java.nio.channels.spi.AbstractSelector;
public class KQueueSelectorProvider
extends SelectorProviderImpl
diff --git a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java
index 43a40283c80..ca8f2678a1e 100644
--- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java
+++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -26,7 +26,6 @@
package sun.nio.fs;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.nio.file.spi.FileTypeDetector;
import sun.security.action.GetPropertyAction;
@@ -46,7 +45,7 @@ public class MacOSXFileSystemProvider extends BsdFileSystemProvider {
@Override
FileTypeDetector getFileTypeDetector() {
- Path userMimeTypes = Paths.get(GetPropertyAction
+ Path userMimeTypes = Path.of(GetPropertyAction
.privilegedGetProperty("user.home"), ".mime.types");
return chain(new MimeTypesFileTypeDetector(userMimeTypes),
diff --git a/src/java.base/macosx/native/libnio/ch/KQueue.c b/src/java.base/macosx/native/libnio/ch/KQueue.c
index 3484cac2905..04d500c4847 100644
--- a/src/java.base/macosx/native/libnio/ch/KQueue.c
+++ b/src/java.base/macosx/native/libnio/ch/KQueue.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, 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
@@ -23,76 +23,91 @@
* questions.
*/
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-#include "nio_util.h"
-
-#include "sun_nio_ch_KQueue.h"
-
#include
#include
#include
#include
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "nio.h"
+#include "nio_util.h"
+
+#include "sun_nio_ch_KQueue.h"
+
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueue_keventSize(JNIEnv* env, jclass this)
+Java_sun_nio_ch_KQueue_keventSize(JNIEnv* env, jclass clazz)
{
return sizeof(struct kevent);
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueue_identOffset(JNIEnv* env, jclass this)
+Java_sun_nio_ch_KQueue_identOffset(JNIEnv* env, jclass clazz)
{
return offsetof(struct kevent, ident);
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueue_filterOffset(JNIEnv* env, jclass this)
+Java_sun_nio_ch_KQueue_filterOffset(JNIEnv* env, jclass clazz)
{
return offsetof(struct kevent, filter);
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueue_flagsOffset(JNIEnv* env, jclass this)
+Java_sun_nio_ch_KQueue_flagsOffset(JNIEnv* env, jclass clazz)
{
return offsetof(struct kevent, flags);
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueue_kqueue(JNIEnv *env, jclass c) {
+Java_sun_nio_ch_KQueue_create(JNIEnv *env, jclass clazz) {
int kqfd = kqueue();
if (kqfd < 0) {
JNU_ThrowIOExceptionWithLastError(env, "kqueue failed");
+ return IOS_THROWN;
}
return kqfd;
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueue_keventRegister(JNIEnv *env, jclass c, jint kqfd,
- jint fd, jint filter, jint flags)
+Java_sun_nio_ch_KQueue_register(JNIEnv *env, jclass clazz, jint kqfd,
+ jint fd, jint filter, jint flags)
{
struct kevent changes[1];
- struct timespec timeout = {0, 0};
int res;
EV_SET(&changes[0], fd, filter, flags, 0, 0, 0);
- RESTARTABLE(kevent(kqfd, &changes[0], 1, NULL, 0, &timeout), res);
+ RESTARTABLE(kevent(kqfd, &changes[0], 1, NULL, 0, NULL), res);
return (res == -1) ? errno : 0;
}
JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueue_keventPoll(JNIEnv *env, jclass c,
- jint kqfd, jlong address, jint nevents)
+Java_sun_nio_ch_KQueue_poll(JNIEnv *env, jclass clazz, jint kqfd, jlong address,
+ jint nevents, jlong timeout)
{
struct kevent *events = jlong_to_ptr(address);
int res;
+ struct timespec ts;
+ struct timespec *tsp;
- RESTARTABLE(kevent(kqfd, NULL, 0, events, nevents, NULL), res);
+ if (timeout >= 0) {
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ tsp = &ts;
+ } else {
+ tsp = NULL;
+ }
+
+ res = kevent(kqfd, NULL, 0, events, nevents, tsp);
if (res < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "kqueue failed");
+ if (errno == EINTR) {
+ return IOS_INTERRUPTED;
+ } else {
+ JNU_ThrowIOExceptionWithLastError(env, "kqueue failed");
+ return IOS_THROWN;
+ }
}
return res;
}
diff --git a/src/java.base/macosx/native/libnio/ch/KQueueArrayWrapper.c b/src/java.base/macosx/native/libnio/ch/KQueueArrayWrapper.c
deleted file mode 100644
index 0b7a6c2fb59..00000000000
--- a/src/java.base/macosx/native/libnio/ch/KQueueArrayWrapper.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2011, 2018, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-/*
- * KQueueArrayWrapper.c
- * Implementation of Selector using FreeBSD / Mac OS X kqueues
- * Derived from Sun's DevPollArrayWrapper
- */
-
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-#include "nio_util.h"
-
-#include
-#include
-#include
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_KQueueArrayWrapper_initStructSizes(JNIEnv *env, jclass clazz)
-{
-#define CHECK_EXCEPTION() { \
- if ((*env)->ExceptionCheck(env)) { \
- goto exceptionOccurred; \
- } \
-}
-
-#define CHECK_ERROR_AND_EXCEPTION(_field) { \
- if (_field == NULL) { \
- goto badField; \
- } \
- CHECK_EXCEPTION(); \
-}
-
-
- jfieldID field;
-
- field = (*env)->GetStaticFieldID(env, clazz, "EVFILT_READ", "S");
- CHECK_ERROR_AND_EXCEPTION(field);
- (*env)->SetStaticShortField(env, clazz, field, EVFILT_READ);
- CHECK_EXCEPTION();
-
- field = (*env)->GetStaticFieldID(env, clazz, "EVFILT_WRITE", "S");
- CHECK_ERROR_AND_EXCEPTION(field);
- (*env)->SetStaticShortField(env, clazz, field, EVFILT_WRITE);
- CHECK_EXCEPTION();
-
- field = (*env)->GetStaticFieldID(env, clazz, "SIZEOF_KEVENT", "S");
- CHECK_ERROR_AND_EXCEPTION(field);
- (*env)->SetStaticShortField(env, clazz, field, (short) sizeof(struct kevent));
- CHECK_EXCEPTION();
-
- field = (*env)->GetStaticFieldID(env, clazz, "FD_OFFSET", "S");
- CHECK_ERROR_AND_EXCEPTION(field);
- (*env)->SetStaticShortField(env, clazz, field, (short) offsetof(struct kevent, ident));
- CHECK_EXCEPTION();
-
- field = (*env)->GetStaticFieldID(env, clazz, "FILTER_OFFSET", "S");
- CHECK_ERROR_AND_EXCEPTION(field);
- (*env)->SetStaticShortField(env, clazz, field, (short) offsetof(struct kevent, filter));
- CHECK_EXCEPTION();
- return;
-
-badField:
- return;
-
-exceptionOccurred:
- return;
-
-#undef CHECK_EXCEPTION
-#undef CHECK_ERROR_AND_EXCEPTION
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueueArrayWrapper_init(JNIEnv *env, jobject this)
-{
- int kq = kqueue();
- if (kq < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "KQueueArrayWrapper: kqueue() failed");
- }
- return kq;
-}
-
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_KQueueArrayWrapper_register0(JNIEnv *env, jobject this,
- jint kq, jint fd, jint r, jint w)
-{
- struct kevent changes[2];
- struct kevent errors[2];
- struct timespec dontBlock = {0, 0};
-
- // if (r) then { register for read } else { unregister for read }
- // if (w) then { register for write } else { unregister for write }
- // Ignore errors - they're probably complaints about deleting non-
- // added filters - but provide an error array anyway because
- // kqueue behaves erratically if some of its registrations fail.
- EV_SET(&changes[0], fd, EVFILT_READ, r ? EV_ADD : EV_DELETE, 0, 0, 0);
- EV_SET(&changes[1], fd, EVFILT_WRITE, w ? EV_ADD : EV_DELETE, 0, 0, 0);
- kevent(kq, changes, 2, errors, 2, &dontBlock);
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_KQueueArrayWrapper_kevent0(JNIEnv *env, jobject this, jint kq,
- jlong kevAddr, jint kevCount,
- jlong timeout)
-{
- struct kevent *kevs = (struct kevent *)jlong_to_ptr(kevAddr);
- struct timespec ts;
- struct timespec *tsp;
- int result;
-
- // Java timeout is in milliseconds. Convert to struct timespec.
- // Java timeout == -1 : wait forever : timespec timeout of NULL
- // Java timeout == 0 : return immediately : timespec timeout of zero
- if (timeout >= 0) {
- // For some indeterminate reason kevent(2) has been found to fail with
- // an EINVAL error for timeout values greater than or equal to
- // 100000001000L. To avoid this problem, clamp the timeout arbitrarily
- // to the maximum value of a 32-bit signed integer which is
- // approximately 25 days in milliseconds.
- const jlong timeoutMax = 0x7fffffff; // java.lang.Integer.MAX_VALUE
- if (timeout > timeoutMax) {
- timeout = timeoutMax;
- }
- ts.tv_sec = timeout / 1000;
- ts.tv_nsec = (timeout % 1000) * 1000000; //nanosec = 1 million millisec
- tsp = &ts;
- } else {
- tsp = NULL;
- }
-
- RESTARTABLE(kevent(kq, NULL, 0, kevs, kevCount, tsp), result);
- if (result < 0) {
- JNU_ThrowIOExceptionWithLastError(env,
- "KQueueArrayWrapper: kevent poll failed");
- }
-
- return result;
-}
-
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_KQueueArrayWrapper_interrupt(JNIEnv *env, jclass cls, jint fd)
-{
- char c = 1;
- if (1 != write(fd, &c, 1)) {
- JNU_ThrowIOExceptionWithLastError(env, "KQueueArrayWrapper: interrupt failed");
- }
-}
-
diff --git a/src/java.base/macosx/native/libnio/ch/KQueuePort.c b/src/java.base/macosx/native/libnio/ch/KQueuePort.c
deleted file mode 100644
index b0bc419d278..00000000000
--- a/src/java.base/macosx/native/libnio/ch/KQueuePort.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-#include "nio_util.h"
-
-#include "sun_nio_ch_KQueuePort.h"
-
-#include
-#include
-#include
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_KQueuePort_socketpair(JNIEnv* env, jclass clazz, jintArray sv) {
- int sp[2];
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) {
- JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
- } else {
- jint res[2];
- res[0] = (jint)sp[0];
- res[1] = (jint)sp[1];
- (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]);
- }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_KQueuePort_interrupt(JNIEnv *env, jclass c, jint fd) {
- int res;
- int buf[1];
- buf[0] = 1;
- RESTARTABLE(write(fd, buf, 1), res);
- if (res < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "write failed");
- }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_KQueuePort_drain1(JNIEnv *env, jclass cl, jint fd) {
- int res;
- char buf[1];
- RESTARTABLE(read(fd, buf, 1), res);
- if (res < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "drain1 failed");
- }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_KQueuePort_close0(JNIEnv *env, jclass c, jint fd) {
- int res;
- RESTARTABLE(close(fd), res);
-}
diff --git a/src/java.base/share/classes/java/io/ByteArrayInputStream.java b/src/java.base/share/classes/java/io/ByteArrayInputStream.java
index 99dd0287354..cb20f8ce76a 100644
--- a/src/java.base/share/classes/java/io/ByteArrayInputStream.java
+++ b/src/java.base/share/classes/java/io/ByteArrayInputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2018, 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,12 +25,15 @@
package java.io;
+import java.util.Arrays;
+import java.util.Objects;
+
/**
- * A ByteArrayInputStream contains
+ * A {@code ByteArrayInputStream} contains
* an internal buffer that contains bytes that
* may be read from the stream. An internal
* counter keeps track of the next byte to
- * be supplied by the read method.
+ * be supplied by the {@code read} method.
*