Merge
authorprr
Fri, 23 Mar 2018 08:49:58 -0700
changeset 49311 67b897123581
parent 49310 edbc57573a1c (current diff)
parent 49290 07779973cbe2 (diff)
child 49312 f4188d890101
Merge
make/mapfiles/libjsoundalsa/mapfile-vers
src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java
src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c
src/java.base/linux/native/libnio/ch/EPollPort.c
src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
src/java.base/macosx/native/libnio/ch/KQueueArrayWrapper.c
src/java.base/macosx/native/libnio/ch/KQueuePort.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.h
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiIn.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiOut.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.h
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.h
src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_Ports.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.h
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h
src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Ports.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.c
src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.h
test/jdk/java/nio/channels/DatagramChannel/SendToUnresolved.java
--- a/.hgtags	Thu Mar 22 14:10:30 2018 -0700
+++ b/.hgtags	Fri Mar 23 08:49:58 2018 -0700
@@ -476,3 +476,4 @@
 1fd4d6068f54561cfc67d54fc9ca84af7212c4f8 jdk-11+3
 e59941f7247d451fa7df9eaef3fce0f492f8420c jdk-11+4
 d5c43e9f08fb9a7c74aae0d48daf17f2ad2afaef jdk-11+5
+3acb379b86725c47e7f33358cb22efa8752ae532 jdk-11+6
--- a/make/lib/SoundLibraries.gmk	Thu Mar 22 14:10:30 2018 -0700
+++ b/make/lib/SoundLibraries.gmk	Fri Mar 23 08:49:58 2018 -0700
@@ -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
+ifneq ($(OPENJDK_TARGET_OS), solaris)
+  LIBJSOUND_CFLAGS += \
+      -DUSE_PLATFORM_MIDI_OUT=TRUE \
+      -DUSE_PLATFORM_MIDI_IN=TRUE \
+      #
+endif
 
 ifeq ($(OPENJDK_TARGET_OS), windows)
-  EXTRA_SOUND_JNI_LIBS += jsoundds
-  LIBJSOUND_CFLAGS += -DX_PLATFORM=X_WINDOWS \
-      -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
+  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 @@
     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 @@
 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
--- a/make/mapfiles/libjsound/mapfile-vers	Thu Mar 22 14:10:30 2018 -0700
+++ b/make/mapfiles/libjsound/mapfile-vers	Fri Mar 23 08:49:58 2018 -0700
@@ -65,8 +65,6 @@
 		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;
--- a/make/mapfiles/libjsoundalsa/mapfile-vers	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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:
-        *;
-};
--- a/make/mapfiles/libnio/mapfile-linux	Thu Mar 22 14:10:30 2018 -0700
+++ b/make/mapfiles/libnio/mapfile-linux	Fri Mar 23 08:49:58 2018 -0700
@@ -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 @@
                 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 @@
                 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;
--- a/make/mapfiles/libnio/mapfile-macosx	Thu Mar 22 14:10:30 2018 -0700
+++ b/make/mapfiles/libnio/mapfile-macosx	Fri Mar 23 08:49:58 2018 -0700
@@ -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 @@
                 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 @@
                 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:
 		*;
--- a/make/mapfiles/libnio/mapfile-solaris	Thu Mar 22 14:10:30 2018 -0700
+++ b/make/mapfiles/libnio/mapfile-solaris	Fri Mar 23 08:49:58 2018 -0700
@@ -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 @@
                 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 @@
                 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;
--- a/src/java.base/linux/classes/sun/nio/ch/EPoll.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/linux/classes/sun/nio/ch/EPoll.java	Fri Mar 23 08:49:58 2018 -0700
@@ -109,11 +109,11 @@
 
     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 {
--- a/src/java.base/linux/classes/sun/nio/ch/EPollArrayWrapper.java	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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<Integer,Byte> 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();
-}
--- a/src/java.base/linux/classes/sun/nio/ch/EPollPort.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollPort.java	Fri Mar 23 08:49:58 2018 -0700
@@ -30,7 +30,13 @@
 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 @@
     // 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 @@
     // 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 @@
     {
         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 @@
                 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 @@
     @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 @@
         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 @@
                     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 @@
 
                             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 @@
             }
         }
     }
-
-    // -- 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();
-    }
 }
--- a/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
 
-    // Maps from file descriptors to keys
-    private final Map<Integer, SelectionKeyImpl> 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<SelectionKeyImpl> newKeys = new ArrayDeque<>();
+    private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
+    private final Deque<Integer> 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 @@
      */
     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();
         }
@@ -102,20 +145,69 @@
     }
 
     /**
+     * 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<numEntries; i++) {
-            int nextFD = pollWrapper.getDescriptor(i);
-            if (nextFD == fd0) {
+            long event = EPoll.getEvent(pollArrayAddress, i);
+            int fd = EPoll.getDescriptor(event);
+            if (fd == fd0) {
                 interrupted = true;
             } else {
-                SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
+                SelectionKeyImpl ski = fdToKey.get(fd);
                 if (ski != null) {
-                    int rOps = pollWrapper.getEventOps(i);
+                    int rOps = EPoll.getEvents(event);
                     if (selectedKeys.contains(ski)) {
                         if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
                             numKeysUpdated++;
@@ -140,16 +232,17 @@
 
     @Override
     protected void implClose() throws IOException {
-        if (closed)
-            return;
-        closed = true;
+        assert Thread.holdsLock(this);
+        assert Thread.holdsLock(nioKeys());
 
         // prevent further wakeup
         synchronized (interruptLock) {
             interruptTriggered = true;
         }
 
-        pollWrapper.close();
+        FileDispatcherImpl.closeIntFD(epfd);
+        EPoll.freePollArray(pollArrayAddress);
+
         FileDispatcherImpl.closeIntFD(fd0);
         FileDispatcherImpl.closeIntFD(fd1);
 
@@ -167,42 +260,57 @@
 
     @Override
     protected void implRegister(SelectionKeyImpl ski) {
+        assert Thread.holdsLock(nioKeys());
         ensureOpen();
-        SelChImpl ch = ski.channel;
-        int fd = Integer.valueOf(ch.getFDVal());
-        fdToKey.put(fd, ski);
-        pollWrapper.add(fd);
+        synchronized (updateLock) {
+            newKeys.addLast(ski);
+        }
         keys.add(ski);
     }
 
     @Override
     protected void implDereg(SelectionKeyImpl ski) throws IOException {
-        assert (ski.getIndex() >= 0);
-        SelChImpl ch = ski.channel;
-        int fd = ch.getFDVal();
-        fdToKey.remove(Integer.valueOf(fd));
-        pollWrapper.remove(fd);
-        ski.setIndex(-1);
+        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);
-        selectedKeys.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;
             }
         }
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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 @@
     @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));
--- a/src/java.base/linux/native/libnio/ch/EPoll.c	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/linux/native/libnio/ch/EPoll.c	Fri Mar 23 08:49:58 2018 -0700
@@ -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 <dlfcn.h>
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <sys/epoll.h>
+
 #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 <dlfcn.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/epoll.h>
-
 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 @@
     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;
 }
--- a/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <unistd.h>
-#include <sys/time.h>
-#include <sys/epoll.h>
-
-#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");
-    }
-}
--- a/src/java.base/linux/native/libnio/ch/EPollPort.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-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);
-}
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueue.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueue.java	Fri Mar 23 08:49:58 2018 -0700
@@ -84,17 +84,17 @@
     }
 
     /**
-     * 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 @@
 
     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 {
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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<Update> updateList = new LinkedList<Update>();
-
-    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<Update> 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);
-}
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueuePort.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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.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 @@
     // 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 @@
     // 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 @@
     {
         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);
+            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;
+        }
 
-            // register one end with kqueue
-            keventRegister(kqfd, sv[0], EVFILT_READ, EV_ADD);
-        } catch (IOException x) {
-            close0(kqfd);
-            throw x;
-        }
-        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<Event>(MAX_KEVENTS_TO_POLL);
+        this.queue = new ArrayBlockingQueue<>(MAX_KEVENTS_TO_POLL);
         this.queue.offer(NEED_TO_POLL);
     }
 
@@ -121,17 +122,18 @@
                 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 @@
         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 @@
         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 @@
                     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 @@
 
                             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 @@
             }
         }
     }
-
-    // -- 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();
-    }
 }
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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.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<Integer, SelectionKeyImpl> fdToKey = new HashMap<>();
+
+    // file descriptors registered with kqueue, synchronize on selector
+    private final BitSet registeredReadFilter = new BitSet();
+    private final BitSet registeredWriteFilter = new BitSet();
 
-    // Map from a file descriptor to an entry containing the selection key
-    private final HashMap<Integer, MapEntry> fdMap;
+    // pending new registrations/updates, queued by implRegister and putEventOps
+    private final Object updateLock = new Object();
+    private final Deque<SelectionKeyImpl> newKeys = new ArrayDeque<>();
+    private final Deque<SelectionKeyImpl> updateKeys = new ArrayDeque<>();
+    private final Deque<Integer> updateOps = new ArrayDeque<>();
 
-    // True if this Selector has been closed
-    private boolean closed;
-
-    // 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();
         }
@@ -123,39 +144,100 @@
     }
 
     /**
+     * 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 @@
                         if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
                             selectedKeys.add(ski);
                             numKeysUpdated++;
-                            me.updateCount = updateCount;
+                            ski.lastPolled = pollCount;
                         }
                     }
                 }
@@ -181,63 +263,90 @@
 
     @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;
+        }
+
+        FileDispatcherImpl.closeIntFD(kqfd);
+        KQueue.freePollArray(pollArrayAddress);
 
-            kqueueWrapper.close();
-            FileDispatcherImpl.closeIntFD(fd0);
-            FileDispatcherImpl.closeIntFD(fd1);
+        FileDispatcherImpl.closeIntFD(fd0);
+        FileDispatcherImpl.closeIntFD(fd1);
 
-            // Deregister channels
-            Iterator<SelectionKey> 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();
-            }
+        // Deregister channels
+        Iterator<SelectionKey> 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);
+        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);
-        selectedKeys.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;
             }
         }
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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
--- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(GetPropertyAction
+        Path userMimeTypes = Path.of(GetPropertyAction
                 .privilegedGetProperty("user.home"), ".mime.types");
 
         return chain(new MimeTypesFileTypeDetector(userMimeTypes),
--- a/src/java.base/macosx/native/libnio/ch/KQueue.c	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/macosx/native/libnio/ch/KQueue.c	Fri Mar 23 08:49:58 2018 -0700
@@ -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 <strings.h>
 #include <sys/types.h>
 #include <sys/event.h>
 #include <sys/time.h>
 
+#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;
 }
--- a/src/java.base/macosx/native/libnio/ch/KQueueArrayWrapper.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <sys/types.h>
-#include <sys/event.h>
-#include <sys/time.h>
-
-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");
-    }
-}
-
--- a/src/java.base/macosx/native/libnio/ch/KQueuePort.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-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);
-}
--- a/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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,6 @@
 import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Objects;
@@ -63,7 +62,7 @@
         }
         try {
             path = path.trim();
-            final Path dir = Paths.get(path.length() == 0 ? "." : path);
+            final Path dir = Path.of(path.length() == 0 ? "." : path);
             AccessController.doPrivileged(new PrivilegedAction<>() {
                     @Override
                     public Void run() {
--- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -34,7 +34,6 @@
 import java.lang.reflect.Method;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -346,11 +345,11 @@
                         int i = name.lastIndexOf('.');
                         Path path;
                         if (i > 0) {
-                            Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar));
+                            Path dir = Path.of(name.substring(0, i).replace('.', File.separatorChar));
                             Files.createDirectories(dir);
                             path = dir.resolve(name.substring(i+1, name.length()) + ".class");
                         } else {
-                            path = Paths.get(name + ".class");
+                            path = Path.of(name + ".class");
                         }
                         Files.write(path, classFile);
                         return null;
--- a/src/java.base/share/classes/java/nio/channels/DatagramChannel.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/nio/channels/DatagramChannel.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -279,6 +279,9 @@
      *
      * @return  This datagram channel
      *
+     * @throws  AlreadyConnectedException
+     *          If this channel is already connected
+     *
      * @throws  ClosedChannelException
      *          If this channel is closed
      *
@@ -292,6 +295,12 @@
      *          closing the channel and setting the current thread's
      *          interrupt status
      *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     *
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     *
      * @throws  SecurityException
      *          If a security manager has been installed
      *          and it does not permit access to the given remote address
@@ -444,6 +453,10 @@
      *           zero if there was insufficient room for the datagram in the
      *           underlying output buffer
      *
+     * @throws  AlreadyConnectedException
+     *          If this channel is connected to a different address
+     *          from that specified by {@code target}
+     *
      * @throws  ClosedChannelException
      *          If this channel is closed
      *
@@ -457,6 +470,12 @@
      *          closing the channel and setting the current thread's
      *          interrupt status
      *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     *
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     *
      * @throws  SecurityException
      *          If a security manager has been installed
      *          and it does not permit datagrams to be sent
--- a/src/java.base/share/classes/java/nio/file/Path.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/nio/file/Path.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -28,6 +28,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
+import java.nio.file.spi.FileSystemProvider;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
@@ -93,13 +94,125 @@
  * multiple concurrent threads.
  *
  * @since 1.7
- * @see Paths
  */
 
 public interface Path
     extends Comparable<Path>, Iterable<Path>, Watchable
 {
     /**
+     * Returns a {@code Path} by converting a path string, or a sequence of
+     * strings that when joined form a path string. If {@code more} does not
+     * specify any elements then the value of the {@code first} parameter is
+     * the path string to convert. If {@code more} specifies one or more
+     * elements then each non-empty string, including {@code first}, is
+     * considered to be a sequence of name elements and is joined to form a
+     * path string. The details as to how the Strings are joined is provider
+     * specific but typically they will be joined using the
+     * {@link FileSystem#getSeparator name-separator} as the separator.
+     * For example, if the name separator is "{@code /}" and
+     * {@code getPath("/foo","bar","gus")} is invoked, then the path string
+     * {@code "/foo/bar/gus"} is converted to a {@code Path}. A {@code Path}
+     * representing an empty path is returned if {@code first} is the empty
+     * string and {@code more} does not contain any non-empty strings.
+     *
+     * <p> The {@code Path} is obtained by invoking the {@link FileSystem#getPath
+     * getPath} method of the {@link FileSystems#getDefault default} {@link
+     * FileSystem}.
+     *
+     * <p> Note that while this method is very convenient, using it will imply
+     * an assumed reference to the default {@code FileSystem} and limit the
+     * utility of the calling code. Hence it should not be used in library code
+     * intended for flexible reuse. A more flexible alternative is to use an
+     * existing {@code Path} instance as an anchor, such as:
+     * <pre>{@code
+     *     Path dir = ...
+     *     Path path = dir.resolve("file");
+     * }</pre>
+     *
+     * @param   first
+     *          the path string or initial part of the path string
+     * @param   more
+     *          additional strings to be joined to form the path string
+     *
+     * @return  the resulting {@code Path}
+     *
+     * @throws  InvalidPathException
+     *          if the path string cannot be converted to a {@code Path}
+     *
+     * @see FileSystem#getPath
+     *
+     * @since 11
+     */
+    public static Path of(String first, String... more) {
+        return FileSystems.getDefault().getPath(first, more);
+    }
+
+    /**
+     * Returns a {@code Path} by converting a URI.
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers to locate the provider that is identified by the
+     * URI {@link URI#getScheme scheme} of the given URI. URI schemes are
+     * compared without regard to case. If the provider is found then its {@link
+     * FileSystemProvider#getPath getPath} method is invoked to convert the
+     * URI.
+     *
+     * <p> In the case of the default provider, identified by the URI scheme
+     * "file", the given URI has a non-empty path component, and undefined query
+     * and fragment components. Whether the authority component may be present
+     * is platform specific. The returned {@code Path} is associated with the
+     * {@link FileSystems#getDefault default} file system.
+     *
+     * <p> The default provider provides a similar <em>round-trip</em> guarantee
+     * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
+     * is guaranteed that
+     * <blockquote>{@code
+     * Path.of(}<i>p</i>{@code .}{@link Path#toUri() toUri}{@code ()).equals(}
+     * <i>p</i>{@code .}{@link Path#toAbsolutePath() toAbsolutePath}{@code ())}
+     * </blockquote>
+     * so long as the original {@code Path}, the {@code URI}, and the new {@code
+     * Path} are all created in (possibly different invocations of) the same
+     * Java virtual machine. Whether other providers make any guarantees is
+     * provider specific and therefore unspecified.
+     *
+     * @param   uri
+     *          the URI to convert
+     *
+     * @return  the resulting {@code Path}
+     *
+     * @throws  IllegalArgumentException
+     *          if preconditions on the {@code uri} parameter do not hold. The
+     *          format of the URI is provider specific.
+     * @throws  FileSystemNotFoundException
+     *          The file system, identified by the URI, does not exist and
+     *          cannot be created automatically, or the provider identified by
+     *          the URI's scheme component is not installed
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission to access the file system
+     *
+     * @since 11
+     */
+    public static Path of(URI uri) {
+        String scheme =  uri.getScheme();
+        if (scheme == null)
+            throw new IllegalArgumentException("Missing scheme");
+
+        // check for default provider to avoid loading of installed providers
+        if (scheme.equalsIgnoreCase("file"))
+            return FileSystems.getDefault().provider().getPath(uri);
+
+        // try to find provider
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (provider.getScheme().equalsIgnoreCase(scheme)) {
+                return provider.getPath(uri);
+            }
+        }
+
+        throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
+    }
+
+    /**
      * Returns the file system that created this object.
      *
      * @return  the file system that created this object
@@ -527,7 +640,7 @@
      * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
      * is guaranteed that
      * <blockquote>
-     * {@link Paths#get(URI) Paths.get}{@code (}<i>p</i>{@code .toUri()).equals(}<i>p</i>
+     * {@link Path#of(URI) Path.of}{@code (}<i>p</i>{@code .toUri()).equals(}<i>p</i>
      * {@code .}{@link #toAbsolutePath() toAbsolutePath}{@code ())}
      * </blockquote>
      * so long as the original {@code Path}, the {@code URI}, and the new {@code
--- a/src/java.base/share/classes/java/nio/file/Paths.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/nio/file/Paths.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -32,7 +32,13 @@
  * This class consists exclusively of static methods that return a {@link Path}
  * by converting a path string or {@link URI}.
  *
+ * @apiNote
+ * It is recommended to obtain a {@code Path} via the {@code Path.of} methods
+ * instead of via the {@code get} methods defined in this class as this class
+ * may be deprecated in a future release.
+ *
  * @since 1.7
+ * @see Path
  */
 
 public final class Paths {
@@ -40,33 +46,11 @@
 
     /**
      * Converts a path string, or a sequence of strings that when joined form
-     * a path string, to a {@code Path}. If {@code more} does not specify any
-     * elements then the value of the {@code first} parameter is the path string
-     * to convert. If {@code more} specifies one or more elements then each
-     * non-empty string, including {@code first}, is considered to be a sequence
-     * of name elements (see {@link Path}) and is joined to form a path string.
-     * The details as to how the Strings are joined is provider specific but
-     * typically they will be joined using the {@link FileSystem#getSeparator
-     * name-separator} as the separator. For example, if the name separator is
-     * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
-     * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
-     * A {@code Path} representing an empty path is returned if {@code first}
-     * is the empty string and {@code more} does not contain any non-empty
-     * strings.
+     * a path string, to a {@code Path}.
      *
-     * <p> The {@code Path} is obtained by invoking the {@link FileSystem#getPath
-     * getPath} method of the {@link FileSystems#getDefault default} {@link
-     * FileSystem}.
-     *
-     * <p> Note that while this method is very convenient, using it will imply
-     * an assumed reference to the default {@code FileSystem} and limit the
-     * utility of the calling code. Hence it should not be used in library code
-     * intended for flexible reuse. A more flexible alternative is to use an
-     * existing {@code Path} instance as an anchor, such as:
-     * <pre>
-     *     Path dir = ...
-     *     Path path = dir.resolve("file");
-     * </pre>
+     * @implSpec
+     * This method simply invokes {@link Path#of(String,String...)
+     * Path.of(String, String...)} with the given parameters.
      *
      * @param   first
      *          the path string or initial part of the path string
@@ -79,38 +63,17 @@
      *          if the path string cannot be converted to a {@code Path}
      *
      * @see FileSystem#getPath
+     * @see Path#of(String,String...)
      */
     public static Path get(String first, String... more) {
-        return FileSystems.getDefault().getPath(first, more);
+        return Path.of(first, more);
     }
 
     /**
      * Converts the given URI to a {@link Path} object.
      *
-     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
-     * installed} providers to locate the provider that is identified by the
-     * URI {@link URI#getScheme scheme} of the given URI. URI schemes are
-     * compared without regard to case. If the provider is found then its {@link
-     * FileSystemProvider#getPath getPath} method is invoked to convert the
-     * URI.
-     *
-     * <p> In the case of the default provider, identified by the URI scheme
-     * "file", the given URI has a non-empty path component, and undefined query
-     * and fragment components. Whether the authority component may be present
-     * is platform specific. The returned {@code Path} is associated with the
-     * {@link FileSystems#getDefault default} file system.
-     *
-     * <p> The default provider provides a similar <em>round-trip</em> guarantee
-     * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
-     * is guaranteed that
-     * <blockquote>{@code
-     * Paths.get(}<i>p</i>{@code .}{@link Path#toUri() toUri}{@code ()).equals(}
-     * <i>p</i>{@code .}{@link Path#toAbsolutePath() toAbsolutePath}{@code ())}
-     * </blockquote>
-     * so long as the original {@code Path}, the {@code URI}, and the new {@code
-     * Path} are all created in (possibly different invocations of) the same
-     * Java virtual machine. Whether other providers make any guarantees is
-     * provider specific and therefore unspecified.
+     * @implSpec
+     * This method simply invokes {@link Path#of(URI) * Path.of(URI)} with the given parameter.
      *
      * @param   uri
      *          the URI to convert
@@ -127,23 +90,10 @@
      * @throws  SecurityException
      *          if a security manager is installed and it denies an unspecified
      *          permission to access the file system
+     *
+     * @see Path#of(URI)
      */
     public static Path get(URI uri) {
-        String scheme =  uri.getScheme();
-        if (scheme == null)
-            throw new IllegalArgumentException("Missing scheme");
-
-        // check for default provider to avoid loading of installed providers
-        if (scheme.equalsIgnoreCase("file"))
-            return FileSystems.getDefault().provider().getPath(uri);
-
-        // try to find provider
-        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
-            if (provider.getScheme().equalsIgnoreCase(scheme)) {
-                return provider.getPath(uri);
-            }
-        }
-
-        throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
+        return Path.of(uri);
     }
 }
--- a/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -46,7 +46,7 @@
 
     // temporary directory location
     private static final Path tmpdir =
-        Paths.get(GetPropertyAction.privilegedGetProperty("java.io.tmpdir"));
+        Path.of(GetPropertyAction.privilegedGetProperty("java.io.tmpdir"));
 
     private static final boolean isPosix =
         FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
--- a/src/java.base/share/classes/java/util/AbstractSet.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/util/AbstractSet.java	Fri Mar 23 08:49:58 2018 -0700
@@ -93,9 +93,7 @@
             return false;
         try {
             return containsAll(c);
-        } catch (ClassCastException unused)   {
-            return false;
-        } catch (NullPointerException unused) {
+        } catch (ClassCastException | NullPointerException unused) {
             return false;
         }
     }
--- a/src/java.base/share/classes/java/util/ImmutableCollections.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/util/ImmutableCollections.java	Fri Mar 23 08:49:58 2018 -0700
@@ -70,46 +70,297 @@
 
     static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
 
-    // ---------- List Implementations ----------
-
-    abstract static class AbstractImmutableList<E> extends AbstractList<E>
-                                                implements RandomAccess, Serializable {
+    static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> {
+        // all mutating methods throw UnsupportedOperationException
         @Override public boolean add(E e) { throw uoe(); }
         @Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
-        @Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
         @Override public void    clear() { throw uoe(); }
         @Override public boolean remove(Object o) { throw uoe(); }
         @Override public boolean removeAll(Collection<?> c) { throw uoe(); }
         @Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
+        @Override public boolean retainAll(Collection<?> c) { throw uoe(); }
+    }
+
+    // ---------- List Implementations ----------
+
+    @SuppressWarnings("unchecked")
+    static <E> List<E> emptyList() {
+        return (List<E>) ListN.EMPTY_LIST;
+    }
+
+    static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
+            implements List<E>, RandomAccess {
+
+        // all mutating methods throw UnsupportedOperationException
+        @Override public void    add(int index, E element) { throw uoe(); }
+        @Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
+        @Override public E       remove(int index) { throw uoe(); }
         @Override public void    replaceAll(UnaryOperator<E> operator) { throw uoe(); }
-        @Override public boolean retainAll(Collection<?> c) { throw uoe(); }
+        @Override public E       set(int index, E element) { throw uoe(); }
         @Override public void    sort(Comparator<? super E> c) { throw uoe(); }
+
+        @Override
+        public List<E> subList(int fromIndex, int toIndex) {
+            int size = size();
+            subListRangeCheck(fromIndex, toIndex, size);
+            return SubList.fromList(this, fromIndex, toIndex);
+        }
+
+        static void subListRangeCheck(int fromIndex, int toIndex, int size) {
+            if (fromIndex < 0)
+                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
+            if (toIndex > size)
+                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
+            if (fromIndex > toIndex)
+                throw new IllegalArgumentException("fromIndex(" + fromIndex +
+                        ") > toIndex(" + toIndex + ")");
+        }
+
+        @Override
+        public Iterator<E> iterator() {
+            return new ListItr<E>(this, size());
+        }
+
+        @Override
+        public ListIterator<E> listIterator() {
+            return listIterator(0);
+        }
+
+        @Override
+        public ListIterator<E> listIterator(final int index) {
+            int size = size();
+            if (index < 0 || index > size) {
+                throw outOfBounds(index);
+            }
+            return new ListItr<E>(this, size, index);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+
+            if (!(o instanceof List)) {
+                return false;
+            }
+
+            Iterator<?> oit = ((List<?>) o).iterator();
+            for (int i = 0, s = size(); i < s; i++) {
+                if (!oit.hasNext() || !get(i).equals(oit.next())) {
+                    return false;
+                }
+            }
+            return !oit.hasNext();
+        }
+
+        @Override
+        public int indexOf(Object o) {
+            Objects.requireNonNull(o);
+            for (int i = 0, s = size(); i < s; i++) {
+                if (o.equals(get(i))) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        @Override
+        public int lastIndexOf(Object o) {
+            Objects.requireNonNull(o);
+            for (int i = size() - 1; i >= 0; i--) {
+                if (o.equals(get(i))) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 1;
+            for (int i = 0, s = size(); i < s; i++) {
+                hash = 31 * hash + get(i).hashCode();
+            }
+            return hash;
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            return indexOf(o) >= 0;
+        }
+
+        IndexOutOfBoundsException outOfBounds(int index) {
+            return new IndexOutOfBoundsException("Index: " + index + " Size: " + size());
+        }
     }
 
-    static final class List0<E> extends AbstractImmutableList<E> {
-        private static final List0<?> INSTANCE = new List0<>();
+    static final class ListItr<E> implements ListIterator<E> {
+
+        @Stable
+        private final List<E> list;
+
+        @Stable
+        private final int size;
+
+        private int cursor;
+
+        ListItr(List<E> list, int size) {
+            this(list, size, 0);
+        }
+
+        ListItr(List<E> list, int size, int index) {
+            this.list = list;
+            this.size = size;
+            this.cursor = index;
+        }
+
+        public boolean hasNext() {
+            return cursor != size;
+        }
 
-        @SuppressWarnings("unchecked")
-        static <T> List0<T> instance() {
-            return (List0<T>) INSTANCE;
+        public E next() {
+            try {
+                int i = cursor;
+                E next = list.get(i);
+                cursor = i + 1;
+                return next;
+            } catch (IndexOutOfBoundsException e) {
+                throw new NoSuchElementException();
+            }
+        }
+
+        public void remove() {
+            throw uoe();
+        }
+
+        public boolean hasPrevious() {
+            return cursor != 0;
+        }
+
+        public E previous() {
+            try {
+                int i = cursor - 1;
+                E previous = list.get(i);
+                cursor = i;
+                return previous;
+            } catch (IndexOutOfBoundsException e) {
+                throw new NoSuchElementException();
+            }
+        }
+
+        public int nextIndex() {
+            return cursor;
+        }
+
+        public int previousIndex() {
+            return cursor - 1;
+        }
+
+        public void set(E e) {
+            throw uoe();
         }
 
-        private List0() { }
+        public void add(E e) {
+            throw uoe();
+        }
+    }
+
+    static final class SubList<E> extends AbstractImmutableList<E>
+            implements RandomAccess {
+
+        @Stable
+        private final List<E> root;
+
+        @Stable
+        private final int offset;
+
+        @Stable
+        private final int size;
+
+        private SubList(List<E> root, int offset, int size) {
+            this.root = root;
+            this.offset = offset;
+            this.size = size;
+        }
+
+        /**
+         * Constructs a sublist of another SubList.
+         */
+        static <E> SubList<E> fromSubList(SubList<E> parent, int fromIndex, int toIndex) {
+            return new SubList<E>(parent.root, parent.offset + fromIndex, toIndex - fromIndex);
+        }
+
+        /**
+         * Constructs a sublist of an arbitrary AbstractImmutableList, which is
+         * not a SubList itself.
+         */
+        static <E> SubList<E> fromList(List<E> list, int fromIndex, int toIndex) {
+            return new SubList<E>(list, fromIndex, toIndex - fromIndex);
+        }
+
+        public E get(int index) {
+            Objects.checkIndex(index, size);
+            return root.get(offset + index);
+        }
+
+        public int size() {
+            return size;
+        }
+
+        public Iterator<E> iterator() {
+            return new ListItr<E>(this, size());
+        }
+
+        public ListIterator<E> listIterator(int index) {
+            rangeCheck(index);
+            return new ListItr<E>(this, size(), index);
+        }
+
+        public List<E> subList(int fromIndex, int toIndex) {
+            subListRangeCheck(fromIndex, toIndex, size);
+            return SubList.fromSubList(this, fromIndex, toIndex);
+        }
+
+        private void rangeCheck(int index) {
+            if (index < 0 || index > size) {
+                throw outOfBounds(index);
+            }
+        }
+    }
+
+    static final class List12<E> extends AbstractImmutableList<E>
+            implements Serializable {
+
+        @Stable
+        private final E e0;
+
+        @Stable
+        private final E e1;
+
+        List12(E e0) {
+            this.e0 = Objects.requireNonNull(e0);
+            this.e1 = null;
+        }
+
+        List12(E e0, E e1) {
+            this.e0 = Objects.requireNonNull(e0);
+            this.e1 = Objects.requireNonNull(e1);
+        }
 
         @Override
         public int size() {
-            return 0;
+            return e1 != null ? 2 : 1;
         }
 
         @Override
         public E get(int index) {
-            Objects.checkIndex(index, 0); // always throws IndexOutOfBoundsException
-            return null;                  // but the compiler doesn't know this
-        }
-
-        @Override
-        public Iterator<E> iterator() {
-            return Collections.emptyIterator();
+            if (index == 0) {
+                return e0;
+            } else if (index == 1 && e1 != null) {
+                return e1;
+            }
+            throw outOfBounds(index);
         }
 
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -117,111 +368,20 @@
         }
 
         private Object writeReplace() {
-            return new CollSer(CollSer.IMM_LIST);
-        }
-
-        @Override
-        public boolean contains(Object o) {
-            Objects.requireNonNull(o);
-            return false;
-        }
-
-        @Override
-        public boolean containsAll(Collection<?> o) {
-            return o.isEmpty(); // implicit nullcheck of o
-        }
-
-        @Override
-        public int hashCode() {
-            return 1;
-        }
-    }
-
-    static final class List1<E> extends AbstractImmutableList<E> {
-        @Stable
-        private final E e0;
-
-        List1(E e0) {
-            this.e0 = Objects.requireNonNull(e0);
-        }
-
-        @Override
-        public int size() {
-            return 1;
-        }
-
-        @Override
-        public E get(int index) {
-            Objects.checkIndex(index, 1);
-            return e0;
-        }
-
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            throw new InvalidObjectException("not serial proxy");
-        }
-
-        private Object writeReplace() {
-            return new CollSer(CollSer.IMM_LIST, e0);
-        }
-
-        @Override
-        public boolean contains(Object o) {
-            return o.equals(e0); // implicit nullcheck of o
-        }
-
-        @Override
-        public int hashCode() {
-            return 31 + e0.hashCode();
-        }
-    }
-
-    static final class List2<E> extends AbstractImmutableList<E> {
-        @Stable
-        private final E e0;
-        @Stable
-        private final E e1;
-
-        List2(E e0, E e1) {
-            this.e0 = Objects.requireNonNull(e0);
-            this.e1 = Objects.requireNonNull(e1);
-        }
-
-        @Override
-        public int size() {
-            return 2;
-        }
-
-        @Override
-        public E get(int index) {
-            Objects.checkIndex(index, 2);
-            if (index == 0) {
-                return e0;
-            } else { // index == 1
-                return e1;
+            if (e1 == null) {
+                return new CollSer(CollSer.IMM_LIST, e0);
+            } else {
+                return new CollSer(CollSer.IMM_LIST, e0, e1);
             }
         }
 
-        @Override
-        public boolean contains(Object o) {
-            return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 31 + e0.hashCode();
-            return 31 * hash + e1.hashCode();
-        }
-
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            throw new InvalidObjectException("not serial proxy");
-        }
-
-        private Object writeReplace() {
-            return new CollSer(CollSer.IMM_LIST, e0, e1);
-        }
     }
 
-    static final class ListN<E> extends AbstractImmutableList<E> {
+    static final class ListN<E> extends AbstractImmutableList<E>
+            implements Serializable {
+
+        static final List<?> EMPTY_LIST = new ListN<>();
+
         @Stable
         private final E[] elements;
 
@@ -233,7 +393,12 @@
             for (int i = 0; i < input.length; i++) {
                 tmp[i] = Objects.requireNonNull(input[i]);
             }
-            this.elements = tmp;
+            elements = tmp;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return size() == 0;
         }
 
         @Override
@@ -243,29 +408,9 @@
 
         @Override
         public E get(int index) {
-            Objects.checkIndex(index, elements.length);
             return elements[index];
         }
 
-        @Override
-        public boolean contains(Object o) {
-            for (E e : elements) {
-                if (o.equals(e)) { // implicit nullcheck of o
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 1;
-            for (E e : elements) {
-                hash = 31 * hash + e.hashCode();
-            }
-            return hash;
-        }
-
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
             throw new InvalidObjectException("not serial proxy");
         }
@@ -277,105 +422,52 @@
 
     // ---------- Set Implementations ----------
 
-    abstract static class AbstractImmutableSet<E> extends AbstractSet<E> implements Serializable {
-        @Override public boolean add(E e) { throw uoe(); }
-        @Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
-        @Override public void    clear() { throw uoe(); }
-        @Override public boolean remove(Object o) { throw uoe(); }
-        @Override public boolean removeAll(Collection<?> c) { throw uoe(); }
-        @Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
-        @Override public boolean retainAll(Collection<?> c) { throw uoe(); }
-    }
-
-    static final class Set0<E> extends AbstractImmutableSet<E> {
-        private static final Set0<?> INSTANCE = new Set0<>();
-
-        @SuppressWarnings("unchecked")
-        static <T> Set0<T> instance() {
-            return (Set0<T>) INSTANCE;
-        }
-
-        private Set0() { }
+    static abstract class AbstractImmutableSet<E> extends AbstractImmutableCollection<E>
+            implements Set<E> {
 
         @Override
-        public int size() {
-            return 0;
-        }
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            } else if (!(o instanceof Set)) {
+                return false;
+            }
 
-        @Override
-        public boolean contains(Object o) {
-            Objects.requireNonNull(o);
-            return false;
-        }
-
-        @Override
-        public boolean containsAll(Collection<?> o) {
-            return o.isEmpty(); // implicit nullcheck of o
+            Collection<?> c = (Collection<?>) o;
+            if (c.size() != size()) {
+                return false;
+            }
+            for (Object e : c) {
+                if (e == null || !contains(e)) {
+                    return false;
+                }
+            }
+            return true;
         }
 
         @Override
-        public Iterator<E> iterator() {
-            return Collections.emptyIterator();
-        }
-
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            throw new InvalidObjectException("not serial proxy");
-        }
-
-        private Object writeReplace() {
-            return new CollSer(CollSer.IMM_SET);
-        }
-
-        @Override
-        public int hashCode() {
-            return 0;
-        }
+        public abstract int hashCode();
     }
 
-    static final class Set1<E> extends AbstractImmutableSet<E> {
-        @Stable
-        private final E e0;
-
-        Set1(E e0) {
-            this.e0 = Objects.requireNonNull(e0);
-        }
-
-        @Override
-        public int size() {
-            return 1;
-        }
-
-        @Override
-        public boolean contains(Object o) {
-            return o.equals(e0); // implicit nullcheck of o
-        }
-
-        @Override
-        public Iterator<E> iterator() {
-            return Collections.singletonIterator(e0);
-        }
-
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            throw new InvalidObjectException("not serial proxy");
-        }
-
-        private Object writeReplace() {
-            return new CollSer(CollSer.IMM_SET, e0);
-        }
-
-        @Override
-        public int hashCode() {
-            return e0.hashCode();
-        }
+    @SuppressWarnings("unchecked")
+    static <E> Set<E> emptySet() {
+        return (Set<E>) SetN.EMPTY_SET;
     }
 
-    static final class Set2<E> extends AbstractImmutableSet<E> {
+    static final class Set12<E> extends AbstractImmutableSet<E>
+            implements Serializable {
+
         @Stable
         final E e0;
         @Stable
         final E e1;
 
-        Set2(E e0, E e1) {
+        Set12(E e0) {
+            this.e0 = Objects.requireNonNull(e0);
+            this.e1 = null;
+        }
+
+        Set12(E e0, E e1) {
             if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
                 throw new IllegalArgumentException("duplicate element: " + e0);
             }
@@ -391,7 +483,7 @@
 
         @Override
         public int size() {
-            return 2;
+            return (e1 == null) ? 1 : 2;
         }
 
         @Override
@@ -401,26 +493,26 @@
 
         @Override
         public int hashCode() {
-            return e0.hashCode() + e1.hashCode();
+            return e0.hashCode() + (e1 == null ? 0 : e1.hashCode());
         }
 
         @Override
         public Iterator<E> iterator() {
-            return new Iterator<E>() {
-                private int idx = 0;
+            return new Iterator<>() {
+                private int idx = size();
 
                 @Override
                 public boolean hasNext() {
-                    return idx < 2;
+                    return idx > 0;
                 }
 
                 @Override
                 public E next() {
-                    if (idx == 0) {
-                        idx = 1;
+                    if (idx == 1) {
+                        idx = 0;
                         return e0;
-                    } else if (idx == 1) {
-                        idx = 2;
+                    } else if (idx == 2) {
+                        idx = 1;
                         return e1;
                     } else {
                         throw new NoSuchElementException();
@@ -434,7 +526,11 @@
         }
 
         private Object writeReplace() {
-            return new CollSer(CollSer.IMM_SET, e0, e1);
+            if (e1 == null) {
+                return new CollSer(CollSer.IMM_SET, e0);
+            } else {
+                return new CollSer(CollSer.IMM_SET, e0, e1);
+            }
         }
     }
 
@@ -444,7 +540,11 @@
      * least one null is always present.
      * @param <E> the element type
      */
-    static final class SetN<E> extends AbstractImmutableSet<E> {
+    static final class SetN<E> extends AbstractImmutableSet<E>
+            implements Serializable {
+
+        static final Set<?> EMPTY_SET = new SetN<>();
+
         @Stable
         final E[] elements;
         @Stable
@@ -474,12 +574,13 @@
 
         @Override
         public boolean contains(Object o) {
-            return probe(o) >= 0; // implicit nullcheck of o
+            Objects.requireNonNull(o);
+            return size > 0 && probe(o) >= 0;
         }
 
         @Override
         public Iterator<E> iterator() {
-            return new Iterator<E>() {
+            return new Iterator<>() {
                 private int idx = 0;
 
                 @Override
@@ -549,6 +650,11 @@
 
     // ---------- Map Implementations ----------
 
+    @SuppressWarnings("unchecked")
+    static <K,V> Map<K,V> emptyMap() {
+        return (Map<K,V>) MapN.EMPTY_MAP;
+    }
+
     abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable {
         @Override public void clear() { throw uoe(); }
         @Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
@@ -565,47 +671,6 @@
         @Override public void replaceAll(BiFunction<? super K,? super V,? extends V> f) { throw uoe(); }
     }
 
-    static final class Map0<K,V> extends AbstractImmutableMap<K,V> {
-        private static final Map0<?,?> INSTANCE = new Map0<>();
-
-        @SuppressWarnings("unchecked")
-        static <K,V> Map0<K,V> instance() {
-            return (Map0<K,V>) INSTANCE;
-        }
-
-        private Map0() { }
-
-        @Override
-        public Set<Map.Entry<K,V>> entrySet() {
-            return Set.of();
-        }
-
-        @Override
-        public boolean containsKey(Object o) {
-            Objects.requireNonNull(o);
-            return false;
-        }
-
-        @Override
-        public boolean containsValue(Object o) {
-            Objects.requireNonNull(o);
-            return false;
-        }
-
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            throw new InvalidObjectException("not serial proxy");
-        }
-
-        private Object writeReplace() {
-            return new CollSer(CollSer.IMM_MAP);
-        }
-
-        @Override
-        public int hashCode() {
-            return 0;
-        }
-    }
-
     static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
         @Stable
         private final K k0;
@@ -656,8 +721,12 @@
      * @param <V> the value type
      */
     static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
+
+        static final Map<?,?> EMPTY_MAP = new MapN<>();
+
         @Stable
         final Object[] table; // pairs of key, value
+
         @Stable
         final int size; // number of pairs
 
@@ -689,14 +758,16 @@
 
         @Override
         public boolean containsKey(Object o) {
-            return probe(o) >= 0; // implicit nullcheck of o
+            Objects.requireNonNull(o);
+            return size > 0 && probe(o) >= 0;
         }
 
         @Override
         public boolean containsValue(Object o) {
+            Objects.requireNonNull(o);
             for (int i = 1; i < table.length; i += 2) {
                 Object v = table[i];
-                if (v != null && o.equals(v)) { // implicit nullcheck of o
+                if (v != null && o.equals(v)) {
                     return true;
                 }
             }
@@ -718,6 +789,10 @@
         @Override
         @SuppressWarnings("unchecked")
         public V get(Object o) {
+            if (size == 0) {
+                Objects.requireNonNull(o);
+                return null;
+            }
             int i = probe(o);
             if (i >= 0) {
                 return (V)table[i+1];
@@ -733,7 +808,7 @@
 
         @Override
         public Set<Map.Entry<K,V>> entrySet() {
-            return new AbstractSet<Map.Entry<K,V>>() {
+            return new AbstractSet<>() {
                 @Override
                 public int size() {
                     return MapN.this.size;
@@ -741,7 +816,7 @@
 
                 @Override
                 public Iterator<Map.Entry<K,V>> iterator() {
-                    return new Iterator<Map.Entry<K,V>>() {
+                    return new Iterator<>() {
                         int idx = 0;
 
                         @Override
@@ -948,7 +1023,7 @@
                     return Set.of(array);
                 case IMM_MAP:
                     if (array.length == 0) {
-                        return ImmutableCollections.Map0.instance();
+                        return ImmutableCollections.emptyMap();
                     } else if (array.length == 2) {
                         return new ImmutableCollections.Map1<>(array[0], array[1]);
                     } else {
--- a/src/java.base/share/classes/java/util/List.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/util/List.java	Fri Mar 23 08:49:58 2018 -0700
@@ -788,7 +788,7 @@
      * @since 9
      */
     static <E> List<E> of() {
-        return ImmutableCollections.List0.instance();
+        return ImmutableCollections.emptyList();
     }
 
     /**
@@ -804,7 +804,7 @@
      * @since 9
      */
     static <E> List<E> of(E e1) {
-        return new ImmutableCollections.List1<>(e1);
+        return new ImmutableCollections.List12<>(e1);
     }
 
     /**
@@ -821,7 +821,7 @@
      * @since 9
      */
     static <E> List<E> of(E e1, E e2) {
-        return new ImmutableCollections.List2<>(e1, e2);
+        return new ImmutableCollections.List12<>(e1, e2);
     }
 
     /**
@@ -1031,11 +1031,11 @@
     static <E> List<E> of(E... elements) {
         switch (elements.length) { // implicit null check of elements
             case 0:
-                return ImmutableCollections.List0.instance();
+                return ImmutableCollections.emptyList();
             case 1:
-                return new ImmutableCollections.List1<>(elements[0]);
+                return new ImmutableCollections.List12<>(elements[0]);
             case 2:
-                return new ImmutableCollections.List2<>(elements[0], elements[1]);
+                return new ImmutableCollections.List12<>(elements[0], elements[1]);
             default:
                 return new ImmutableCollections.ListN<>(elements);
         }
--- a/src/java.base/share/classes/java/util/Map.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/util/Map.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1287,7 +1287,7 @@
      * @since 9
      */
     static <K, V> Map<K, V> of() {
-        return ImmutableCollections.Map0.instance();
+        return ImmutableCollections.emptyMap();
     }
 
     /**
@@ -1604,11 +1604,11 @@
     @SuppressWarnings("varargs")
     static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
         if (entries.length == 0) { // implicit null check of entries array
-            return ImmutableCollections.Map0.instance();
+            return ImmutableCollections.emptyMap();
         } else if (entries.length == 1) {
             // implicit null check of the array slot
             return new ImmutableCollections.Map1<>(entries[0].getKey(),
-                                                   entries[0].getValue());
+                    entries[0].getValue());
         } else {
             Object[] kva = new Object[entries.length << 1];
             int a = 0;
--- a/src/java.base/share/classes/java/util/Scanner.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/util/Scanner.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -2897,7 +2897,7 @@
      * letters:
      *
      * <pre>{@code
-     * try (Scanner sc = new Scanner(Paths.get("input.txt"))) {
+     * try (Scanner sc = new Scanner(Path.of("input.txt"))) {
      *     Pattern pat = Pattern.compile("[A-Z]{7,}");
      *     List<String> capWords = sc.findAll(pat)
      *                               .map(MatchResult::group)
--- a/src/java.base/share/classes/java/util/Set.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/java/util/Set.java	Fri Mar 23 08:49:58 2018 -0700
@@ -449,7 +449,7 @@
      * @since 9
      */
     static <E> Set<E> of() {
-        return ImmutableCollections.Set0.instance();
+        return ImmutableCollections.emptySet();
     }
 
     /**
@@ -464,7 +464,7 @@
      * @since 9
      */
     static <E> Set<E> of(E e1) {
-        return new ImmutableCollections.Set1<>(e1);
+        return new ImmutableCollections.Set12<>(e1);
     }
 
     /**
@@ -481,7 +481,7 @@
      * @since 9
      */
     static <E> Set<E> of(E e1, E e2) {
-        return new ImmutableCollections.Set2<>(e1, e2);
+        return new ImmutableCollections.Set12<>(e1, e2);
     }
 
     /**
@@ -692,11 +692,11 @@
     static <E> Set<E> of(E... elements) {
         switch (elements.length) { // implicit null check of elements
             case 0:
-                return ImmutableCollections.Set0.instance();
+                return ImmutableCollections.emptySet();
             case 1:
-                return new ImmutableCollections.Set1<>(elements[0]);
+                return new ImmutableCollections.Set12<>(elements[0]);
             case 2:
-                return new ImmutableCollections.Set2<>(elements[0], elements[1]);
+                return new ImmutableCollections.Set12<>(elements[0], elements[1]);
             default:
                 return new ImmutableCollections.SetN<>(elements);
         }
--- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -32,7 +32,6 @@
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
@@ -243,8 +242,8 @@
                 mn = location.substring(5, location.length());
             } else if (location.startsWith("file:/")) {
                 // named module in exploded image
-                Path path = Paths.get(URI.create(location));
-                Path modulesDir = Paths.get(JAVA_HOME, "modules");
+                Path path = Path.of(URI.create(location));
+                Path modulesDir = Path.of(JAVA_HOME, "modules");
                 if (path.startsWith(modulesDir)) {
                     mn = path.getFileName().toString();
                 }
@@ -267,7 +266,7 @@
         private static URL toFileURL(String location) {
             return AccessController.doPrivileged(new PrivilegedAction<>() {
                 public URL run() {
-                    Path path = Paths.get(location);
+                    Path path = Path.of(location);
                     if (Files.isRegularFile(path)) {
                         try {
                             return path.toUri().toURL();
@@ -285,7 +284,7 @@
         private static Manifest getManifest(String location) {
             return AccessController.doPrivileged(new PrivilegedAction<>() {
                 public Manifest run() {
-                    Path jar = Paths.get(location);
+                    Path jar = Path.of(location);
                     try (InputStream in = Files.newInputStream(jar);
                          JarInputStream jis = new JarInputStream(in, false)) {
                         return jis.getManifest();
--- a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -28,7 +28,7 @@
 import java.io.IOException;
 import java.net.URL;
 import java.nio.file.InvalidPathException;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.security.CodeSource;
 import java.security.PermissionCollection;
 import java.util.jar.Manifest;
@@ -223,7 +223,7 @@
             // Use an intermediate File object to construct a URI/URL without
             // authority component as URLClassPath can't handle URLs with a UNC
             // server name in the authority component.
-            return Paths.get(s).toRealPath().toFile().toURI().toURL();
+            return Path.of(s).toRealPath().toFile().toURI().toURL();
         } catch (InvalidPathException | IOException ignore) {
             // malformed path string or class path element does not exist
             return null;
--- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -34,7 +34,6 @@
 import java.lang.module.ResolvedModule;
 import java.net.URI;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -539,7 +538,7 @@
             Path[] paths = new Path[dirs.length];
             int i = 0;
             for (String dir: dirs) {
-                paths[i++] = Paths.get(dir);
+                paths[i++] = Path.of(dir);
             }
             return ModulePath.of(patcher, paths);
         }
--- a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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,6 @@
 import java.lang.module.ResolvedModule;
 import java.net.URI;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayDeque;
 import java.util.Collections;
 import java.util.Deque;
@@ -129,7 +128,7 @@
             () -> new InternalError("Selected module " + name + " not on module path"));
 
         URI uri = rm.reference().location().get();
-        Path path = Paths.get(uri);
+        Path path = Path.of(uri);
         String fn = path.getFileName().toString();
         if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
             throw new UnsupportedOperationException(path + " is not a modular JAR or jmod file");
--- a/src/java.base/share/classes/jdk/internal/module/ModulePath.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/module/ModulePath.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -43,7 +43,6 @@
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -360,7 +359,7 @@
         URI uri = mref.location().orElse(null);
         if (uri != null) {
             if (uri.getScheme().equalsIgnoreCase("file")) {
-                Path file = Paths.get(uri);
+                Path file = Path.of(uri);
                 return file.getFileName().toString();
             } else {
                 return uri.toString();
--- a/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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 @@
 import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayDeque;
@@ -185,7 +184,7 @@
 
         // probe to see if this is an images build
         String home = System.getProperty("java.home");
-        Path modules = Paths.get(home, "lib", "modules");
+        Path modules = Path.of(home, "lib", "modules");
         if (Files.isRegularFile(modules)) {
             if (USE_FAST_PATH) {
                 SystemModules systemModules = allSystemModules();
@@ -205,7 +204,7 @@
         }
 
         // exploded build (do not cache module finder)
-        Path dir = Paths.get(home, "modules");
+        Path dir = Path.of(home, "modules");
         if (!Files.isDirectory(dir))
             throw new InternalError("Unable to detect the run-time image");
         ModuleFinder f = ModulePath.of(ModuleBootstrap.patcher(), dir);
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -508,8 +508,7 @@
                 if (remote != null) {
                     // connected
                     if (!target.equals(remote)) {
-                        throw new IllegalArgumentException(
-                            "Connected address not equal to target address");
+                        throw new AlreadyConnectedException();
                     }
                     do {
                         n = IOUtil.write(fd, src, -1, nd);
--- a/src/java.base/share/classes/sun/nio/ch/IOUtil.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/IOUtil.java	Fri Mar 23 08:49:58 2018 -0700
@@ -397,7 +397,9 @@
      * The read end of the pipe is returned in the high 32 bits,
      * while the write end is returned in the low 32 bits.
      */
-    static native long makePipe(boolean blocking);
+    static native long makePipe(boolean blocking) throws IOException;
+
+    static native int write1(int fd, byte b) throws IOException;
 
     static native boolean drain(int fd) throws IOException;
 
--- a/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/SelectionKeyImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -33,10 +33,10 @@
 
 
 /**
- * An implementation of SelectionKey for Solaris.
+ * An implementation of SelectionKey.
  */
 
-public class SelectionKeyImpl
+public final class SelectionKeyImpl
     extends AbstractSelectionKey
 {
 
@@ -54,12 +54,14 @@
         selector = sel;
     }
 
+    @Override
     public SelectableChannel channel() {
         return (SelectableChannel)channel;
     }
 
+    @Override
     public Selector selector() {
-        return selector;
+        return (Selector)selector;
     }
 
     int getIndex() {                                    // package-private
@@ -75,16 +77,19 @@
             throw new CancelledKeyException();
     }
 
+    @Override
     public int interestOps() {
         ensureValid();
         return interestOps;
     }
 
+    @Override
     public SelectionKey interestOps(int ops) {
         ensureValid();
         return nioInterestOps(ops);
     }
 
+    @Override
     public int readyOps() {
         ensureValid();
         return readyOps;
@@ -131,4 +136,6 @@
         return sb.toString();
     }
 
+    // used by Selector implementations to record when the key was selected
+    int lastPolled;
 }
--- a/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -78,6 +78,16 @@
         return publicSelectedKeys;
     }
 
+    /**
+     * Returns the public view of the key sets
+     */
+    protected final Set<SelectionKey> nioKeys() {
+        return publicKeys;
+    }
+    protected final Set<SelectionKey> nioSelectedKeys() {
+        return publicSelectedKeys;
+    }
+
     protected abstract int doSelect(long timeout) throws IOException;
 
     private int lockAndDoSelect(long timeout) throws IOException {
@@ -125,8 +135,6 @@
 
     protected abstract void implClose() throws IOException;
 
-    public abstract void putEventOps(SelectionKeyImpl sk, int ops);
-
     @Override
     protected final SelectionKey register(AbstractSelectableChannel ch,
                                           int ops,
@@ -166,4 +174,9 @@
             }
         }
     }
+
+    /**
+     * Invoked to change the key's interest set
+     */
+    public abstract void putEventOps(SelectionKeyImpl ski, int ops);
 }
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -210,25 +210,20 @@
 
     @Override
     public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException {
-        acceptLock.lock();
-        try {
-            synchronized (stateLock) {
-                ensureOpen();
-                if (localAddress != null)
-                    throw new AlreadyBoundException();
-                InetSocketAddress isa = (local == null)
-                                        ? new InetSocketAddress(0)
-                                        : Net.checkAddress(local);
-                SecurityManager sm = System.getSecurityManager();
-                if (sm != null)
-                    sm.checkListen(isa.getPort());
-                NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
-                Net.bind(fd, isa.getAddress(), isa.getPort());
-                Net.listen(fd, backlog < 1 ? 50 : backlog);
-                localAddress = Net.localAddress(fd);
-            }
-        } finally {
-            acceptLock.unlock();
+        synchronized (stateLock) {
+            ensureOpen();
+            if (localAddress != null)
+                throw new AlreadyBoundException();
+            InetSocketAddress isa = (local == null)
+                                    ? new InetSocketAddress(0)
+                                    : Net.checkAddress(local);
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkListen(isa.getPort());
+            NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
+            Net.bind(fd, isa.getAddress(), isa.getPort());
+            Net.listen(fd, backlog < 1 ? 50 : backlog);
+            localAddress = Net.localAddress(fd);
         }
         return this;
     }
--- a/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Fri Mar 23 08:49:58 2018 -0700
@@ -30,7 +30,7 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URI;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.*;
 import java.security.*;
 import java.security.cert.Certificate;
@@ -278,7 +278,7 @@
             public URL run() {
                 String sep = File.separator;
                 try {
-                    return Paths.get(System.getProperty("java.home"),
+                    return Path.of(System.getProperty("java.home"),
                                      "lib", "security",
                                      "default.policy").toUri().toURL();
                 } catch (MalformedURLException mue) {
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Mar 23 08:49:58 2018 -0700
@@ -27,7 +27,7 @@
 
 import java.io.*;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.security.CodeSigner;
 import java.security.CryptoPrimitive;
 import java.security.KeyStore;
@@ -2189,7 +2189,7 @@
                 inplaceBackupName = srcksfname + ".old" + (n == 1 ? "" : n);
                 File bkFile = new File(inplaceBackupName);
                 if (!bkFile.exists()) {
-                    Files.copy(Paths.get(srcksfname), bkFile.toPath());
+                    Files.copy(Path.of(srcksfname), bkFile.toPath());
                     break;
                 }
             }
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Fri Mar 23 08:49:58 2018 -0700
@@ -127,7 +127,7 @@
     // descriptor is registered with /dev/poll.
     private final BitSet registered = new BitSet();
 
-    DevPollArrayWrapper() {
+    DevPollArrayWrapper() throws IOException {
         int allocationSize = NUM_POLLFDS * SIZE_POLLFD;
         pollArray = new AllocatedNativeObject(allocationSize, true);
         pollArrayAddress = pollArray.address();
@@ -136,7 +136,7 @@
             eventsHigh = new HashMap<>();
     }
 
-    void initInterrupt(int fd0, int fd1) {
+    void initInterrupt(int fd0, int fd1) throws IOException {
         outgoingInterruptFD = fd1;
         incomingInterruptFD = fd0;
         register(wfd, fd0, POLLIN);
@@ -200,7 +200,7 @@
         }
     }
 
-    void release(int fd) {
+    void release(int fd) throws IOException {
         synchronized (updateLock) {
             // ignore any pending update for this file descriptor
             setUpdateEvents(fd, IGNORE);
@@ -297,7 +297,11 @@
     boolean interrupted = false;
 
     public void interrupt() {
-        interrupt(outgoingInterruptFD);
+        try {
+            IOUtil.write1(outgoingInterruptFD, (byte)0);
+        } catch (IOException ioe) {
+            throw new InternalError(ioe);
+        }
     }
 
     public int interruptedIndex() {
@@ -312,13 +316,12 @@
         interrupted = false;
     }
 
-    private native int init();
-    private native void register(int wfd, int fd, int mask);
+    private native int init() throws IOException;
+    private native void register(int wfd, int fd, int mask) throws IOException;
     private native void registerMultiple(int wfd, long address, int len)
         throws IOException;
-    private native int poll0(long pollAddress, int numfds, long timeout,
-                             int wfd);
-    private static native void interrupt(int fd);
+    private native int poll0(long pollAddress, int numfds, long timeout, int wfd)
+        throws IOException;
 
     static {
         IOUtil.load();
--- a/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -61,7 +61,7 @@
      * Package private constructor called by factory method in
      * the abstract superclass Selector.
      */
-    DevPollSelectorImpl(SelectorProvider sp) {
+    DevPollSelectorImpl(SelectorProvider sp) throws IOException {
         super(sp);
         long pipeFds = IOUtil.makePipe(false);
         fd0 = (int) (pipeFds >>> 32);
--- a/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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
@@ -181,12 +181,26 @@
         }
 
         // poll for events
-        int updated = port_getn(pfd, pollArrayAddress, POLL_MAX, timeout);
+        int numEntries;
+        long to = timeout;
+        boolean timedPoll = (to > 0);
+        do {
+            long startTime = timedPoll ? System.currentTimeMillis() : 0;
+            numEntries = port_getn(pfd, pollArrayAddress, POLL_MAX, timeout);
+            if (numEntries == IOStatus.INTERRUPTED && timedPoll) {
+                // timed poll interrupted so need to adjust timeout
+                to -= System.currentTimeMillis() - startTime;
+                if (to <= 0) {
+                    // timeout also expired so no retry
+                    numEntries = 0;
+                }
+            }
+        } while (numEntries == IOStatus.INTERRUPTED);
 
         // after polling we need to queue all polled file descriptors as they
         // are candidates to register for the next poll.
         synchronized (updateLock) {
-            for (int i=0; i<updated; i++) {
+            for (int i=0; i<numEntries; i++) {
                 if (getSource(i) == PORT_SOURCE_USER) {
                     interrupted = true;
                     setDescriptor(i, -1);
@@ -199,7 +213,7 @@
             }
         }
 
-        return updated;
+        return numEntries;
     }
 
     private void setInterest(int fd) {
--- a/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, 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
@@ -164,7 +164,10 @@
                     // A error here is fatal (thread will not be replaced)
                     replaceMe = false;
                     try {
-                        port_get(port, address);
+                        int n;
+                        do {
+                            n = port_get(port, address);
+                        } while (n == IOStatus.INTERRUPTED);
                     } catch (IOException x) {
                         x.printStackTrace();
                         return;
@@ -240,7 +243,7 @@
     /**
      * Retrieves a single event from a port
      */
-    static native void port_get(int port, long pe) throws IOException;
+    static native int port_get(int port, long address) throws IOException;
 
     /**
      * Retrieves at most {@code max} events from a port.
--- a/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Fri Mar 23 08:49:58 2018 -0700
@@ -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
@@ -84,9 +84,9 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(
+        Path userMimeTypes = Path.of(
             GetPropertyAction.privilegedGetProperty("user.home"), ".mime.types");
-        Path etcMimeTypes = Paths.get("/etc/mime.types");
+        Path etcMimeTypes = Path.of("/etc/mime.types");
 
         return chain(new MimeTypesFileTypeDetector(userMimeTypes),
                      new MimeTypesFileTypeDetector(etcMimeTypes));
--- a/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, 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
@@ -176,14 +176,3 @@
     }
     return result;
 }
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_DevPollArrayWrapper_interrupt(JNIEnv *env, jclass this, jint fd)
-{
-    int fakebuf[1];
-    fakebuf[0] = 1;
-    if (write(fd, fakebuf, 1) < 0) {
-        JNU_ThrowIOExceptionWithLastError(env,
-                                          "Write to interrupt fd failed");
-    }
-}
--- a/src/java.base/solaris/native/libnio/ch/SolarisEventPort.c	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/solaris/native/libnio/ch/SolarisEventPort.c	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, 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,17 +23,18 @@
  * questions.
  */
 
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <port.h>
+
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
 #include "jlong.h"
+#include "nio.h"
 #include "nio_util.h"
 
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <port.h>
-
 #include "sun_nio_ch_SolarisEventPort.h"
 
 JNIEXPORT jint JNICALL
@@ -51,8 +52,10 @@
 Java_sun_nio_ch_SolarisEventPort_port_1close
     (JNIEnv* env, jclass clazz, jint port)
 {
-    int res;
-    RESTARTABLE(close(port), res);
+    int res = close(port);
+    if (res < 0 && res != EINTR) {
+        JNU_ThrowIOExceptionWithLastError(env, "close failed");
+    }
 }
 
 JNIEXPORT jboolean JNICALL
@@ -93,17 +96,23 @@
     }
 }
 
-JNIEXPORT void JNICALL
+JNIEXPORT jint JNICALL
 Java_sun_nio_ch_SolarisEventPort_port_1get(JNIEnv* env, jclass clazz,
     jint port, jlong eventAddress)
 {
     int res;
     port_event_t* ev = (port_event_t*)jlong_to_ptr(eventAddress);
 
-    RESTARTABLE(port_get((int)port, ev, NULL), res);
+    res = port_get((int)port, ev, NULL);
     if (res == -1) {
-        JNU_ThrowIOExceptionWithLastError(env, "port_get");
+        if (errno == EINTR) {
+            return IOS_INTERRUPTED;
+        } else {
+            JNU_ThrowIOExceptionWithLastError(env, "port_get failed");
+            return IOS_THROWN;
+        }
     }
+    return res;
 }
 
 JNIEXPORT jint JNICALL
@@ -125,9 +134,13 @@
     }
 
     res = port_getn((int)port, list, (uint_t)max, &n, tsp);
-    if (res == -1) {
-        if (errno != ETIME && errno != EINTR)
-            JNU_ThrowIOExceptionWithLastError(env, "port_getn");
+    if (res == -1 && errno != ETIME) {
+        if (errno == EINTR) {
+            return IOS_INTERRUPTED;
+        } else {
+            JNU_ThrowIOExceptionWithLastError(env, "port_getn failed");
+            return IOS_THROWN;
+        }
     }
 
     return (jint)n;
--- a/src/java.base/unix/classes/sun/nio/ch/PipeImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/unix/classes/sun/nio/ch/PipeImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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,7 @@
     private final SourceChannel source;
     private final SinkChannel sink;
 
-    PipeImpl(SelectorProvider sp) {
+    PipeImpl(SelectorProvider sp) throws IOException {
         long pipeFds = IOUtil.makePipe(true);
         int readFd = (int) (pipeFds >>> 32);
         int writeFd = (int) pipeFds;
--- a/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, 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
@@ -51,7 +51,7 @@
      * Package private constructor called by factory method in
      * the abstract superclass Selector.
      */
-    PollSelectorImpl(SelectorProvider sp) {
+    PollSelectorImpl(SelectorProvider sp) throws IOException {
         super(sp, 1, 1);
         long pipeFds = IOUtil.makePipe(false);
         fd0 = (int) (pipeFds >>> 32);
--- a/src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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,15 +25,15 @@
 
 package sun.nio.ch;
 
-import java.io.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
 
 /**
  * Allows different platforms to call different native methods
  * for read and write operations.
  */
 
-class SocketDispatcher extends NativeDispatcher
-{
+class SocketDispatcher extends NativeDispatcher {
 
     int read(FileDescriptor fd, long address, int len) throws IOException {
         return FileDispatcherImpl.read0(fd, address, len);
--- a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2017, 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
@@ -260,7 +260,7 @@
     private static Properties loadProperties() {
         Properties result = new Properties();
         String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
-        Path file = Paths.get(fstypes);
+        Path file = Path.of(fstypes);
         try {
             try (ReadableByteChannel rbc = Files.newByteChannel(file)) {
                 result.load(Channels.newReader(rbc, "UTF-8"));
--- a/src/java.base/unix/native/libnio/ch/IOUtil.c	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.base/unix/native/libnio/ch/IOUtil.c	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -104,10 +104,19 @@
     return ((jlong) fd[0] << 32) | (jlong) fd[1];
 }
 
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_write1(JNIEnv *env, jclass cl, jint fd, jbyte b)
+{
+    char c = (char)b;
+    return convertReturnVal(env, write(fd, &c, 1), JNI_FALSE);
+}
+
+
 JNIEXPORT jboolean JNICALL
 Java_sun_nio_ch_IOUtil_drain(JNIEnv *env, jclass cl, jint fd)
 {
-    char buf[128];
+    char buf[16];
     int tn = 0;
 
     for (;;) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2003, 2015, 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 USE_ERROR
+//#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+
+static void alsaDebugOutput(const char *file, int line, const char *function, int err, const char *fmt, ...) {
+#ifdef USE_ERROR
+    va_list args;
+    va_start(args, fmt);
+    printf("%s:%d function %s: error %d: %s\n", file, line, function, err, snd_strerror(err));
+    if (strlen(fmt) > 0) {
+        vprintf(fmt, args);
+    }
+    va_end(args);
+#endif
+}
+
+static int alsa_inited = 0;
+static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
+static int alsa_enumerate_midi_subdevices = FALSE; // default: no
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+void initAlsaSupport() {
+    char* enumerate;
+    if (!alsa_inited) {
+        alsa_inited = TRUE;
+        snd_lib_error_set_handler(&alsaDebugOutput);
+
+        enumerate = getenv(ENV_ENUMERATE_PCM_SUBDEVICES);
+        if (enumerate != NULL && strlen(enumerate) > 0
+            && (enumerate[0] != 'f')   // false
+            && (enumerate[0] != 'F')   // False
+            && (enumerate[0] != 'n')   // no
+            && (enumerate[0] != 'N')) { // NO
+            alsa_enumerate_pcm_subdevices = TRUE;
+        }
+#ifdef ALSA_MIDI_ENUMERATE_SUBDEVICES
+        alsa_enumerate_midi_subdevices = TRUE;
+#endif
+    }
+}
+
+
+/* if true (non-zero), ALSA sub devices should be listed as separate devices
+ */
+int needEnumerateSubdevices(int isMidi) {
+    initAlsaSupport();
+    return isMidi ? alsa_enumerate_midi_subdevices
+                  : alsa_enumerate_pcm_subdevices;
+}
+
+
+/*
+ * deviceID contains packed card, device and subdevice numbers
+ * each number takes 10 bits
+ * "default" device has id == ALSA_DEFAULT_DEVICE_ID
+ */
+UINT32 encodeDeviceID(int card, int device, int subdevice) {
+    return (((card & 0x3FF) << 20) | ((device & 0x3FF) << 10)
+           | (subdevice & 0x3FF)) + 1;
+}
+
+
+void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
+                    int isMidi) {
+    deviceID--;
+    *card = (deviceID >> 20) & 0x3FF;
+    *device = (deviceID >> 10) & 0x3FF;
+    if (needEnumerateSubdevices(isMidi)) {
+        *subdevice = deviceID  & 0x3FF;
+    } else {
+        *subdevice = -1; // ALSA will choose any subdevices
+    }
+}
+
+
+void getDeviceString(char* buffer, int card, int device, int subdevice,
+                     int usePlugHw, int isMidi) {
+    if (needEnumerateSubdevices(isMidi)) {
+        sprintf(buffer, "%s:%d,%d,%d",
+                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
+                        card, device, subdevice);
+    } else {
+        sprintf(buffer, "%s:%d,%d",
+                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
+                        card, device);
+    }
+}
+
+
+void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
+                                 int usePlugHw, int isMidi) {
+    int card, device, subdevice;
+
+    if (deviceID == ALSA_DEFAULT_DEVICE_ID) {
+        strcpy(buffer, ALSA_DEFAULT_DEVICE_NAME);
+    } else {
+        decodeDeviceID(deviceID, &card, &device, &subdevice, isMidi);
+        getDeviceString(buffer, card, device, subdevice, usePlugHw, isMidi);
+    }
+}
+
+
+static int hasGottenALSAVersion = FALSE;
+#define ALSAVersionString_LENGTH 200
+static char ALSAVersionString[ALSAVersionString_LENGTH];
+
+void getALSAVersion(char* buffer, int len) {
+    if (!hasGottenALSAVersion) {
+        // get alsa version from proc interface
+        FILE* file;
+        int curr, len, totalLen, inVersionString;
+        file = fopen(ALSA_VERSION_PROC_FILE, "r");
+        ALSAVersionString[0] = 0;
+        if (file) {
+            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
+                // parse for version number
+                totalLen = strlen(ALSAVersionString);
+                inVersionString = FALSE;
+                len = 0;
+                curr = 0;
+                while (curr < totalLen) {
+                    if (!inVersionString) {
+                        // is this char the beginning of a version string ?
+                        if (ALSAVersionString[curr] >= '0'
+                            && ALSAVersionString[curr] <= '9') {
+                            inVersionString = TRUE;
+                        }
+                    }
+                    if (inVersionString) {
+                        // the version string ends with white space
+                        if (ALSAVersionString[curr] <= 32) {
+                            break;
+                        }
+                        if (curr != len) {
+                            // copy this char to the beginning of the string
+                            ALSAVersionString[len] = ALSAVersionString[curr];
+                        }
+                        len++;
+                    }
+                    curr++;
+                }
+                // remove trailing dots
+                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
+                    len--;
+                }
+                // null terminate
+                ALSAVersionString[len] = 0;
+            }
+            fclose(file);
+            hasGottenALSAVersion = TRUE;
+        }
+    }
+    strncpy(buffer, ALSAVersionString, len);
+}
+
+
+/* end */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2003, 2007, 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 <alsa/asoundlib.h>
+#include "Utilities.h"
+
+#ifndef PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
+#define PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
+
+#define ALSA_VERSION_PROC_FILE "/proc/asound/version"
+#define ALSA_HARDWARE "hw"
+#define ALSA_HARDWARE_CARD ALSA_HARDWARE":%d"
+#define ALSA_HARDWARE_DEVICE ALSA_HARDWARE_CARD",%d"
+#define ALSA_HARDWARE_SUBDEVICE ALSA_HARDWARE_DEVICE",%d"
+
+#define ALSA_PLUGHARDWARE "plughw"
+#define ALSA_DEFAULT_DEVICE_NAME "default"
+
+#define ALSA_DEFAULT_DEVICE_ID (0)
+
+#define ALSA_PCM     (0)
+#define ALSA_RAWMIDI (1)
+
+// for use in info objects
+#define ALSA_VENDOR "ALSA (http://www.alsa-project.org)"
+
+// Environment variable for inclusion of subdevices in device listing.
+// If this variable is unset or "no", then subdevices are ignored, and
+// it's ALSA's choice which one to use (enables hardware mixing)
+#define ENV_ENUMERATE_PCM_SUBDEVICES "ALSA_ENUMERATE_PCM_SUBDEVICES"
+
+// if defined, subdevices are listed.
+//#undef ALSA_MIDI_ENUMERATE_SUBDEVICES
+#define ALSA_MIDI_ENUMERATE_SUBDEVICES
+
+// must be called before any ALSA calls
+void initAlsaSupport();
+
+/* if true (non-zero), ALSA sub devices should be listed as separate devices
+ */
+int needEnumerateSubdevices(int isMidi);
+
+
+/*
+ * deviceID contains packed card, device and subdevice numbers
+ * each number takes 10 bits
+ * "default" device has id == ALSA_DEFAULT_DEVICE_ID
+ */
+UINT32 encodeDeviceID(int card, int device, int subdevice);
+
+void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
+                    int isMidi);
+
+void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
+                                 int usePlugHw, int isMidi);
+
+void getALSAVersion(char* buffer, int len);
+
+
+#endif // PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2003, 2010, 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 USE_ERROR
+#define USE_TRACE
+
+#if USE_PLATFORM_MIDI_IN == TRUE
+
+
+#include <alsa/asoundlib.h>
+#include "PlatformMidi.h"
+#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+#if defined(i586)
+#include <sys/utsname.h>
+#endif
+
+/*
+ * Helper methods
+ */
+
+static inline UINT32 packMessage(int status, int data1, int data2) {
+    return ((status & 0xFF) | ((data1 & 0xFF) << 8) | ((data2 & 0xFF) << 16));
+}
+
+
+static void setShortMessage(MidiMessage* message,
+                            int status, int data1, int data2) {
+    message->type = SHORT_MESSAGE;
+    message->data.s.packedMsg = packMessage(status, data1, data2);
+}
+
+
+static void setRealtimeMessage(MidiMessage* message, int status) {
+    setShortMessage(message, status, 0, 0);
+}
+
+
+static void set14bitMessage(MidiMessage* message, int status, int value) {
+    TRACE3("14bit value: %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
+    value &= 0x3FFF;
+    TRACE3("14bit value (2): %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
+    setShortMessage(message, status,
+                    value & 0x7F,
+                    (value >> 7) & 0x7F);
+}
+
+
+/*
+ * implementation of the platform-dependent
+ * MIDI in functions declared in PlatformMidi.h
+ */
+
+char* MIDI_IN_GetErrorStr(INT32 err) {
+    return (char*) getErrorStr(err);
+}
+
+INT32 MIDI_IN_GetNumDevices() {
+/* Workaround for 6842956: 32bit app on 64bit linux
+ * gets assertion failure trying to open midiIn ports.
+ * Untill the issue is fixed in ALSA
+ * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
+ * report no midi in devices in the configuration.
+ */
+#if defined(i586)
+    static int jre32onlinux64 = -1;
+    if (jre32onlinux64 < 0) {
+        jre32onlinux64 = 0;
+        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
+         * environment variable.
+         */
+        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
+            struct utsname u;
+            jre32onlinux64 = 0;
+            if (uname(&u) == 0) {
+                if (strstr(u.machine, "64") != NULL) {
+                    TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
+                    jre32onlinux64 = 1;
+                }
+            }
+        }
+    }
+    if (jre32onlinux64) {
+        return 0;
+    }
+#endif
+
+    TRACE0("MIDI_IN_GetNumDevices()\n");
+
+    return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
+}
+
+
+INT32 MIDI_IN_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceName(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
+                                name, nameLength);
+    return ret;
+}
+
+
+INT32 MIDI_IN_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceVendor(deviceIndex, name, nameLength);
+    return ret;
+}
+
+
+INT32 MIDI_IN_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceDescription(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
+                                       name, nameLength);
+    return ret;
+}
+
+
+INT32 MIDI_IN_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    int ret = getMidiDeviceVersion(deviceIndex, name, nameLength);
+    return ret;
+}
+
+/*************************************************************************/
+
+INT32 MIDI_IN_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
+    INT32 ret;
+    TRACE0("> MIDI_IN_OpenDevice\n");
+    ret = openMidiDevice(SND_RAWMIDI_STREAM_INPUT, deviceIndex, handle);
+    TRACE1("< MIDI_IN_OpenDevice: returning %d\n", (int) ret);
+    return ret;
+}
+
+
+INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle) {
+    INT32 ret;
+    TRACE0("> MIDI_IN_CloseDevice\n");
+    ret = closeMidiDevice(handle);
+    TRACE1("< MIDI_IN_CloseDevice: returning %d\n", (int) ret);
+    return ret;
+}
+
+
+INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle) {
+    TRACE0("MIDI_IN_StartDevice\n");
+    return MIDI_SUCCESS;
+}
+
+
+INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle) {
+    TRACE0("MIDI_IN_StopDevice\n");
+    return MIDI_SUCCESS;
+}
+
+
+INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle) {
+    return getMidiTimestamp(handle);
+}
+
+
+/* read the next message from the queue */
+MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) {
+    snd_seq_event_t alsa_message;
+    MidiMessage* jdk_message;
+    int err;
+    char buffer[1];
+    int status;
+
+    TRACE0("> MIDI_IN_GetMessage\n");
+    if (!handle) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): handle is NULL\n");
+        return NULL;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): native handle is NULL\n");
+        return NULL;
+    }
+    if (!handle->platformData) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): platformData is NULL\n");
+        return NULL;
+    }
+
+    /* For MIDI In, the device is left in non blocking mode. So if there is
+       no data from the device, snd_rawmidi_read() returns with -11 (EAGAIN).
+       This results in jumping back to the Java layer. */
+    while (TRUE) {
+        TRACE0("before snd_rawmidi_read()\n");
+        err = snd_rawmidi_read((snd_rawmidi_t*) handle->deviceHandle, buffer, 1);
+        TRACE0("after snd_rawmidi_read()\n");
+        if (err != 1) {
+            ERROR2("< ERROR: MIDI_IN_GetMessage(): snd_rawmidi_read() returned %d : %s\n", err, snd_strerror(err));
+            return NULL;
+        }
+        // printf("received byte: %d\n", buffer[0]);
+        err = snd_midi_event_encode_byte((snd_midi_event_t*) handle->platformData,
+                                         (int) buffer[0],
+                                         &alsa_message);
+        if (err == 1) {
+            break;
+        } else if (err < 0) {
+            ERROR1("< ERROR: MIDI_IN_GetMessage(): snd_midi_event_encode_byte() returned %d\n", err);
+            return NULL;
+        }
+    }
+    jdk_message = (MidiMessage*) calloc(sizeof(MidiMessage), 1);
+    if (!jdk_message) {
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
+        return NULL;
+    }
+    // TODO: tra
+    switch (alsa_message.type) {
+    case SND_SEQ_EVENT_NOTEON:
+    case SND_SEQ_EVENT_NOTEOFF:
+    case SND_SEQ_EVENT_KEYPRESS:
+        status = (alsa_message.type == SND_SEQ_EVENT_KEYPRESS) ? 0xA0 :
+            (alsa_message.type == SND_SEQ_EVENT_NOTEON) ? 0x90 : 0x80;
+        status |= alsa_message.data.note.channel;
+        setShortMessage(jdk_message, status,
+                        alsa_message.data.note.note,
+                        alsa_message.data.note.velocity);
+        break;
+
+    case SND_SEQ_EVENT_CONTROLLER:
+        status = 0xB0 | alsa_message.data.control.channel;
+        setShortMessage(jdk_message, status,
+                        alsa_message.data.control.param,
+                        alsa_message.data.control.value);
+        break;
+
+    case SND_SEQ_EVENT_PGMCHANGE:
+    case SND_SEQ_EVENT_CHANPRESS:
+        status = (alsa_message.type == SND_SEQ_EVENT_PGMCHANGE) ? 0xC0 : 0xD0;
+        status |= alsa_message.data.control.channel;
+        setShortMessage(jdk_message, status,
+                        alsa_message.data.control.value, 0);
+        break;
+
+    case SND_SEQ_EVENT_PITCHBEND:
+        status = 0xE0 | alsa_message.data.control.channel;
+        // $$mp 2003-09-23:
+        // possible hack to work around a bug in ALSA. Necessary for
+        // ALSA 0.9.2. May be fixed in newer versions of ALSA.
+        // alsa_message.data.control.value ^= 0x2000;
+        // TRACE1("pitchbend value: %d\n", alsa_message.data.control.value);
+        set14bitMessage(jdk_message, status,
+                        alsa_message.data.control.value);
+        break;
+
+        /* System exclusive messages */
+
+    case SND_SEQ_EVENT_SYSEX:
+        jdk_message->type = LONG_MESSAGE;
+        jdk_message->data.l.size = alsa_message.data.ext.len;
+        jdk_message->data.l.data = malloc(alsa_message.data.ext.len);
+        if (jdk_message->data.l.data == NULL) {
+            ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
+            free(jdk_message);
+            jdk_message = NULL;
+        } else {
+            memcpy(jdk_message->data.l.data, alsa_message.data.ext.ptr, alsa_message.data.ext.len);
+        }
+        break;
+
+        /* System common messages */
+
+    case SND_SEQ_EVENT_QFRAME:
+        setShortMessage(jdk_message, 0xF1,
+                        alsa_message.data.control.value & 0x7F, 0);
+        break;
+
+    case SND_SEQ_EVENT_SONGPOS:
+        set14bitMessage(jdk_message, 0xF2,
+                        alsa_message.data.control.value);
+        break;
+
+    case SND_SEQ_EVENT_SONGSEL:
+        setShortMessage(jdk_message, 0xF3,
+                        alsa_message.data.control.value & 0x7F, 0);
+        break;
+
+    case SND_SEQ_EVENT_TUNE_REQUEST:
+        setRealtimeMessage(jdk_message, 0xF6);
+        break;
+
+        /* System realtime messages */
+
+    case SND_SEQ_EVENT_CLOCK:
+        setRealtimeMessage(jdk_message, 0xF8);
+        break;
+
+    case SND_SEQ_EVENT_START:
+        setRealtimeMessage(jdk_message, 0xFA);
+        break;
+
+    case SND_SEQ_EVENT_CONTINUE:
+        setRealtimeMessage(jdk_message, 0xFB);
+        break;
+
+    case SND_SEQ_EVENT_STOP:
+        setRealtimeMessage(jdk_message, 0xFC);
+        break;
+
+    case SND_SEQ_EVENT_SENSING:
+        setRealtimeMessage(jdk_message, 0xFE);
+        break;
+
+    case SND_SEQ_EVENT_RESET:
+        setRealtimeMessage(jdk_message, 0xFF);
+        break;
+
+    default:
+        ERROR0("< ERROR: MIDI_IN_GetMessage(): unhandled ALSA MIDI message type\n");
+        free(jdk_message);
+        jdk_message = NULL;
+
+    }
+
+    // set timestamp
+    if (jdk_message != NULL) {
+        jdk_message->timestamp = getMidiTimestamp(handle);
+    }
+    TRACE1("< MIDI_IN_GetMessage: returning %p\n", jdk_message);
+    return jdk_message;
+}
+
+
+void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg) {
+    if (!msg) {
+        ERROR0("< ERROR: MIDI_IN_ReleaseMessage(): message is NULL\n");
+        return;
+    }
+    if (msg->type == LONG_MESSAGE && msg->data.l.data) {
+        free(msg->data.l.data);
+    }
+    free(msg);
+}
+
+#endif /* USE_PLATFORM_MIDI_IN */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2003, 2007, 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 USE_ERROR
+#define USE_TRACE
+
+#if USE_PLATFORM_MIDI_OUT == TRUE
+
+#include <alsa/asoundlib.h>
+#include "PlatformMidi.h"
+#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+
+
+
+static int CHANNEL_MESSAGE_LENGTH[] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 3, 3, 2, 2, 3 };
+/*                                 8x 9x Ax Bx Cx Dx Ex */
+
+static int SYSTEM_MESSAGE_LENGTH[] = {
+    -1, 2, 3, 2, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1 };
+/*  F0 F1 F2 F3  F4  F5 F6 F7 F8  F9 FA FB FC  FD FE FF */
+
+
+// the returned length includes the status byte.
+// for illegal messages, -1 is returned.
+static int getShortMessageLength(int status) {
+        int     dataLength = 0;
+        if (status < 0xF0) { // channel voice message
+                dataLength = CHANNEL_MESSAGE_LENGTH[(status >> 4) & 0xF];
+        } else {
+                dataLength = SYSTEM_MESSAGE_LENGTH[status & 0xF];
+        }
+        return dataLength;
+}
+
+
+/*
+ * implementation of the platform-dependent
+ * MIDI out functions declared in PlatformMidi.h
+ */
+char* MIDI_OUT_GetErrorStr(INT32 err) {
+    return (char*) getErrorStr(err);
+}
+
+
+INT32 MIDI_OUT_GetNumDevices() {
+    TRACE0("MIDI_OUT_GetNumDevices()\n");
+    return getMidiDeviceCount(SND_RAWMIDI_STREAM_OUTPUT);
+}
+
+
+INT32 MIDI_OUT_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceName()\n");
+    return getMidiDeviceName(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
+                             name, nameLength);
+}
+
+
+INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceVendor()\n");
+    return getMidiDeviceVendor(deviceIndex, name, nameLength);
+}
+
+
+INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceDescription()\n");
+    return getMidiDeviceDescription(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
+                                    name, nameLength);
+}
+
+
+INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
+    TRACE0("MIDI_OUT_GetDeviceVersion()\n");
+    return getMidiDeviceVersion(deviceIndex, name, nameLength);
+}
+
+
+/* *************************** MidiOutDevice implementation *************** */
+
+INT32 MIDI_OUT_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
+    TRACE1("MIDI_OUT_OpenDevice(): deviceIndex: %d\n", (int) deviceIndex);
+    return openMidiDevice(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex, handle);
+}
+
+
+INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
+    TRACE0("MIDI_OUT_CloseDevice()\n");
+    return closeMidiDevice(handle);
+}
+
+
+INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
+    return getMidiTimestamp(handle);
+}
+
+
+INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg,
+                                UINT32 timestamp) {
+    int err;
+    int status;
+    int data1;
+    int data2;
+    char buffer[3];
+
+    TRACE2("> MIDI_OUT_SendShortMessage() %x, time: %u\n", packedMsg, (unsigned int) timestamp);
+    if (!handle) {
+        ERROR0("< ERROR: MIDI_OUT_SendShortMessage(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    status = (packedMsg & 0xFF);
+    buffer[0] = (char) status;
+    buffer[1]  = (char) ((packedMsg >> 8) & 0xFF);
+    buffer[2]  = (char) ((packedMsg >> 16) & 0xFF);
+    TRACE4("status: %d, data1: %d, data2: %d, length: %d\n", (int) buffer[0], (int) buffer[1], (int) buffer[2], getShortMessageLength(status));
+    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle, buffer, getShortMessageLength(status));
+    if (err < 0) {
+        ERROR1("  ERROR: MIDI_OUT_SendShortMessage(): snd_rawmidi_write() returned %d\n", err);
+    }
+
+    TRACE0("< MIDI_OUT_SendShortMessage()\n");
+    return err;
+}
+
+
+INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data,
+                               UINT32 size, UINT32 timestamp) {
+    int err;
+
+    TRACE2("> MIDI_OUT_SendLongMessage() size %u, time: %u\n", (unsigned int) size, (unsigned int) timestamp);
+    if (!handle) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!data) {
+        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): data is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle,
+                            data, size);
+    if (err < 0) {
+        ERROR1("  ERROR: MIDI_OUT_SendLongMessage(): snd_rawmidi_write() returned %d\n", err);
+    }
+
+    TRACE0("< MIDI_OUT_SendLongMessage()\n");
+    return err;
+}
+
+
+#endif /* USE_PLATFORM_MIDI_OUT */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+#include <string.h>
+#include <sys/time.h>
+
+static INT64 getTimeInMicroseconds() {
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return (tv.tv_sec * 1000000UL) + tv.tv_usec;
+}
+
+
+const char* getErrorStr(INT32 err) {
+        return snd_strerror((int) err);
+}
+
+
+
+// callback for iteration through devices
+// returns TRUE if iteration should continue
+typedef int (*DeviceIteratorPtr)(UINT32 deviceID,
+                                 snd_rawmidi_info_t* rawmidi_info,
+                                 snd_ctl_card_info_t* cardinfo,
+                                 void *userData);
+
+// for each ALSA device, call iterator. userData is passed to the iterator
+// returns total number of iterations
+static int iterateRawmidiDevices(snd_rawmidi_stream_t direction,
+                                 DeviceIteratorPtr iterator,
+                                 void* userData) {
+    int count = 0;
+    int subdeviceCount;
+    int card, dev, subDev;
+    char devname[16];
+    int err;
+    snd_ctl_t *handle;
+    snd_rawmidi_t *rawmidi;
+    snd_rawmidi_info_t *rawmidi_info;
+    snd_ctl_card_info_t *card_info, *defcardinfo = NULL;
+    UINT32 deviceID;
+    int doContinue = TRUE;
+
+    snd_rawmidi_info_malloc(&rawmidi_info);
+    snd_ctl_card_info_malloc(&card_info);
+
+    // 1st try "default" device
+    if (direction == SND_RAWMIDI_STREAM_INPUT) {
+        err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME,
+                               SND_RAWMIDI_NONBLOCK);
+    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
+        err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME,
+                               SND_RAWMIDI_NONBLOCK);
+    } else {
+        ERROR0("ERROR: iterateRawmidiDevices(): direction is neither"
+               " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
+        err = MIDI_INVALID_ARGUMENT;
+    }
+    if (err < 0) {
+        ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n",
+               snd_strerror(err));
+    } else {
+        err = snd_rawmidi_info(rawmidi, rawmidi_info);
+
+        snd_rawmidi_close(rawmidi);
+        if (err < 0) {
+            ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n",
+                    snd_strerror(err));
+        } else {
+            // try to get card info
+            card = snd_rawmidi_info_get_card(rawmidi_info);
+            if (card >= 0) {
+                sprintf(devname, ALSA_HARDWARE_CARD, card);
+                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
+                    if (snd_ctl_card_info(handle, card_info) >= 0) {
+                        defcardinfo = card_info;
+                    }
+                    snd_ctl_close(handle);
+                }
+            }
+            // call calback function for the device
+            if (iterator != NULL) {
+                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info,
+                                         defcardinfo, userData);
+            }
+            count++;
+        }
+    }
+
+    // iterate cards
+    card = -1;
+    TRACE0("testing for cards...\n");
+    if (snd_card_next(&card) >= 0) {
+        TRACE1("Found card %d\n", card);
+        while (doContinue && (card >= 0)) {
+            sprintf(devname, ALSA_HARDWARE_CARD, card);
+            TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname);
+            err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
+            if (err < 0) {
+                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
+            } else {
+                TRACE0("snd_ctl_open() SUCCESS\n");
+                err = snd_ctl_card_info(handle, card_info);
+                if (err < 0) {
+                    ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err));
+                } else {
+                    TRACE0("snd_ctl_card_info() SUCCESS\n");
+                    dev = -1;
+                    while (doContinue) {
+                        if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) {
+                            ERROR0("snd_ctl_rawmidi_next_device\n");
+                        }
+                        TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n");
+                        if (dev < 0) {
+                            break;
+                        }
+                        snd_rawmidi_info_set_device(rawmidi_info, dev);
+                        snd_rawmidi_info_set_subdevice(rawmidi_info, 0);
+                        snd_rawmidi_info_set_stream(rawmidi_info, direction);
+                        err = snd_ctl_rawmidi_info(handle, rawmidi_info);
+                        TRACE0("after snd_ctl_rawmidi_info()\n");
+                        if (err < 0) {
+                            if (err != -ENOENT) {
+                                ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err));
+                            }
+                        } else {
+                            TRACE0("snd_ctl_rawmidi_info() SUCCESS\n");
+                            subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI)
+                                ? snd_rawmidi_info_get_subdevices_count(rawmidi_info)
+                                : 1;
+                            if (iterator!=NULL) {
+                                for (subDev = 0; subDev < subdeviceCount; subDev++) {
+                                    TRACE3("  Iterating %d,%d,%d\n", card, dev, subDev);
+                                    deviceID = encodeDeviceID(card, dev, subDev);
+                                    doContinue = (*iterator)(deviceID, rawmidi_info,
+                                                             card_info, userData);
+                                    count++;
+                                    TRACE0("returned from iterator\n");
+                                    if (!doContinue) {
+                                        break;
+                                    }
+                                }
+                            } else {
+                                count += subdeviceCount;
+                            }
+                        }
+                    } // of while(doContinue)
+                }
+                snd_ctl_close(handle);
+            }
+            if (snd_card_next(&card) < 0) {
+                break;
+            }
+        }
+    } else {
+        ERROR0("No cards found!\n");
+    }
+    snd_ctl_card_info_free(card_info);
+    snd_rawmidi_info_free(rawmidi_info);
+    return count;
+}
+
+
+
+int getMidiDeviceCount(snd_rawmidi_stream_t direction) {
+    int deviceCount;
+    TRACE0("> getMidiDeviceCount()\n");
+    initAlsaSupport();
+    deviceCount = iterateRawmidiDevices(direction, NULL, NULL);
+    TRACE0("< getMidiDeviceCount()\n");
+    return deviceCount;
+}
+
+
+
+/*
+  userData is assumed to be a pointer to ALSA_MIDIDeviceDescription.
+  ALSA_MIDIDeviceDescription->index has to be set to the index of the device
+  we want to get information of before this method is called the first time via
+  iterateRawmidiDevices(). On each call of this method,
+  ALSA_MIDIDeviceDescription->index is decremented. If it is equal to zero,
+  we have reached the desired device, so action is taken.
+  So after successful completion of iterateRawmidiDevices(),
+  ALSA_MIDIDeviceDescription->index is zero. If it isn't, this is an
+  indication of an error.
+*/
+static int deviceInfoIterator(UINT32 deviceID, snd_rawmidi_info_t *rawmidi_info,
+                              snd_ctl_card_info_t *cardinfo, void *userData) {
+    char buffer[300];
+    ALSA_MIDIDeviceDescription* desc = (ALSA_MIDIDeviceDescription*)userData;
+#ifdef ALSA_MIDI_USE_PLUGHW
+    int usePlugHw = 1;
+#else
+    int usePlugHw = 0;
+#endif
+
+    TRACE0("deviceInfoIterator\n");
+    initAlsaSupport();
+    if (desc->index == 0) {
+        // we found the device with correct index
+        desc->deviceID = deviceID;
+
+        buffer[0]=' '; buffer[1]='[';
+        // buffer[300] is enough to store the actual device string w/o overrun
+        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_RAWMIDI);
+        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
+        strncpy(desc->name,
+                (cardinfo != NULL)
+                    ? snd_ctl_card_info_get_id(cardinfo)
+                    : snd_rawmidi_info_get_id(rawmidi_info),
+                desc->strLen - strlen(buffer));
+        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
+        desc->description[0] = 0;
+        if (cardinfo != NULL) {
+            strncpy(desc->description, snd_ctl_card_info_get_name(cardinfo),
+                    desc->strLen);
+            strncat(desc->description, ", ",
+                    desc->strLen - strlen(desc->description));
+        }
+        strncat(desc->description, snd_rawmidi_info_get_id(rawmidi_info),
+                desc->strLen - strlen(desc->description));
+        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
+        strncat(desc->description, snd_rawmidi_info_get_name(rawmidi_info),
+                desc->strLen - strlen(desc->description));
+        TRACE2("Returning %s, %s\n", desc->name, desc->description);
+        return FALSE; // do not continue iteration
+    }
+    desc->index--;
+    return TRUE;
+}
+
+
+static int getMIDIDeviceDescriptionByIndex(snd_rawmidi_stream_t direction,
+                                           ALSA_MIDIDeviceDescription* desc) {
+    initAlsaSupport();
+    TRACE1(" getMIDIDeviceDescriptionByIndex (index = %d)\n", desc->index);
+    iterateRawmidiDevices(direction, &deviceInfoIterator, desc);
+    return (desc->index == 0) ? MIDI_SUCCESS : MIDI_INVALID_DEVICEID;
+}
+
+
+
+int initMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc, int index) {
+    int ret = MIDI_SUCCESS;
+    desc->index = index;
+    desc->strLen = 200;
+    desc->name = (char*) calloc(desc->strLen + 1, 1);
+    desc->description = (char*) calloc(desc->strLen + 1, 1);
+    if (! desc->name ||
+        ! desc->description) {
+        ret = MIDI_OUT_OF_MEMORY;
+    }
+    return ret;
+}
+
+
+void freeMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc) {
+    if (desc->name) {
+        free(desc->name);
+    }
+    if (desc->description) {
+        free(desc->description);
+    }
+}
+
+
+int getMidiDeviceName(snd_rawmidi_stream_t direction, int index, char *name,
+                      UINT32 nameLength) {
+    ALSA_MIDIDeviceDescription desc;
+    int ret;
+
+    TRACE1("getMidiDeviceName: nameLength: %d\n", (int) nameLength);
+    ret = initMIDIDeviceDescription(&desc, index);
+    if (ret == MIDI_SUCCESS) {
+        TRACE0("getMidiDeviceName: initMIDIDeviceDescription() SUCCESS\n");
+        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
+        if (ret == MIDI_SUCCESS) {
+            TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
+            strncpy(name, desc.name, nameLength - 1);
+            name[nameLength - 1] = 0;
+        }
+    }
+    freeMIDIDeviceDescription(&desc);
+    return ret;
+}
+
+
+int getMidiDeviceVendor(int index, char *name, UINT32 nameLength) {
+    strncpy(name, ALSA_VENDOR, nameLength - 1);
+    name[nameLength - 1] = 0;
+    return MIDI_SUCCESS;
+}
+
+
+int getMidiDeviceDescription(snd_rawmidi_stream_t direction,
+                             int index, char *name, UINT32 nameLength) {
+    ALSA_MIDIDeviceDescription desc;
+    int ret;
+
+    ret = initMIDIDeviceDescription(&desc, index);
+    if (ret == MIDI_SUCCESS) {
+        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
+        if (ret == MIDI_SUCCESS) {
+            strncpy(name, desc.description, nameLength - 1);
+            name[nameLength - 1] = 0;
+        }
+    }
+    freeMIDIDeviceDescription(&desc);
+    return ret;
+}
+
+
+int getMidiDeviceVersion(int index, char *name, UINT32 nameLength) {
+    getALSAVersion(name, nameLength);
+    return MIDI_SUCCESS;
+}
+
+
+static int getMidiDeviceID(snd_rawmidi_stream_t direction, int index,
+                           UINT32* deviceID) {
+    ALSA_MIDIDeviceDescription desc;
+    int ret;
+
+    ret = initMIDIDeviceDescription(&desc, index);
+    if (ret == MIDI_SUCCESS) {
+        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
+        if (ret == MIDI_SUCCESS) {
+            // TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
+            *deviceID = desc.deviceID;
+        }
+    }
+    freeMIDIDeviceDescription(&desc);
+    return ret;
+}
+
+
+/*
+  direction has to be either SND_RAWMIDI_STREAM_INPUT or
+  SND_RAWMIDI_STREAM_OUTPUT.
+  Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT
+   or a negative ALSA error code is returned.
+*/
+INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
+                     MidiDeviceHandle** handle) {
+    snd_rawmidi_t* native_handle;
+    snd_midi_event_t* event_parser = NULL;
+    int err;
+    UINT32 deviceID = 0;
+    char devicename[100];
+#ifdef ALSA_MIDI_USE_PLUGHW
+    int usePlugHw = 1;
+#else
+    int usePlugHw = 0;
+#endif
+
+    TRACE0("> openMidiDevice()\n");
+
+    (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1);
+    if (!(*handle)) {
+        ERROR0("ERROR: openDevice: out of memory\n");
+        return MIDI_OUT_OF_MEMORY;
+    }
+
+    // TODO: iterate to get dev ID from index
+    err = getMidiDeviceID(direction, deviceIndex, &deviceID);
+    TRACE1("  openMidiDevice(): deviceID: %d\n", (int) deviceID);
+    getDeviceStringFromDeviceID(devicename, deviceID,
+                                usePlugHw, ALSA_RAWMIDI);
+    TRACE1("  openMidiDevice(): deviceString: %s\n", devicename);
+
+    // finally open the device
+    if (direction == SND_RAWMIDI_STREAM_INPUT) {
+        err = snd_rawmidi_open(&native_handle, NULL, devicename,
+                               SND_RAWMIDI_NONBLOCK);
+    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
+        err = snd_rawmidi_open(NULL, &native_handle, devicename,
+                               SND_RAWMIDI_NONBLOCK);
+    } else {
+        ERROR0("  ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
+        err = MIDI_INVALID_ARGUMENT;
+    }
+    if (err < 0) {
+        ERROR1("<  ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err);
+        free(*handle);
+        (*handle) = NULL;
+        return err;
+    }
+    /* We opened with non-blocking behaviour to not get hung if the device
+       is used by a different process. Writing, however, should
+       be blocking. So we change it here. */
+    if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
+        err = snd_rawmidi_nonblock(native_handle, 0);
+        if (err < 0) {
+            ERROR1("  ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err);
+            snd_rawmidi_close(native_handle);
+            free(*handle);
+            (*handle) = NULL;
+            return err;
+        }
+    }
+    if (direction == SND_RAWMIDI_STREAM_INPUT) {
+        err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser);
+        if (err < 0) {
+            ERROR1("  ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err);
+            snd_rawmidi_close(native_handle);
+            free(*handle);
+            (*handle) = NULL;
+            return err;
+        }
+    }
+
+    (*handle)->deviceHandle = (void*) native_handle;
+    (*handle)->startTime = getTimeInMicroseconds();
+    (*handle)->platformData = event_parser;
+    TRACE0("< openMidiDevice(): succeeded\n");
+    return err;
+}
+
+
+
+INT32 closeMidiDevice(MidiDeviceHandle* handle) {
+    int err;
+
+    TRACE0("> closeMidiDevice()\n");
+    if (!handle) {
+        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    if (!handle->deviceHandle) {
+        ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle);
+    TRACE1("  snd_rawmidi_close() returns %d\n", err);
+    if (handle->platformData) {
+        snd_midi_event_free((snd_midi_event_t*) handle->platformData);
+    }
+    free(handle);
+    TRACE0("< closeMidiDevice: succeeded\n");
+    return err;
+}
+
+
+INT64 getMidiTimestamp(MidiDeviceHandle* handle) {
+    if (!handle) {
+        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
+        return MIDI_INVALID_HANDLE;
+    }
+    return getTimeInMicroseconds() - handle->startTime;
+}
+
+
+/* end */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.h	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2003, 2007, 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 <alsa/asoundlib.h>
+#include "Utilities.h"
+#include "PlatformMidi.h"
+
+
+#ifndef PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
+#define PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
+
+#define EVENT_PARSER_BUFSIZE (2048)
+
+// if this is defined, use plughw: devices
+//#define ALSA_MIDI_USE_PLUGHW
+#undef ALSA_MIDI_USE_PLUGHW
+
+typedef struct tag_ALSA_MIDIDeviceDescription {
+        int index;          // in
+        int strLen;         // in
+        INT32 deviceID;    // out
+        char* name;         // out
+        char* description;  // out
+} ALSA_MIDIDeviceDescription;
+
+
+const char* getErrorStr(INT32 err);
+
+/* Returns the number of devices. */
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+int getMidiDeviceCount(snd_rawmidi_stream_t direction);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+int getMidiDeviceName(snd_rawmidi_stream_t direction, int index,
+                      char *name, UINT32 nameLength);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+int getMidiDeviceVendor(int index, char *name, UINT32 nameLength);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+int getMidiDeviceDescription(snd_rawmidi_stream_t direction, int index,
+                             char *name, UINT32 nameLength);
+
+/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
+int getMidiDeviceVersion(int index, char *name, UINT32 nameLength);
+
+// returns 0 on success, otherwise MIDI_OUT_OF_MEMORY or ALSA error code
+/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
+   SND_RAWMIDI_STREAM_INPUT. */
+INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
+                     MidiDeviceHandle** handle);
+
+// returns 0 on success, otherwise a (negative) ALSA error code
+INT32 closeMidiDevice(MidiDeviceHandle* handle);
+
+INT64 getMidiTimestamp(MidiDeviceHandle* handle);
+
+#endif // PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,941 @@
+/*
+ * Copyright (c) 2002, 2011, 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 USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+#include "DirectAudio.h"
+
+#if USE_DAUDIO == TRUE
+
+// GetPosition method 1: based on how many bytes are passed to the kernel driver
+//                       + does not need much processor resources
+//                       - not very exact, "jumps"
+// GetPosition method 2: ask kernel about actual position of playback.
+//                       - very exact
+//                       - switch to kernel layer for each call
+// GetPosition method 3: use snd_pcm_avail() call - not yet in official ALSA
+// quick tests on a Pentium 200MMX showed max. 1.5% processor usage
+// for playing back a CD-quality file and printing 20x per second a line
+// on the console with the current time. So I guess performance is not such a
+// factor here.
+//#define GET_POSITION_METHOD1
+#define GET_POSITION_METHOD2
+
+
+// The default time for a period in microseconds.
+// For very small buffers, only 2 periods are used.
+#define DEFAULT_PERIOD_TIME 20000 /* 20ms */
+
+///// implemented functions of DirectAudio.h
+
+INT32 DAUDIO_GetDirectAudioDeviceCount() {
+    return (INT32) getAudioDeviceCount();
+}
+
+
+INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, DirectAudioDeviceDescription* description) {
+    ALSA_AudioDeviceDescription adesc;
+
+    adesc.index = (int) mixerIndex;
+    adesc.strLen = DAUDIO_STRING_LENGTH;
+
+    adesc.maxSimultaneousLines = (int*) (&(description->maxSimulLines));
+    adesc.deviceID = &(description->deviceID);
+    adesc.name = description->name;
+    adesc.vendor = description->vendor;
+    adesc.description = description->description;
+    adesc.version = description->version;
+
+    return getAudioDeviceDescriptionByIndex(&adesc);
+}
+
+#define MAX_BIT_INDEX 6
+// returns
+// 6: for anything above 24-bit
+// 5: for 4 bytes sample size, 24-bit
+// 4: for 3 bytes sample size, 24-bit
+// 3: for 3 bytes sample size, 20-bit
+// 2: for 2 bytes sample size, 16-bit
+// 1: for 1 byte sample size, 8-bit
+// 0: for anything else
+int getBitIndex(int sampleSizeInBytes, int significantBits) {
+    if (significantBits > 24) return 6;
+    if (sampleSizeInBytes == 4 && significantBits == 24) return 5;
+    if (sampleSizeInBytes == 3) {
+        if (significantBits == 24) return 4;
+        if (significantBits == 20) return 3;
+    }
+    if (sampleSizeInBytes == 2 && significantBits == 16) return 2;
+    if (sampleSizeInBytes == 1 && significantBits == 8) return 1;
+    return 0;
+}
+
+int getSampleSizeInBytes(int bitIndex, int sampleSizeInBytes) {
+    switch(bitIndex) {
+    case 1: return 1;
+    case 2: return 2;
+    case 3: /* fall through */
+    case 4: return 3;
+    case 5: return 4;
+    }
+    return sampleSizeInBytes;
+}
+
+int getSignificantBits(int bitIndex, int significantBits) {
+    switch(bitIndex) {
+    case 1: return 8;
+    case 2: return 16;
+    case 3: return 20;
+    case 4: /* fall through */
+    case 5: return 24;
+    }
+    return significantBits;
+}
+
+void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
+    snd_pcm_t* handle;
+    snd_pcm_format_mask_t* formatMask;
+    snd_pcm_format_t format;
+    snd_pcm_hw_params_t* hwParams;
+    int handledBits[MAX_BIT_INDEX+1];
+
+    int ret;
+    int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
+    int origSampleSizeInBytes, origSignificantBits;
+    unsigned int channels, minChannels, maxChannels;
+    int rate, bitIndex;
+
+    for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
+    if (openPCMfromDeviceID(deviceID, &handle, isSource, TRUE /*query hardware*/) < 0) {
+        return;
+    }
+    ret = snd_pcm_format_mask_malloc(&formatMask);
+    if (ret != 0) {
+        ERROR1("snd_pcm_format_mask_malloc returned error %d\n", ret);
+    } else {
+        ret = snd_pcm_hw_params_malloc(&hwParams);
+        if (ret != 0) {
+            ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
+        } else {
+            ret = snd_pcm_hw_params_any(handle, hwParams);
+            /* snd_pcm_hw_params_any can return a positive value on success too */
+            if (ret < 0) {
+                 ERROR1("snd_pcm_hw_params_any returned error %d\n", ret);
+            } else {
+                /* for the logic following this code, set ret to 0 to indicate success */
+                ret = 0;
+            }
+        }
+        snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
+        if (ret == 0) {
+            ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
+            if (ret != 0) {
+                ERROR1("snd_pcm_hw_params_get_channels_min returned error %d\n", ret);
+            }
+        }
+        if (ret == 0) {
+            ret = snd_pcm_hw_params_get_channels_max(hwParams, &maxChannels);
+            if (ret != 0) {
+                ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
+            }
+        }
+
+        // since we queried the hw: device, for many soundcards, it will only
+        // report the maximum number of channels (which is the only way to talk
+        // to the hw: device). Since we will, however, open the plughw: device
+        // when opening the Source/TargetDataLine, we can safely assume that
+        // also the channels 1..maxChannels are available.
+#ifdef ALSA_PCM_USE_PLUGHW
+        minChannels = 1;
+#endif
+        if (ret == 0) {
+            // plughw: supports any sample rate
+            rate = -1;
+            for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
+                if (snd_pcm_format_mask_test(formatMask, format)) {
+                    // format exists
+                    if (getFormatFromAlsaFormat(format, &origSampleSizeInBytes,
+                                                &origSignificantBits,
+                                                &isSigned, &isBigEndian, &enc)) {
+                        // now if we use plughw:, we can use any bit size below the
+                        // natively supported ones. Some ALSA drivers only support the maximum
+                        // bit size, so we add any sample rates below the reported one.
+                        // E.g. this iteration reports support for 16-bit.
+                        // getBitIndex will return 2, so it will add entries for
+                        // 16-bit (bitIndex=2) and in the next do-while loop iteration,
+                        // it will decrease bitIndex and will therefore add 8-bit support.
+                        bitIndex = getBitIndex(origSampleSizeInBytes, origSignificantBits);
+                        do {
+                            if (bitIndex == 0
+                                || bitIndex == MAX_BIT_INDEX
+                                || !handledBits[bitIndex]) {
+                                handledBits[bitIndex] = TRUE;
+                                sampleSizeInBytes = getSampleSizeInBytes(bitIndex, origSampleSizeInBytes);
+                                significantBits = getSignificantBits(bitIndex, origSignificantBits);
+                                if (maxChannels - minChannels > MAXIMUM_LISTED_CHANNELS) {
+                                    // avoid too many channels explicitly listed
+                                    // just add -1, min, and max
+                                    DAUDIO_AddAudioFormat(creator, significantBits,
+                                                          -1, -1, rate,
+                                                          enc, isSigned, isBigEndian);
+                                    DAUDIO_AddAudioFormat(creator, significantBits,
+                                                          sampleSizeInBytes * minChannels,
+                                                          minChannels, rate,
+                                                          enc, isSigned, isBigEndian);
+                                    DAUDIO_AddAudioFormat(creator, significantBits,
+                                                          sampleSizeInBytes * maxChannels,
+                                                          maxChannels, rate,
+                                                          enc, isSigned, isBigEndian);
+                                } else {
+                                    for (channels = minChannels; channels <= maxChannels; channels++) {
+                                        DAUDIO_AddAudioFormat(creator, significantBits,
+                                                              sampleSizeInBytes * channels,
+                                                              channels, rate,
+                                                              enc, isSigned, isBigEndian);
+                                    }
+                                }
+                            }
+#ifndef ALSA_PCM_USE_PLUGHW
+                            // without plugin, do not add fake formats
+                            break;
+#endif
+                        } while (--bitIndex > 0);
+                    } else {
+                        TRACE1("could not get format from alsa for format %d\n", format);
+                    }
+                } else {
+                    //TRACE1("Format %d not supported\n", format);
+                }
+            } // for loop
+            snd_pcm_hw_params_free(hwParams);
+        }
+        snd_pcm_format_mask_free(formatMask);
+    }
+    snd_pcm_close(handle);
+}
+
+/** Workaround for cr 7033899, 7030629:
+ * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty
+ * (just opened, underruned or already flushed).
+ * Sometimes it causes PCM falls to -EBADFD error,
+ * sometimes causes bufferSize change.
+ * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used.
+ */
+/* ******* ALSA PCM INFO ******************** */
+typedef struct tag_AlsaPcmInfo {
+    snd_pcm_t* handle;
+    snd_pcm_hw_params_t* hwParams;
+    snd_pcm_sw_params_t* swParams;
+    int bufferSizeInBytes;
+    int frameSize; // storage size in Bytes
+    unsigned int periods;
+    snd_pcm_uframes_t periodSize;
+    short int isRunning;    // see comment above
+    short int isFlushed;    // see comment above
+#ifdef GET_POSITION_METHOD2
+    // to be used exclusively by getBytePosition!
+    snd_pcm_status_t* positionStatus;
+#endif
+} AlsaPcmInfo;
+
+
+int setStartThresholdNoCommit(AlsaPcmInfo* info, int useThreshold) {
+    int ret;
+    int threshold;
+
+    if (useThreshold) {
+        // start device whenever anything is written to the buffer
+        threshold = 1;
+    } else {
+        // never start the device automatically
+        threshold = 2000000000; /* near UINT_MAX */
+    }
+    ret = snd_pcm_sw_params_set_start_threshold(info->handle, info->swParams, threshold);
+    if (ret < 0) {
+        ERROR1("Unable to set start threshold mode: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+int setStartThreshold(AlsaPcmInfo* info, int useThreshold) {
+    int ret = 0;
+
+    if (!setStartThresholdNoCommit(info, useThreshold)) {
+        ret = -1;
+    }
+    if (ret == 0) {
+        // commit it
+        ret = snd_pcm_sw_params(info->handle, info->swParams);
+        if (ret < 0) {
+            ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
+        }
+    }
+    return (ret == 0)?TRUE:FALSE;
+}
+
+
+// returns TRUE if successful
+int setHWParams(AlsaPcmInfo* info,
+                float sampleRate,
+                int channels,
+                int bufferSizeInFrames,
+                snd_pcm_format_t format) {
+    unsigned int rrate, periodTime, periods;
+    int ret, dir;
+    snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
+
+    /* choose all parameters */
+    ret = snd_pcm_hw_params_any(info->handle, info->hwParams);
+    if (ret < 0) {
+        ERROR1("Broken configuration: no configurations available: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the interleaved read/write format */
+    ret = snd_pcm_hw_params_set_access(info->handle, info->hwParams, SND_PCM_ACCESS_RW_INTERLEAVED);
+    if (ret < 0) {
+        ERROR1("SND_PCM_ACCESS_RW_INTERLEAVED access type not available: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the sample format */
+    ret = snd_pcm_hw_params_set_format(info->handle, info->hwParams, format);
+    if (ret < 0) {
+        ERROR1("Sample format not available: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the count of channels */
+    ret = snd_pcm_hw_params_set_channels(info->handle, info->hwParams, channels);
+    if (ret < 0) {
+        ERROR2("Channels count (%d) not available: %s\n", channels, snd_strerror(ret));
+        return FALSE;
+    }
+    /* set the stream rate */
+    rrate = (int) (sampleRate + 0.5f);
+    dir = 0;
+    ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
+    if (ret < 0) {
+        ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
+        return FALSE;
+    }
+    if ((rrate-sampleRate > 2) || (rrate-sampleRate < - 2)) {
+        ERROR2("Rate doesn't match (requested %2.2fHz, got %dHz)\n", sampleRate, rrate);
+        return FALSE;
+    }
+    /* set the buffer time */
+    ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
+    if (ret < 0) {
+        ERROR2("Unable to set buffer size to %d frames: %s\n",
+               (int) alsaBufferSizeInFrames, snd_strerror(ret));
+        return FALSE;
+    }
+    bufferSizeInFrames = (int) alsaBufferSizeInFrames;
+    /* set the period time */
+    if (bufferSizeInFrames > 1024) {
+        dir = 0;
+        periodTime = DEFAULT_PERIOD_TIME;
+        ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
+        if (ret < 0) {
+            ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
+            return FALSE;
+        }
+    } else {
+        /* set the period count for very small buffer sizes to 2 */
+        dir = 0;
+        periods = 2;
+        ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
+        if (ret < 0) {
+            ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
+            return FALSE;
+        }
+    }
+    /* write the parameters to device */
+    ret = snd_pcm_hw_params(info->handle, info->hwParams);
+    if (ret < 0) {
+        ERROR1("Unable to set hw params: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+// returns 1 if successful
+int setSWParams(AlsaPcmInfo* info) {
+    int ret;
+
+    /* get the current swparams */
+    ret = snd_pcm_sw_params_current(info->handle, info->swParams);
+    if (ret < 0) {
+        ERROR1("Unable to determine current swparams: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* never start the transfer automatically */
+    if (!setStartThresholdNoCommit(info, FALSE /* don't use threshold */)) {
+        return FALSE;
+    }
+
+    /* allow the transfer when at least period_size samples can be processed */
+    ret = snd_pcm_sw_params_set_avail_min(info->handle, info->swParams, info->periodSize);
+    if (ret < 0) {
+        ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    /* write the parameters to the playback device */
+    ret = snd_pcm_sw_params(info->handle, info->swParams);
+    if (ret < 0) {
+        ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static snd_output_t* ALSA_OUTPUT = NULL;
+
+void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
+                  int encoding, float sampleRate, int sampleSizeInBits,
+                  int frameSize, int channels,
+                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
+    snd_pcm_format_mask_t* formatMask;
+    snd_pcm_format_t format;
+    int dir;
+    int ret = 0;
+    AlsaPcmInfo* info = NULL;
+    /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
+    snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
+
+
+    TRACE0("> DAUDIO_Open\n");
+#ifdef USE_TRACE
+    // for using ALSA debug dump methods
+    if (ALSA_OUTPUT == NULL) {
+        snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
+    }
+#endif
+    if (channels <= 0) {
+        ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+        return NULL;
+    }
+    info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
+    if (!info) {
+        ERROR0("Out of memory\n");
+        return NULL;
+    }
+    memset(info, 0, sizeof(AlsaPcmInfo));
+    // initial values are: stopped, flushed
+    info->isRunning = 0;
+    info->isFlushed = 1;
+
+    ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/);
+    if (ret == 0) {
+        // set to blocking mode
+        snd_pcm_nonblock(info->handle, 0);
+        ret = snd_pcm_hw_params_malloc(&(info->hwParams));
+        if (ret != 0) {
+            ERROR1("  snd_pcm_hw_params_malloc returned error %d\n", ret);
+        } else {
+            ret = -1;
+            if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits,
+                                        isSigned, isBigEndian, encoding)) {
+                if (setHWParams(info,
+                                sampleRate,
+                                channels,
+                                bufferSizeInBytes / frameSize,
+                                format)) {
+                    info->frameSize = frameSize;
+                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
+                    if (ret < 0) {
+                        ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
+                    }
+                    snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
+                    snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
+                    info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
+                    TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
+                           (int) info->periodSize, info->periods, info->bufferSizeInBytes);
+                }
+            }
+        }
+        if (ret == 0) {
+            // set software parameters
+            ret = snd_pcm_sw_params_malloc(&(info->swParams));
+            if (ret != 0) {
+                ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
+            } else {
+                if (!setSWParams(info)) {
+                    ret = -1;
+                }
+            }
+        }
+        if (ret == 0) {
+            // prepare device
+            ret = snd_pcm_prepare(info->handle);
+            if (ret < 0) {
+                ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
+            }
+        }
+
+#ifdef GET_POSITION_METHOD2
+        if (ret == 0) {
+            ret = snd_pcm_status_malloc(&(info->positionStatus));
+            if (ret != 0) {
+                ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret));
+            }
+        }
+#endif
+    }
+    if (ret != 0) {
+        DAUDIO_Close((void*) info, isSource);
+        info = NULL;
+    } else {
+        // set to non-blocking mode
+        snd_pcm_nonblock(info->handle, 1);
+        TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n",
+               (void*) info->handle);
+    }
+    return (void*) info;
+}
+
+#ifdef USE_TRACE
+void printState(snd_pcm_state_t state) {
+    if (state == SND_PCM_STATE_OPEN) {
+        TRACE0("State: SND_PCM_STATE_OPEN\n");
+    }
+    else if (state == SND_PCM_STATE_SETUP) {
+        TRACE0("State: SND_PCM_STATE_SETUP\n");
+    }
+    else if (state == SND_PCM_STATE_PREPARED) {
+        TRACE0("State: SND_PCM_STATE_PREPARED\n");
+    }
+    else if (state == SND_PCM_STATE_RUNNING) {
+        TRACE0("State: SND_PCM_STATE_RUNNING\n");
+    }
+    else if (state == SND_PCM_STATE_XRUN) {
+        TRACE0("State: SND_PCM_STATE_XRUN\n");
+    }
+    else if (state == SND_PCM_STATE_DRAINING) {
+        TRACE0("State: SND_PCM_STATE_DRAINING\n");
+    }
+    else if (state == SND_PCM_STATE_PAUSED) {
+        TRACE0("State: SND_PCM_STATE_PAUSED\n");
+    }
+    else if (state == SND_PCM_STATE_SUSPENDED) {
+        TRACE0("State: SND_PCM_STATE_SUSPENDED\n");
+    }
+}
+#endif
+
+int DAUDIO_Start(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+    snd_pcm_state_t state;
+
+    TRACE0("> DAUDIO_Start\n");
+    // set to blocking mode
+    snd_pcm_nonblock(info->handle, 0);
+    // set start mode so that it always starts as soon as data is there
+    setStartThreshold(info, TRUE /* use threshold */);
+    state = snd_pcm_state(info->handle);
+    if (state == SND_PCM_STATE_PAUSED) {
+        // in case it was stopped previously
+        TRACE0("  Un-pausing...\n");
+        ret = snd_pcm_pause(info->handle, FALSE);
+        if (ret != 0) {
+            ERROR2("  NOTE: error in snd_pcm_pause:%d: %s\n", ret, snd_strerror(ret));
+        }
+    }
+    if (state == SND_PCM_STATE_SUSPENDED) {
+        TRACE0("  Resuming...\n");
+        ret = snd_pcm_resume(info->handle);
+        if (ret < 0) {
+            if ((ret != -EAGAIN) && (ret != -ENOSYS)) {
+                ERROR2("  ERROR: error in snd_pcm_resume:%d: %s\n", ret, snd_strerror(ret));
+            }
+        }
+    }
+    if (state == SND_PCM_STATE_SETUP) {
+        TRACE0("need to call prepare again...\n");
+        // prepare device
+        ret = snd_pcm_prepare(info->handle);
+        if (ret < 0) {
+            ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
+        }
+    }
+    // in case there is still data in the buffers
+    ret = snd_pcm_start(info->handle);
+    if (ret != 0) {
+        if (ret != -EPIPE) {
+            ERROR2("  NOTE: error in snd_pcm_start: %d: %s\n", ret, snd_strerror(ret));
+        }
+    }
+    // set to non-blocking mode
+    ret = snd_pcm_nonblock(info->handle, 1);
+    if (ret != 0) {
+        ERROR1("  ERROR in snd_pcm_nonblock: %s\n", snd_strerror(ret));
+    }
+    state = snd_pcm_state(info->handle);
+#ifdef USE_TRACE
+    printState(state);
+#endif
+    ret = (state == SND_PCM_STATE_PREPARED)
+        || (state == SND_PCM_STATE_RUNNING)
+        || (state == SND_PCM_STATE_XRUN)
+        || (state == SND_PCM_STATE_SUSPENDED);
+    if (ret) {
+        info->isRunning = 1;
+        // source line should keep isFlushed value until Write() is called;
+        // for target data line reset it right now.
+        if (!isSource) {
+            info->isFlushed = 0;
+        }
+    }
+    TRACE1("< DAUDIO_Start %s\n", ret?"success":"error");
+    return ret?TRUE:FALSE;
+}
+
+int DAUDIO_Stop(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+
+    TRACE0("> DAUDIO_Stop\n");
+    // set to blocking mode
+    snd_pcm_nonblock(info->handle, 0);
+    setStartThreshold(info, FALSE /* don't use threshold */); // device will not start after buffer xrun
+    ret = snd_pcm_pause(info->handle, 1);
+    // set to non-blocking mode
+    snd_pcm_nonblock(info->handle, 1);
+    if (ret != 0) {
+        ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+    info->isRunning = 0;
+    TRACE0("< DAUDIO_Stop success\n");
+    return TRUE;
+}
+
+void DAUDIO_Close(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+
+    TRACE0("DAUDIO_Close\n");
+    if (info != NULL) {
+        if (info->handle != NULL) {
+            snd_pcm_close(info->handle);
+        }
+        if (info->hwParams) {
+            snd_pcm_hw_params_free(info->hwParams);
+        }
+        if (info->swParams) {
+            snd_pcm_sw_params_free(info->swParams);
+        }
+#ifdef GET_POSITION_METHOD2
+        if (info->positionStatus) {
+            snd_pcm_status_free(info->positionStatus);
+        }
+#endif
+        free(info);
+    }
+}
+
+/*
+ * Underrun and suspend recovery
+ * returns
+ * 0:  exit native and return 0
+ * 1:  try again to write/read
+ * -1: error - exit native with return value -1
+ */
+int xrun_recovery(AlsaPcmInfo* info, int err) {
+    int ret;
+
+    if (err == -EPIPE) {    /* underrun / overflow */
+        TRACE0("xrun_recovery: underrun/overflow.\n");
+        ret = snd_pcm_prepare(info->handle);
+        if (ret < 0) {
+            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
+            return -1;
+        }
+        return 1;
+    } else if (err == -ESTRPIPE) {
+        TRACE0("xrun_recovery: suspended.\n");
+        ret = snd_pcm_resume(info->handle);
+        if (ret < 0) {
+            if (ret == -EAGAIN) {
+                return 0; /* wait until the suspend flag is released */
+            }
+            return -1;
+        }
+        ret = snd_pcm_prepare(info->handle);
+        if (ret < 0) {
+            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
+            return -1;
+        }
+        return 1;
+    } else if (err == -EAGAIN) {
+        TRACE0("xrun_recovery: EAGAIN try again flag.\n");
+        return 0;
+    }
+
+    TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err));
+    return -1;
+}
+
+// returns -1 on error
+int DAUDIO_Write(void* id, char* data, int byteSize) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret, count;
+    snd_pcm_sframes_t frameSize, writtenFrames;
+
+    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
+
+    /* sanity */
+    if (byteSize <= 0 || info->frameSize <= 0) {
+        ERROR2(" DAUDIO_Write: byteSize=%d, frameSize=%d!\n",
+               (int) byteSize, (int) info->frameSize);
+        TRACE0("< DAUDIO_Write returning -1\n");
+        return -1;
+    }
+
+    count = 2; // maximum number of trials to recover from underrun
+    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
+    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
+    do {
+        writtenFrames = snd_pcm_writei(info->handle, (const void*) data, (snd_pcm_uframes_t) frameSize);
+
+        if (writtenFrames < 0) {
+            ret = xrun_recovery(info, (int) writtenFrames);
+            if (ret <= 0) {
+                TRACE1("DAUDIO_Write: xrun recovery returned %d -> return.\n", ret);
+                return ret;
+            }
+            if (count-- <= 0) {
+                ERROR0("DAUDIO_Write: too many attempts to recover from xrun/suspend\n");
+                return -1;
+            }
+        } else {
+            break;
+        }
+    } while (TRUE);
+    //ret =  snd_pcm_frames_to_bytes(info->handle, writtenFrames);
+
+    if (writtenFrames > 0) {
+        // reset "flushed" flag
+        info->isFlushed = 0;
+    }
+
+    ret =  (int) (writtenFrames * info->frameSize);
+    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
+    return ret;
+}
+
+// returns -1 on error
+int DAUDIO_Read(void* id, char* data, int byteSize) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret, count;
+    snd_pcm_sframes_t frameSize, readFrames;
+
+    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
+    /*TRACE3("  info=%p, data=%p, byteSize=%d\n",
+      (void*) info, (void*) data, (int) byteSize);
+      TRACE2("  info->frameSize=%d, info->handle=%p\n",
+      (int) info->frameSize, (void*) info->handle);
+    */
+    /* sanity */
+    if (byteSize <= 0 || info->frameSize <= 0) {
+        ERROR2(" DAUDIO_Read: byteSize=%d, frameSize=%d!\n",
+               (int) byteSize, (int) info->frameSize);
+        TRACE0("< DAUDIO_Read returning -1\n");
+        return -1;
+    }
+    if (!info->isRunning && info->isFlushed) {
+        // PCM has nothing to read
+        return 0;
+    }
+
+    count = 2; // maximum number of trials to recover from error
+    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
+    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
+    do {
+        readFrames = snd_pcm_readi(info->handle, (void*) data, (snd_pcm_uframes_t) frameSize);
+        if (readFrames < 0) {
+            ret = xrun_recovery(info, (int) readFrames);
+            if (ret <= 0) {
+                TRACE1("DAUDIO_Read: xrun recovery returned %d -> return.\n", ret);
+                return ret;
+            }
+            if (count-- <= 0) {
+                ERROR0("DAUDIO_Read: too many attempts to recover from xrun/suspend\n");
+                return -1;
+            }
+        } else {
+            break;
+        }
+    } while (TRUE);
+    //ret =  snd_pcm_frames_to_bytes(info->handle, readFrames);
+    ret =  (int) (readFrames * info->frameSize);
+    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
+    return ret;
+}
+
+
+int DAUDIO_GetBufferSize(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+
+    return info->bufferSizeInBytes;
+}
+
+int DAUDIO_StillDraining(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    snd_pcm_state_t state;
+
+    state = snd_pcm_state(info->handle);
+    //printState(state);
+    //TRACE1("Still draining: %s\n", (state != SND_PCM_STATE_XRUN)?"TRUE":"FALSE");
+    return (state == SND_PCM_STATE_RUNNING)?TRUE:FALSE;
+}
+
+
+int DAUDIO_Flush(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+
+    TRACE0("DAUDIO_Flush\n");
+
+    if (info->isFlushed) {
+        // nothing to drop
+        return 1;
+    }
+
+    ret = snd_pcm_drop(info->handle);
+    if (ret != 0) {
+        ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret));
+        return FALSE;
+    }
+
+    info->isFlushed = 1;
+    if (info->isRunning) {
+        ret = DAUDIO_Start(id, isSource);
+    }
+    return ret;
+}
+
+int DAUDIO_GetAvailable(void* id, int isSource) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    snd_pcm_sframes_t availableInFrames;
+    snd_pcm_state_t state;
+    int ret;
+
+    state = snd_pcm_state(info->handle);
+    if (info->isFlushed || state == SND_PCM_STATE_XRUN) {
+        // if in xrun state then we have the entire buffer available,
+        // not 0 as alsa reports
+        ret = info->bufferSizeInBytes;
+    } else {
+        availableInFrames = snd_pcm_avail_update(info->handle);
+        if (availableInFrames < 0) {
+            ret = 0;
+        } else {
+            //ret = snd_pcm_frames_to_bytes(info->handle, availableInFrames);
+            ret = (int) (availableInFrames * info->frameSize);
+        }
+    }
+    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
+    return ret;
+}
+
+INT64 estimatePositionFromAvail(AlsaPcmInfo* info, int isSource, INT64 javaBytePos, int availInBytes) {
+    // estimate the current position with the buffer size and
+    // the available bytes to read or write in the buffer.
+    // not an elegant solution - bytePos will stop on xruns,
+    // and in race conditions it may jump backwards
+    // Advantage is that it is indeed based on the samples that go through
+    // the system (rather than time-based methods)
+    if (isSource) {
+        // javaBytePos is the position that is reached when the current
+        // buffer is played completely
+        return (INT64) (javaBytePos - info->bufferSizeInBytes + availInBytes);
+    } else {
+        // javaBytePos is the position that was when the current buffer was empty
+        return (INT64) (javaBytePos + availInBytes);
+    }
+}
+
+INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
+    int ret;
+    INT64 result = javaBytePos;
+    snd_pcm_state_t state;
+    state = snd_pcm_state(info->handle);
+
+    if (!info->isFlushed && state != SND_PCM_STATE_XRUN) {
+#ifdef GET_POSITION_METHOD2
+        snd_timestamp_t* ts;
+        snd_pcm_uframes_t framesAvail;
+
+        // note: slight race condition if this is called simultaneously from 2 threads
+        ret = snd_pcm_status(info->handle, info->positionStatus);
+        if (ret != 0) {
+            ERROR1("ERROR in snd_pcm_status: %s\n", snd_strerror(ret));
+            result = javaBytePos;
+        } else {
+            // calculate from time value, or from available bytes
+            framesAvail = snd_pcm_status_get_avail(info->positionStatus);
+            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
+        }
+#endif
+#ifdef GET_POSITION_METHOD3
+        snd_pcm_uframes_t framesAvail;
+        ret = snd_pcm_avail(info->handle, &framesAvail);
+        if (ret != 0) {
+            ERROR1("ERROR in snd_pcm_avail: %s\n", snd_strerror(ret));
+            result = javaBytePos;
+        } else {
+            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
+        }
+#endif
+#ifdef GET_POSITION_METHOD1
+        result = estimatePositionFromAvail(info, isSource, javaBytePos, DAUDIO_GetAvailable(id, isSource));
+#endif
+    }
+    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
+    return result;
+}
+
+
+
+void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    /* save to ignore, since GetBytePosition
+     * takes the javaBytePos param into account
+     */
+}
+
+int DAUDIO_RequiresServicing(void* id, int isSource) {
+    // never need servicing on Linux
+    return FALSE;
+}
+
+void DAUDIO_Service(void* id, int isSource) {
+    // never need servicing on Linux
+}
+
+
+#endif // USE_DAUDIO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 USE_ERROR
+//#define USE_TRACE
+
+#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+
+
+
+// callback for iteration through devices
+// returns TRUE if iteration should continue
+// NOTE: cardinfo may be NULL (for "default" device)
+typedef int (*DeviceIteratorPtr)(UINT32 deviceID, snd_pcm_info_t* pcminfo,
+                             snd_ctl_card_info_t* cardinfo, void *userData);
+
+// for each ALSA device, call iterator. userData is passed to the iterator
+// returns total number of iterations
+int iteratePCMDevices(DeviceIteratorPtr iterator, void* userData) {
+    int count = 0;
+    int subdeviceCount;
+    int card, dev, subDev;
+    char devname[16];
+    int err;
+    snd_ctl_t *handle;
+    snd_pcm_t *pcm;
+    snd_pcm_info_t* pcminfo;
+    snd_ctl_card_info_t *cardinfo, *defcardinfo = NULL;
+    UINT32 deviceID;
+    int doContinue = TRUE;
+
+    snd_pcm_info_malloc(&pcminfo);
+    snd_ctl_card_info_malloc(&cardinfo);
+
+    // 1st try "default" device
+    err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
+                       SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+    if (err < 0) {
+        // try with the other direction
+        err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
+                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
+    }
+    if (err < 0) {
+        ERROR1("ERROR: snd_pcm_open (\"default\"): %s\n", snd_strerror(err));
+    } else {
+        err = snd_pcm_info(pcm, pcminfo);
+        snd_pcm_close(pcm);
+        if (err < 0) {
+            ERROR1("ERROR: snd_pcm_info (\"default\"): %s\n",
+                    snd_strerror(err));
+        } else {
+            // try to get card info
+            card = snd_pcm_info_get_card(pcminfo);
+            if (card >= 0) {
+                sprintf(devname, ALSA_HARDWARE_CARD, card);
+                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
+                    if (snd_ctl_card_info(handle, cardinfo) >= 0) {
+                        defcardinfo = cardinfo;
+                    }
+                    snd_ctl_close(handle);
+                }
+            }
+            // call callback function for the device
+            if (iterator != NULL) {
+                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, pcminfo,
+                                         defcardinfo, userData);
+            }
+            count++;
+        }
+    }
+
+    // iterate cards
+    card = -1;
+    while (doContinue) {
+        if (snd_card_next(&card) < 0) {
+            break;
+        }
+        if (card < 0) {
+            break;
+        }
+        sprintf(devname, ALSA_HARDWARE_CARD, card);
+        TRACE1("Opening alsa device \"%s\"...\n", devname);
+        err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
+        if (err < 0) {
+            ERROR2("ERROR: snd_ctl_open, card=%d: %s\n",
+                    card, snd_strerror(err));
+        } else {
+            err = snd_ctl_card_info(handle, cardinfo);
+            if (err < 0) {
+                ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n",
+                        card, snd_strerror(err));
+            } else {
+                dev = -1;
+                while (doContinue) {
+                    if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
+                        ERROR0("snd_ctl_pcm_next_device\n");
+                    }
+                    if (dev < 0) {
+                        break;
+                    }
+                    snd_pcm_info_set_device(pcminfo, dev);
+                    snd_pcm_info_set_subdevice(pcminfo, 0);
+                    snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
+                    err = snd_ctl_pcm_info(handle, pcminfo);
+                    if (err == -ENOENT) {
+                        // try with the other direction
+                        snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
+                        err = snd_ctl_pcm_info(handle, pcminfo);
+                    }
+                    if (err < 0) {
+                        if (err != -ENOENT) {
+                            ERROR2("ERROR: snd_ctl_pcm_info, card=%d: %s",
+                                    card, snd_strerror(err));
+                        }
+                    } else {
+                        subdeviceCount = needEnumerateSubdevices(ALSA_PCM) ?
+                            snd_pcm_info_get_subdevices_count(pcminfo) : 1;
+                        if (iterator!=NULL) {
+                            for (subDev = 0; subDev < subdeviceCount; subDev++) {
+                                deviceID = encodeDeviceID(card, dev, subDev);
+                                doContinue = (*iterator)(deviceID, pcminfo,
+                                                         cardinfo, userData);
+                                count++;
+                                if (!doContinue) {
+                                    break;
+                                }
+                            }
+                        } else {
+                            count += subdeviceCount;
+                        }
+                    }
+                } // of while(doContinue)
+            }
+            snd_ctl_close(handle);
+        }
+    }
+    snd_ctl_card_info_free(cardinfo);
+    snd_pcm_info_free(pcminfo);
+    return count;
+}
+
+int getAudioDeviceCount() {
+    initAlsaSupport();
+    return iteratePCMDevices(NULL, NULL);
+}
+
+int deviceInfoIterator(UINT32 deviceID, snd_pcm_info_t* pcminfo,
+                       snd_ctl_card_info_t* cardinfo, void* userData) {
+    char buffer[300];
+    ALSA_AudioDeviceDescription* desc = (ALSA_AudioDeviceDescription*)userData;
+#ifdef ALSA_PCM_USE_PLUGHW
+    int usePlugHw = 1;
+#else
+    int usePlugHw = 0;
+#endif
+
+    initAlsaSupport();
+    if (desc->index == 0) {
+        // we found the device with correct index
+        *(desc->maxSimultaneousLines) = needEnumerateSubdevices(ALSA_PCM) ?
+                1 : snd_pcm_info_get_subdevices_count(pcminfo);
+        *desc->deviceID = deviceID;
+        buffer[0]=' '; buffer[1]='[';
+        // buffer[300] is enough to store the actual device string w/o overrun
+        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_PCM);
+        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
+        strncpy(desc->name,
+                (cardinfo != NULL)
+                    ? snd_ctl_card_info_get_id(cardinfo)
+                    : snd_pcm_info_get_id(pcminfo),
+                desc->strLen - strlen(buffer));
+        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
+        strncpy(desc->vendor, "ALSA (http://www.alsa-project.org)", desc->strLen);
+        strncpy(desc->description,
+                (cardinfo != NULL)
+                    ? snd_ctl_card_info_get_name(cardinfo)
+                    : snd_pcm_info_get_name(pcminfo),
+                desc->strLen);
+        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
+        strncat(desc->description, snd_pcm_info_get_id(pcminfo), desc->strLen - strlen(desc->description));
+        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
+        strncat(desc->description, snd_pcm_info_get_name(pcminfo), desc->strLen - strlen(desc->description));
+        getALSAVersion(desc->version, desc->strLen);
+        TRACE4("Returning %s, %s, %s, %s\n", desc->name, desc->vendor, desc->description, desc->version);
+        return FALSE; // do not continue iteration
+    }
+    desc->index--;
+    return TRUE;
+}
+
+// returns 0 if successful
+int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware) {
+    char buffer[200];
+    int ret;
+
+    initAlsaSupport();
+    getDeviceStringFromDeviceID(buffer, deviceID, !hardware, ALSA_PCM);
+
+    TRACE1("Opening ALSA device %s\n", buffer);
+    ret = snd_pcm_open(handle, buffer,
+                       isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
+                       SND_PCM_NONBLOCK);
+    if (ret != 0) {
+        ERROR1("snd_pcm_open returned error code %d \n", ret);
+        *handle = NULL;
+    }
+    return ret;
+}
+
+
+int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc) {
+    initAlsaSupport();
+    TRACE1(" getAudioDeviceDescriptionByIndex(mixerIndex = %d\n", desc->index);
+    iteratePCMDevices(&deviceInfoIterator, desc);
+    return (desc->index == 0)?TRUE:FALSE;
+}
+
+// returns 1 if successful
+// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
+int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
+                            int* sampleSizeInBytes, int* significantBits,
+                            int* isSigned, int* isBigEndian, int* enc) {
+
+    *sampleSizeInBytes = (snd_pcm_format_physical_width(alsaFormat) + 7) / 8;
+    *significantBits = snd_pcm_format_width(alsaFormat);
+
+    // defaults
+    *enc = 0; // PCM
+    *isSigned = (snd_pcm_format_signed(alsaFormat) > 0);
+    *isBigEndian = (snd_pcm_format_big_endian(alsaFormat) > 0);
+
+    // non-PCM formats
+    if (alsaFormat == SND_PCM_FORMAT_MU_LAW) { // Mu-Law
+        *sampleSizeInBytes = 8; *enc = 1; *significantBits = *sampleSizeInBytes;
+    }
+    else if (alsaFormat == SND_PCM_FORMAT_A_LAW) {     // A-Law
+        *sampleSizeInBytes = 8; *enc = 2; *significantBits = *sampleSizeInBytes;
+    }
+    else if (snd_pcm_format_linear(alsaFormat) < 1) {
+        return 0;
+    }
+    return (*sampleSizeInBytes > 0);
+}
+
+// returns 1 if successful
+int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
+                            int sampleSizeInBytes, int significantBits,
+                            int isSigned, int isBigEndian, int enc) {
+    *alsaFormat = SND_PCM_FORMAT_UNKNOWN;
+
+    if (enc == 0) {
+        *alsaFormat = snd_pcm_build_linear_format(significantBits,
+                                                  sampleSizeInBytes * 8,
+                                                  isSigned?0:1,
+                                                  isBigEndian?1:0);
+    }
+    else if ((sampleSizeInBytes == 1) && (significantBits == 8)) {
+        if (enc == 1) { // ULAW
+            *alsaFormat = SND_PCM_FORMAT_MU_LAW;
+        }
+        else if (enc == 2) { // ALAW
+            *alsaFormat = SND_PCM_FORMAT_A_LAW;
+        }
+    }
+    return (*alsaFormat == SND_PCM_FORMAT_UNKNOWN)?0:1;
+}
+
+
+/* end */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2003, 2010, 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 this with a later version of ALSA than 0.9.0rc3
+// (starting from 1.0.0 it became default behaviour)
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#include <alsa/asoundlib.h>
+#include "Utilities.h"
+
+#ifndef PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
+#define PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
+
+// if this is defined, use plughw: devices
+#define ALSA_PCM_USE_PLUGHW
+//#undef ALSA_PCM_USE_PLUGHW
+
+
+// maximum number of channels that is listed in the formats. If more, than
+// just -1 for channel count is used.
+#define MAXIMUM_LISTED_CHANNELS 32
+
+typedef struct tag_ALSA_AudioDeviceDescription {
+    int index;          // in
+    int strLen;         // in
+    INT32* deviceID;    // out
+    int* maxSimultaneousLines; // out
+    char* name;         // out
+    char* vendor;       // out
+    char* description;  // out
+    char* version;      // out
+} ALSA_AudioDeviceDescription;
+
+
+
+int getAudioDeviceCount();
+int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc);
+
+// returns ALSA error code, or 0 if successful
+int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware);
+
+// returns 1 if successful
+// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
+int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
+                            int* sampleSizeInBytes, int* significantBits,
+                            int* isSigned, int* isBigEndian, int* enc);
+
+int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
+                            int sampleSizeInBytes, int significantBits,
+                            int isSigned, int isBigEndian, int enc);
+
+#endif // PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,724 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+#define USE_ERROR
+//#define USE_TRACE
+
+#include "Ports.h"
+#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
+#include <alsa/asoundlib.h>
+
+#if USE_PORTS == TRUE
+
+#define MAX_ELEMS (300)
+#define MAX_CONTROLS (MAX_ELEMS * 4)
+
+#define CHANNELS_MONO (SND_MIXER_SCHN_LAST + 1)
+#define CHANNELS_STEREO (SND_MIXER_SCHN_LAST + 2)
+
+typedef struct {
+    snd_mixer_elem_t* elem;
+    INT32 portType; /* one of PORT_XXX_xx */
+    char* controlType; /* one of CONTROL_TYPE_xx */
+    /* Values: either SND_MIXER_SCHN_FRONT_xx, CHANNELS_MONO or CHANNELS_STEREO.
+       For SND_MIXER_SCHN_FRONT_xx, exactly this channel is set/retrieved directly.
+       For CHANNELS_MONO, ALSA channel SND_MIXER_SCHN_MONO is set/retrieved directly.
+       For CHANNELS_STEREO, ALSA channels SND_MIXER_SCHN_FRONT_LEFT and SND_MIXER_SCHN_FRONT_RIGHT
+       are set after a calculation that takes balance into account. Retrieved? Average of both
+       channels? (Using a cached value is not a good idea since the value in the HW may have been
+       altered.) */
+    INT32 channel;
+} PortControl;
+
+
+typedef struct tag_PortMixer {
+    snd_mixer_t* mixer_handle;
+    /* Number of array elements used in elems and types. */
+    int numElems;
+    snd_mixer_elem_t** elems;
+    /* Array of port types (PORT_SRC_UNKNOWN etc.). Indices are the same as in elems. */
+    INT32* types;
+    /* Number of array elements used in controls. */
+    int numControls;
+    PortControl* controls;
+} PortMixer;
+
+
+///// implemented functions of Ports.h
+
+INT32 PORT_GetPortMixerCount() {
+    INT32 mixerCount;
+    int card;
+    char devname[16];
+    int err;
+    snd_ctl_t *handle;
+    snd_ctl_card_info_t* info;
+
+    TRACE0("> PORT_GetPortMixerCount\n");
+
+    initAlsaSupport();
+
+    snd_ctl_card_info_malloc(&info);
+    card = -1;
+    mixerCount = 0;
+    if (snd_card_next(&card) >= 0) {
+        while (card >= 0) {
+            sprintf(devname, ALSA_HARDWARE_CARD, card);
+            TRACE1("PORT_GetPortMixerCount: Opening alsa device \"%s\"...\n", devname);
+            err = snd_ctl_open(&handle, devname, 0);
+            if (err < 0) {
+                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
+            } else {
+                mixerCount++;
+                snd_ctl_close(handle);
+            }
+            if (snd_card_next(&card) < 0) {
+                break;
+            }
+        }
+    }
+    snd_ctl_card_info_free(info);
+    TRACE0("< PORT_GetPortMixerCount\n");
+    return mixerCount;
+}
+
+
+INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
+    snd_ctl_t* handle;
+    snd_ctl_card_info_t* card_info;
+    char devname[16];
+    int err;
+    char buffer[100];
+
+    TRACE0("> PORT_GetPortMixerDescription\n");
+    snd_ctl_card_info_malloc(&card_info);
+
+    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
+    TRACE1("Opening alsa device \"%s\"...\n", devname);
+    err = snd_ctl_open(&handle, devname, 0);
+    if (err < 0) {
+        ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
+        return FALSE;
+    }
+    err = snd_ctl_card_info(handle, card_info);
+    if (err < 0) {
+        ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
+    }
+    strncpy(description->name, snd_ctl_card_info_get_id(card_info), PORT_STRING_LENGTH - 1);
+    sprintf(buffer, " [%s]", devname);
+    strncat(description->name, buffer, PORT_STRING_LENGTH - 1 - strlen(description->name));
+    strncpy(description->vendor, "ALSA (http://www.alsa-project.org)", PORT_STRING_LENGTH - 1);
+    strncpy(description->description, snd_ctl_card_info_get_name(card_info), PORT_STRING_LENGTH - 1);
+    strncat(description->description, ", ", PORT_STRING_LENGTH - 1 - strlen(description->description));
+    strncat(description->description, snd_ctl_card_info_get_mixername(card_info), PORT_STRING_LENGTH - 1 - strlen(description->description));
+    getALSAVersion(description->version, PORT_STRING_LENGTH - 1);
+
+    snd_ctl_close(handle);
+    snd_ctl_card_info_free(card_info);
+    TRACE0("< PORT_GetPortMixerDescription\n");
+    return TRUE;
+}
+
+
+void* PORT_Open(INT32 mixerIndex) {
+    char devname[16];
+    snd_mixer_t* mixer_handle;
+    int err;
+    PortMixer* handle;
+
+    TRACE0("> PORT_Open\n");
+    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
+    if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) {
+        ERROR2("Mixer %s open error: %s", devname, snd_strerror(err));
+        return NULL;
+    }
+    if ((err = snd_mixer_attach(mixer_handle, devname)) < 0) {
+        ERROR2("Mixer attach %s error: %s", devname, snd_strerror(err));
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0) {
+        ERROR1("Mixer register error: %s", snd_strerror(err));
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    err = snd_mixer_load(mixer_handle);
+    if (err < 0) {
+        ERROR2("Mixer %s load error: %s", devname, snd_strerror(err));
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    handle = (PortMixer*) calloc(1, sizeof(PortMixer));
+    if (handle == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        return NULL;
+    }
+    handle->numElems = 0;
+    handle->elems = (snd_mixer_elem_t**) calloc(MAX_ELEMS, sizeof(snd_mixer_elem_t*));
+    if (handle->elems == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        free(handle);
+        return NULL;
+    }
+    handle->types = (INT32*) calloc(MAX_ELEMS, sizeof(INT32));
+    if (handle->types == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        free(handle->elems);
+        free(handle);
+        return NULL;
+    }
+    handle->controls = (PortControl*) calloc(MAX_CONTROLS, sizeof(PortControl));
+    if (handle->controls == NULL) {
+        ERROR0("malloc() failed.");
+        snd_mixer_close(mixer_handle);
+        free(handle->elems);
+        free(handle->types);
+        free(handle);
+        return NULL;
+    }
+    handle->mixer_handle = mixer_handle;
+    // necessary to initialize data structures
+    PORT_GetPortCount(handle);
+    TRACE0("< PORT_Open\n");
+    return handle;
+}
+
+
+void PORT_Close(void* id) {
+    TRACE0("> PORT_Close\n");
+    if (id != NULL) {
+        PortMixer* handle = (PortMixer*) id;
+        if (handle->mixer_handle != NULL) {
+            snd_mixer_close(handle->mixer_handle);
+        }
+        if (handle->elems != NULL) {
+            free(handle->elems);
+        }
+        if (handle->types != NULL) {
+            free(handle->types);
+        }
+        if (handle->controls != NULL) {
+            free(handle->controls);
+        }
+        free(handle);
+    }
+    TRACE0("< PORT_Close\n");
+}
+
+
+
+INT32 PORT_GetPortCount(void* id) {
+    PortMixer* portMixer;
+    snd_mixer_elem_t *elem;
+
+    TRACE0("> PORT_GetPortCount\n");
+    if (id == NULL) {
+        // $$mp: Should become a descriptive error code (invalid handle).
+        return -1;
+    }
+    portMixer = (PortMixer*) id;
+    if (portMixer->numElems == 0) {
+        for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
+            if (!snd_mixer_selem_is_active(elem))
+                continue;
+            TRACE2("Simple mixer control '%s',%i\n",
+                   snd_mixer_selem_get_name(elem),
+                   snd_mixer_selem_get_index(elem));
+            if (snd_mixer_selem_has_playback_volume(elem)) {
+                portMixer->elems[portMixer->numElems] = elem;
+                portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN;
+                portMixer->numElems++;
+            }
+            // to prevent buffer overflow
+            if (portMixer->numElems >= MAX_ELEMS) {
+                break;
+            }
+            /* If an element has both playback an capture volume, it is put into the arrays
+               twice. */
+            if (snd_mixer_selem_has_capture_volume(elem)) {
+                portMixer->elems[portMixer->numElems] = elem;
+                portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN;
+                portMixer->numElems++;
+            }
+            // to prevent buffer overflow
+            if (portMixer->numElems >= MAX_ELEMS) {
+                break;
+            }
+        }
+    }
+    TRACE0("< PORT_GetPortCount\n");
+    return portMixer->numElems;
+}
+
+
+INT32 PORT_GetPortType(void* id, INT32 portIndex) {
+    PortMixer* portMixer;
+    INT32 type;
+    TRACE0("> PORT_GetPortType\n");
+    if (id == NULL) {
+        // $$mp: Should become a descriptive error code (invalid handle).
+        return -1;
+    }
+    portMixer = (PortMixer*) id;
+    if (portIndex < 0 || portIndex >= portMixer->numElems) {
+        // $$mp: Should become a descriptive error code (index out of bounds).
+        return -1;
+    }
+    type = portMixer->types[portIndex];
+    TRACE0("< PORT_GetPortType\n");
+    return type;
+}
+
+
+INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
+    PortMixer* portMixer;
+    const char* nam;
+
+    TRACE0("> PORT_GetPortName\n");
+    if (id == NULL) {
+        // $$mp: Should become a descriptive error code (invalid handle).
+        return -1;
+    }
+    portMixer = (PortMixer*) id;
+    if (portIndex < 0 || portIndex >= portMixer->numElems) {
+        // $$mp: Should become a descriptive error code (index out of bounds).
+        return -1;
+    }
+    nam = snd_mixer_selem_get_name(portMixer->elems[portIndex]);
+    strncpy(name, nam, len - 1);
+    name[len - 1] = 0;
+    TRACE0("< PORT_GetPortName\n");
+    return TRUE;
+}
+
+
+static int isPlaybackFunction(INT32 portType) {
+        return (portType & PORT_DST_MASK);
+}
+
+
+/* Sets portControl to a pointer to the next free array element in the PortControl (pointer)
+   array of the passed portMixer. Returns TRUE if successful. May return FALSE if there is no
+   free slot. In this case, portControl is not altered */
+static int getControlSlot(PortMixer* portMixer, PortControl** portControl) {
+    if (portMixer->numControls >= MAX_CONTROLS) {
+        return FALSE;
+    } else {
+        *portControl = &(portMixer->controls[portMixer->numControls]);
+        portMixer->numControls++;
+        return TRUE;
+    }
+}
+
+
+/* Protect against illegal min-max values, preventing divisions by zero.
+ */
+inline static long getRange(long min, long max) {
+    if (max > min) {
+        return max - min;
+    } else {
+        return 1;
+    }
+}
+
+
+/* Idea: we may specify that if unit is an empty string, the values are linear and if unit is "dB",
+   the values are logarithmic.
+*/
+static void* createVolumeControl(PortControlCreator* creator,
+                                 PortControl* portControl,
+                                 snd_mixer_elem_t* elem, int isPlayback) {
+    void* control;
+    float precision;
+    long min, max;
+
+    if (isPlayback) {
+        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
+    } else {
+        snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
+    }
+    /* $$mp: The volume values retrieved with the ALSA API are strongly supposed to be logarithmic.
+       So the following calculation is wrong. However, there is no correct calculation, since
+       for equal-distant logarithmic steps, the precision expressed in linear varies over the
+       scale. */
+    precision = 1.0F / getRange(min, max);
+    control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_VOLUME, 0.0F, +1.0F, precision, "");
+    return control;
+}
+
+
+void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
+    PortMixer* portMixer;
+    snd_mixer_elem_t* elem;
+    void* control;
+    PortControl* portControl;
+    void* controls[10];
+    int numControls;
+    char* portName;
+    int isPlayback = 0;
+    int isMono;
+    int isStereo;
+    char* type;
+    snd_mixer_selem_channel_id_t channel;
+    memset(controls, 0, sizeof(controls));
+
+    TRACE0("> PORT_GetControls\n");
+    if (id == NULL) {
+        ERROR0("Invalid handle!");
+        // $$mp: an error code should be returned.
+        return;
+    }
+    portMixer = (PortMixer*) id;
+    if (portIndex < 0 || portIndex >= portMixer->numElems) {
+        ERROR0("Port index out of range!");
+        // $$mp: an error code should be returned.
+        return;
+    }
+    numControls = 0;
+    elem = portMixer->elems[portIndex];
+    if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) {
+        /* Since we've split/duplicated elements with both playback and capture on the recovery
+           of elements, we now can assume that we handle only to deal with either playback or
+           capture. */
+        isPlayback = isPlaybackFunction(portMixer->types[portIndex]);
+        isMono = (isPlayback && snd_mixer_selem_is_playback_mono(elem)) ||
+            (!isPlayback && snd_mixer_selem_is_capture_mono(elem));
+        isStereo = (isPlayback &&
+                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
+                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) ||
+            (!isPlayback &&
+             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
+             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT));
+        // single volume control
+        if (isMono || isStereo) {
+            if (getControlSlot(portMixer, &portControl)) {
+                portControl->elem = elem;
+                portControl->portType = portMixer->types[portIndex];
+                portControl->controlType = CONTROL_TYPE_VOLUME;
+                if (isMono) {
+                    portControl->channel = CHANNELS_MONO;
+                } else {
+                    portControl->channel = CHANNELS_STEREO;
+                }
+                control = createVolumeControl(creator, portControl, elem, isPlayback);
+                if (control != NULL) {
+                    controls[numControls++] = control;
+                }
+            }
+        } else { // more than two channels, each channels has its own control.
+            for (channel = SND_MIXER_SCHN_FRONT_LEFT; channel <= SND_MIXER_SCHN_LAST; channel++) {
+                if ((isPlayback && snd_mixer_selem_has_playback_channel(elem, channel)) ||
+                    (!isPlayback && snd_mixer_selem_has_capture_channel(elem, channel))) {
+                    if (getControlSlot(portMixer, &portControl)) {
+                        portControl->elem = elem;
+                        portControl->portType = portMixer->types[portIndex];
+                        portControl->controlType = CONTROL_TYPE_VOLUME;
+                        portControl->channel = channel;
+                        control = createVolumeControl(creator, portControl, elem, isPlayback);
+                        // We wrap in a compound control to provide the channel name.
+                        if (control != NULL) {
+                            /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
+                               declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
+                               to take a const char* parameter. */
+                            control = (creator->newCompoundControl)(creator, (char*) snd_mixer_selem_channel_name(channel), &control, 1);
+                        }
+                        if (control != NULL) {
+                            controls[numControls++] = control;
+                        }
+                    }
+                }
+            }
+        }
+        // BALANCE control
+        if (isStereo) {
+            if (getControlSlot(portMixer, &portControl)) {
+                portControl->elem = elem;
+                portControl->portType = portMixer->types[portIndex];
+                portControl->controlType = CONTROL_TYPE_BALANCE;
+                portControl->channel = CHANNELS_STEREO;
+                /* $$mp: The value for precision is chosen more or less arbitrarily. */
+                control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_BALANCE, -1.0F, 1.0F, 0.01F, "");
+                if (control != NULL) {
+                    controls[numControls++] = control;
+                }
+            }
+        }
+    }
+    if (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_capture_switch(elem)) {
+        if (getControlSlot(portMixer, &portControl)) {
+            type = isPlayback ? CONTROL_TYPE_MUTE : CONTROL_TYPE_SELECT;
+            portControl->elem = elem;
+            portControl->portType = portMixer->types[portIndex];
+            portControl->controlType = type;
+            control = (creator->newBooleanControl)(creator, portControl, type);
+            if (control != NULL) {
+                controls[numControls++] = control;
+            }
+        }
+    }
+    /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
+       declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
+       to take a const char* parameter. */
+    portName = (char*) snd_mixer_selem_get_name(elem);
+    control = (creator->newCompoundControl)(creator, portName, controls, numControls);
+    if (control != NULL) {
+        (creator->addControl)(creator, control);
+    }
+    TRACE0("< PORT_GetControls\n");
+}
+
+
+INT32 PORT_GetIntValue(void* controlIDV) {
+    PortControl* portControl = (PortControl*) controlIDV;
+    int value = 0;
+    snd_mixer_selem_channel_id_t channel;
+
+    if (portControl != NULL) {
+        switch (portControl->channel) {
+        case CHANNELS_MONO:
+            channel = SND_MIXER_SCHN_MONO;
+            break;
+
+        case CHANNELS_STEREO:
+            channel = SND_MIXER_SCHN_FRONT_LEFT;
+            break;
+
+        default:
+            channel = portControl->channel;
+        }
+        if (portControl->controlType == CONTROL_TYPE_MUTE ||
+            portControl->controlType == CONTROL_TYPE_SELECT) {
+            if (isPlaybackFunction(portControl->portType)) {
+                snd_mixer_selem_get_playback_switch(portControl->elem, channel, &value);
+            } else {
+                snd_mixer_selem_get_capture_switch(portControl->elem, channel, &value);
+            }
+            if (portControl->controlType == CONTROL_TYPE_MUTE) {
+                value = ! value;
+            }
+        } else {
+            ERROR1("PORT_GetIntValue(): inappropriate control type: %s\n",
+                   portControl->controlType);
+        }
+    }
+    return (INT32) value;
+}
+
+
+void PORT_SetIntValue(void* controlIDV, INT32 value) {
+    PortControl* portControl = (PortControl*) controlIDV;
+    snd_mixer_selem_channel_id_t channel;
+
+    if (portControl != NULL) {
+        if (portControl->controlType == CONTROL_TYPE_MUTE) {
+            value = ! value;
+        }
+        if (portControl->controlType == CONTROL_TYPE_MUTE ||
+            portControl->controlType == CONTROL_TYPE_SELECT) {
+            if (isPlaybackFunction(portControl->portType)) {
+                snd_mixer_selem_set_playback_switch_all(portControl->elem, value);
+            } else {
+                snd_mixer_selem_set_capture_switch_all(portControl->elem, value);
+            }
+        } else {
+            ERROR1("PORT_SetIntValue(): inappropriate control type: %s\n",
+                   portControl->controlType);
+        }
+    }
+}
+
+
+static float scaleVolumeValueToNormalized(long value, long min, long max) {
+    return (float) (value - min) / getRange(min, max);
+}
+
+
+static long scaleVolumeValueToHardware(float value, long min, long max) {
+    return (long)(value * getRange(min, max) + min);
+}
+
+
+float getRealVolume(PortControl* portControl,
+                    snd_mixer_selem_channel_id_t channel) {
+    float fValue;
+    long lValue = 0;
+    long min = 0;
+    long max = 0;
+
+    if (isPlaybackFunction(portControl->portType)) {
+        snd_mixer_selem_get_playback_volume_range(portControl->elem,
+                                                  &min, &max);
+        snd_mixer_selem_get_playback_volume(portControl->elem,
+                                            channel, &lValue);
+    } else {
+        snd_mixer_selem_get_capture_volume_range(portControl->elem,
+                                                 &min, &max);
+        snd_mixer_selem_get_capture_volume(portControl->elem,
+                                           channel, &lValue);
+    }
+    fValue = scaleVolumeValueToNormalized(lValue, min, max);
+    return fValue;
+}
+
+
+void setRealVolume(PortControl* portControl,
+                   snd_mixer_selem_channel_id_t channel, float value) {
+    long lValue = 0;
+    long min = 0;
+    long max = 0;
+
+    if (isPlaybackFunction(portControl->portType)) {
+        snd_mixer_selem_get_playback_volume_range(portControl->elem,
+                                                  &min, &max);
+        lValue = scaleVolumeValueToHardware(value, min, max);
+        snd_mixer_selem_set_playback_volume(portControl->elem,
+                                            channel, lValue);
+    } else {
+        snd_mixer_selem_get_capture_volume_range(portControl->elem,
+                                                 &min, &max);
+        lValue = scaleVolumeValueToHardware(value, min, max);
+        snd_mixer_selem_set_capture_volume(portControl->elem,
+                                           channel, lValue);
+    }
+}
+
+
+static float getFakeBalance(PortControl* portControl) {
+    float volL, volR;
+
+    // pan is the ratio of left and right
+    volL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
+    volR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
+    if (volL > volR) {
+        return -1.0f + (volR / volL);
+    }
+    else if (volR > volL) {
+        return 1.0f - (volL / volR);
+    }
+    return 0.0f;
+}
+
+
+static float getFakeVolume(PortControl* portControl) {
+    float valueL;
+    float valueR;
+    float value;
+
+    valueL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
+    valueR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
+    // volume is the greater value of both
+    value = valueL > valueR ? valueL : valueR ;
+    return value;
+}
+
+
+/*
+ * sets the unsigned values for left and right volume according to
+ * the given volume (0...1) and balance (-1..0..+1)
+ */
+static void setFakeVolume(PortControl* portControl, float vol, float bal) {
+    float volumeLeft;
+    float volumeRight;
+
+    if (bal < 0.0f) {
+        volumeLeft = vol;
+        volumeRight = vol * (bal + 1.0f);
+    } else {
+        volumeLeft = vol * (1.0f - bal);
+        volumeRight = vol;
+    }
+    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT, volumeLeft);
+    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT, volumeRight);
+}
+
+
+float PORT_GetFloatValue(void* controlIDV) {
+    PortControl* portControl = (PortControl*) controlIDV;
+    float value = 0.0F;
+
+    if (portControl != NULL) {
+        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
+            switch (portControl->channel) {
+            case CHANNELS_MONO:
+                value = getRealVolume(portControl, SND_MIXER_SCHN_MONO);
+                break;
+
+            case CHANNELS_STEREO:
+                value = getFakeVolume(portControl);
+                break;
+
+            default:
+                value = getRealVolume(portControl, portControl->channel);
+            }
+        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
+            if (portControl->channel == CHANNELS_STEREO) {
+                value = getFakeBalance(portControl);
+            } else {
+                ERROR0("PORT_GetFloatValue(): Balance only allowed for stereo channels!\n");
+            }
+        } else {
+            ERROR1("PORT_GetFloatValue(): inappropriate control type: %s!\n",
+                   portControl->controlType);
+        }
+    }
+    return value;
+}
+
+
+void PORT_SetFloatValue(void* controlIDV, float value) {
+    PortControl* portControl = (PortControl*) controlIDV;
+
+    if (portControl != NULL) {
+        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
+            switch (portControl->channel) {
+            case CHANNELS_MONO:
+                setRealVolume(portControl, SND_MIXER_SCHN_MONO, value);
+                break;
+
+            case CHANNELS_STEREO:
+                setFakeVolume(portControl, value, getFakeBalance(portControl));
+                break;
+
+            default:
+                setRealVolume(portControl, portControl->channel, value);
+            }
+        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
+            if (portControl->channel == CHANNELS_STEREO) {
+                setFakeVolume(portControl, getFakeVolume(portControl), value);
+            } else {
+                ERROR0("PORT_SetFloatValue(): Balance only allowed for stereo channels!\n");
+            }
+        } else {
+            ERROR1("PORT_SetFloatValue(): inappropriate control type: %s!\n",
+                   portControl->controlType);
+        }
+    }
+}
+
+
+#endif // USE_PORTS
--- a/src/java.desktop/share/classes/com/sun/media/sound/Platform.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/media/sound/Platform.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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,23 +38,9 @@
 final class Platform {
 
     // native library we need to load
-    private static final String libNameMain     = "jsound";
-    private static final String libNameALSA     = "jsoundalsa";
-    private static final String libNameDSound   = "jsoundds";
-
-    // extra libs handling: bit flags for each different library
-    public static final int LIB_MAIN     = 1;
-    public static final int LIB_ALSA     = 2;
-    public static final int LIB_DSOUND   = 4;
+    private static final String libName = "jsound";
 
-    // bit field of the constants above. Willbe set in loadLibraries
-    private static int loadedLibs = 0;
-
-    // features: the main native library jsound reports which feature is
-    // contained in which lib
-    public static final int FEATURE_MIDIIO       = 1;
-    public static final int FEATURE_PORTS        = 2;
-    public static final int FEATURE_DIRECT_AUDIO = 3;
+    private static boolean isNativeLibLoaded;
 
     // SYSTEM CHARACTERISTICS
     // vary according to hardware architecture
@@ -66,7 +52,6 @@
         if(Printer.trace)Printer.trace(">> Platform.java: static");
 
         loadLibraries();
-        readProperties();
     }
 
     /**
@@ -95,72 +80,37 @@
     private static void loadLibraries() {
         if(Printer.trace)Printer.trace(">>Platform.loadLibraries");
 
-        // load the main library
-        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-            System.loadLibrary(libNameMain);
-            return null;
-        });
-        // just for the heck of it...
-        loadedLibs |= LIB_MAIN;
-
-        // now try to load extra libs. They are defined at compile time in the Makefile
-        // with the define EXTRA_SOUND_JNI_LIBS
-        String extraLibs = nGetExtraLibraries();
-        // the string is the libraries, separated by white space
-        StringTokenizer st = new StringTokenizer(extraLibs);
-        while (st.hasMoreTokens()) {
-            final String lib = st.nextToken();
-            try {
-                AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-                    System.loadLibrary(lib);
-                    return null;
-                });
-
-                if (lib.equals(libNameALSA)) {
-                    loadedLibs |= LIB_ALSA;
-                    if (Printer.debug) Printer.debug("Loaded ALSA lib successfully.");
-                } else if (lib.equals(libNameDSound)) {
-                    loadedLibs |= LIB_DSOUND;
-                    if (Printer.debug) Printer.debug("Loaded DirectSound lib successfully.");
-                } else {
-                    if (Printer.err) Printer.err("Loaded unknown lib '"+lib+"' successfully.");
-                }
-            } catch (Throwable t) {
-                if (Printer.err) Printer.err("Couldn't load library "+lib+": "+t.toString());
-            }
+        // load the native library
+        isNativeLibLoaded = true;
+        try {
+            AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                System.loadLibrary(libName);
+                return null;
+            });
+        } catch (Throwable t) {
+            if (Printer.err) Printer.err("Couldn't load library "+libName+": "+t.toString());
+            isNativeLibLoaded = false;
+        }
+        if (isNativeLibLoaded) {
+            bigEndian = nIsBigEndian();
         }
     }
 
     static boolean isMidiIOEnabled() {
-        return isFeatureLibLoaded(FEATURE_MIDIIO);
+        if (Printer.debug) Printer.debug("Platform: Checking for MidiIO; library is loaded=" + isNativeLibLoaded);
+        return isNativeLibLoaded;
     }
 
     static boolean isPortsEnabled() {
-        return isFeatureLibLoaded(FEATURE_PORTS);
+        if (Printer.debug) Printer.debug("Platform: Checking for Ports; library is loaded=" + isNativeLibLoaded);
+        return isNativeLibLoaded;
     }
 
     static boolean isDirectAudioEnabled() {
-        return isFeatureLibLoaded(FEATURE_DIRECT_AUDIO);
-    }
-
-    private static boolean isFeatureLibLoaded(int feature) {
-        if (Printer.debug) Printer.debug("Platform: Checking for feature "+feature+"...");
-        int requiredLib = nGetLibraryForFeature(feature);
-        boolean isLoaded = (requiredLib != 0) && ((loadedLibs & requiredLib) == requiredLib);
-        if (Printer.debug) Printer.debug("          ...needs library "+requiredLib+". Result is loaded="+isLoaded);
-        return isLoaded;
+        if (Printer.debug) Printer.debug("Platform: Checking for DirectAudio; library is loaded=" + isNativeLibLoaded);
+        return isNativeLibLoaded;
     }
 
-    // the following native methods are implemented in Platform.c
+    // the following native method is implemented in Platform.c
     private static native boolean nIsBigEndian();
-    private static native String nGetExtraLibraries();
-    private static native int nGetLibraryForFeature(int feature);
-
-    /**
-     * Read the required system properties.
-     */
-    private static void readProperties() {
-        // $$fb 2002-03-06: implement check for endianness in native. Facilitates porting !
-        bigEndian = nIsBigEndian();
-    }
 }
--- a/src/java.desktop/share/native/libjsound/Platform.c	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/java.desktop/share/native/libjsound/Platform.c	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -41,83 +41,3 @@
 JNIEXPORT jboolean JNICALL Java_com_sun_media_sound_Platform_nIsBigEndian(JNIEnv *env, jclass clss) {
     return UTIL_IsBigEndianPlatform();
 }
-
-/*
- * Class:     com_sun_media_sound_Platform
- * Method:    nGetExtraLibraries
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_com_sun_media_sound_Platform_nGetExtraLibraries(JNIEnv *env, jclass clss) {
-    return (*env)->NewStringUTF(env, EXTRA_SOUND_JNI_LIBS);
-}
-
-/*
- * Class:     com_sun_media_sound_Platform
- * Method:    nGetLibraryForFeature
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_com_sun_media_sound_Platform_nGetLibraryForFeature
-  (JNIEnv *env, jclass clazz, jint feature) {
-
-// for every OS
-#if X_PLATFORM == X_WINDOWS
-    switch (feature) {
-    case com_sun_media_sound_Platform_FEATURE_MIDIIO:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    case com_sun_media_sound_Platform_FEATURE_PORTS:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    case com_sun_media_sound_Platform_FEATURE_DIRECT_AUDIO:
-        return com_sun_media_sound_Platform_LIB_DSOUND;
-    }
-#endif
-#if (X_PLATFORM == X_SOLARIS)
-    switch (feature) {
-    case com_sun_media_sound_Platform_FEATURE_MIDIIO:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    case com_sun_media_sound_Platform_FEATURE_PORTS:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    case com_sun_media_sound_Platform_FEATURE_DIRECT_AUDIO:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    }
-#endif
-#if (X_PLATFORM == X_LINUX)
-    switch (feature) {
-    case com_sun_media_sound_Platform_FEATURE_MIDIIO:
-        return com_sun_media_sound_Platform_LIB_ALSA;
-    case com_sun_media_sound_Platform_FEATURE_PORTS:
-        return com_sun_media_sound_Platform_LIB_ALSA;
-    case com_sun_media_sound_Platform_FEATURE_DIRECT_AUDIO:
-        return com_sun_media_sound_Platform_LIB_ALSA;
-    }
-#endif
-#if (X_PLATFORM == X_MACOSX)
-    switch (feature) {
-    case com_sun_media_sound_Platform_FEATURE_MIDIIO:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    case com_sun_media_sound_Platform_FEATURE_PORTS:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    case com_sun_media_sound_Platform_FEATURE_DIRECT_AUDIO:
-        return com_sun_media_sound_Platform_LIB_MAIN;
-    }
-#endif
-#if (X_PLATFORM == X_BSD)
-    switch (feature) {
-    case com_sun_media_sound_Platform_FEATURE_MIDIIO:
-       return com_sun_media_sound_Platform_LIB_MAIN;
-#ifdef __FreeBSD__
-    case com_sun_media_sound_Platform_FEATURE_PORTS:
-       return com_sun_media_sound_Platform_LIB_ALSA;
-    case com_sun_media_sound_Platform_FEATURE_DIRECT_AUDIO:
-       return com_sun_media_sound_Platform_LIB_ALSA;
-#else
-    case com_sun_media_sound_Platform_FEATURE_PORTS:
-       return com_sun_media_sound_Platform_LIB_MAIN;
-    case com_sun_media_sound_Platform_FEATURE_DIRECT_AUDIO:
-       // XXXBSD: When native Direct Audio support is ported change
-       // this back to returning com_sun_media_sound_Platform_LIB_MAIN
-       return 0;
-#endif
-    }
-#endif
-    return 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_PCM.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,626 @@
+/*
+ * Copyright (c) 2003, 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 USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_SolarisOS_Utils.h"
+#include "DirectAudio.h"
+
+#if USE_DAUDIO == TRUE
+
+
+// The default buffer time
+#define DEFAULT_PERIOD_TIME_MILLIS 50
+
+///// implemented functions of DirectAudio.h
+
+INT32 DAUDIO_GetDirectAudioDeviceCount() {
+    return (INT32) getAudioDeviceCount();
+}
+
+
+INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex,
+                                             DirectAudioDeviceDescription* description) {
+    AudioDeviceDescription desc;
+
+    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
+        description->maxSimulLines = desc.maxSimulLines;
+        strncpy(description->name, desc.name, DAUDIO_STRING_LENGTH-1);
+        description->name[DAUDIO_STRING_LENGTH-1] = 0;
+        strncpy(description->vendor, desc.vendor, DAUDIO_STRING_LENGTH-1);
+        description->vendor[DAUDIO_STRING_LENGTH-1] = 0;
+        strncpy(description->version, desc.version, DAUDIO_STRING_LENGTH-1);
+        description->version[DAUDIO_STRING_LENGTH-1] = 0;
+        /*strncpy(description->description, desc.description, DAUDIO_STRING_LENGTH-1);*/
+        strncpy(description->description, "Solaris Mixer", DAUDIO_STRING_LENGTH-1);
+        description->description[DAUDIO_STRING_LENGTH-1] = 0;
+        return TRUE;
+    }
+    return FALSE;
+
+}
+
+#define MAX_SAMPLE_RATES   20
+
+void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
+    int fd = -1;
+    AudioDeviceDescription desc;
+    am_sample_rates_t      *sr;
+    /* hardcoded bits and channels */
+    int bits[] = {8, 16};
+    int bitsCount = 2;
+    int channels[] = {1, 2};
+    int channelsCount = 2;
+    /* for querying sample rates */
+    int err;
+    int ch, b, s;
+
+    TRACE2("DAUDIO_GetFormats, mixer %d, isSource=%d\n", mixerIndex, isSource);
+    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
+        fd = open(desc.pathctl, O_RDONLY);
+    }
+    if (fd < 0) {
+        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
+        return;
+    }
+
+    /* get sample rates */
+    sr = (am_sample_rates_t*) malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(MAX_SAMPLE_RATES));
+    if (sr == NULL) {
+        ERROR1("DAUDIO_GetFormats: out of memory for mixer %d\n", (int) mixerIndex);
+        close(fd);
+        return;
+    }
+
+    sr->num_samp_rates = MAX_SAMPLE_RATES;
+    sr->type = isSource?AUDIO_PLAY:AUDIO_RECORD;
+    sr->samp_rates[0] = -2;
+    err = ioctl(fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr);
+    if (err < 0) {
+        ERROR1("  DAUDIO_GetFormats: AUDIO_MIXER_GET_SAMPLE_RATES failed for mixer %d!\n",
+               (int)mixerIndex);
+        ERROR2(" -> num_sample_rates=%d sample_rates[0] = %d\n",
+               (int) sr->num_samp_rates,
+               (int) sr->samp_rates[0]);
+        /* Some Solaris 8 drivers fail for get sample rates!
+         * Do as if we support all sample rates
+         */
+        sr->flags = MIXER_SR_LIMITS;
+    }
+    if ((sr->flags & MIXER_SR_LIMITS)
+        || (sr->num_samp_rates > MAX_SAMPLE_RATES)) {
+#ifdef USE_TRACE
+        if ((sr->flags & MIXER_SR_LIMITS)) {
+            TRACE1("  DAUDIO_GetFormats: floating sample rate allowed by mixer %d\n",
+                   (int)mixerIndex);
+        }
+        if (sr->num_samp_rates > MAX_SAMPLE_RATES) {
+            TRACE2("  DAUDIO_GetFormats: more than %d formats. Use -1 for sample rates mixer %d\n",
+                   MAX_SAMPLE_RATES, (int)mixerIndex);
+        }
+#endif
+        /*
+         * Fake it to have only one sample rate: -1
+         */
+        sr->num_samp_rates = 1;
+        sr->samp_rates[0] = -1;
+    }
+    close(fd);
+
+    for (ch = 0; ch < channelsCount; ch++) {
+        for (b = 0; b < bitsCount; b++) {
+            for (s = 0; s < sr->num_samp_rates; s++) {
+                DAUDIO_AddAudioFormat(creator,
+                                      bits[b], /* significant bits */
+                                      0, /* frameSize: let it be calculated */
+                                      channels[ch],
+                                      (float) ((int) sr->samp_rates[s]),
+                                      DAUDIO_PCM, /* encoding - let's only do PCM */
+                                      (bits[b] > 8)?TRUE:TRUE, /* isSigned */
+#ifdef _LITTLE_ENDIAN
+                                      FALSE /* little endian */
+#else
+                                      (bits[b] > 8)?TRUE:FALSE  /* big endian */
+#endif
+                                      );
+            }
+        }
+    }
+    free(sr);
+}
+
+
+typedef struct {
+    int fd;
+    audio_info_t info;
+    int bufferSizeInBytes;
+    int frameSize; /* storage size in Bytes */
+    /* how many bytes were written or read */
+    INT32 transferedBytes;
+    /* if transferedBytes exceed 32-bit boundary,
+     * it will be reset and positionOffset will receive
+     * the offset
+     */
+    INT64 positionOffset;
+} SolPcmInfo;
+
+
+void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
+                  int encoding, float sampleRate, int sampleSizeInBits,
+                  int frameSize, int channels,
+                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
+    int err = 0;
+    int openMode;
+    AudioDeviceDescription desc;
+    SolPcmInfo* info;
+
+    TRACE0("> DAUDIO_Open\n");
+    if (encoding != DAUDIO_PCM) {
+        ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
+        return NULL;
+    }
+    if (channels <= 0) {
+        ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
+        return NULL;
+    }
+
+    info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
+    if (!info) {
+        ERROR0("Out of memory\n");
+        return NULL;
+    }
+    memset(info, 0, sizeof(SolPcmInfo));
+    info->frameSize = frameSize;
+    info->fd = -1;
+
+    if (isSource) {
+        openMode = O_WRONLY;
+    } else {
+        openMode = O_RDONLY;
+    }
+
+#ifndef __linux__
+    /* blackdown does not use NONBLOCK */
+    openMode |= O_NONBLOCK;
+#endif
+
+    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
+        info->fd = open(desc.path, openMode);
+    }
+    if (info->fd < 0) {
+        ERROR1("Couldn't open audio device for mixer %d!\n", mixerIndex);
+        free(info);
+        return NULL;
+    }
+    /* set to multiple open */
+    if (ioctl(info->fd, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
+        TRACE1("DAUDIO_Open: %s set to multiple open\n", desc.path);
+    } else {
+        ERROR1("DAUDIO_Open: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", desc.path);
+    }
+
+    AUDIO_INITINFO(&(info->info));
+    /* need AUDIO_GETINFO ioctl to get this to work on solaris x86  */
+    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
+
+    /* not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO. */
+    AUDIO_INITINFO(&(info->info));
+
+    if (isSource) {
+        info->info.play.sample_rate = sampleRate;
+        info->info.play.precision = sampleSizeInBits;
+        info->info.play.channels = channels;
+        info->info.play.encoding = AUDIO_ENCODING_LINEAR;
+        info->info.play.buffer_size = bufferSizeInBytes;
+        info->info.play.pause = 1;
+    } else {
+        info->info.record.sample_rate = sampleRate;
+        info->info.record.precision = sampleSizeInBits;
+        info->info.record.channels = channels;
+        info->info.record.encoding = AUDIO_ENCODING_LINEAR;
+        info->info.record.buffer_size = bufferSizeInBytes;
+        info->info.record.pause = 1;
+    }
+    err = ioctl(info->fd, AUDIO_SETINFO,  &(info->info));
+    if (err < 0) {
+        ERROR0("DAUDIO_Open: could not set info!\n");
+        DAUDIO_Close((void*) info, isSource);
+        return NULL;
+    }
+    DAUDIO_Flush((void*) info, isSource);
+
+    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
+    if (err >= 0) {
+        if (isSource) {
+            info->bufferSizeInBytes = info->info.play.buffer_size;
+        } else {
+            info->bufferSizeInBytes = info->info.record.buffer_size;
+        }
+        TRACE2("DAUDIO: buffersize in bytes: requested=%d, got %d\n",
+               (int) bufferSizeInBytes,
+               (int) info->bufferSizeInBytes);
+    } else {
+        ERROR0("DAUDIO_Open: cannot get info!\n");
+        DAUDIO_Close((void*) info, isSource);
+        return NULL;
+    }
+    TRACE0("< DAUDIO_Open: Opened device successfully.\n");
+    return (void*) info;
+}
+
+
+int DAUDIO_Start(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int err, modified;
+    audio_info_t audioInfo;
+
+    TRACE0("> DAUDIO_Start\n");
+
+    AUDIO_INITINFO(&audioInfo);
+    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
+    if (err >= 0) {
+        // unpause
+        modified = FALSE;
+        if (isSource && audioInfo.play.pause) {
+            audioInfo.play.pause = 0;
+            modified = TRUE;
+        }
+        if (!isSource && audioInfo.record.pause) {
+            audioInfo.record.pause = 0;
+            modified = TRUE;
+        }
+        if (modified) {
+            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
+        }
+    }
+
+    TRACE1("< DAUDIO_Start %s\n", (err>=0)?"success":"error");
+    return (err >= 0)?TRUE:FALSE;
+}
+
+int DAUDIO_Stop(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int err, modified;
+    audio_info_t audioInfo;
+
+    TRACE0("> DAUDIO_Stop\n");
+
+    AUDIO_INITINFO(&audioInfo);
+    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
+    if (err >= 0) {
+        // pause
+        modified = FALSE;
+        if (isSource && !audioInfo.play.pause) {
+            audioInfo.play.pause = 1;
+            modified = TRUE;
+        }
+        if (!isSource && !audioInfo.record.pause) {
+            audioInfo.record.pause = 1;
+            modified = TRUE;
+        }
+        if (modified) {
+            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
+        }
+    }
+
+    TRACE1("< DAUDIO_Stop %s\n", (err>=0)?"success":"error");
+    return (err >= 0)?TRUE:FALSE;
+}
+
+void DAUDIO_Close(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+
+    TRACE0("DAUDIO_Close\n");
+    if (info != NULL) {
+        if (info->fd >= 0) {
+            DAUDIO_Flush(id, isSource);
+            close(info->fd);
+        }
+        free(info);
+    }
+}
+
+#ifndef USE_TRACE
+/* close to 2^31 */
+#define POSITION_MAX 2000000000
+#else
+/* for testing */
+#define POSITION_MAX 1000000
+#endif
+
+void resetErrorFlagAndAdjustPosition(SolPcmInfo* info, int isSource, int count) {
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+    int err;
+    int offset = -1;
+    int underrun = FALSE;
+    int devBytes = 0;
+
+    if (count > 0) {
+        info->transferedBytes += count;
+
+        if (isSource) {
+            prinfo = &(audioInfo.play);
+        } else {
+            prinfo = &(audioInfo.record);
+        }
+        AUDIO_INITINFO(&audioInfo);
+        err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
+        if (err >= 0) {
+            underrun = prinfo->error;
+            devBytes = prinfo->samples * info->frameSize;
+        }
+        AUDIO_INITINFO(&audioInfo);
+        if (underrun) {
+            /* if an underrun occurred, reset */
+            ERROR1("DAUDIO_Write/Read: Underrun/overflow: adjusting positionOffset by %d:\n",
+                   (devBytes - info->transferedBytes));
+            ERROR1("    devBytes from %d to 0, ", devBytes);
+            ERROR2(" positionOffset from %d to %d ",
+                   (int) info->positionOffset,
+                   (int) (info->positionOffset + info->transferedBytes));
+            ERROR1(" transferedBytes from %d to 0\n",
+                   (int) info->transferedBytes);
+            prinfo->samples = 0;
+            info->positionOffset += info->transferedBytes;
+            info->transferedBytes = 0;
+        }
+        else if (info->transferedBytes > POSITION_MAX) {
+            /* we will reset transferedBytes and
+             * the samples field in prinfo
+             */
+            offset = devBytes;
+            prinfo->samples = 0;
+        }
+        /* reset error flag */
+        prinfo->error = 0;
+
+        err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
+        if (err >= 0) {
+            if (offset > 0) {
+                /* upon exit of AUDIO_SETINFO, the samples parameter
+                 * was set to the previous value. This is our
+                 * offset.
+                 */
+                TRACE1("Adjust samplePos: offset=%d, ", (int) offset);
+                TRACE2("transferedBytes=%d -> %d, ",
+                       (int) info->transferedBytes,
+                       (int) (info->transferedBytes - offset));
+                TRACE2("positionOffset=%d -> %d\n",
+                       (int) (info->positionOffset),
+                       (int) (((int) info->positionOffset) + offset));
+                info->transferedBytes -= offset;
+                info->positionOffset += offset;
+            }
+        } else {
+            ERROR0("DAUDIO: resetErrorFlagAndAdjustPosition ioctl failed!\n");
+        }
+    }
+}
+
+// returns -1 on error
+int DAUDIO_Write(void* id, char* data, int byteSize) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret = -1;
+
+    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
+    if (info!=NULL) {
+        ret = write(info->fd, data, byteSize);
+        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
+        /* sets ret to -1 if buffer full, no error! */
+        if (ret < 0) {
+            ret = 0;
+        }
+    }
+    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
+    return ret;
+}
+
+// returns -1 on error
+int DAUDIO_Read(void* id, char* data, int byteSize) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret = -1;
+
+    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
+    if (info != NULL) {
+        ret = read(info->fd, data, byteSize);
+        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
+        /* sets ret to -1 if buffer full, no error! */
+        if (ret < 0) {
+            ret = 0;
+        }
+    }
+    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
+    return ret;
+}
+
+
+int DAUDIO_GetBufferSize(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    if (info) {
+        return info->bufferSizeInBytes;
+    }
+    return 0;
+}
+
+int DAUDIO_StillDraining(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+    int ret = FALSE;
+
+    if (info!=NULL) {
+        if (isSource) {
+            prinfo = &(audioInfo.play);
+        } else {
+            prinfo = &(audioInfo.record);
+        }
+        /* check error flag */
+        AUDIO_INITINFO(&audioInfo);
+        ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
+        ret = (prinfo->error != 0)?FALSE:TRUE;
+    }
+    return ret;
+}
+
+
+int getDevicePosition(SolPcmInfo* info, int isSource) {
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+    int err;
+
+    if (isSource) {
+        prinfo = &(audioInfo.play);
+    } else {
+        prinfo = &(audioInfo.record);
+    }
+    AUDIO_INITINFO(&audioInfo);
+    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
+    if (err >= 0) {
+        /*TRACE2("---> device paused: %d  eof=%d\n",
+               prinfo->pause, prinfo->eof);
+        */
+        return (int) (prinfo->samples * info->frameSize);
+    }
+    ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n");
+    return -1;
+}
+
+int DAUDIO_Flush(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int err = -1;
+    int pos;
+
+    TRACE0("DAUDIO_Flush\n");
+    if (info) {
+        if (isSource) {
+            err = ioctl(info->fd, I_FLUSH, FLUSHW);
+        } else {
+            err = ioctl(info->fd, I_FLUSH, FLUSHR);
+        }
+        if (err >= 0) {
+            /* resets the transferedBytes parameter to
+             * the current samples count of the device
+             */
+            pos = getDevicePosition(info, isSource);
+            if (pos >= 0) {
+                info->transferedBytes = pos;
+            }
+        }
+    }
+    if (err < 0) {
+        ERROR0("ERROR in DAUDIO_Flush\n");
+    }
+    return (err < 0)?FALSE:TRUE;
+}
+
+int DAUDIO_GetAvailable(void* id, int isSource) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret = 0;
+    int pos;
+
+    if (info) {
+        /* unfortunately, the STREAMS architecture
+         * seems to not have a method for querying
+         * the available bytes to read/write!
+         * estimate it...
+         */
+        pos = getDevicePosition(info, isSource);
+        if (pos >= 0) {
+            if (isSource) {
+                /* we usually have written more bytes
+                 * to the queue than the device position should be
+                 */
+                ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos);
+            } else {
+                /* for record, the device stream should
+                 * be usually ahead of our read actions
+                 */
+                ret = pos - info->transferedBytes;
+            }
+            if (ret > info->bufferSizeInBytes) {
+                ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n",
+                       (int) ret, (int) info->bufferSizeInBytes);
+                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
+                       (int) pos, (int) info->transferedBytes);
+                ret = info->bufferSizeInBytes;
+            }
+            else if (ret < 0) {
+                ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n",
+                       (int) ret);
+                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
+                       (int) pos, (int) info->transferedBytes);
+                ret = 0;
+            }
+        }
+    }
+
+    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
+    return ret;
+}
+
+INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret;
+    int pos;
+    INT64 result = javaBytePos;
+
+    if (info) {
+        pos = getDevicePosition(info, isSource);
+        if (pos >= 0) {
+            result = info->positionOffset + pos;
+        }
+    }
+
+    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
+    return result;
+}
+
+
+void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
+    SolPcmInfo* info = (SolPcmInfo*) id;
+    int ret;
+    int pos;
+
+    if (info) {
+        pos = getDevicePosition(info, isSource);
+        if (pos >= 0) {
+            info->positionOffset = javaBytePos - pos;
+        }
+    }
+}
+
+int DAUDIO_RequiresServicing(void* id, int isSource) {
+    // never need servicing on Solaris
+    return FALSE;
+}
+
+void DAUDIO_Service(void* id, int isSource) {
+    // never need servicing on Solaris
+}
+
+
+#endif // USE_DAUDIO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Ports.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+#define USE_ERROR
+//#define USE_TRACE
+
+#include "Ports.h"
+#include "PLATFORM_API_SolarisOS_Utils.h"
+
+#if USE_PORTS == TRUE
+
+#define MONITOR_GAIN_STRING "Monitor Gain"
+
+#define ALL_TARGET_PORT_COUNT 6
+
+// define the following to not use audio_prinfo_t.mod_ports
+#define SOLARIS7_COMPATIBLE
+
+// Solaris audio defines
+static int targetPorts[ALL_TARGET_PORT_COUNT] = {
+    AUDIO_SPEAKER,
+    AUDIO_HEADPHONE,
+    AUDIO_LINE_OUT,
+    AUDIO_AUX1_OUT,
+    AUDIO_AUX2_OUT,
+    AUDIO_SPDIF_OUT
+};
+
+static char* targetPortNames[ALL_TARGET_PORT_COUNT] = {
+    "Speaker",
+    "Headphone",
+    "Line Out",
+    "AUX1 Out",
+    "AUX2 Out",
+    "SPDIF Out"
+};
+
+// defined in Ports.h
+static int targetPortJavaSoundMapping[ALL_TARGET_PORT_COUNT] = {
+    PORT_DST_SPEAKER,
+    PORT_DST_HEADPHONE,
+    PORT_DST_LINE_OUT,
+    PORT_DST_UNKNOWN,
+    PORT_DST_UNKNOWN,
+    PORT_DST_UNKNOWN,
+};
+
+#define ALL_SOURCE_PORT_COUNT 7
+
+// Solaris audio defines
+static int sourcePorts[ALL_SOURCE_PORT_COUNT] = {
+    AUDIO_MICROPHONE,
+    AUDIO_LINE_IN,
+    AUDIO_CD,
+    AUDIO_AUX1_IN,
+    AUDIO_AUX2_IN,
+    AUDIO_SPDIF_IN,
+    AUDIO_CODEC_LOOPB_IN
+};
+
+static char* sourcePortNames[ALL_SOURCE_PORT_COUNT] = {
+    "Microphone In",
+    "Line In",
+    "Compact Disc In",
+    "AUX1 In",
+    "AUX2 In",
+    "SPDIF In",
+    "Internal Loopback"
+};
+
+// Ports.h defines
+static int sourcePortJavaSoundMapping[ALL_SOURCE_PORT_COUNT] = {
+    PORT_SRC_MICROPHONE,
+    PORT_SRC_LINE_IN,
+    PORT_SRC_COMPACT_DISC,
+    PORT_SRC_UNKNOWN,
+    PORT_SRC_UNKNOWN,
+    PORT_SRC_UNKNOWN,
+    PORT_SRC_UNKNOWN
+};
+
+struct tag_PortControlID;
+
+typedef struct tag_PortInfo {
+    int fd;                    // file descriptor of the pseudo device
+    audio_info_t audioInfo;
+    // ports
+    int targetPortCount;
+    int sourcePortCount;
+    // indexes to sourcePorts/targetPorts
+    // contains first target ports, then source ports
+    int ports[ALL_TARGET_PORT_COUNT + ALL_SOURCE_PORT_COUNT];
+    // controls
+    int maxControlCount;       // upper bound of number of controls
+    int usedControlIDs;        // number of items already filled in controlIDs
+    struct tag_PortControlID* controlIDs; // the control IDs themselves
+} PortInfo;
+
+#define PORT_CONTROL_TYPE_PLAY          0x4000000
+#define PORT_CONTROL_TYPE_RECORD        0x8000000
+#define PORT_CONTROL_TYPE_SELECT_PORT   1
+#define PORT_CONTROL_TYPE_GAIN          2
+#define PORT_CONTROL_TYPE_BALANCE       3
+#define PORT_CONTROL_TYPE_MONITOR_GAIN  10
+#define PORT_CONTROL_TYPE_OUTPUT_MUTED  11
+#define PORT_CONTROL_TYPE_PLAYRECORD_MASK PORT_CONTROL_TYPE_PLAY | PORT_CONTROL_TYPE_RECORD
+#define PORT_CONTROL_TYPE_MASK 0xFFFFFF
+
+
+typedef struct tag_PortControlID {
+    PortInfo*  portInfo;
+    INT32                 controlType;  // PORT_CONTROL_TYPE_XX
+    uint_t                port;
+} PortControlID;
+
+
+///// implemented functions of Ports.h
+
+INT32 PORT_GetPortMixerCount() {
+    return (INT32) getAudioDeviceCount();
+}
+
+
+INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
+    AudioDeviceDescription desc;
+
+    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
+        strncpy(description->name, desc.name, PORT_STRING_LENGTH-1);
+        description->name[PORT_STRING_LENGTH-1] = 0;
+        strncpy(description->vendor, desc.vendor, PORT_STRING_LENGTH-1);
+        description->vendor[PORT_STRING_LENGTH-1] = 0;
+        strncpy(description->version, desc.version, PORT_STRING_LENGTH-1);
+        description->version[PORT_STRING_LENGTH-1] = 0;
+        /*strncpy(description->description, desc.description, PORT_STRING_LENGTH-1);*/
+        strncpy(description->description, "Solaris Ports", PORT_STRING_LENGTH-1);
+        description->description[PORT_STRING_LENGTH-1] = 0;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
+void* PORT_Open(INT32 mixerIndex) {
+    PortInfo* info = NULL;
+    int fd = -1;
+    AudioDeviceDescription desc;
+    int success = FALSE;
+
+    TRACE0("PORT_Open\n");
+    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
+        fd = open(desc.pathctl, O_RDWR);
+    }
+    if (fd < 0) {
+        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
+        return NULL;
+    }
+
+    info = (PortInfo*) malloc(sizeof(PortInfo));
+    if (info != NULL) {
+        memset(info, 0, sizeof(PortInfo));
+        info->fd = fd;
+        success = TRUE;
+    }
+    if (!success) {
+        if (fd >= 0) {
+            close(fd);
+        }
+        PORT_Close((void*) info);
+        info = NULL;
+    }
+    return info;
+}
+
+void PORT_Close(void* id) {
+    TRACE0("PORT_Close\n");
+    if (id != NULL) {
+        PortInfo* info = (PortInfo*) id;
+        if (info->fd >= 0) {
+            close(info->fd);
+            info->fd = -1;
+        }
+        if (info->controlIDs) {
+            free(info->controlIDs);
+            info->controlIDs = NULL;
+        }
+        free(info);
+    }
+}
+
+
+
+INT32 PORT_GetPortCount(void* id) {
+    int ret = 0;
+    PortInfo* info = (PortInfo*) id;
+    if (info != NULL) {
+        if (!info->targetPortCount && !info->sourcePortCount) {
+            int i;
+            AUDIO_INITINFO(&info->audioInfo);
+            if (ioctl(info->fd, AUDIO_GETINFO, &info->audioInfo) >= 0) {
+                for (i = 0; i < ALL_TARGET_PORT_COUNT; i++) {
+                    if (info->audioInfo.play.avail_ports & targetPorts[i]) {
+                        info->ports[info->targetPortCount] = i;
+                        info->targetPortCount++;
+                    }
+#ifdef SOLARIS7_COMPATIBLE
+                    TRACE3("Target %d %s: avail=%d\n", i, targetPortNames[i],
+                           info->audioInfo.play.avail_ports & targetPorts[i]);
+#else
+                    TRACE4("Target %d %s: avail=%d  mod=%d\n", i, targetPortNames[i],
+                           info->audioInfo.play.avail_ports & targetPorts[i],
+                           info->audioInfo.play.mod_ports & targetPorts[i]);
+#endif
+                }
+                for (i = 0; i < ALL_SOURCE_PORT_COUNT; i++) {
+                    if (info->audioInfo.record.avail_ports & sourcePorts[i]) {
+                        info->ports[info->targetPortCount + info->sourcePortCount] = i;
+                        info->sourcePortCount++;
+                    }
+#ifdef SOLARIS7_COMPATIBLE
+                    TRACE3("Source %d %s: avail=%d\n", i, sourcePortNames[i],
+                           info->audioInfo.record.avail_ports & sourcePorts[i]);
+#else
+                    TRACE4("Source %d %s: avail=%d  mod=%d\n", i, sourcePortNames[i],
+                           info->audioInfo.record.avail_ports & sourcePorts[i],
+                           info->audioInfo.record.mod_ports & sourcePorts[i]);
+#endif
+                }
+            }
+        }
+        ret = info->targetPortCount + info->sourcePortCount;
+    }
+    return ret;
+}
+
+int isSourcePort(PortInfo* info, INT32 portIndex) {
+    return (portIndex >= info->targetPortCount);
+}
+
+INT32 PORT_GetPortType(void* id, INT32 portIndex) {
+    PortInfo* info = (PortInfo*) id;
+    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
+        if (isSourcePort(info, portIndex)) {
+            return sourcePortJavaSoundMapping[info->ports[portIndex]];
+        } else {
+            return targetPortJavaSoundMapping[info->ports[portIndex]];
+        }
+    }
+    return 0;
+}
+
+// pre-condition: portIndex must have been verified!
+char* getPortName(PortInfo* info, INT32 portIndex) {
+    char* ret = NULL;
+
+    if (isSourcePort(info, portIndex)) {
+        ret = sourcePortNames[info->ports[portIndex]];
+    } else {
+        ret = targetPortNames[info->ports[portIndex]];
+    }
+    return ret;
+}
+
+INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
+    PortInfo* info = (PortInfo*) id;
+    char* n;
+
+    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
+        n = getPortName(info, portIndex);
+        if (n) {
+            strncpy(name, n, len-1);
+            name[len-1] = 0;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+void createPortControl(PortInfo* info, PortControlCreator* creator, INT32 portIndex,
+                       INT32 type, void** controlObjects, int* controlCount) {
+    PortControlID* controlID;
+    void* newControl = NULL;
+    int controlIndex;
+    char* jsType = NULL;
+    int isBoolean = FALSE;
+
+    TRACE0(">createPortControl\n");
+
+    // fill the ControlID structure and add this control
+    if (info->usedControlIDs >= info->maxControlCount) {
+        ERROR1("not enough free controlIDs !! maxControlIDs = %d\n", info->maxControlCount);
+        return;
+    }
+    controlID = &(info->controlIDs[info->usedControlIDs]);
+    controlID->portInfo = info;
+    controlID->controlType = type;
+    controlIndex = info->ports[portIndex];
+    if (isSourcePort(info, portIndex)) {
+        controlID->port = sourcePorts[controlIndex];
+    } else {
+        controlID->port = targetPorts[controlIndex];
+    }
+    switch (type & PORT_CONTROL_TYPE_MASK) {
+    case PORT_CONTROL_TYPE_SELECT_PORT:
+        jsType = CONTROL_TYPE_SELECT; isBoolean = TRUE; break;
+    case PORT_CONTROL_TYPE_GAIN:
+        jsType = CONTROL_TYPE_VOLUME;  break;
+    case PORT_CONTROL_TYPE_BALANCE:
+        jsType = CONTROL_TYPE_BALANCE; break;
+    case PORT_CONTROL_TYPE_MONITOR_GAIN:
+        jsType = CONTROL_TYPE_VOLUME; break;
+    case PORT_CONTROL_TYPE_OUTPUT_MUTED:
+        jsType = CONTROL_TYPE_MUTE; isBoolean = TRUE; break;
+    }
+    if (isBoolean) {
+        TRACE0(" PORT_CONTROL_TYPE_BOOLEAN\n");
+        newControl = (creator->newBooleanControl)(creator, controlID, jsType);
+    }
+    else if (jsType == CONTROL_TYPE_BALANCE) {
+        TRACE0(" PORT_CONTROL_TYPE_BALANCE\n");
+        newControl = (creator->newFloatControl)(creator, controlID, jsType,
+                                                -1.0f, 1.0f, 2.0f / 65.0f, "");
+    } else {
+        TRACE0(" PORT_CONTROL_TYPE_FLOAT\n");
+        newControl = (creator->newFloatControl)(creator, controlID, jsType,
+                                                0.0f, 1.0f, 1.0f / 256.0f, "");
+    }
+    if (newControl) {
+        controlObjects[*controlCount] = newControl;
+        (*controlCount)++;
+        info->usedControlIDs++;
+    }
+    TRACE0("<createPortControl\n");
+}
+
+
+void addCompoundControl(PortInfo* info, PortControlCreator* creator, char* name, void** controlObjects, int* controlCount) {
+    void* compControl;
+
+    TRACE1(">addCompoundControl %d controls\n", *controlCount);
+    if (*controlCount) {
+        // create compound control and add it to the vector
+        compControl = (creator->newCompoundControl)(creator, name, controlObjects, *controlCount);
+        if (compControl) {
+            TRACE1(" addCompoundControl: calling addControl %p\n", compControl);
+            (creator->addControl)(creator, compControl);
+        }
+        *controlCount = 0;
+    }
+    TRACE0("<addCompoundControl\n");
+}
+
+void addAllControls(PortInfo* info, PortControlCreator* creator, void** controlObjects, int* controlCount) {
+    int i = 0;
+
+    TRACE0(">addAllControl\n");
+    // go through all controls and add them to the vector
+    for (i = 0; i < *controlCount; i++) {
+        (creator->addControl)(creator, controlObjects[i]);
+    }
+    *controlCount = 0;
+    TRACE0("<addAllControl\n");
+}
+
+void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
+    PortInfo* info = (PortInfo*) id;
+    int portCount = PORT_GetPortCount(id);
+    void* controls[4];
+    int controlCount = 0;
+    INT32 type;
+    int selectable = 1;
+    memset(controls, 0, sizeof(controls));
+
+    TRACE4(">PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n",
+           id, portIndex, info->controlIDs, info->maxControlCount);
+    if ((portIndex >= 0) && (portIndex < portCount)) {
+        // if the memory isn't reserved for the control structures, allocate it
+        if (!info->controlIDs) {
+            int maxCount = 0;
+            TRACE0("getControl: allocate mem\n");
+            // get a maximum number of controls:
+            // each port has a select, balance, and volume control.
+            maxCount = 3 * portCount;
+            // then there is monitorGain and outputMuted
+            maxCount += (2 * info->targetPortCount);
+            info->maxControlCount = maxCount;
+            info->controlIDs = (PortControlID*) malloc(sizeof(PortControlID) * maxCount);
+        }
+        if (!isSourcePort(info, portIndex)) {
+            type = PORT_CONTROL_TYPE_PLAY;
+            // add master mute control
+            createPortControl(info, creator, portIndex,
+                              type | PORT_CONTROL_TYPE_OUTPUT_MUTED,
+                              controls, &controlCount);
+            addAllControls(info, creator, controls, &controlCount);
+#ifdef SOLARIS7_COMPATIBLE
+            selectable = info->audioInfo.play.avail_ports & targetPorts[info->ports[portIndex]];
+#else
+            selectable = info->audioInfo.play.mod_ports & targetPorts[info->ports[portIndex]];
+#endif
+        } else {
+            type = PORT_CONTROL_TYPE_RECORD;
+#ifdef SOLARIS7_COMPATIBLE
+            selectable = info->audioInfo.record.avail_ports & sourcePorts[info->ports[portIndex]];
+#else
+            selectable = info->audioInfo.record.mod_ports & sourcePorts[info->ports[portIndex]];
+#endif
+        }
+        // add a mixer strip with volume, ...
+        createPortControl(info, creator, portIndex,
+                          type | PORT_CONTROL_TYPE_GAIN,
+                          controls, &controlCount);
+        // ... balance, ...
+        createPortControl(info, creator, portIndex,
+                          type | PORT_CONTROL_TYPE_BALANCE,
+                          controls, &controlCount);
+        // ... and select control (if not always on)...
+        if (selectable) {
+            createPortControl(info, creator, portIndex,
+                              type | PORT_CONTROL_TYPE_SELECT_PORT,
+                              controls, &controlCount);
+        }
+        // ... packaged in a compound control.
+        addCompoundControl(info, creator, getPortName(info, portIndex), controls, &controlCount);
+
+        if (type == PORT_CONTROL_TYPE_PLAY) {
+            // add a single strip for source ports with monitor gain
+            createPortControl(info, creator, portIndex,
+                              type | PORT_CONTROL_TYPE_MONITOR_GAIN,
+                              controls, &controlCount);
+            // also in a compound control
+            addCompoundControl(info, creator, MONITOR_GAIN_STRING, controls, &controlCount);
+        }
+    }
+    TRACE0("< PORT_getControls\n");
+}
+
+INT32 PORT_GetIntValue(void* controlIDV) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+
+    AUDIO_INITINFO(&audioInfo);
+    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
+        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+            prinfo = &(audioInfo.play);
+        } else {
+            prinfo = &(audioInfo.record);
+        }
+        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+        case PORT_CONTROL_TYPE_SELECT_PORT:
+            return (prinfo->port & controlID->port)?TRUE:FALSE;
+        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
+            return (audioInfo.output_muted)?TRUE:FALSE;
+        default:
+            ERROR1("PORT_GetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        }
+    }
+    ERROR0("PORT_GetIntValue: Could not ioctl!\n");
+    return 0;
+}
+
+void PORT_SetIntValue(void* controlIDV, INT32 value) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+    int setPort;
+
+    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+        prinfo = &(audioInfo.play);
+    } else {
+        prinfo = &(audioInfo.record);
+    }
+    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+    case PORT_CONTROL_TYPE_SELECT_PORT:
+        // first try to just add this port. if that fails, set ONLY to this port.
+        AUDIO_INITINFO(&audioInfo);
+        if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
+            if (value) {
+                setPort = (prinfo->port | controlID->port);
+            } else {
+                setPort = (prinfo->port - controlID->port);
+            }
+            AUDIO_INITINFO(&audioInfo);
+            prinfo->port = setPort;
+            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+                // didn't work. Either this line doesn't support to select several
+                // ports at once (e.g. record), or a real error
+                if (value) {
+                    // set to ONLY this port (and disable any other currently selected ports)
+                    AUDIO_INITINFO(&audioInfo);
+                    prinfo->port = controlID->port;
+                    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+                        ERROR2("Error setting output select port %d to port %d!\n", controlID->port, controlID->port);
+                    }
+                } else {
+                    // assume it's an error
+                    ERROR2("Error setting output select port %d to port %d!\n", controlID->port, setPort);
+                }
+            }
+            break;
+        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
+            AUDIO_INITINFO(&audioInfo);
+            audioInfo.output_muted = (value?TRUE:FALSE);
+            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+                ERROR2("Error setting output muted on port %d to %d!\n", controlID->port, value);
+            }
+            break;
+        default:
+            ERROR1("PORT_SetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        }
+    }
+}
+
+float PORT_GetFloatValue(void* controlIDV) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+
+    AUDIO_INITINFO(&audioInfo);
+    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
+        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+            prinfo = &(audioInfo.play);
+        } else {
+            prinfo = &(audioInfo.record);
+        }
+        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+        case PORT_CONTROL_TYPE_GAIN:
+            return ((float) (prinfo->gain - AUDIO_MIN_GAIN))
+                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
+        case PORT_CONTROL_TYPE_BALANCE:
+            return ((float) ((prinfo->balance - AUDIO_LEFT_BALANCE - AUDIO_MID_BALANCE) << 1))
+                / ((float) (AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE));
+        case PORT_CONTROL_TYPE_MONITOR_GAIN:
+            return ((float) (audioInfo.monitor_gain - AUDIO_MIN_GAIN))
+                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
+        default:
+            ERROR1("PORT_GetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        }
+    }
+    ERROR0("PORT_GetFloatValue: Could not ioctl!\n");
+    return 0.0f;
+}
+
+void PORT_SetFloatValue(void* controlIDV, float value) {
+    PortControlID* controlID = (PortControlID*) controlIDV;
+    audio_info_t audioInfo;
+    audio_prinfo_t* prinfo;
+
+    AUDIO_INITINFO(&audioInfo);
+
+    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
+        prinfo = &(audioInfo.play);
+    } else {
+        prinfo = &(audioInfo.record);
+    }
+    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
+    case PORT_CONTROL_TYPE_GAIN:
+        prinfo->gain = AUDIO_MIN_GAIN
+            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
+        break;
+    case PORT_CONTROL_TYPE_BALANCE:
+        prinfo->balance =  AUDIO_LEFT_BALANCE + AUDIO_MID_BALANCE
+            + ((int) (value * ((float) ((AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE) >> 1))) + 0.5f);
+        break;
+    case PORT_CONTROL_TYPE_MONITOR_GAIN:
+        audioInfo.monitor_gain = AUDIO_MIN_GAIN
+            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
+        break;
+    default:
+        ERROR1("PORT_SetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
+        return;
+    }
+    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
+        ERROR0("PORT_SetFloatValue: Could not ioctl!\n");
+    }
+}
+
+#endif // USE_PORTS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.c	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2002, 2007, 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 USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_SolarisOS_Utils.h"
+
+#define MAX_AUDIO_DEVICES 20
+
+// not thread safe...
+static AudioDevicePath globalADPaths[MAX_AUDIO_DEVICES];
+static int globalADCount = -1;
+static int globalADCacheTime = -1;
+/* how many seconds do we cache devices */
+#define AD_CACHE_TIME 30
+
+// return seconds
+long getTimeInSeconds() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec;
+}
+
+
+int getAudioDeviceCount() {
+    int count = MAX_AUDIO_DEVICES;
+
+    getAudioDevices(globalADPaths, &count);
+    return count;
+}
+
+/* returns TRUE if the path exists at all */
+int addAudioDevice(char* path, AudioDevicePath* adPath, int* count) {
+    int i;
+    int found = 0;
+    int fileExists = 0;
+    // not thread safe...
+    static struct stat statBuf;
+
+    // get stats on the file
+    if (stat(path, &statBuf) == 0) {
+        // file exists.
+        fileExists = 1;
+        // If it is not yet in the adPath array, add it to the array
+        for (i = 0; i < *count; i++) {
+            if (adPath[i].st_ino == statBuf.st_ino
+                && adPath[i].st_dev == statBuf.st_dev) {
+                found = 1;
+                break;
+            }
+        }
+        if (!found) {
+            adPath[*count].st_ino = statBuf.st_ino;
+            adPath[*count].st_dev = statBuf.st_dev;
+            strncpy(adPath[*count].path, path, MAX_NAME_LENGTH);
+            adPath[*count].path[MAX_NAME_LENGTH - 1] = 0;
+            (*count)++;
+            TRACE1("Added audio device %s\n", path);
+        }
+    }
+    return fileExists;
+}
+
+
+void getAudioDevices(AudioDevicePath* adPath, int* count) {
+    int maxCount = *count;
+    char* audiodev;
+    char devsound[15];
+    int i;
+    long timeInSeconds = getTimeInSeconds();
+
+    if (globalADCount < 0
+        || (getTimeInSeconds() - globalADCacheTime) > AD_CACHE_TIME
+        || (adPath != globalADPaths)) {
+        *count = 0;
+        // first device, if set, is AUDIODEV variable
+        audiodev = getenv("AUDIODEV");
+        if (audiodev != NULL && audiodev[0] != 0) {
+            addAudioDevice(audiodev, adPath, count);
+        }
+        // then try /dev/audio
+        addAudioDevice("/dev/audio", adPath, count);
+        // then go through all of the /dev/sound/? devices
+        for (i = 0; i < 100; i++) {
+            sprintf(devsound, "/dev/sound/%d", i);
+            if (!addAudioDevice(devsound, adPath, count)) {
+                break;
+            }
+        }
+        if (adPath == globalADPaths) {
+            /* commit cache */
+            globalADCount = *count;
+            /* set cache time */
+            globalADCacheTime = timeInSeconds;
+        }
+    } else {
+        /* return cache */
+        *count = globalADCount;
+    }
+    // that's it
+}
+
+int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames) {
+    int count = MAX_AUDIO_DEVICES;
+    int ret = 0;
+
+    getAudioDevices(globalADPaths, &count);
+    if (index>=0 && index < count) {
+        ret = getAudioDeviceDescription(globalADPaths[index].path, adDesc, getNames);
+    }
+    return ret;
+}
+
+int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames) {
+    int fd;
+    int mixerMode;
+    int len;
+    audio_info_t info;
+    audio_device_t deviceInfo;
+
+    strncpy(adDesc->path, path, MAX_NAME_LENGTH);
+    adDesc->path[MAX_NAME_LENGTH] = 0;
+    strcpy(adDesc->pathctl, adDesc->path);
+    strcat(adDesc->pathctl, "ctl");
+    strcpy(adDesc->name, adDesc->path);
+    adDesc->vendor[0] = 0;
+    adDesc->version[0] = 0;
+    adDesc->description[0] = 0;
+    adDesc->maxSimulLines = 1;
+
+    // try to open the pseudo device and get more information
+    fd = open(adDesc->pathctl, O_WRONLY | O_NONBLOCK);
+    if (fd >= 0) {
+        close(fd);
+        if (getNames) {
+            fd = open(adDesc->pathctl, O_RDONLY);
+            if (fd >= 0) {
+                if (ioctl(fd, AUDIO_GETDEV, &deviceInfo) >= 0) {
+                    strncpy(adDesc->vendor, deviceInfo.name, MAX_AUDIO_DEV_LEN);
+                    adDesc->vendor[MAX_AUDIO_DEV_LEN] = 0;
+                    strncpy(adDesc->version, deviceInfo.version, MAX_AUDIO_DEV_LEN);
+                    adDesc->version[MAX_AUDIO_DEV_LEN] = 0;
+                    /* add config string to the dev name
+                     * creates a string like "/dev/audio (onboard1)"
+                     */
+                    len = strlen(adDesc->name) + 1;
+                    if (MAX_NAME_LENGTH - len > 3) {
+                        strcat(adDesc->name, " (");
+                        strncat(adDesc->name, deviceInfo.config, MAX_NAME_LENGTH - len);
+                        strcat(adDesc->name, ")");
+                    }
+                    adDesc->name[MAX_NAME_LENGTH-1] = 0;
+                }
+                if (ioctl(fd, AUDIO_MIXERCTL_GET_MODE, &mixerMode) >= 0) {
+                    if (mixerMode == AM_MIXER_MODE) {
+                        TRACE1(" getAudioDeviceDescription: %s is in mixer mode\n", adDesc->path);
+                        adDesc->maxSimulLines = -1;
+                    }
+                } else {
+                    ERROR1("ioctl AUDIO_MIXERCTL_GET_MODE failed on %s!\n", adDesc->path);
+                }
+                close(fd);
+            } else {
+                ERROR1("could not open %s!\n", adDesc->pathctl);
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.h	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+#include <Utilities.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+/* does not work on Solaris 2.7 */
+#include <sys/audio.h>
+#include <sys/mixer.h>
+#include <sys/types.h>
+#ifndef __linux__
+#include <stropts.h>
+#endif
+#include <sys/conf.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifndef PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
+#define PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
+
+/* defines for Solaris 2.7
+   #ifndef AUDIO_AUX1_OUT
+   #define AUDIO_AUX1_OUT   (0x08)  // output to aux1 out
+   #define AUDIO_AUX2_OUT   (0x10)  // output to aux2 out
+   #define AUDIO_SPDIF_OUT  (0x20)  // output to SPDIF port
+   #define AUDIO_AUX1_IN    (0x08)    // input from aux1 in
+   #define AUDIO_AUX2_IN    (0x10)    // input from aux2 in
+   #define AUDIO_SPDIF_IN   (0x20)    // input from SPDIF port
+   #endif
+*/
+
+/* input from Codec inter. loopback */
+#ifndef AUDIO_CODEC_LOOPB_IN
+#define AUDIO_CODEC_LOOPB_IN       (0x40)
+#endif
+
+
+#define MAX_NAME_LENGTH 300
+
+typedef struct tag_AudioDevicePath {
+    char path[MAX_NAME_LENGTH];
+    ino_t st_ino; // inode number to detect duplicate devices
+    dev_t st_dev; // device ID to detect duplicate audio devices
+} AudioDevicePath;
+
+typedef struct tag_AudioDeviceDescription {
+    INT32 maxSimulLines;
+    char path[MAX_NAME_LENGTH+1];
+    char pathctl[MAX_NAME_LENGTH+4];
+    char name[MAX_NAME_LENGTH+1];
+    char vendor[MAX_NAME_LENGTH+1];
+    char version[MAX_NAME_LENGTH+1];
+    char description[MAX_NAME_LENGTH+1];
+} AudioDeviceDescription;
+
+int getAudioDeviceCount();
+
+/*
+ * adPath is an array of AudioDevicePath structures
+ * count contains initially the number of elements in adPath
+ *       and will be set to the returned number of paths.
+ */
+void getAudioDevices(AudioDevicePath* adPath, int* count);
+
+/*
+ * fills adDesc from the audio device given in path
+ * returns 0 if an error occurred
+ * if getNames is 0, only path and pathctl are filled
+ */
+int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames);
+int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames);
+
+
+#endif // PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-//#define USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-
-static void alsaDebugOutput(const char *file, int line, const char *function, int err, const char *fmt, ...) {
-#ifdef USE_ERROR
-    va_list args;
-    va_start(args, fmt);
-    printf("%s:%d function %s: error %d: %s\n", file, line, function, err, snd_strerror(err));
-    if (strlen(fmt) > 0) {
-        vprintf(fmt, args);
-    }
-    va_end(args);
-#endif
-}
-
-static int alsa_inited = 0;
-static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
-static int alsa_enumerate_midi_subdevices = FALSE; // default: no
-
-void initAlsaSupport() {
-    char* enumerate;
-    if (!alsa_inited) {
-        alsa_inited = TRUE;
-        snd_lib_error_set_handler(&alsaDebugOutput);
-
-        enumerate = getenv(ENV_ENUMERATE_PCM_SUBDEVICES);
-        if (enumerate != NULL && strlen(enumerate) > 0
-            && (enumerate[0] != 'f')   // false
-            && (enumerate[0] != 'F')   // False
-            && (enumerate[0] != 'n')   // no
-            && (enumerate[0] != 'N')) { // NO
-            alsa_enumerate_pcm_subdevices = TRUE;
-        }
-#ifdef ALSA_MIDI_ENUMERATE_SUBDEVICES
-        alsa_enumerate_midi_subdevices = TRUE;
-#endif
-    }
-}
-
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi) {
-    initAlsaSupport();
-    return isMidi ? alsa_enumerate_midi_subdevices
-                  : alsa_enumerate_pcm_subdevices;
-}
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice) {
-    return (((card & 0x3FF) << 20) | ((device & 0x3FF) << 10)
-           | (subdevice & 0x3FF)) + 1;
-}
-
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi) {
-    deviceID--;
-    *card = (deviceID >> 20) & 0x3FF;
-    *device = (deviceID >> 10) & 0x3FF;
-    if (needEnumerateSubdevices(isMidi)) {
-        *subdevice = deviceID  & 0x3FF;
-    } else {
-        *subdevice = -1; // ALSA will choose any subdevices
-    }
-}
-
-
-void getDeviceString(char* buffer, int card, int device, int subdevice,
-                     int usePlugHw, int isMidi) {
-    if (needEnumerateSubdevices(isMidi)) {
-        sprintf(buffer, "%s:%d,%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device, subdevice);
-    } else {
-        sprintf(buffer, "%s:%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device);
-    }
-}
-
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi) {
-    int card, device, subdevice;
-
-    if (deviceID == ALSA_DEFAULT_DEVICE_ID) {
-        strcpy(buffer, ALSA_DEFAULT_DEVICE_NAME);
-    } else {
-        decodeDeviceID(deviceID, &card, &device, &subdevice, isMidi);
-        getDeviceString(buffer, card, device, subdevice, usePlugHw, isMidi);
-    }
-}
-
-
-static int hasGottenALSAVersion = FALSE;
-#define ALSAVersionString_LENGTH 200
-static char ALSAVersionString[ALSAVersionString_LENGTH];
-
-void getALSAVersion(char* buffer, int len) {
-    if (!hasGottenALSAVersion) {
-        // get alsa version from proc interface
-        FILE* file;
-        int curr, len, totalLen, inVersionString;
-        file = fopen(ALSA_VERSION_PROC_FILE, "r");
-        ALSAVersionString[0] = 0;
-        if (file) {
-            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
-                // parse for version number
-                totalLen = strlen(ALSAVersionString);
-                inVersionString = FALSE;
-                len = 0;
-                curr = 0;
-                while (curr < totalLen) {
-                    if (!inVersionString) {
-                        // is this char the beginning of a version string ?
-                        if (ALSAVersionString[curr] >= '0'
-                            && ALSAVersionString[curr] <= '9') {
-                            inVersionString = TRUE;
-                        }
-                    }
-                    if (inVersionString) {
-                        // the version string ends with white space
-                        if (ALSAVersionString[curr] <= 32) {
-                            break;
-                        }
-                        if (curr != len) {
-                            // copy this char to the beginning of the string
-                            ALSAVersionString[len] = ALSAVersionString[curr];
-                        }
-                        len++;
-                    }
-                    curr++;
-                }
-                // remove trailing dots
-                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
-                    len--;
-                }
-                // null terminate
-                ALSAVersionString[len] = 0;
-            }
-            fclose(file);
-            hasGottenALSAVersion = TRUE;
-        }
-    }
-    strncpy(buffer, ALSAVersionString, len);
-}
-
-
-/* end */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_CommonUtils.h	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2003, 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 <alsa/asoundlib.h>
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_BSDOS_ALSA_COMMONUTILS_H_INCLUDED
-#define PLATFORM_API_BSDOS_ALSA_COMMONUTILS_H_INCLUDED
-
-#define ALSA_VERSION_PROC_FILE "/proc/asound/version"
-#define ALSA_HARDWARE "hw"
-#define ALSA_HARDWARE_CARD ALSA_HARDWARE":%d"
-#define ALSA_HARDWARE_DEVICE ALSA_HARDWARE_CARD",%d"
-#define ALSA_HARDWARE_SUBDEVICE ALSA_HARDWARE_DEVICE",%d"
-
-#define ALSA_PLUGHARDWARE "plughw"
-#define ALSA_DEFAULT_DEVICE_NAME "default"
-
-#define ALSA_DEFAULT_DEVICE_ID (0)
-
-#define ALSA_PCM     (0)
-#define ALSA_RAWMIDI (1)
-
-// for use in info objects
-#define ALSA_VENDOR "ALSA (http://www.alsa-project.org)"
-
-// Environment variable for inclusion of subdevices in device listing.
-// If this variable is unset or "no", then subdevices are ignored, and
-// it's ALSA's choice which one to use (enables hardware mixing)
-#define ENV_ENUMERATE_PCM_SUBDEVICES "ALSA_ENUMERATE_PCM_SUBDEVICES"
-
-// if defined, subdevices are listed.
-//#undef ALSA_MIDI_ENUMERATE_SUBDEVICES
-#define ALSA_MIDI_ENUMERATE_SUBDEVICES
-
-// must be called before any ALSA calls
-void initAlsaSupport();
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi);
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice);
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi);
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi);
-
-void getALSAVersion(char* buffer, int len);
-
-
-#endif // PLATFORM_API_BSDOS_ALSA_COMMONUTILS_H_INCLUDED
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiIn.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_IN == TRUE
-
-
-#include <alsa/asoundlib.h>
-#include "PlatformMidi.h"
-#include "PLATFORM_API_BsdOS_ALSA_MidiUtils.h"
-#if defined(i586)
-#include <sys/utsname.h>
-#endif
-
-/*
- * Helper methods
- */
-
-static inline UINT32 packMessage(int status, int data1, int data2) {
-    return ((status & 0xFF) | ((data1 & 0xFF) << 8) | ((data2 & 0xFF) << 16));
-}
-
-
-static void setShortMessage(MidiMessage* message,
-                            int status, int data1, int data2) {
-    message->type = SHORT_MESSAGE;
-    message->data.s.packedMsg = packMessage(status, data1, data2);
-}
-
-
-static void setRealtimeMessage(MidiMessage* message, int status) {
-    setShortMessage(message, status, 0, 0);
-}
-
-
-static void set14bitMessage(MidiMessage* message, int status, int value) {
-    TRACE3("14bit value: %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    value &= 0x3FFF;
-    TRACE3("14bit value (2): %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    setShortMessage(message, status,
-                    value & 0x7F,
-                    (value >> 7) & 0x7F);
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI in functions declared in PlatformMidi.h
- */
-
-char* MIDI_IN_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-INT32 MIDI_IN_GetNumDevices() {
-/* Workaround for 6842956: 32bit app on 64bit bsd
- * gets assertion failure trying to open midiIn ports.
- * Untill the issue is fixed in ALSA
- * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
- * report no midi in devices in the configuration.
- */
-#if defined(i586)
-    static int jre32onbsd64 = -1;
-    if (jre32onbsd64 < 0) {
-        jre32onbsd64 = 0;
-        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
-         * environment variable.
-         */
-        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
-            struct utsname u;
-            jre32onbsd64 = 0;
-            if (uname(&u) == 0) {
-                if (strstr(u.machine, "64") != NULL) {
-                    TRACE0("jre32 on bsd64 detected - report no midiIn devices\n");
-                    jre32onbsd64 = 1;
-                }
-            }
-        }
-    }
-    if (jre32onbsd64) {
-        return 0;
-    }
-#endif
-
-    TRACE0("MIDI_IN_GetNumDevices()\n");
-
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
-}
-
-
-INT32 MIDI_IN_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceName(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVendor(deviceIndex, name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceDescription(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                       name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVersion(deviceIndex, name, nameLength);
-    return ret;
-}
-
-/*************************************************************************/
-
-INT32 MIDI_IN_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_OpenDevice\n");
-    ret = openMidiDevice(SND_RAWMIDI_STREAM_INPUT, deviceIndex, handle);
-    TRACE1("< MIDI_IN_OpenDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_CloseDevice\n");
-    ret = closeMidiDevice(handle);
-    TRACE1("< MIDI_IN_CloseDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StartDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StopDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-/* read the next message from the queue */
-MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) {
-    snd_seq_event_t alsa_message;
-    MidiMessage* jdk_message;
-    int err;
-    char buffer[1];
-    int status;
-
-    TRACE0("> MIDI_IN_GetMessage\n");
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): native handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->platformData) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): platformData is NULL\n");
-        return NULL;
-    }
-
-    /* For MIDI In, the device is left in non blocking mode. So if there is
-       no data from the device, snd_rawmidi_read() returns with -11 (EAGAIN).
-       This results in jumping back to the Java layer. */
-    while (TRUE) {
-        TRACE0("before snd_rawmidi_read()\n");
-        err = snd_rawmidi_read((snd_rawmidi_t*) handle->deviceHandle, buffer, 1);
-        TRACE0("after snd_rawmidi_read()\n");
-        if (err != 1) {
-            ERROR2("< ERROR: MIDI_IN_GetMessage(): snd_rawmidi_read() returned %d : %s\n", err, snd_strerror(err));
-            return NULL;
-        }
-        // printf("received byte: %d\n", buffer[0]);
-        err = snd_midi_event_encode_byte((snd_midi_event_t*) handle->platformData,
-                                         (int) buffer[0],
-                                         &alsa_message);
-        if (err == 1) {
-            break;
-        } else if (err < 0) {
-            ERROR1("< ERROR: MIDI_IN_GetMessage(): snd_midi_event_encode_byte() returned %d\n", err);
-            return NULL;
-        }
-    }
-    jdk_message = (MidiMessage*) calloc(sizeof(MidiMessage), 1);
-    if (!jdk_message) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-        return NULL;
-    }
-    // TODO: tra
-    switch (alsa_message.type) {
-    case SND_SEQ_EVENT_NOTEON:
-    case SND_SEQ_EVENT_NOTEOFF:
-    case SND_SEQ_EVENT_KEYPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_KEYPRESS) ? 0xA0 :
-            (alsa_message.type == SND_SEQ_EVENT_NOTEON) ? 0x90 : 0x80;
-        status |= alsa_message.data.note.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.note.note,
-                        alsa_message.data.note.velocity);
-        break;
-
-    case SND_SEQ_EVENT_CONTROLLER:
-        status = 0xB0 | alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.param,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_PGMCHANGE:
-    case SND_SEQ_EVENT_CHANPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_PGMCHANGE) ? 0xC0 : 0xD0;
-        status |= alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.value, 0);
-        break;
-
-    case SND_SEQ_EVENT_PITCHBEND:
-        status = 0xE0 | alsa_message.data.control.channel;
-        // $$mp 2003-09-23:
-        // possible hack to work around a bug in ALSA. Necessary for
-        // ALSA 0.9.2. May be fixed in newer versions of ALSA.
-        // alsa_message.data.control.value ^= 0x2000;
-        // TRACE1("pitchbend value: %d\n", alsa_message.data.control.value);
-        set14bitMessage(jdk_message, status,
-                        alsa_message.data.control.value);
-        break;
-
-        /* System exclusive messages */
-
-    case SND_SEQ_EVENT_SYSEX:
-        jdk_message->type = LONG_MESSAGE;
-        jdk_message->data.l.size = alsa_message.data.ext.len;
-        jdk_message->data.l.data = malloc(alsa_message.data.ext.len);
-        if (jdk_message->data.l.data == NULL) {
-            ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-            free(jdk_message);
-            jdk_message = NULL;
-        } else {
-            memcpy(jdk_message->data.l.data, alsa_message.data.ext.ptr, alsa_message.data.ext.len);
-        }
-        break;
-
-        /* System common messages */
-
-    case SND_SEQ_EVENT_QFRAME:
-        setShortMessage(jdk_message, 0xF1,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_SONGPOS:
-        set14bitMessage(jdk_message, 0xF2,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_SONGSEL:
-        setShortMessage(jdk_message, 0xF3,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_TUNE_REQUEST:
-        setRealtimeMessage(jdk_message, 0xF6);
-        break;
-
-        /* System realtime messages */
-
-    case SND_SEQ_EVENT_CLOCK:
-        setRealtimeMessage(jdk_message, 0xF8);
-        break;
-
-    case SND_SEQ_EVENT_START:
-        setRealtimeMessage(jdk_message, 0xFA);
-        break;
-
-    case SND_SEQ_EVENT_CONTINUE:
-        setRealtimeMessage(jdk_message, 0xFB);
-        break;
-
-    case SND_SEQ_EVENT_STOP:
-        setRealtimeMessage(jdk_message, 0xFC);
-        break;
-
-    case SND_SEQ_EVENT_SENSING:
-        setRealtimeMessage(jdk_message, 0xFE);
-        break;
-
-    case SND_SEQ_EVENT_RESET:
-        setRealtimeMessage(jdk_message, 0xFF);
-        break;
-
-    default:
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): unhandled ALSA MIDI message type\n");
-        free(jdk_message);
-        jdk_message = NULL;
-
-    }
-
-    // set timestamp
-    if (jdk_message != NULL) {
-        jdk_message->timestamp = getMidiTimestamp(handle);
-    }
-    TRACE1("< MIDI_IN_GetMessage: returning %p\n", jdk_message);
-    return jdk_message;
-}
-
-
-void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg) {
-    if (!msg) {
-        ERROR0("< ERROR: MIDI_IN_ReleaseMessage(): message is NULL\n");
-        return;
-    }
-    if (msg->type == LONG_MESSAGE && msg->data.l.data) {
-        free(msg->data.l.data);
-    }
-    free(msg);
-}
-
-#endif /* USE_PLATFORM_MIDI_IN */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiOut.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_OUT == TRUE
-
-#include <alsa/asoundlib.h>
-#include "PlatformMidi.h"
-#include "PLATFORM_API_BsdOS_ALSA_MidiUtils.h"
-
-
-
-static int CHANNEL_MESSAGE_LENGTH[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 3, 3, 2, 2, 3 };
-/*                                 8x 9x Ax Bx Cx Dx Ex */
-
-static int SYSTEM_MESSAGE_LENGTH[] = {
-    -1, 2, 3, 2, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1 };
-/*  F0 F1 F2 F3  F4  F5 F6 F7 F8  F9 FA FB FC  FD FE FF */
-
-
-// the returned length includes the status byte.
-// for illegal messages, -1 is returned.
-static int getShortMessageLength(int status) {
-        int     dataLength = 0;
-        if (status < 0xF0) { // channel voice message
-                dataLength = CHANNEL_MESSAGE_LENGTH[(status >> 4) & 0xF];
-        } else {
-                dataLength = SYSTEM_MESSAGE_LENGTH[status & 0xF];
-        }
-        return dataLength;
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI out functions declared in PlatformMidi.h
- */
-char* MIDI_OUT_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-
-INT32 MIDI_OUT_GetNumDevices() {
-    TRACE0("MIDI_OUT_GetNumDevices()\n");
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_OUTPUT);
-}
-
-
-INT32 MIDI_OUT_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceName()\n");
-    return getMidiDeviceName(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                             name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVendor()\n");
-    return getMidiDeviceVendor(deviceIndex, name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceDescription()\n");
-    return getMidiDeviceDescription(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                                    name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVersion()\n");
-    return getMidiDeviceVersion(deviceIndex, name, nameLength);
-}
-
-
-/* *************************** MidiOutDevice implementation *************** */
-
-INT32 MIDI_OUT_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    TRACE1("MIDI_OUT_OpenDevice(): deviceIndex: %d\n", (int) deviceIndex);
-    return openMidiDevice(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex, handle);
-}
-
-
-INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_OUT_CloseDevice()\n");
-    return closeMidiDevice(handle);
-}
-
-
-INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg,
-                                UINT32 timestamp) {
-    int err;
-    int status;
-    int data1;
-    int data2;
-    char buffer[3];
-
-    TRACE2("> MIDI_OUT_SendShortMessage() %x, time: %u\n", packedMsg, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendShortMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    status = (packedMsg & 0xFF);
-    buffer[0] = (char) status;
-    buffer[1]  = (char) ((packedMsg >> 8) & 0xFF);
-    buffer[2]  = (char) ((packedMsg >> 16) & 0xFF);
-    TRACE4("status: %d, data1: %d, data2: %d, length: %d\n", (int) buffer[0], (int) buffer[1], (int) buffer[2], getShortMessageLength(status));
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle, buffer, getShortMessageLength(status));
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendShortMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendShortMessage()\n");
-    return err;
-}
-
-
-INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data,
-                               UINT32 size, UINT32 timestamp) {
-    int err;
-
-    TRACE2("> MIDI_OUT_SendLongMessage() size %u, time: %u\n", (unsigned int) size, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!data) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): data is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle,
-                            data, size);
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendLongMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendLongMessage()\n");
-    return err;
-}
-
-
-#endif /* USE_PLATFORM_MIDI_OUT */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,481 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_MidiUtils.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-#include <string.h>
-#include <sys/time.h>
-
-static INT64 getTimeInMicroseconds() {
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-    return (tv.tv_sec * 1000000UL) + tv.tv_usec;
-}
-
-
-const char* getErrorStr(INT32 err) {
-        return snd_strerror((int) err);
-}
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID,
-                                 snd_rawmidi_info_t* rawmidi_info,
-                                 snd_ctl_card_info_t* cardinfo,
-                                 void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-static int iterateRawmidiDevices(snd_rawmidi_stream_t direction,
-                                 DeviceIteratorPtr iterator,
-                                 void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_rawmidi_t *rawmidi;
-    snd_rawmidi_info_t *rawmidi_info;
-    snd_ctl_card_info_t *card_info, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_rawmidi_info_malloc(&rawmidi_info);
-    snd_ctl_card_info_malloc(&card_info);
-
-    // 1st try "default" device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("ERROR: iterateRawmidiDevices(): direction is neither"
-               " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n",
-               snd_strerror(err));
-    } else {
-        err = snd_rawmidi_info(rawmidi, rawmidi_info);
-
-        snd_rawmidi_close(rawmidi);
-        if (err < 0) {
-            ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_rawmidi_info_get_card(rawmidi_info);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, card_info) >= 0) {
-                        defcardinfo = card_info;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call calback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    TRACE0("testing for cards...\n");
-    if (snd_card_next(&card) >= 0) {
-        TRACE1("Found card %d\n", card);
-        while (doContinue && (card >= 0)) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                TRACE0("snd_ctl_open() SUCCESS\n");
-                err = snd_ctl_card_info(handle, card_info);
-                if (err < 0) {
-                    ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err));
-                } else {
-                    TRACE0("snd_ctl_card_info() SUCCESS\n");
-                    dev = -1;
-                    while (doContinue) {
-                        if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) {
-                            ERROR0("snd_ctl_rawmidi_next_device\n");
-                        }
-                        TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n");
-                        if (dev < 0) {
-                            break;
-                        }
-                        snd_rawmidi_info_set_device(rawmidi_info, dev);
-                        snd_rawmidi_info_set_subdevice(rawmidi_info, 0);
-                        snd_rawmidi_info_set_stream(rawmidi_info, direction);
-                        err = snd_ctl_rawmidi_info(handle, rawmidi_info);
-                        TRACE0("after snd_ctl_rawmidi_info()\n");
-                        if (err < 0) {
-                            if (err != -ENOENT) {
-                                ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err));
-                            }
-                        } else {
-                            TRACE0("snd_ctl_rawmidi_info() SUCCESS\n");
-                            subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI)
-                                ? snd_rawmidi_info_get_subdevices_count(rawmidi_info)
-                                : 1;
-                            if (iterator!=NULL) {
-                                for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                    TRACE3("  Iterating %d,%d,%d\n", card, dev, subDev);
-                                    deviceID = encodeDeviceID(card, dev, subDev);
-                                    doContinue = (*iterator)(deviceID, rawmidi_info,
-                                                             card_info, userData);
-                                    count++;
-                                    TRACE0("returned from iterator\n");
-                                    if (!doContinue) {
-                                        break;
-                                    }
-                                }
-                            } else {
-                                count += subdeviceCount;
-                            }
-                        }
-                    } // of while(doContinue)
-                }
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    } else {
-        ERROR0("No cards found!\n");
-    }
-    snd_ctl_card_info_free(card_info);
-    snd_rawmidi_info_free(rawmidi_info);
-    return count;
-}
-
-
-
-int getMidiDeviceCount(snd_rawmidi_stream_t direction) {
-    int deviceCount;
-    TRACE0("> getMidiDeviceCount()\n");
-    initAlsaSupport();
-    deviceCount = iterateRawmidiDevices(direction, NULL, NULL);
-    TRACE0("< getMidiDeviceCount()\n");
-    return deviceCount;
-}
-
-
-
-/*
-  userData is assumed to be a pointer to ALSA_MIDIDeviceDescription.
-  ALSA_MIDIDeviceDescription->index has to be set to the index of the device
-  we want to get information of before this method is called the first time via
-  iterateRawmidiDevices(). On each call of this method,
-  ALSA_MIDIDeviceDescription->index is decremented. If it is equal to zero,
-  we have reached the desired device, so action is taken.
-  So after successful completion of iterateRawmidiDevices(),
-  ALSA_MIDIDeviceDescription->index is zero. If it isn't, this is an
-  indication of an error.
-*/
-static int deviceInfoIterator(UINT32 deviceID, snd_rawmidi_info_t *rawmidi_info,
-                              snd_ctl_card_info_t *cardinfo, void *userData) {
-    char buffer[300];
-    ALSA_MIDIDeviceDescription* desc = (ALSA_MIDIDeviceDescription*)userData;
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("deviceInfoIterator\n");
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        desc->deviceID = deviceID;
-
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_RAWMIDI);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        desc->description[0] = 0;
-        if (cardinfo != NULL) {
-            strncpy(desc->description, snd_ctl_card_info_get_name(cardinfo),
-                    desc->strLen);
-            strncat(desc->description, ", ",
-                    desc->strLen - strlen(desc->description));
-        }
-        strncat(desc->description, snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_rawmidi_info_get_name(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        TRACE2("Returning %s, %s\n", desc->name, desc->description);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-
-static int getMIDIDeviceDescriptionByIndex(snd_rawmidi_stream_t direction,
-                                           ALSA_MIDIDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getMIDIDeviceDescriptionByIndex (index = %d)\n", desc->index);
-    iterateRawmidiDevices(direction, &deviceInfoIterator, desc);
-    return (desc->index == 0) ? MIDI_SUCCESS : MIDI_INVALID_DEVICEID;
-}
-
-
-
-int initMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc, int index) {
-    int ret = MIDI_SUCCESS;
-    desc->index = index;
-    desc->strLen = 200;
-    desc->name = (char*) calloc(desc->strLen + 1, 1);
-    desc->description = (char*) calloc(desc->strLen + 1, 1);
-    if (! desc->name ||
-        ! desc->description) {
-        ret = MIDI_OUT_OF_MEMORY;
-    }
-    return ret;
-}
-
-
-void freeMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc) {
-    if (desc->name) {
-        free(desc->name);
-    }
-    if (desc->description) {
-        free(desc->description);
-    }
-}
-
-
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index, char *name,
-                      UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    TRACE1("getMidiDeviceName: nameLength: %d\n", (int) nameLength);
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        TRACE0("getMidiDeviceName: initMIDIDeviceDescription() SUCCESS\n");
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            strncpy(name, desc.name, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength) {
-    strncpy(name, ALSA_VENDOR, nameLength - 1);
-    name[nameLength - 1] = 0;
-    return MIDI_SUCCESS;
-}
-
-
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction,
-                             int index, char *name, UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            strncpy(name, desc.description, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength) {
-    getALSAVersion(name, nameLength);
-    return MIDI_SUCCESS;
-}
-
-
-static int getMidiDeviceID(snd_rawmidi_stream_t direction, int index,
-                           UINT32* deviceID) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            // TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            *deviceID = desc.deviceID;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-/*
-  direction has to be either SND_RAWMIDI_STREAM_INPUT or
-  SND_RAWMIDI_STREAM_OUTPUT.
-  Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT
-   or a negative ALSA error code is returned.
-*/
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle) {
-    snd_rawmidi_t* native_handle;
-    snd_midi_event_t* event_parser = NULL;
-    int err;
-    UINT32 deviceID = 0;
-    char devicename[100];
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("> openMidiDevice()\n");
-
-    (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1);
-    if (!(*handle)) {
-        ERROR0("ERROR: openDevice: out of memory\n");
-        return MIDI_OUT_OF_MEMORY;
-    }
-
-    // TODO: iterate to get dev ID from index
-    err = getMidiDeviceID(direction, deviceIndex, &deviceID);
-    TRACE1("  openMidiDevice(): deviceID: %d\n", (int) deviceID);
-    getDeviceStringFromDeviceID(devicename, deviceID,
-                                usePlugHw, ALSA_RAWMIDI);
-    TRACE1("  openMidiDevice(): deviceString: %s\n", devicename);
-
-    // finally open the device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&native_handle, NULL, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &native_handle, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("  ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("<  ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err);
-        free(*handle);
-        (*handle) = NULL;
-        return err;
-    }
-    /* We opened with non-blocking behaviour to not get hung if the device
-       is used by a different process. Writing, however, should
-       be blocking. So we change it here. */
-    if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_nonblock(native_handle, 0);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-
-    (*handle)->deviceHandle = (void*) native_handle;
-    (*handle)->startTime = getTimeInMicroseconds();
-    (*handle)->platformData = event_parser;
-    TRACE0("< openMidiDevice(): succeeded\n");
-    return err;
-}
-
-
-
-INT32 closeMidiDevice(MidiDeviceHandle* handle) {
-    int err;
-
-    TRACE0("> closeMidiDevice()\n");
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle);
-    TRACE1("  snd_rawmidi_close() returns %d\n", err);
-    if (handle->platformData) {
-        snd_midi_event_free((snd_midi_event_t*) handle->platformData);
-    }
-    free(handle);
-    TRACE0("< closeMidiDevice: succeeded\n");
-    return err;
-}
-
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle) {
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    return getTimeInMicroseconds() - handle->startTime;
-}
-
-
-/* end */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_MidiUtils.h	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2003, 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 <alsa/asoundlib.h>
-#include "Utilities.h"
-#include "PlatformMidi.h"
-
-
-#ifndef PLATFORM_API_BSDOS_ALSA_MIDIUTILS_H_INCLUDED
-#define PLATFORM_API_BSDOS_ALSA_MIDIUTILS_H_INCLUDED
-
-#define EVENT_PARSER_BUFSIZE (2048)
-
-// if this is defined, use plughw: devices
-//#define ALSA_MIDI_USE_PLUGHW
-#undef ALSA_MIDI_USE_PLUGHW
-
-typedef struct tag_ALSA_MIDIDeviceDescription {
-        int index;          // in
-        int strLen;         // in
-        INT32 deviceID;    // out
-        char* name;         // out
-        char* description;  // out
-} ALSA_MIDIDeviceDescription;
-
-
-const char* getErrorStr(INT32 err);
-
-/* Returns the number of devices. */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceCount(snd_rawmidi_stream_t direction);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index,
-                      char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction, int index,
-                             char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength);
-
-// returns 0 on success, otherwise MIDI_OUT_OF_MEMORY or ALSA error code
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle);
-
-// returns 0 on success, otherwise a (negative) ALSA error code
-INT32 closeMidiDevice(MidiDeviceHandle* handle);
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle);
-
-#endif // PLATFORM_API_BSDOS_ALSA_MIDIUTILS_H_INCLUDED
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,941 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- */
-
-#define USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-#include "DirectAudio.h"
-
-#if USE_DAUDIO == TRUE
-
-// GetPosition method 1: based on how many bytes are passed to the kernel driver
-//                       + does not need much processor resources
-//                       - not very exact, "jumps"
-// GetPosition method 2: ask kernel about actual position of playback.
-//                       - very exact
-//                       - switch to kernel layer for each call
-// GetPosition method 3: use snd_pcm_avail() call - not yet in official ALSA
-// quick tests on a Pentium 200MMX showed max. 1.5% processor usage
-// for playing back a CD-quality file and printing 20x per second a line
-// on the console with the current time. So I guess performance is not such a
-// factor here.
-//#define GET_POSITION_METHOD1
-#define GET_POSITION_METHOD2
-
-
-// The default time for a period in microseconds.
-// For very small buffers, only 2 periods are used.
-#define DEFAULT_PERIOD_TIME 20000 /* 20ms */
-
-///// implemented functions of DirectAudio.h
-
-INT32 DAUDIO_GetDirectAudioDeviceCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, DirectAudioDeviceDescription* description) {
-    ALSA_AudioDeviceDescription adesc;
-
-    adesc.index = (int) mixerIndex;
-    adesc.strLen = DAUDIO_STRING_LENGTH;
-
-    adesc.maxSimultaneousLines = (int*) (&(description->maxSimulLines));
-    adesc.deviceID = &(description->deviceID);
-    adesc.name = description->name;
-    adesc.vendor = description->vendor;
-    adesc.description = description->description;
-    adesc.version = description->version;
-
-    return getAudioDeviceDescriptionByIndex(&adesc);
-}
-
-#define MAX_BIT_INDEX 6
-// returns
-// 6: for anything above 24-bit
-// 5: for 4 bytes sample size, 24-bit
-// 4: for 3 bytes sample size, 24-bit
-// 3: for 3 bytes sample size, 20-bit
-// 2: for 2 bytes sample size, 16-bit
-// 1: for 1 byte sample size, 8-bit
-// 0: for anything else
-int getBitIndex(int sampleSizeInBytes, int significantBits) {
-    if (significantBits > 24) return 6;
-    if (sampleSizeInBytes == 4 && significantBits == 24) return 5;
-    if (sampleSizeInBytes == 3) {
-        if (significantBits == 24) return 4;
-        if (significantBits == 20) return 3;
-    }
-    if (sampleSizeInBytes == 2 && significantBits == 16) return 2;
-    if (sampleSizeInBytes == 1 && significantBits == 8) return 1;
-    return 0;
-}
-
-int getSampleSizeInBytes(int bitIndex, int sampleSizeInBytes) {
-    switch(bitIndex) {
-    case 1: return 1;
-    case 2: return 2;
-    case 3: /* fall through */
-    case 4: return 3;
-    case 5: return 4;
-    }
-    return sampleSizeInBytes;
-}
-
-int getSignificantBits(int bitIndex, int significantBits) {
-    switch(bitIndex) {
-    case 1: return 8;
-    case 2: return 16;
-    case 3: return 20;
-    case 4: /* fall through */
-    case 5: return 24;
-    }
-    return significantBits;
-}
-
-void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
-    snd_pcm_t* handle;
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    snd_pcm_hw_params_t* hwParams;
-    int handledBits[MAX_BIT_INDEX+1];
-
-    int ret;
-    int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
-    int origSampleSizeInBytes, origSignificantBits;
-    unsigned int channels, minChannels, maxChannels;
-    int rate, bitIndex;
-
-    for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
-    if (openPCMfromDeviceID(deviceID, &handle, isSource, TRUE /*query hardware*/) < 0) {
-        return;
-    }
-    ret = snd_pcm_format_mask_malloc(&formatMask);
-    if (ret != 0) {
-        ERROR1("snd_pcm_format_mask_malloc returned error %d\n", ret);
-    } else {
-        ret = snd_pcm_hw_params_malloc(&hwParams);
-        if (ret != 0) {
-            ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = snd_pcm_hw_params_any(handle, hwParams);
-            /* snd_pcm_hw_params_any can return a positive value on success too */
-            if (ret < 0) {
-                 ERROR1("snd_pcm_hw_params_any returned error %d\n", ret);
-            } else {
-                /* for the logic following this code, set ret to 0 to indicate success */
-                ret = 0;
-            }
-        }
-        snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_min returned error %d\n", ret);
-            }
-        }
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_max(hwParams, &maxChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
-            }
-        }
-
-        // since we queried the hw: device, for many soundcards, it will only
-        // report the maximum number of channels (which is the only way to talk
-        // to the hw: device). Since we will, however, open the plughw: device
-        // when opening the Source/TargetDataLine, we can safely assume that
-        // also the channels 1..maxChannels are available.
-#ifdef ALSA_PCM_USE_PLUGHW
-        minChannels = 1;
-#endif
-        if (ret == 0) {
-            // plughw: supports any sample rate
-            rate = -1;
-            for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
-                if (snd_pcm_format_mask_test(formatMask, format)) {
-                    // format exists
-                    if (getFormatFromAlsaFormat(format, &origSampleSizeInBytes,
-                                                &origSignificantBits,
-                                                &isSigned, &isBigEndian, &enc)) {
-                        // now if we use plughw:, we can use any bit size below the
-                        // natively supported ones. Some ALSA drivers only support the maximum
-                        // bit size, so we add any sample rates below the reported one.
-                        // E.g. this iteration reports support for 16-bit.
-                        // getBitIndex will return 2, so it will add entries for
-                        // 16-bit (bitIndex=2) and in the next do-while loop iteration,
-                        // it will decrease bitIndex and will therefore add 8-bit support.
-                        bitIndex = getBitIndex(origSampleSizeInBytes, origSignificantBits);
-                        do {
-                            if (bitIndex == 0
-                                || bitIndex == MAX_BIT_INDEX
-                                || !handledBits[bitIndex]) {
-                                handledBits[bitIndex] = TRUE;
-                                sampleSizeInBytes = getSampleSizeInBytes(bitIndex, origSampleSizeInBytes);
-                                significantBits = getSignificantBits(bitIndex, origSignificantBits);
-                                if (maxChannels - minChannels > MAXIMUM_LISTED_CHANNELS) {
-                                    // avoid too many channels explicitly listed
-                                    // just add -1, min, and max
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          -1, -1, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * minChannels,
-                                                          minChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * maxChannels,
-                                                          maxChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                } else {
-                                    for (channels = minChannels; channels <= maxChannels; channels++) {
-                                        DAUDIO_AddAudioFormat(creator, significantBits,
-                                                              sampleSizeInBytes * channels,
-                                                              channels, rate,
-                                                              enc, isSigned, isBigEndian);
-                                    }
-                                }
-                            }
-#ifndef ALSA_PCM_USE_PLUGHW
-                            // without plugin, do not add fake formats
-                            break;
-#endif
-                        } while (--bitIndex > 0);
-                    } else {
-                        TRACE1("could not get format from alsa for format %d\n", format);
-                    }
-                } else {
-                    //TRACE1("Format %d not supported\n", format);
-                }
-            } // for loop
-            snd_pcm_hw_params_free(hwParams);
-        }
-        snd_pcm_format_mask_free(formatMask);
-    }
-    snd_pcm_close(handle);
-}
-
-/** Workaround for cr 7033899, 7030629:
- * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty
- * (just opened, underruned or already flushed).
- * Sometimes it causes PCM falls to -EBADFD error,
- * sometimes causes bufferSize change.
- * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used.
- */
-/* ******* ALSA PCM INFO ******************** */
-typedef struct tag_AlsaPcmInfo {
-    snd_pcm_t* handle;
-    snd_pcm_hw_params_t* hwParams;
-    snd_pcm_sw_params_t* swParams;
-    int bufferSizeInBytes;
-    int frameSize; // storage size in Bytes
-    unsigned int periods;
-    snd_pcm_uframes_t periodSize;
-    short int isRunning;    // see comment above
-    short int isFlushed;    // see comment above
-#ifdef GET_POSITION_METHOD2
-    // to be used exclusively by getBytePosition!
-    snd_pcm_status_t* positionStatus;
-#endif
-} AlsaPcmInfo;
-
-
-int setStartThresholdNoCommit(AlsaPcmInfo* info, int useThreshold) {
-    int ret;
-    int threshold;
-
-    if (useThreshold) {
-        // start device whenever anything is written to the buffer
-        threshold = 1;
-    } else {
-        // never start the device automatically
-        threshold = 2000000000; /* near UINT_MAX */
-    }
-    ret = snd_pcm_sw_params_set_start_threshold(info->handle, info->swParams, threshold);
-    if (ret < 0) {
-        ERROR1("Unable to set start threshold mode: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-int setStartThreshold(AlsaPcmInfo* info, int useThreshold) {
-    int ret = 0;
-
-    if (!setStartThresholdNoCommit(info, useThreshold)) {
-        ret = -1;
-    }
-    if (ret == 0) {
-        // commit it
-        ret = snd_pcm_sw_params(info->handle, info->swParams);
-        if (ret < 0) {
-            ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        }
-    }
-    return (ret == 0)?TRUE:FALSE;
-}
-
-
-// returns TRUE if successful
-int setHWParams(AlsaPcmInfo* info,
-                float sampleRate,
-                int channels,
-                int bufferSizeInFrames,
-                snd_pcm_format_t format) {
-    unsigned int rrate, periodTime, periods;
-    int ret, dir;
-    snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
-
-    /* choose all parameters */
-    ret = snd_pcm_hw_params_any(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Broken configuration: no configurations available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the interleaved read/write format */
-    ret = snd_pcm_hw_params_set_access(info->handle, info->hwParams, SND_PCM_ACCESS_RW_INTERLEAVED);
-    if (ret < 0) {
-        ERROR1("SND_PCM_ACCESS_RW_INTERLEAVED access type not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the sample format */
-    ret = snd_pcm_hw_params_set_format(info->handle, info->hwParams, format);
-    if (ret < 0) {
-        ERROR1("Sample format not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the count of channels */
-    ret = snd_pcm_hw_params_set_channels(info->handle, info->hwParams, channels);
-    if (ret < 0) {
-        ERROR2("Channels count (%d) not available: %s\n", channels, snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the stream rate */
-    rrate = (int) (sampleRate + 0.5f);
-    dir = 0;
-    ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
-    if (ret < 0) {
-        ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
-        return FALSE;
-    }
-    if ((rrate-sampleRate > 2) || (rrate-sampleRate < - 2)) {
-        ERROR2("Rate doesn't match (requested %2.2fHz, got %dHz)\n", sampleRate, rrate);
-        return FALSE;
-    }
-    /* set the buffer time */
-    ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
-    if (ret < 0) {
-        ERROR2("Unable to set buffer size to %d frames: %s\n",
-               (int) alsaBufferSizeInFrames, snd_strerror(ret));
-        return FALSE;
-    }
-    bufferSizeInFrames = (int) alsaBufferSizeInFrames;
-    /* set the period time */
-    if (bufferSizeInFrames > 1024) {
-        dir = 0;
-        periodTime = DEFAULT_PERIOD_TIME;
-        ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
-            return FALSE;
-        }
-    } else {
-        /* set the period count for very small buffer sizes to 2 */
-        dir = 0;
-        periods = 2;
-        ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
-            return FALSE;
-        }
-    }
-    /* write the parameters to device */
-    ret = snd_pcm_hw_params(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Unable to set hw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-// returns 1 if successful
-int setSWParams(AlsaPcmInfo* info) {
-    int ret;
-
-    /* get the current swparams */
-    ret = snd_pcm_sw_params_current(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to determine current swparams: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* never start the transfer automatically */
-    if (!setStartThresholdNoCommit(info, FALSE /* don't use threshold */)) {
-        return FALSE;
-    }
-
-    /* allow the transfer when at least period_size samples can be processed */
-    ret = snd_pcm_sw_params_set_avail_min(info->handle, info->swParams, info->periodSize);
-    if (ret < 0) {
-        ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* write the parameters to the playback device */
-    ret = snd_pcm_sw_params(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static snd_output_t* ALSA_OUTPUT = NULL;
-
-void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
-                  int encoding, float sampleRate, int sampleSizeInBits,
-                  int frameSize, int channels,
-                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    int dir;
-    int ret = 0;
-    AlsaPcmInfo* info = NULL;
-    /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
-    snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
-
-
-    TRACE0("> DAUDIO_Open\n");
-#ifdef USE_TRACE
-    // for using ALSA debug dump methods
-    if (ALSA_OUTPUT == NULL) {
-        snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
-    }
-#endif
-    if (channels <= 0) {
-        ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
-        return NULL;
-    }
-    info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
-    if (!info) {
-        ERROR0("Out of memory\n");
-        return NULL;
-    }
-    memset(info, 0, sizeof(AlsaPcmInfo));
-    // initial values are: stopped, flushed
-    info->isRunning = 0;
-    info->isFlushed = 1;
-
-    ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/);
-    if (ret == 0) {
-        // set to blocking mode
-        snd_pcm_nonblock(info->handle, 0);
-        ret = snd_pcm_hw_params_malloc(&(info->hwParams));
-        if (ret != 0) {
-            ERROR1("  snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = -1;
-            if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits,
-                                        isSigned, isBigEndian, encoding)) {
-                if (setHWParams(info,
-                                sampleRate,
-                                channels,
-                                bufferSizeInBytes / frameSize,
-                                format)) {
-                    info->frameSize = frameSize;
-                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
-                    if (ret < 0) {
-                        ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
-                    }
-                    snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
-                    snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
-                    info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
-                    TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
-                           (int) info->periodSize, info->periods, info->bufferSizeInBytes);
-                }
-            }
-        }
-        if (ret == 0) {
-            // set software parameters
-            ret = snd_pcm_sw_params_malloc(&(info->swParams));
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-            } else {
-                if (!setSWParams(info)) {
-                    ret = -1;
-                }
-            }
-        }
-        if (ret == 0) {
-            // prepare device
-            ret = snd_pcm_prepare(info->handle);
-            if (ret < 0) {
-                ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-            }
-        }
-
-#ifdef GET_POSITION_METHOD2
-        if (ret == 0) {
-            ret = snd_pcm_status_malloc(&(info->positionStatus));
-            if (ret != 0) {
-                ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret));
-            }
-        }
-#endif
-    }
-    if (ret != 0) {
-        DAUDIO_Close((void*) info, isSource);
-        info = NULL;
-    } else {
-        // set to non-blocking mode
-        snd_pcm_nonblock(info->handle, 1);
-        TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n",
-               (void*) info->handle);
-    }
-    return (void*) info;
-}
-
-#ifdef USE_TRACE
-void printState(snd_pcm_state_t state) {
-    if (state == SND_PCM_STATE_OPEN) {
-        TRACE0("State: SND_PCM_STATE_OPEN\n");
-    }
-    else if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("State: SND_PCM_STATE_SETUP\n");
-    }
-    else if (state == SND_PCM_STATE_PREPARED) {
-        TRACE0("State: SND_PCM_STATE_PREPARED\n");
-    }
-    else if (state == SND_PCM_STATE_RUNNING) {
-        TRACE0("State: SND_PCM_STATE_RUNNING\n");
-    }
-    else if (state == SND_PCM_STATE_XRUN) {
-        TRACE0("State: SND_PCM_STATE_XRUN\n");
-    }
-    else if (state == SND_PCM_STATE_DRAINING) {
-        TRACE0("State: SND_PCM_STATE_DRAINING\n");
-    }
-    else if (state == SND_PCM_STATE_PAUSED) {
-        TRACE0("State: SND_PCM_STATE_PAUSED\n");
-    }
-    else if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("State: SND_PCM_STATE_SUSPENDED\n");
-    }
-}
-#endif
-
-int DAUDIO_Start(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    snd_pcm_state_t state;
-
-    TRACE0("> DAUDIO_Start\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    // set start mode so that it always starts as soon as data is there
-    setStartThreshold(info, TRUE /* use threshold */);
-    state = snd_pcm_state(info->handle);
-    if (state == SND_PCM_STATE_PAUSED) {
-        // in case it was stopped previously
-        TRACE0("  Un-pausing...\n");
-        ret = snd_pcm_pause(info->handle, FALSE);
-        if (ret != 0) {
-            ERROR2("  NOTE: error in snd_pcm_pause:%d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("  Resuming...\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if ((ret != -EAGAIN) && (ret != -ENOSYS)) {
-                ERROR2("  ERROR: error in snd_pcm_resume:%d: %s\n", ret, snd_strerror(ret));
-            }
-        }
-    }
-    if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("need to call prepare again...\n");
-        // prepare device
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-        }
-    }
-    // in case there is still data in the buffers
-    ret = snd_pcm_start(info->handle);
-    if (ret != 0) {
-        if (ret != -EPIPE) {
-            ERROR2("  NOTE: error in snd_pcm_start: %d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    // set to non-blocking mode
-    ret = snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("  ERROR in snd_pcm_nonblock: %s\n", snd_strerror(ret));
-    }
-    state = snd_pcm_state(info->handle);
-#ifdef USE_TRACE
-    printState(state);
-#endif
-    ret = (state == SND_PCM_STATE_PREPARED)
-        || (state == SND_PCM_STATE_RUNNING)
-        || (state == SND_PCM_STATE_XRUN)
-        || (state == SND_PCM_STATE_SUSPENDED);
-    if (ret) {
-        info->isRunning = 1;
-        // source line should keep isFlushed value until Write() is called;
-        // for target data line reset it right now.
-        if (!isSource) {
-            info->isFlushed = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Start %s\n", ret?"success":"error");
-    return ret?TRUE:FALSE;
-}
-
-int DAUDIO_Stop(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("> DAUDIO_Stop\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    setStartThreshold(info, FALSE /* don't use threshold */); // device will not start after buffer xrun
-    ret = snd_pcm_pause(info->handle, 1);
-    // set to non-blocking mode
-    snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    info->isRunning = 0;
-    TRACE0("< DAUDIO_Stop success\n");
-    return TRUE;
-}
-
-void DAUDIO_Close(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    TRACE0("DAUDIO_Close\n");
-    if (info != NULL) {
-        if (info->handle != NULL) {
-            snd_pcm_close(info->handle);
-        }
-        if (info->hwParams) {
-            snd_pcm_hw_params_free(info->hwParams);
-        }
-        if (info->swParams) {
-            snd_pcm_sw_params_free(info->swParams);
-        }
-#ifdef GET_POSITION_METHOD2
-        if (info->positionStatus) {
-            snd_pcm_status_free(info->positionStatus);
-        }
-#endif
-        free(info);
-    }
-}
-
-/*
- * Underrun and suspend recovery
- * returns
- * 0:  exit native and return 0
- * 1:  try again to write/read
- * -1: error - exit native with return value -1
- */
-int xrun_recovery(AlsaPcmInfo* info, int err) {
-    int ret;
-
-    if (err == -EPIPE) {    /* underrun / overflow */
-        TRACE0("xrun_recovery: underrun/overflow.\n");
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -ESTRPIPE) {
-        TRACE0("xrun_recovery: suspended.\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if (ret == -EAGAIN) {
-                return 0; /* wait until the suspend flag is released */
-            }
-            return -1;
-        }
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -EAGAIN) {
-        TRACE0("xrun_recovery: EAGAIN try again flag.\n");
-        return 0;
-    }
-
-    TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err));
-    return -1;
-}
-
-// returns -1 on error
-int DAUDIO_Write(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, writtenFrames;
-
-    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
-
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Write: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Write returning -1\n");
-        return -1;
-    }
-
-    count = 2; // maximum number of trials to recover from underrun
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        writtenFrames = snd_pcm_writei(info->handle, (const void*) data, (snd_pcm_uframes_t) frameSize);
-
-        if (writtenFrames < 0) {
-            ret = xrun_recovery(info, (int) writtenFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Write: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Write: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, writtenFrames);
-
-    if (writtenFrames > 0) {
-        // reset "flushed" flag
-        info->isFlushed = 0;
-    }
-
-    ret =  (int) (writtenFrames * info->frameSize);
-    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
-    return ret;
-}
-
-// returns -1 on error
-int DAUDIO_Read(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, readFrames;
-
-    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
-    /*TRACE3("  info=%p, data=%p, byteSize=%d\n",
-      (void*) info, (void*) data, (int) byteSize);
-      TRACE2("  info->frameSize=%d, info->handle=%p\n",
-      (int) info->frameSize, (void*) info->handle);
-    */
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Read: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Read returning -1\n");
-        return -1;
-    }
-    if (!info->isRunning && info->isFlushed) {
-        // PCM has nothing to read
-        return 0;
-    }
-
-    count = 2; // maximum number of trials to recover from error
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        readFrames = snd_pcm_readi(info->handle, (void*) data, (snd_pcm_uframes_t) frameSize);
-        if (readFrames < 0) {
-            ret = xrun_recovery(info, (int) readFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Read: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Read: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, readFrames);
-    ret =  (int) (readFrames * info->frameSize);
-    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
-    return ret;
-}
-
-
-int DAUDIO_GetBufferSize(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    return info->bufferSizeInBytes;
-}
-
-int DAUDIO_StillDraining(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_state_t state;
-
-    state = snd_pcm_state(info->handle);
-    //printState(state);
-    //TRACE1("Still draining: %s\n", (state != SND_PCM_STATE_XRUN)?"TRUE":"FALSE");
-    return (state == SND_PCM_STATE_RUNNING)?TRUE:FALSE;
-}
-
-
-int DAUDIO_Flush(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("DAUDIO_Flush\n");
-
-    if (info->isFlushed) {
-        // nothing to drop
-        return 1;
-    }
-
-    ret = snd_pcm_drop(info->handle);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-
-    info->isFlushed = 1;
-    if (info->isRunning) {
-        ret = DAUDIO_Start(id, isSource);
-    }
-    return ret;
-}
-
-int DAUDIO_GetAvailable(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_sframes_t availableInFrames;
-    snd_pcm_state_t state;
-    int ret;
-
-    state = snd_pcm_state(info->handle);
-    if (info->isFlushed || state == SND_PCM_STATE_XRUN) {
-        // if in xrun state then we have the entire buffer available,
-        // not 0 as alsa reports
-        ret = info->bufferSizeInBytes;
-    } else {
-        availableInFrames = snd_pcm_avail_update(info->handle);
-        if (availableInFrames < 0) {
-            ret = 0;
-        } else {
-            //ret = snd_pcm_frames_to_bytes(info->handle, availableInFrames);
-            ret = (int) (availableInFrames * info->frameSize);
-        }
-    }
-    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
-    return ret;
-}
-
-INT64 estimatePositionFromAvail(AlsaPcmInfo* info, int isSource, INT64 javaBytePos, int availInBytes) {
-    // estimate the current position with the buffer size and
-    // the available bytes to read or write in the buffer.
-    // not an elegant solution - bytePos will stop on xruns,
-    // and in race conditions it may jump backwards
-    // Advantage is that it is indeed based on the samples that go through
-    // the system (rather than time-based methods)
-    if (isSource) {
-        // javaBytePos is the position that is reached when the current
-        // buffer is played completely
-        return (INT64) (javaBytePos - info->bufferSizeInBytes + availInBytes);
-    } else {
-        // javaBytePos is the position that was when the current buffer was empty
-        return (INT64) (javaBytePos + availInBytes);
-    }
-}
-
-INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    INT64 result = javaBytePos;
-    snd_pcm_state_t state;
-    state = snd_pcm_state(info->handle);
-
-    if (!info->isFlushed && state != SND_PCM_STATE_XRUN) {
-#ifdef GET_POSITION_METHOD2
-        snd_timestamp_t* ts;
-        snd_pcm_uframes_t framesAvail;
-
-        // note: slight race condition if this is called simultaneously from 2 threads
-        ret = snd_pcm_status(info->handle, info->positionStatus);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_status: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            // calculate from time value, or from available bytes
-            framesAvail = snd_pcm_status_get_avail(info->positionStatus);
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD3
-        snd_pcm_uframes_t framesAvail;
-        ret = snd_pcm_avail(info->handle, &framesAvail);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_avail: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD1
-        result = estimatePositionFromAvail(info, isSource, javaBytePos, DAUDIO_GetAvailable(id, isSource));
-#endif
-    }
-    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
-    return result;
-}
-
-
-
-void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    /* save to ignore, since GetBytePosition
-     * takes the javaBytePos param into account
-     */
-}
-
-int DAUDIO_RequiresServicing(void* id, int isSource) {
-    // never need servicing on Bsd
-    return FALSE;
-}
-
-void DAUDIO_Service(void* id, int isSource) {
-    // never need servicing on Bsd
-}
-
-
-#endif // USE_DAUDIO
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_BsdOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-// NOTE: cardinfo may be NULL (for "default" device)
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                             snd_ctl_card_info_t* cardinfo, void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-int iteratePCMDevices(DeviceIteratorPtr iterator, void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_pcm_t *pcm;
-    snd_pcm_info_t* pcminfo;
-    snd_ctl_card_info_t *cardinfo, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_pcm_info_malloc(&pcminfo);
-    snd_ctl_card_info_malloc(&cardinfo);
-
-    // 1st try "default" device
-    err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                       SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
-    if (err < 0) {
-        // try with the other direction
-        err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_pcm_open (\"default\"): %s\n", snd_strerror(err));
-    } else {
-        err = snd_pcm_info(pcm, pcminfo);
-        snd_pcm_close(pcm);
-        if (err < 0) {
-            ERROR1("ERROR: snd_pcm_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_pcm_info_get_card(pcminfo);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, cardinfo) >= 0) {
-                        defcardinfo = cardinfo;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call callback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, pcminfo,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    while (doContinue) {
-        if (snd_card_next(&card) < 0) {
-            break;
-        }
-        if (card < 0) {
-            break;
-        }
-        sprintf(devname, ALSA_HARDWARE_CARD, card);
-        TRACE1("Opening alsa device \"%s\"...\n", devname);
-        err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-        if (err < 0) {
-            ERROR2("ERROR: snd_ctl_open, card=%d: %s\n",
-                    card, snd_strerror(err));
-        } else {
-            err = snd_ctl_card_info(handle, cardinfo);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n",
-                        card, snd_strerror(err));
-            } else {
-                dev = -1;
-                while (doContinue) {
-                    if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
-                        ERROR0("snd_ctl_pcm_next_device\n");
-                    }
-                    if (dev < 0) {
-                        break;
-                    }
-                    snd_pcm_info_set_device(pcminfo, dev);
-                    snd_pcm_info_set_subdevice(pcminfo, 0);
-                    snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
-                    err = snd_ctl_pcm_info(handle, pcminfo);
-                    if (err == -ENOENT) {
-                        // try with the other direction
-                        snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
-                        err = snd_ctl_pcm_info(handle, pcminfo);
-                    }
-                    if (err < 0) {
-                        if (err != -ENOENT) {
-                            ERROR2("ERROR: snd_ctl_pcm_info, card=%d: %s",
-                                    card, snd_strerror(err));
-                        }
-                    } else {
-                        subdeviceCount = needEnumerateSubdevices(ALSA_PCM) ?
-                            snd_pcm_info_get_subdevices_count(pcminfo) : 1;
-                        if (iterator!=NULL) {
-                            for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                deviceID = encodeDeviceID(card, dev, subDev);
-                                doContinue = (*iterator)(deviceID, pcminfo,
-                                                         cardinfo, userData);
-                                count++;
-                                if (!doContinue) {
-                                    break;
-                                }
-                            }
-                        } else {
-                            count += subdeviceCount;
-                        }
-                    }
-                } // of while(doContinue)
-            }
-            snd_ctl_close(handle);
-        }
-    }
-    snd_ctl_card_info_free(cardinfo);
-    snd_pcm_info_free(pcminfo);
-    return count;
-}
-
-int getAudioDeviceCount() {
-    initAlsaSupport();
-    return iteratePCMDevices(NULL, NULL);
-}
-
-int deviceInfoIterator(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                       snd_ctl_card_info_t* cardinfo, void* userData) {
-    char buffer[300];
-    ALSA_AudioDeviceDescription* desc = (ALSA_AudioDeviceDescription*)userData;
-#ifdef ALSA_PCM_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        *(desc->maxSimultaneousLines) = needEnumerateSubdevices(ALSA_PCM) ?
-                1 : snd_pcm_info_get_subdevices_count(pcminfo);
-        *desc->deviceID = deviceID;
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_PCM);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_pcm_info_get_id(pcminfo),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        strncpy(desc->vendor, "ALSA (http://www.alsa-project.org)", desc->strLen);
-        strncpy(desc->description,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_name(cardinfo)
-                    : snd_pcm_info_get_name(pcminfo),
-                desc->strLen);
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_id(pcminfo), desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_name(pcminfo), desc->strLen - strlen(desc->description));
-        getALSAVersion(desc->version, desc->strLen);
-        TRACE4("Returning %s, %s, %s, %s\n", desc->name, desc->vendor, desc->description, desc->version);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-// returns 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware) {
-    char buffer[200];
-    int ret;
-
-    initAlsaSupport();
-    getDeviceStringFromDeviceID(buffer, deviceID, !hardware, ALSA_PCM);
-
-    TRACE1("Opening ALSA device %s\n", buffer);
-    ret = snd_pcm_open(handle, buffer,
-                       isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
-                       SND_PCM_NONBLOCK);
-    if (ret != 0) {
-        ERROR1("snd_pcm_open returned error code %d \n", ret);
-        *handle = NULL;
-    }
-    return ret;
-}
-
-
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getAudioDeviceDescriptionByIndex(mixerIndex = %d\n", desc->index);
-    iteratePCMDevices(&deviceInfoIterator, desc);
-    return (desc->index == 0)?TRUE:FALSE;
-}
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc) {
-
-    *sampleSizeInBytes = (snd_pcm_format_physical_width(alsaFormat) + 7) / 8;
-    *significantBits = snd_pcm_format_width(alsaFormat);
-
-    // defaults
-    *enc = 0; // PCM
-    *isSigned = (snd_pcm_format_signed(alsaFormat) > 0);
-    *isBigEndian = (snd_pcm_format_big_endian(alsaFormat) > 0);
-
-    // non-PCM formats
-    if (alsaFormat == SND_PCM_FORMAT_MU_LAW) { // Mu-Law
-        *sampleSizeInBytes = 8; *enc = 1; *significantBits = *sampleSizeInBytes;
-    }
-    else if (alsaFormat == SND_PCM_FORMAT_A_LAW) {     // A-Law
-        *sampleSizeInBytes = 8; *enc = 2; *significantBits = *sampleSizeInBytes;
-    }
-    else if (snd_pcm_format_linear(alsaFormat) < 1) {
-        return 0;
-    }
-    return (*sampleSizeInBytes > 0);
-}
-
-// returns 1 if successful
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc) {
-    *alsaFormat = SND_PCM_FORMAT_UNKNOWN;
-
-    if (enc == 0) {
-        *alsaFormat = snd_pcm_build_linear_format(significantBits,
-                                                  sampleSizeInBytes * 8,
-                                                  isSigned?0:1,
-                                                  isBigEndian?1:0);
-    }
-    else if ((sampleSizeInBytes == 1) && (significantBits == 8)) {
-        if (enc == 1) { // ULAW
-            *alsaFormat = SND_PCM_FORMAT_MU_LAW;
-        }
-        else if (enc == 2) { // ALAW
-            *alsaFormat = SND_PCM_FORMAT_A_LAW;
-        }
-    }
-    return (*alsaFormat == SND_PCM_FORMAT_UNKNOWN)?0:1;
-}
-
-
-/* end */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCMUtils.h	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-// define this with a later version of ALSA than 0.9.0rc3
-// (starting from 1.0.0 it became default behaviour)
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#include <alsa/asoundlib.h>
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_BSDOS_ALSA_PCMUTILS_H_INCLUDED
-#define PLATFORM_API_BSDOS_ALSA_PCMUTILS_H_INCLUDED
-
-// if this is defined, use plughw: devices
-#define ALSA_PCM_USE_PLUGHW
-//#undef ALSA_PCM_USE_PLUGHW
-
-
-// maximum number of channels that is listed in the formats. If more, than
-// just -1 for channel count is used.
-#define MAXIMUM_LISTED_CHANNELS 32
-
-typedef struct tag_ALSA_AudioDeviceDescription {
-    int index;          // in
-    int strLen;         // in
-    INT32* deviceID;    // out
-    int* maxSimultaneousLines; // out
-    char* name;         // out
-    char* vendor;       // out
-    char* description;  // out
-    char* version;      // out
-} ALSA_AudioDeviceDescription;
-
-
-
-int getAudioDeviceCount();
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc);
-
-// returns ALSA error code, or 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware);
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc);
-
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc);
-
-#endif // PLATFORM_API_BSDOS_ALSA_PCMUTILS_H_INCLUDED
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_Ports.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,724 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-#define USE_ERROR
-//#define USE_TRACE
-
-#include "Ports.h"
-#include "PLATFORM_API_BsdOS_ALSA_CommonUtils.h"
-#include <alsa/asoundlib.h>
-
-#if USE_PORTS == TRUE
-
-#define MAX_ELEMS (300)
-#define MAX_CONTROLS (MAX_ELEMS * 4)
-
-#define CHANNELS_MONO (SND_MIXER_SCHN_LAST + 1)
-#define CHANNELS_STEREO (SND_MIXER_SCHN_LAST + 2)
-
-typedef struct {
-    snd_mixer_elem_t* elem;
-    INT32 portType; /* one of PORT_XXX_xx */
-    char* controlType; /* one of CONTROL_TYPE_xx */
-    /* Values: either SND_MIXER_SCHN_FRONT_xx, CHANNELS_MONO or CHANNELS_STEREO.
-       For SND_MIXER_SCHN_FRONT_xx, exactly this channel is set/retrieved directly.
-       For CHANNELS_MONO, ALSA channel SND_MIXER_SCHN_MONO is set/retrieved directly.
-       For CHANNELS_STEREO, ALSA channels SND_MIXER_SCHN_FRONT_LEFT and SND_MIXER_SCHN_FRONT_RIGHT
-       are set after a calculation that takes balance into account. Retrieved? Average of both
-       channels? (Using a cached value is not a good idea since the value in the HW may have been
-       altered.) */
-    INT32 channel;
-} PortControl;
-
-
-typedef struct tag_PortMixer {
-    snd_mixer_t* mixer_handle;
-    /* Number of array elements used in elems and types. */
-    int numElems;
-    snd_mixer_elem_t** elems;
-    /* Array of port types (PORT_SRC_UNKNOWN etc.). Indices are the same as in elems. */
-    INT32* types;
-    /* Number of array elements used in controls. */
-    int numControls;
-    PortControl* controls;
-} PortMixer;
-
-
-///// implemented functions of Ports.h
-
-INT32 PORT_GetPortMixerCount() {
-    INT32 mixerCount;
-    int card;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_ctl_card_info_t* info;
-
-    TRACE0("> PORT_GetPortMixerCount\n");
-
-    initAlsaSupport();
-
-    snd_ctl_card_info_malloc(&info);
-    card = -1;
-    mixerCount = 0;
-    if (snd_card_next(&card) >= 0) {
-        while (card >= 0) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("PORT_GetPortMixerCount: Opening alsa device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, 0);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                mixerCount++;
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    }
-    snd_ctl_card_info_free(info);
-    TRACE0("< PORT_GetPortMixerCount\n");
-    return mixerCount;
-}
-
-
-INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
-    snd_ctl_t* handle;
-    snd_ctl_card_info_t* card_info;
-    char devname[16];
-    int err;
-    char buffer[100];
-
-    TRACE0("> PORT_GetPortMixerDescription\n");
-    snd_ctl_card_info_malloc(&card_info);
-
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    TRACE1("Opening alsa device \"%s\"...\n", devname);
-    err = snd_ctl_open(&handle, devname, 0);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-        return FALSE;
-    }
-    err = snd_ctl_card_info(handle, card_info);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-    }
-    strncpy(description->name, snd_ctl_card_info_get_id(card_info), PORT_STRING_LENGTH - 1);
-    sprintf(buffer, " [%s]", devname);
-    strncat(description->name, buffer, PORT_STRING_LENGTH - 1 - strlen(description->name));
-    strncpy(description->vendor, "ALSA (http://www.alsa-project.org)", PORT_STRING_LENGTH - 1);
-    strncpy(description->description, snd_ctl_card_info_get_name(card_info), PORT_STRING_LENGTH - 1);
-    strncat(description->description, ", ", PORT_STRING_LENGTH - 1 - strlen(description->description));
-    strncat(description->description, snd_ctl_card_info_get_mixername(card_info), PORT_STRING_LENGTH - 1 - strlen(description->description));
-    getALSAVersion(description->version, PORT_STRING_LENGTH - 1);
-
-    snd_ctl_close(handle);
-    snd_ctl_card_info_free(card_info);
-    TRACE0("< PORT_GetPortMixerDescription\n");
-    return TRUE;
-}
-
-
-void* PORT_Open(INT32 mixerIndex) {
-    char devname[16];
-    snd_mixer_t* mixer_handle;
-    int err;
-    PortMixer* handle;
-
-    TRACE0("> PORT_Open\n");
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) {
-        ERROR2("Mixer %s open error: %s", devname, snd_strerror(err));
-        return NULL;
-    }
-    if ((err = snd_mixer_attach(mixer_handle, devname)) < 0) {
-        ERROR2("Mixer attach %s error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0) {
-        ERROR1("Mixer register error: %s", snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    err = snd_mixer_load(mixer_handle);
-    if (err < 0) {
-        ERROR2("Mixer %s load error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle = (PortMixer*) calloc(1, sizeof(PortMixer));
-    if (handle == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle->numElems = 0;
-    handle->elems = (snd_mixer_elem_t**) calloc(MAX_ELEMS, sizeof(snd_mixer_elem_t*));
-    if (handle->elems == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle);
-        return NULL;
-    }
-    handle->types = (INT32*) calloc(MAX_ELEMS, sizeof(INT32));
-    if (handle->types == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle);
-        return NULL;
-    }
-    handle->controls = (PortControl*) calloc(MAX_CONTROLS, sizeof(PortControl));
-    if (handle->controls == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle->types);
-        free(handle);
-        return NULL;
-    }
-    handle->mixer_handle = mixer_handle;
-    // necessary to initialize data structures
-    PORT_GetPortCount(handle);
-    TRACE0("< PORT_Open\n");
-    return handle;
-}
-
-
-void PORT_Close(void* id) {
-    TRACE0("> PORT_Close\n");
-    if (id != NULL) {
-        PortMixer* handle = (PortMixer*) id;
-        if (handle->mixer_handle != NULL) {
-            snd_mixer_close(handle->mixer_handle);
-        }
-        if (handle->elems != NULL) {
-            free(handle->elems);
-        }
-        if (handle->types != NULL) {
-            free(handle->types);
-        }
-        if (handle->controls != NULL) {
-            free(handle->controls);
-        }
-        free(handle);
-    }
-    TRACE0("< PORT_Close\n");
-}
-
-
-
-INT32 PORT_GetPortCount(void* id) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t *elem;
-
-    TRACE0("> PORT_GetPortCount\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portMixer->numElems == 0) {
-        for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
-            if (!snd_mixer_selem_is_active(elem))
-                continue;
-            TRACE2("Simple mixer control '%s',%i\n",
-                   snd_mixer_selem_get_name(elem),
-                   snd_mixer_selem_get_index(elem));
-            if (snd_mixer_selem_has_playback_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-            /* If an element has both playback an capture volume, it is put into the arrays
-               twice. */
-            if (snd_mixer_selem_has_capture_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-        }
-    }
-    TRACE0("< PORT_GetPortCount\n");
-    return portMixer->numElems;
-}
-
-
-INT32 PORT_GetPortType(void* id, INT32 portIndex) {
-    PortMixer* portMixer;
-    INT32 type;
-    TRACE0("> PORT_GetPortType\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    type = portMixer->types[portIndex];
-    TRACE0("< PORT_GetPortType\n");
-    return type;
-}
-
-
-INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
-    PortMixer* portMixer;
-    const char* nam;
-
-    TRACE0("> PORT_GetPortName\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    nam = snd_mixer_selem_get_name(portMixer->elems[portIndex]);
-    strncpy(name, nam, len - 1);
-    name[len - 1] = 0;
-    TRACE0("< PORT_GetPortName\n");
-    return TRUE;
-}
-
-
-static int isPlaybackFunction(INT32 portType) {
-        return (portType & PORT_DST_MASK);
-}
-
-
-/* Sets portControl to a pointer to the next free array element in the PortControl (pointer)
-   array of the passed portMixer. Returns TRUE if successful. May return FALSE if there is no
-   free slot. In this case, portControl is not altered */
-static int getControlSlot(PortMixer* portMixer, PortControl** portControl) {
-    if (portMixer->numControls >= MAX_CONTROLS) {
-        return FALSE;
-    } else {
-        *portControl = &(portMixer->controls[portMixer->numControls]);
-        portMixer->numControls++;
-        return TRUE;
-    }
-}
-
-
-/* Protect against illegal min-max values, preventing divisions by zero.
- */
-inline static long getRange(long min, long max) {
-    if (max > min) {
-        return max - min;
-    } else {
-        return 1;
-    }
-}
-
-
-/* Idea: we may specify that if unit is an empty string, the values are linear and if unit is "dB",
-   the values are logarithmic.
-*/
-static void* createVolumeControl(PortControlCreator* creator,
-                                 PortControl* portControl,
-                                 snd_mixer_elem_t* elem, int isPlayback) {
-    void* control;
-    float precision;
-    long min, max;
-
-    if (isPlayback) {
-        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
-    }
-    /* $$mp: The volume values retrieved with the ALSA API are strongly supposed to be logarithmic.
-       So the following calculation is wrong. However, there is no correct calculation, since
-       for equal-distant logarithmic steps, the precision expressed in linear varies over the
-       scale. */
-    precision = 1.0F / getRange(min, max);
-    control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_VOLUME, 0.0F, +1.0F, precision, "");
-    return control;
-}
-
-
-void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t* elem;
-    void* control;
-    PortControl* portControl;
-    void* controls[10];
-    int numControls;
-    char* portName;
-    int isPlayback = 0;
-    int isMono;
-    int isStereo;
-    char* type;
-    snd_mixer_selem_channel_id_t channel;
-    memset(controls, 0, sizeof(controls));
-
-    TRACE0("> PORT_GetControls\n");
-    if (id == NULL) {
-        ERROR0("Invalid handle!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        ERROR0("Port index out of range!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    numControls = 0;
-    elem = portMixer->elems[portIndex];
-    if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) {
-        /* Since we've split/duplicated elements with both playback and capture on the recovery
-           of elements, we now can assume that we handle only to deal with either playback or
-           capture. */
-        isPlayback = isPlaybackFunction(portMixer->types[portIndex]);
-        isMono = (isPlayback && snd_mixer_selem_is_playback_mono(elem)) ||
-            (!isPlayback && snd_mixer_selem_is_capture_mono(elem));
-        isStereo = (isPlayback &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) ||
-            (!isPlayback &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT));
-        // single volume control
-        if (isMono || isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_VOLUME;
-                if (isMono) {
-                    portControl->channel = CHANNELS_MONO;
-                } else {
-                    portControl->channel = CHANNELS_STEREO;
-                }
-                control = createVolumeControl(creator, portControl, elem, isPlayback);
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        } else { // more than two channels, each channels has its own control.
-            for (channel = SND_MIXER_SCHN_FRONT_LEFT; channel <= SND_MIXER_SCHN_LAST; channel++) {
-                if (isPlayback && snd_mixer_selem_has_playback_channel(elem, channel) ||
-                    !isPlayback && snd_mixer_selem_has_capture_channel(elem, channel)) {
-                    if (getControlSlot(portMixer, &portControl)) {
-                        portControl->elem = elem;
-                        portControl->portType = portMixer->types[portIndex];
-                        portControl->controlType = CONTROL_TYPE_VOLUME;
-                        portControl->channel = channel;
-                        control = createVolumeControl(creator, portControl, elem, isPlayback);
-                        // We wrap in a compound control to provide the channel name.
-                        if (control != NULL) {
-                            /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-                               declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-                               to take a const char* parameter. */
-                            control = (creator->newCompoundControl)(creator, (char*) snd_mixer_selem_channel_name(channel), &control, 1);
-                        }
-                        if (control != NULL) {
-                            controls[numControls++] = control;
-                        }
-                    }
-                }
-            }
-        }
-        // BALANCE control
-        if (isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_BALANCE;
-                portControl->channel = CHANNELS_STEREO;
-                /* $$mp: The value for precision is chosen more or less arbitrarily. */
-                control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_BALANCE, -1.0F, 1.0F, 0.01F, "");
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        }
-    }
-    if (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_capture_switch(elem)) {
-        if (getControlSlot(portMixer, &portControl)) {
-            type = isPlayback ? CONTROL_TYPE_MUTE : CONTROL_TYPE_SELECT;
-            portControl->elem = elem;
-            portControl->portType = portMixer->types[portIndex];
-            portControl->controlType = type;
-            control = (creator->newBooleanControl)(creator, portControl, type);
-            if (control != NULL) {
-                controls[numControls++] = control;
-            }
-        }
-    }
-    /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-       declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-       to take a const char* parameter. */
-    portName = (char*) snd_mixer_selem_get_name(elem);
-    control = (creator->newCompoundControl)(creator, portName, controls, numControls);
-    if (control != NULL) {
-        (creator->addControl)(creator, control);
-    }
-    TRACE0("< PORT_GetControls\n");
-}
-
-
-INT32 PORT_GetIntValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    int value = 0;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        switch (portControl->channel) {
-        case CHANNELS_MONO:
-            channel = SND_MIXER_SCHN_MONO;
-            break;
-
-        case CHANNELS_STEREO:
-            channel = SND_MIXER_SCHN_FRONT_LEFT;
-            break;
-
-        default:
-            channel = portControl->channel;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_get_playback_switch(portControl->elem, channel, &value);
-            } else {
-                snd_mixer_selem_get_capture_switch(portControl->elem, channel, &value);
-            }
-            if (portControl->controlType == CONTROL_TYPE_MUTE) {
-                value = ! value;
-            }
-        } else {
-            ERROR1("PORT_GetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-    return (INT32) value;
-}
-
-
-void PORT_SetIntValue(void* controlIDV, INT32 value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_MUTE) {
-            value = ! value;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_set_playback_switch_all(portControl->elem, value);
-            } else {
-                snd_mixer_selem_set_capture_switch_all(portControl->elem, value);
-            }
-        } else {
-            ERROR1("PORT_SetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-static float scaleVolumeValueToNormalized(long value, long min, long max) {
-    return (float) (value - min) / getRange(min, max);
-}
-
-
-static long scaleVolumeValueToHardware(float value, long min, long max) {
-    return (long)(value * getRange(min, max) + min);
-}
-
-
-float getRealVolume(PortControl* portControl,
-                    snd_mixer_selem_channel_id_t channel) {
-    float fValue;
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        snd_mixer_selem_get_playback_volume(portControl->elem,
-                                            channel, &lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        snd_mixer_selem_get_capture_volume(portControl->elem,
-                                           channel, &lValue);
-    }
-    fValue = scaleVolumeValueToNormalized(lValue, min, max);
-    return fValue;
-}
-
-
-void setRealVolume(PortControl* portControl,
-                   snd_mixer_selem_channel_id_t channel, float value) {
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_playback_volume(portControl->elem,
-                                            channel, lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_capture_volume(portControl->elem,
-                                           channel, lValue);
-    }
-}
-
-
-static float getFakeBalance(PortControl* portControl) {
-    float volL, volR;
-
-    // pan is the ratio of left and right
-    volL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    volR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    if (volL > volR) {
-        return -1.0f + (volR / volL);
-    }
-    else if (volR > volL) {
-        return 1.0f - (volL / volR);
-    }
-    return 0.0f;
-}
-
-
-static float getFakeVolume(PortControl* portControl) {
-    float valueL;
-    float valueR;
-    float value;
-
-    valueL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    valueR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    // volume is the greater value of both
-    value = valueL > valueR ? valueL : valueR ;
-    return value;
-}
-
-
-/*
- * sets the unsigned values for left and right volume according to
- * the given volume (0...1) and balance (-1..0..+1)
- */
-static void setFakeVolume(PortControl* portControl, float vol, float bal) {
-    float volumeLeft;
-    float volumeRight;
-
-    if (bal < 0.0f) {
-        volumeLeft = vol;
-        volumeRight = vol * (bal + 1.0f);
-    } else {
-        volumeLeft = vol * (1.0f - bal);
-        volumeRight = vol;
-    }
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT, volumeLeft);
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT, volumeRight);
-}
-
-
-float PORT_GetFloatValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    float value = 0.0F;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                value = getRealVolume(portControl, SND_MIXER_SCHN_MONO);
-                break;
-
-            case CHANNELS_STEREO:
-                value = getFakeVolume(portControl);
-                break;
-
-            default:
-                value = getRealVolume(portControl, portControl->channel);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                value = getFakeBalance(portControl);
-            } else {
-                ERROR0("PORT_GetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_GetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-    return value;
-}
-
-
-void PORT_SetFloatValue(void* controlIDV, float value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                setRealVolume(portControl, SND_MIXER_SCHN_MONO, value);
-                break;
-
-            case CHANNELS_STEREO:
-                setFakeVolume(portControl, value, getFakeBalance(portControl));
-                break;
-
-            default:
-                setRealVolume(portControl, portControl->channel, value);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                setFakeVolume(portControl, getFakeVolume(portControl), value);
-            } else {
-                ERROR0("PORT_SetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_SetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-#endif // USE_PORTS
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2003, 2015, 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 USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-
-static void alsaDebugOutput(const char *file, int line, const char *function, int err, const char *fmt, ...) {
-#ifdef USE_ERROR
-    va_list args;
-    va_start(args, fmt);
-    printf("%s:%d function %s: error %d: %s\n", file, line, function, err, snd_strerror(err));
-    if (strlen(fmt) > 0) {
-        vprintf(fmt, args);
-    }
-    va_end(args);
-#endif
-}
-
-static int alsa_inited = 0;
-static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
-static int alsa_enumerate_midi_subdevices = FALSE; // default: no
-
-/*
- * Declare library specific JNI_Onload entry if static build
- */
-DEF_STATIC_JNI_OnLoad
-
-void initAlsaSupport() {
-    char* enumerate;
-    if (!alsa_inited) {
-        alsa_inited = TRUE;
-        snd_lib_error_set_handler(&alsaDebugOutput);
-
-        enumerate = getenv(ENV_ENUMERATE_PCM_SUBDEVICES);
-        if (enumerate != NULL && strlen(enumerate) > 0
-            && (enumerate[0] != 'f')   // false
-            && (enumerate[0] != 'F')   // False
-            && (enumerate[0] != 'n')   // no
-            && (enumerate[0] != 'N')) { // NO
-            alsa_enumerate_pcm_subdevices = TRUE;
-        }
-#ifdef ALSA_MIDI_ENUMERATE_SUBDEVICES
-        alsa_enumerate_midi_subdevices = TRUE;
-#endif
-    }
-}
-
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi) {
-    initAlsaSupport();
-    return isMidi ? alsa_enumerate_midi_subdevices
-                  : alsa_enumerate_pcm_subdevices;
-}
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice) {
-    return (((card & 0x3FF) << 20) | ((device & 0x3FF) << 10)
-           | (subdevice & 0x3FF)) + 1;
-}
-
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi) {
-    deviceID--;
-    *card = (deviceID >> 20) & 0x3FF;
-    *device = (deviceID >> 10) & 0x3FF;
-    if (needEnumerateSubdevices(isMidi)) {
-        *subdevice = deviceID  & 0x3FF;
-    } else {
-        *subdevice = -1; // ALSA will choose any subdevices
-    }
-}
-
-
-void getDeviceString(char* buffer, int card, int device, int subdevice,
-                     int usePlugHw, int isMidi) {
-    if (needEnumerateSubdevices(isMidi)) {
-        sprintf(buffer, "%s:%d,%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device, subdevice);
-    } else {
-        sprintf(buffer, "%s:%d,%d",
-                        usePlugHw ? ALSA_PLUGHARDWARE : ALSA_HARDWARE,
-                        card, device);
-    }
-}
-
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi) {
-    int card, device, subdevice;
-
-    if (deviceID == ALSA_DEFAULT_DEVICE_ID) {
-        strcpy(buffer, ALSA_DEFAULT_DEVICE_NAME);
-    } else {
-        decodeDeviceID(deviceID, &card, &device, &subdevice, isMidi);
-        getDeviceString(buffer, card, device, subdevice, usePlugHw, isMidi);
-    }
-}
-
-
-static int hasGottenALSAVersion = FALSE;
-#define ALSAVersionString_LENGTH 200
-static char ALSAVersionString[ALSAVersionString_LENGTH];
-
-void getALSAVersion(char* buffer, int len) {
-    if (!hasGottenALSAVersion) {
-        // get alsa version from proc interface
-        FILE* file;
-        int curr, len, totalLen, inVersionString;
-        file = fopen(ALSA_VERSION_PROC_FILE, "r");
-        ALSAVersionString[0] = 0;
-        if (file) {
-            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
-                // parse for version number
-                totalLen = strlen(ALSAVersionString);
-                inVersionString = FALSE;
-                len = 0;
-                curr = 0;
-                while (curr < totalLen) {
-                    if (!inVersionString) {
-                        // is this char the beginning of a version string ?
-                        if (ALSAVersionString[curr] >= '0'
-                            && ALSAVersionString[curr] <= '9') {
-                            inVersionString = TRUE;
-                        }
-                    }
-                    if (inVersionString) {
-                        // the version string ends with white space
-                        if (ALSAVersionString[curr] <= 32) {
-                            break;
-                        }
-                        if (curr != len) {
-                            // copy this char to the beginning of the string
-                            ALSAVersionString[len] = ALSAVersionString[curr];
-                        }
-                        len++;
-                    }
-                    curr++;
-                }
-                // remove trailing dots
-                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
-                    len--;
-                }
-                // null terminate
-                ALSAVersionString[len] = 0;
-            }
-            fclose(file);
-            hasGottenALSAVersion = TRUE;
-        }
-    }
-    strncpy(buffer, ALSAVersionString, len);
-}
-
-
-/* end */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.h	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2003, 2007, 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 <alsa/asoundlib.h>
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
-#define PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
-
-#define ALSA_VERSION_PROC_FILE "/proc/asound/version"
-#define ALSA_HARDWARE "hw"
-#define ALSA_HARDWARE_CARD ALSA_HARDWARE":%d"
-#define ALSA_HARDWARE_DEVICE ALSA_HARDWARE_CARD",%d"
-#define ALSA_HARDWARE_SUBDEVICE ALSA_HARDWARE_DEVICE",%d"
-
-#define ALSA_PLUGHARDWARE "plughw"
-#define ALSA_DEFAULT_DEVICE_NAME "default"
-
-#define ALSA_DEFAULT_DEVICE_ID (0)
-
-#define ALSA_PCM     (0)
-#define ALSA_RAWMIDI (1)
-
-// for use in info objects
-#define ALSA_VENDOR "ALSA (http://www.alsa-project.org)"
-
-// Environment variable for inclusion of subdevices in device listing.
-// If this variable is unset or "no", then subdevices are ignored, and
-// it's ALSA's choice which one to use (enables hardware mixing)
-#define ENV_ENUMERATE_PCM_SUBDEVICES "ALSA_ENUMERATE_PCM_SUBDEVICES"
-
-// if defined, subdevices are listed.
-//#undef ALSA_MIDI_ENUMERATE_SUBDEVICES
-#define ALSA_MIDI_ENUMERATE_SUBDEVICES
-
-// must be called before any ALSA calls
-void initAlsaSupport();
-
-/* if true (non-zero), ALSA sub devices should be listed as separate devices
- */
-int needEnumerateSubdevices(int isMidi);
-
-
-/*
- * deviceID contains packed card, device and subdevice numbers
- * each number takes 10 bits
- * "default" device has id == ALSA_DEFAULT_DEVICE_ID
- */
-UINT32 encodeDeviceID(int card, int device, int subdevice);
-
-void decodeDeviceID(UINT32 deviceID, int* card, int* device, int* subdevice,
-                    int isMidi);
-
-void getDeviceStringFromDeviceID(char* buffer, UINT32 deviceID,
-                                 int usePlugHw, int isMidi);
-
-void getALSAVersion(char* buffer, int len);
-
-
-#endif // PLATFORM_API_LINUXOS_ALSA_COMMONUTILS_H_INCLUDED
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, 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 USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_IN == TRUE
-
-
-#include <alsa/asoundlib.h>
-#include "PlatformMidi.h"
-#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
-#if defined(i586)
-#include <sys/utsname.h>
-#endif
-
-/*
- * Helper methods
- */
-
-static inline UINT32 packMessage(int status, int data1, int data2) {
-    return ((status & 0xFF) | ((data1 & 0xFF) << 8) | ((data2 & 0xFF) << 16));
-}
-
-
-static void setShortMessage(MidiMessage* message,
-                            int status, int data1, int data2) {
-    message->type = SHORT_MESSAGE;
-    message->data.s.packedMsg = packMessage(status, data1, data2);
-}
-
-
-static void setRealtimeMessage(MidiMessage* message, int status) {
-    setShortMessage(message, status, 0, 0);
-}
-
-
-static void set14bitMessage(MidiMessage* message, int status, int value) {
-    TRACE3("14bit value: %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    value &= 0x3FFF;
-    TRACE3("14bit value (2): %d, lsb: %d, msb: %d\n", value, value & 0x7F, (value >> 7) & 0x7F);
-    setShortMessage(message, status,
-                    value & 0x7F,
-                    (value >> 7) & 0x7F);
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI in functions declared in PlatformMidi.h
- */
-
-char* MIDI_IN_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-INT32 MIDI_IN_GetNumDevices() {
-/* Workaround for 6842956: 32bit app on 64bit linux
- * gets assertion failure trying to open midiIn ports.
- * Untill the issue is fixed in ALSA
- * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
- * report no midi in devices in the configuration.
- */
-#if defined(i586)
-    static int jre32onlinux64 = -1;
-    if (jre32onlinux64 < 0) {
-        jre32onlinux64 = 0;
-        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
-         * environment variable.
-         */
-        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
-            struct utsname u;
-            jre32onlinux64 = 0;
-            if (uname(&u) == 0) {
-                if (strstr(u.machine, "64") != NULL) {
-                    TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
-                    jre32onlinux64 = 1;
-                }
-            }
-        }
-    }
-    if (jre32onlinux64) {
-        return 0;
-    }
-#endif
-
-    TRACE0("MIDI_IN_GetNumDevices()\n");
-
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
-}
-
-
-INT32 MIDI_IN_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceName(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVendor(deviceIndex, name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceDescription(SND_RAWMIDI_STREAM_INPUT, deviceIndex,
-                                       name, nameLength);
-    return ret;
-}
-
-
-INT32 MIDI_IN_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    int ret = getMidiDeviceVersion(deviceIndex, name, nameLength);
-    return ret;
-}
-
-/*************************************************************************/
-
-INT32 MIDI_IN_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_OpenDevice\n");
-    ret = openMidiDevice(SND_RAWMIDI_STREAM_INPUT, deviceIndex, handle);
-    TRACE1("< MIDI_IN_OpenDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle) {
-    INT32 ret;
-    TRACE0("> MIDI_IN_CloseDevice\n");
-    ret = closeMidiDevice(handle);
-    TRACE1("< MIDI_IN_CloseDevice: returning %d\n", (int) ret);
-    return ret;
-}
-
-
-INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StartDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_IN_StopDevice\n");
-    return MIDI_SUCCESS;
-}
-
-
-INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-/* read the next message from the queue */
-MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) {
-    snd_seq_event_t alsa_message;
-    MidiMessage* jdk_message;
-    int err;
-    char buffer[1];
-    int status;
-
-    TRACE0("> MIDI_IN_GetMessage\n");
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): native handle is NULL\n");
-        return NULL;
-    }
-    if (!handle->platformData) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): platformData is NULL\n");
-        return NULL;
-    }
-
-    /* For MIDI In, the device is left in non blocking mode. So if there is
-       no data from the device, snd_rawmidi_read() returns with -11 (EAGAIN).
-       This results in jumping back to the Java layer. */
-    while (TRUE) {
-        TRACE0("before snd_rawmidi_read()\n");
-        err = snd_rawmidi_read((snd_rawmidi_t*) handle->deviceHandle, buffer, 1);
-        TRACE0("after snd_rawmidi_read()\n");
-        if (err != 1) {
-            ERROR2("< ERROR: MIDI_IN_GetMessage(): snd_rawmidi_read() returned %d : %s\n", err, snd_strerror(err));
-            return NULL;
-        }
-        // printf("received byte: %d\n", buffer[0]);
-        err = snd_midi_event_encode_byte((snd_midi_event_t*) handle->platformData,
-                                         (int) buffer[0],
-                                         &alsa_message);
-        if (err == 1) {
-            break;
-        } else if (err < 0) {
-            ERROR1("< ERROR: MIDI_IN_GetMessage(): snd_midi_event_encode_byte() returned %d\n", err);
-            return NULL;
-        }
-    }
-    jdk_message = (MidiMessage*) calloc(sizeof(MidiMessage), 1);
-    if (!jdk_message) {
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-        return NULL;
-    }
-    // TODO: tra
-    switch (alsa_message.type) {
-    case SND_SEQ_EVENT_NOTEON:
-    case SND_SEQ_EVENT_NOTEOFF:
-    case SND_SEQ_EVENT_KEYPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_KEYPRESS) ? 0xA0 :
-            (alsa_message.type == SND_SEQ_EVENT_NOTEON) ? 0x90 : 0x80;
-        status |= alsa_message.data.note.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.note.note,
-                        alsa_message.data.note.velocity);
-        break;
-
-    case SND_SEQ_EVENT_CONTROLLER:
-        status = 0xB0 | alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.param,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_PGMCHANGE:
-    case SND_SEQ_EVENT_CHANPRESS:
-        status = (alsa_message.type == SND_SEQ_EVENT_PGMCHANGE) ? 0xC0 : 0xD0;
-        status |= alsa_message.data.control.channel;
-        setShortMessage(jdk_message, status,
-                        alsa_message.data.control.value, 0);
-        break;
-
-    case SND_SEQ_EVENT_PITCHBEND:
-        status = 0xE0 | alsa_message.data.control.channel;
-        // $$mp 2003-09-23:
-        // possible hack to work around a bug in ALSA. Necessary for
-        // ALSA 0.9.2. May be fixed in newer versions of ALSA.
-        // alsa_message.data.control.value ^= 0x2000;
-        // TRACE1("pitchbend value: %d\n", alsa_message.data.control.value);
-        set14bitMessage(jdk_message, status,
-                        alsa_message.data.control.value);
-        break;
-
-        /* System exclusive messages */
-
-    case SND_SEQ_EVENT_SYSEX:
-        jdk_message->type = LONG_MESSAGE;
-        jdk_message->data.l.size = alsa_message.data.ext.len;
-        jdk_message->data.l.data = malloc(alsa_message.data.ext.len);
-        if (jdk_message->data.l.data == NULL) {
-            ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n");
-            free(jdk_message);
-            jdk_message = NULL;
-        } else {
-            memcpy(jdk_message->data.l.data, alsa_message.data.ext.ptr, alsa_message.data.ext.len);
-        }
-        break;
-
-        /* System common messages */
-
-    case SND_SEQ_EVENT_QFRAME:
-        setShortMessage(jdk_message, 0xF1,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_SONGPOS:
-        set14bitMessage(jdk_message, 0xF2,
-                        alsa_message.data.control.value);
-        break;
-
-    case SND_SEQ_EVENT_SONGSEL:
-        setShortMessage(jdk_message, 0xF3,
-                        alsa_message.data.control.value & 0x7F, 0);
-        break;
-
-    case SND_SEQ_EVENT_TUNE_REQUEST:
-        setRealtimeMessage(jdk_message, 0xF6);
-        break;
-
-        /* System realtime messages */
-
-    case SND_SEQ_EVENT_CLOCK:
-        setRealtimeMessage(jdk_message, 0xF8);
-        break;
-
-    case SND_SEQ_EVENT_START:
-        setRealtimeMessage(jdk_message, 0xFA);
-        break;
-
-    case SND_SEQ_EVENT_CONTINUE:
-        setRealtimeMessage(jdk_message, 0xFB);
-        break;
-
-    case SND_SEQ_EVENT_STOP:
-        setRealtimeMessage(jdk_message, 0xFC);
-        break;
-
-    case SND_SEQ_EVENT_SENSING:
-        setRealtimeMessage(jdk_message, 0xFE);
-        break;
-
-    case SND_SEQ_EVENT_RESET:
-        setRealtimeMessage(jdk_message, 0xFF);
-        break;
-
-    default:
-        ERROR0("< ERROR: MIDI_IN_GetMessage(): unhandled ALSA MIDI message type\n");
-        free(jdk_message);
-        jdk_message = NULL;
-
-    }
-
-    // set timestamp
-    if (jdk_message != NULL) {
-        jdk_message->timestamp = getMidiTimestamp(handle);
-    }
-    TRACE1("< MIDI_IN_GetMessage: returning %p\n", jdk_message);
-    return jdk_message;
-}
-
-
-void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg) {
-    if (!msg) {
-        ERROR0("< ERROR: MIDI_IN_ReleaseMessage(): message is NULL\n");
-        return;
-    }
-    if (msg->type == LONG_MESSAGE && msg->data.l.data) {
-        free(msg->data.l.data);
-    }
-    free(msg);
-}
-
-#endif /* USE_PLATFORM_MIDI_IN */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2003, 2007, 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 USE_ERROR
-#define USE_TRACE
-
-#if USE_PLATFORM_MIDI_OUT == TRUE
-
-#include <alsa/asoundlib.h>
-#include "PlatformMidi.h"
-#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
-
-
-
-static int CHANNEL_MESSAGE_LENGTH[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 3, 3, 2, 2, 3 };
-/*                                 8x 9x Ax Bx Cx Dx Ex */
-
-static int SYSTEM_MESSAGE_LENGTH[] = {
-    -1, 2, 3, 2, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1 };
-/*  F0 F1 F2 F3  F4  F5 F6 F7 F8  F9 FA FB FC  FD FE FF */
-
-
-// the returned length includes the status byte.
-// for illegal messages, -1 is returned.
-static int getShortMessageLength(int status) {
-        int     dataLength = 0;
-        if (status < 0xF0) { // channel voice message
-                dataLength = CHANNEL_MESSAGE_LENGTH[(status >> 4) & 0xF];
-        } else {
-                dataLength = SYSTEM_MESSAGE_LENGTH[status & 0xF];
-        }
-        return dataLength;
-}
-
-
-/*
- * implementation of the platform-dependent
- * MIDI out functions declared in PlatformMidi.h
- */
-char* MIDI_OUT_GetErrorStr(INT32 err) {
-    return (char*) getErrorStr(err);
-}
-
-
-INT32 MIDI_OUT_GetNumDevices() {
-    TRACE0("MIDI_OUT_GetNumDevices()\n");
-    return getMidiDeviceCount(SND_RAWMIDI_STREAM_OUTPUT);
-}
-
-
-INT32 MIDI_OUT_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceName()\n");
-    return getMidiDeviceName(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                             name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVendor()\n");
-    return getMidiDeviceVendor(deviceIndex, name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceDescription()\n");
-    return getMidiDeviceDescription(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
-                                    name, nameLength);
-}
-
-
-INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
-    TRACE0("MIDI_OUT_GetDeviceVersion()\n");
-    return getMidiDeviceVersion(deviceIndex, name, nameLength);
-}
-
-
-/* *************************** MidiOutDevice implementation *************** */
-
-INT32 MIDI_OUT_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
-    TRACE1("MIDI_OUT_OpenDevice(): deviceIndex: %d\n", (int) deviceIndex);
-    return openMidiDevice(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex, handle);
-}
-
-
-INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
-    TRACE0("MIDI_OUT_CloseDevice()\n");
-    return closeMidiDevice(handle);
-}
-
-
-INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
-    return getMidiTimestamp(handle);
-}
-
-
-INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg,
-                                UINT32 timestamp) {
-    int err;
-    int status;
-    int data1;
-    int data2;
-    char buffer[3];
-
-    TRACE2("> MIDI_OUT_SendShortMessage() %x, time: %u\n", packedMsg, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendShortMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    status = (packedMsg & 0xFF);
-    buffer[0] = (char) status;
-    buffer[1]  = (char) ((packedMsg >> 8) & 0xFF);
-    buffer[2]  = (char) ((packedMsg >> 16) & 0xFF);
-    TRACE4("status: %d, data1: %d, data2: %d, length: %d\n", (int) buffer[0], (int) buffer[1], (int) buffer[2], getShortMessageLength(status));
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle, buffer, getShortMessageLength(status));
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendShortMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendShortMessage()\n");
-    return err;
-}
-
-
-INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data,
-                               UINT32 size, UINT32 timestamp) {
-    int err;
-
-    TRACE2("> MIDI_OUT_SendLongMessage() size %u, time: %u\n", (unsigned int) size, (unsigned int) timestamp);
-    if (!handle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!data) {
-        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): data is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle,
-                            data, size);
-    if (err < 0) {
-        ERROR1("  ERROR: MIDI_OUT_SendLongMessage(): snd_rawmidi_write() returned %d\n", err);
-    }
-
-    TRACE0("< MIDI_OUT_SendLongMessage()\n");
-    return err;
-}
-
-
-#endif /* USE_PLATFORM_MIDI_OUT */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,481 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-#include <string.h>
-#include <sys/time.h>
-
-static INT64 getTimeInMicroseconds() {
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-    return (tv.tv_sec * 1000000UL) + tv.tv_usec;
-}
-
-
-const char* getErrorStr(INT32 err) {
-        return snd_strerror((int) err);
-}
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID,
-                                 snd_rawmidi_info_t* rawmidi_info,
-                                 snd_ctl_card_info_t* cardinfo,
-                                 void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-static int iterateRawmidiDevices(snd_rawmidi_stream_t direction,
-                                 DeviceIteratorPtr iterator,
-                                 void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_rawmidi_t *rawmidi;
-    snd_rawmidi_info_t *rawmidi_info;
-    snd_ctl_card_info_t *card_info, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_rawmidi_info_malloc(&rawmidi_info);
-    snd_ctl_card_info_malloc(&card_info);
-
-    // 1st try "default" device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("ERROR: iterateRawmidiDevices(): direction is neither"
-               " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n",
-               snd_strerror(err));
-    } else {
-        err = snd_rawmidi_info(rawmidi, rawmidi_info);
-
-        snd_rawmidi_close(rawmidi);
-        if (err < 0) {
-            ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_rawmidi_info_get_card(rawmidi_info);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, card_info) >= 0) {
-                        defcardinfo = card_info;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call calback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    TRACE0("testing for cards...\n");
-    if (snd_card_next(&card) >= 0) {
-        TRACE1("Found card %d\n", card);
-        while (doContinue && (card >= 0)) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                TRACE0("snd_ctl_open() SUCCESS\n");
-                err = snd_ctl_card_info(handle, card_info);
-                if (err < 0) {
-                    ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err));
-                } else {
-                    TRACE0("snd_ctl_card_info() SUCCESS\n");
-                    dev = -1;
-                    while (doContinue) {
-                        if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) {
-                            ERROR0("snd_ctl_rawmidi_next_device\n");
-                        }
-                        TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n");
-                        if (dev < 0) {
-                            break;
-                        }
-                        snd_rawmidi_info_set_device(rawmidi_info, dev);
-                        snd_rawmidi_info_set_subdevice(rawmidi_info, 0);
-                        snd_rawmidi_info_set_stream(rawmidi_info, direction);
-                        err = snd_ctl_rawmidi_info(handle, rawmidi_info);
-                        TRACE0("after snd_ctl_rawmidi_info()\n");
-                        if (err < 0) {
-                            if (err != -ENOENT) {
-                                ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err));
-                            }
-                        } else {
-                            TRACE0("snd_ctl_rawmidi_info() SUCCESS\n");
-                            subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI)
-                                ? snd_rawmidi_info_get_subdevices_count(rawmidi_info)
-                                : 1;
-                            if (iterator!=NULL) {
-                                for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                    TRACE3("  Iterating %d,%d,%d\n", card, dev, subDev);
-                                    deviceID = encodeDeviceID(card, dev, subDev);
-                                    doContinue = (*iterator)(deviceID, rawmidi_info,
-                                                             card_info, userData);
-                                    count++;
-                                    TRACE0("returned from iterator\n");
-                                    if (!doContinue) {
-                                        break;
-                                    }
-                                }
-                            } else {
-                                count += subdeviceCount;
-                            }
-                        }
-                    } // of while(doContinue)
-                }
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    } else {
-        ERROR0("No cards found!\n");
-    }
-    snd_ctl_card_info_free(card_info);
-    snd_rawmidi_info_free(rawmidi_info);
-    return count;
-}
-
-
-
-int getMidiDeviceCount(snd_rawmidi_stream_t direction) {
-    int deviceCount;
-    TRACE0("> getMidiDeviceCount()\n");
-    initAlsaSupport();
-    deviceCount = iterateRawmidiDevices(direction, NULL, NULL);
-    TRACE0("< getMidiDeviceCount()\n");
-    return deviceCount;
-}
-
-
-
-/*
-  userData is assumed to be a pointer to ALSA_MIDIDeviceDescription.
-  ALSA_MIDIDeviceDescription->index has to be set to the index of the device
-  we want to get information of before this method is called the first time via
-  iterateRawmidiDevices(). On each call of this method,
-  ALSA_MIDIDeviceDescription->index is decremented. If it is equal to zero,
-  we have reached the desired device, so action is taken.
-  So after successful completion of iterateRawmidiDevices(),
-  ALSA_MIDIDeviceDescription->index is zero. If it isn't, this is an
-  indication of an error.
-*/
-static int deviceInfoIterator(UINT32 deviceID, snd_rawmidi_info_t *rawmidi_info,
-                              snd_ctl_card_info_t *cardinfo, void *userData) {
-    char buffer[300];
-    ALSA_MIDIDeviceDescription* desc = (ALSA_MIDIDeviceDescription*)userData;
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("deviceInfoIterator\n");
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        desc->deviceID = deviceID;
-
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_RAWMIDI);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        desc->description[0] = 0;
-        if (cardinfo != NULL) {
-            strncpy(desc->description, snd_ctl_card_info_get_name(cardinfo),
-                    desc->strLen);
-            strncat(desc->description, ", ",
-                    desc->strLen - strlen(desc->description));
-        }
-        strncat(desc->description, snd_rawmidi_info_get_id(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_rawmidi_info_get_name(rawmidi_info),
-                desc->strLen - strlen(desc->description));
-        TRACE2("Returning %s, %s\n", desc->name, desc->description);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-
-static int getMIDIDeviceDescriptionByIndex(snd_rawmidi_stream_t direction,
-                                           ALSA_MIDIDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getMIDIDeviceDescriptionByIndex (index = %d)\n", desc->index);
-    iterateRawmidiDevices(direction, &deviceInfoIterator, desc);
-    return (desc->index == 0) ? MIDI_SUCCESS : MIDI_INVALID_DEVICEID;
-}
-
-
-
-int initMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc, int index) {
-    int ret = MIDI_SUCCESS;
-    desc->index = index;
-    desc->strLen = 200;
-    desc->name = (char*) calloc(desc->strLen + 1, 1);
-    desc->description = (char*) calloc(desc->strLen + 1, 1);
-    if (! desc->name ||
-        ! desc->description) {
-        ret = MIDI_OUT_OF_MEMORY;
-    }
-    return ret;
-}
-
-
-void freeMIDIDeviceDescription(ALSA_MIDIDeviceDescription* desc) {
-    if (desc->name) {
-        free(desc->name);
-    }
-    if (desc->description) {
-        free(desc->description);
-    }
-}
-
-
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index, char *name,
-                      UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    TRACE1("getMidiDeviceName: nameLength: %d\n", (int) nameLength);
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        TRACE0("getMidiDeviceName: initMIDIDeviceDescription() SUCCESS\n");
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            strncpy(name, desc.name, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength) {
-    strncpy(name, ALSA_VENDOR, nameLength - 1);
-    name[nameLength - 1] = 0;
-    return MIDI_SUCCESS;
-}
-
-
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction,
-                             int index, char *name, UINT32 nameLength) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            strncpy(name, desc.description, nameLength - 1);
-            name[nameLength - 1] = 0;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength) {
-    getALSAVersion(name, nameLength);
-    return MIDI_SUCCESS;
-}
-
-
-static int getMidiDeviceID(snd_rawmidi_stream_t direction, int index,
-                           UINT32* deviceID) {
-    ALSA_MIDIDeviceDescription desc;
-    int ret;
-
-    ret = initMIDIDeviceDescription(&desc, index);
-    if (ret == MIDI_SUCCESS) {
-        ret = getMIDIDeviceDescriptionByIndex(direction, &desc);
-        if (ret == MIDI_SUCCESS) {
-            // TRACE1("getMidiDeviceName: desc.name: %s\n", desc.name);
-            *deviceID = desc.deviceID;
-        }
-    }
-    freeMIDIDeviceDescription(&desc);
-    return ret;
-}
-
-
-/*
-  direction has to be either SND_RAWMIDI_STREAM_INPUT or
-  SND_RAWMIDI_STREAM_OUTPUT.
-  Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT
-   or a negative ALSA error code is returned.
-*/
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle) {
-    snd_rawmidi_t* native_handle;
-    snd_midi_event_t* event_parser = NULL;
-    int err;
-    UINT32 deviceID = 0;
-    char devicename[100];
-#ifdef ALSA_MIDI_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    TRACE0("> openMidiDevice()\n");
-
-    (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1);
-    if (!(*handle)) {
-        ERROR0("ERROR: openDevice: out of memory\n");
-        return MIDI_OUT_OF_MEMORY;
-    }
-
-    // TODO: iterate to get dev ID from index
-    err = getMidiDeviceID(direction, deviceIndex, &deviceID);
-    TRACE1("  openMidiDevice(): deviceID: %d\n", (int) deviceID);
-    getDeviceStringFromDeviceID(devicename, deviceID,
-                                usePlugHw, ALSA_RAWMIDI);
-    TRACE1("  openMidiDevice(): deviceString: %s\n", devicename);
-
-    // finally open the device
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_rawmidi_open(&native_handle, NULL, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_open(NULL, &native_handle, devicename,
-                               SND_RAWMIDI_NONBLOCK);
-    } else {
-        ERROR0("  ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
-        err = MIDI_INVALID_ARGUMENT;
-    }
-    if (err < 0) {
-        ERROR1("<  ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err);
-        free(*handle);
-        (*handle) = NULL;
-        return err;
-    }
-    /* We opened with non-blocking behaviour to not get hung if the device
-       is used by a different process. Writing, however, should
-       be blocking. So we change it here. */
-    if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
-        err = snd_rawmidi_nonblock(native_handle, 0);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-    if (direction == SND_RAWMIDI_STREAM_INPUT) {
-        err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser);
-        if (err < 0) {
-            ERROR1("  ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err);
-            snd_rawmidi_close(native_handle);
-            free(*handle);
-            (*handle) = NULL;
-            return err;
-        }
-    }
-
-    (*handle)->deviceHandle = (void*) native_handle;
-    (*handle)->startTime = getTimeInMicroseconds();
-    (*handle)->platformData = event_parser;
-    TRACE0("< openMidiDevice(): succeeded\n");
-    return err;
-}
-
-
-
-INT32 closeMidiDevice(MidiDeviceHandle* handle) {
-    int err;
-
-    TRACE0("> closeMidiDevice()\n");
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    if (!handle->deviceHandle) {
-        ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle);
-    TRACE1("  snd_rawmidi_close() returns %d\n", err);
-    if (handle->platformData) {
-        snd_midi_event_free((snd_midi_event_t*) handle->platformData);
-    }
-    free(handle);
-    TRACE0("< closeMidiDevice: succeeded\n");
-    return err;
-}
-
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle) {
-    if (!handle) {
-        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
-        return MIDI_INVALID_HANDLE;
-    }
-    return getTimeInMicroseconds() - handle->startTime;
-}
-
-
-/* end */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.h	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2003, 2007, 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 <alsa/asoundlib.h>
-#include "Utilities.h"
-#include "PlatformMidi.h"
-
-
-#ifndef PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
-#define PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
-
-#define EVENT_PARSER_BUFSIZE (2048)
-
-// if this is defined, use plughw: devices
-//#define ALSA_MIDI_USE_PLUGHW
-#undef ALSA_MIDI_USE_PLUGHW
-
-typedef struct tag_ALSA_MIDIDeviceDescription {
-        int index;          // in
-        int strLen;         // in
-        INT32 deviceID;    // out
-        char* name;         // out
-        char* description;  // out
-} ALSA_MIDIDeviceDescription;
-
-
-const char* getErrorStr(INT32 err);
-
-/* Returns the number of devices. */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceCount(snd_rawmidi_stream_t direction);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceName(snd_rawmidi_stream_t direction, int index,
-                      char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVendor(int index, char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-int getMidiDeviceDescription(snd_rawmidi_stream_t direction, int index,
-                             char *name, UINT32 nameLength);
-
-/* Returns MIDI_SUCCESS or MIDI_INVALID_DEVICEID */
-int getMidiDeviceVersion(int index, char *name, UINT32 nameLength);
-
-// returns 0 on success, otherwise MIDI_OUT_OF_MEMORY or ALSA error code
-/* direction is either SND_RAWMIDI_STREAM_OUTPUT or
-   SND_RAWMIDI_STREAM_INPUT. */
-INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
-                     MidiDeviceHandle** handle);
-
-// returns 0 on success, otherwise a (negative) ALSA error code
-INT32 closeMidiDevice(MidiDeviceHandle* handle);
-
-INT64 getMidiTimestamp(MidiDeviceHandle* handle);
-
-#endif // PLATFORM_API_LINUXOS_ALSA_MIDIUTILS_H_INCLUDED
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,941 +0,0 @@
-/*
- * Copyright (c) 2002, 2011, 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 USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-#include "DirectAudio.h"
-
-#if USE_DAUDIO == TRUE
-
-// GetPosition method 1: based on how many bytes are passed to the kernel driver
-//                       + does not need much processor resources
-//                       - not very exact, "jumps"
-// GetPosition method 2: ask kernel about actual position of playback.
-//                       - very exact
-//                       - switch to kernel layer for each call
-// GetPosition method 3: use snd_pcm_avail() call - not yet in official ALSA
-// quick tests on a Pentium 200MMX showed max. 1.5% processor usage
-// for playing back a CD-quality file and printing 20x per second a line
-// on the console with the current time. So I guess performance is not such a
-// factor here.
-//#define GET_POSITION_METHOD1
-#define GET_POSITION_METHOD2
-
-
-// The default time for a period in microseconds.
-// For very small buffers, only 2 periods are used.
-#define DEFAULT_PERIOD_TIME 20000 /* 20ms */
-
-///// implemented functions of DirectAudio.h
-
-INT32 DAUDIO_GetDirectAudioDeviceCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, DirectAudioDeviceDescription* description) {
-    ALSA_AudioDeviceDescription adesc;
-
-    adesc.index = (int) mixerIndex;
-    adesc.strLen = DAUDIO_STRING_LENGTH;
-
-    adesc.maxSimultaneousLines = (int*) (&(description->maxSimulLines));
-    adesc.deviceID = &(description->deviceID);
-    adesc.name = description->name;
-    adesc.vendor = description->vendor;
-    adesc.description = description->description;
-    adesc.version = description->version;
-
-    return getAudioDeviceDescriptionByIndex(&adesc);
-}
-
-#define MAX_BIT_INDEX 6
-// returns
-// 6: for anything above 24-bit
-// 5: for 4 bytes sample size, 24-bit
-// 4: for 3 bytes sample size, 24-bit
-// 3: for 3 bytes sample size, 20-bit
-// 2: for 2 bytes sample size, 16-bit
-// 1: for 1 byte sample size, 8-bit
-// 0: for anything else
-int getBitIndex(int sampleSizeInBytes, int significantBits) {
-    if (significantBits > 24) return 6;
-    if (sampleSizeInBytes == 4 && significantBits == 24) return 5;
-    if (sampleSizeInBytes == 3) {
-        if (significantBits == 24) return 4;
-        if (significantBits == 20) return 3;
-    }
-    if (sampleSizeInBytes == 2 && significantBits == 16) return 2;
-    if (sampleSizeInBytes == 1 && significantBits == 8) return 1;
-    return 0;
-}
-
-int getSampleSizeInBytes(int bitIndex, int sampleSizeInBytes) {
-    switch(bitIndex) {
-    case 1: return 1;
-    case 2: return 2;
-    case 3: /* fall through */
-    case 4: return 3;
-    case 5: return 4;
-    }
-    return sampleSizeInBytes;
-}
-
-int getSignificantBits(int bitIndex, int significantBits) {
-    switch(bitIndex) {
-    case 1: return 8;
-    case 2: return 16;
-    case 3: return 20;
-    case 4: /* fall through */
-    case 5: return 24;
-    }
-    return significantBits;
-}
-
-void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
-    snd_pcm_t* handle;
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    snd_pcm_hw_params_t* hwParams;
-    int handledBits[MAX_BIT_INDEX+1];
-
-    int ret;
-    int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
-    int origSampleSizeInBytes, origSignificantBits;
-    unsigned int channels, minChannels, maxChannels;
-    int rate, bitIndex;
-
-    for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
-    if (openPCMfromDeviceID(deviceID, &handle, isSource, TRUE /*query hardware*/) < 0) {
-        return;
-    }
-    ret = snd_pcm_format_mask_malloc(&formatMask);
-    if (ret != 0) {
-        ERROR1("snd_pcm_format_mask_malloc returned error %d\n", ret);
-    } else {
-        ret = snd_pcm_hw_params_malloc(&hwParams);
-        if (ret != 0) {
-            ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = snd_pcm_hw_params_any(handle, hwParams);
-            /* snd_pcm_hw_params_any can return a positive value on success too */
-            if (ret < 0) {
-                 ERROR1("snd_pcm_hw_params_any returned error %d\n", ret);
-            } else {
-                /* for the logic following this code, set ret to 0 to indicate success */
-                ret = 0;
-            }
-        }
-        snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_min returned error %d\n", ret);
-            }
-        }
-        if (ret == 0) {
-            ret = snd_pcm_hw_params_get_channels_max(hwParams, &maxChannels);
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
-            }
-        }
-
-        // since we queried the hw: device, for many soundcards, it will only
-        // report the maximum number of channels (which is the only way to talk
-        // to the hw: device). Since we will, however, open the plughw: device
-        // when opening the Source/TargetDataLine, we can safely assume that
-        // also the channels 1..maxChannels are available.
-#ifdef ALSA_PCM_USE_PLUGHW
-        minChannels = 1;
-#endif
-        if (ret == 0) {
-            // plughw: supports any sample rate
-            rate = -1;
-            for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
-                if (snd_pcm_format_mask_test(formatMask, format)) {
-                    // format exists
-                    if (getFormatFromAlsaFormat(format, &origSampleSizeInBytes,
-                                                &origSignificantBits,
-                                                &isSigned, &isBigEndian, &enc)) {
-                        // now if we use plughw:, we can use any bit size below the
-                        // natively supported ones. Some ALSA drivers only support the maximum
-                        // bit size, so we add any sample rates below the reported one.
-                        // E.g. this iteration reports support for 16-bit.
-                        // getBitIndex will return 2, so it will add entries for
-                        // 16-bit (bitIndex=2) and in the next do-while loop iteration,
-                        // it will decrease bitIndex and will therefore add 8-bit support.
-                        bitIndex = getBitIndex(origSampleSizeInBytes, origSignificantBits);
-                        do {
-                            if (bitIndex == 0
-                                || bitIndex == MAX_BIT_INDEX
-                                || !handledBits[bitIndex]) {
-                                handledBits[bitIndex] = TRUE;
-                                sampleSizeInBytes = getSampleSizeInBytes(bitIndex, origSampleSizeInBytes);
-                                significantBits = getSignificantBits(bitIndex, origSignificantBits);
-                                if (maxChannels - minChannels > MAXIMUM_LISTED_CHANNELS) {
-                                    // avoid too many channels explicitly listed
-                                    // just add -1, min, and max
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          -1, -1, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * minChannels,
-                                                          minChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                    DAUDIO_AddAudioFormat(creator, significantBits,
-                                                          sampleSizeInBytes * maxChannels,
-                                                          maxChannels, rate,
-                                                          enc, isSigned, isBigEndian);
-                                } else {
-                                    for (channels = minChannels; channels <= maxChannels; channels++) {
-                                        DAUDIO_AddAudioFormat(creator, significantBits,
-                                                              sampleSizeInBytes * channels,
-                                                              channels, rate,
-                                                              enc, isSigned, isBigEndian);
-                                    }
-                                }
-                            }
-#ifndef ALSA_PCM_USE_PLUGHW
-                            // without plugin, do not add fake formats
-                            break;
-#endif
-                        } while (--bitIndex > 0);
-                    } else {
-                        TRACE1("could not get format from alsa for format %d\n", format);
-                    }
-                } else {
-                    //TRACE1("Format %d not supported\n", format);
-                }
-            } // for loop
-            snd_pcm_hw_params_free(hwParams);
-        }
-        snd_pcm_format_mask_free(formatMask);
-    }
-    snd_pcm_close(handle);
-}
-
-/** Workaround for cr 7033899, 7030629:
- * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty
- * (just opened, underruned or already flushed).
- * Sometimes it causes PCM falls to -EBADFD error,
- * sometimes causes bufferSize change.
- * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used.
- */
-/* ******* ALSA PCM INFO ******************** */
-typedef struct tag_AlsaPcmInfo {
-    snd_pcm_t* handle;
-    snd_pcm_hw_params_t* hwParams;
-    snd_pcm_sw_params_t* swParams;
-    int bufferSizeInBytes;
-    int frameSize; // storage size in Bytes
-    unsigned int periods;
-    snd_pcm_uframes_t periodSize;
-    short int isRunning;    // see comment above
-    short int isFlushed;    // see comment above
-#ifdef GET_POSITION_METHOD2
-    // to be used exclusively by getBytePosition!
-    snd_pcm_status_t* positionStatus;
-#endif
-} AlsaPcmInfo;
-
-
-int setStartThresholdNoCommit(AlsaPcmInfo* info, int useThreshold) {
-    int ret;
-    int threshold;
-
-    if (useThreshold) {
-        // start device whenever anything is written to the buffer
-        threshold = 1;
-    } else {
-        // never start the device automatically
-        threshold = 2000000000; /* near UINT_MAX */
-    }
-    ret = snd_pcm_sw_params_set_start_threshold(info->handle, info->swParams, threshold);
-    if (ret < 0) {
-        ERROR1("Unable to set start threshold mode: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-int setStartThreshold(AlsaPcmInfo* info, int useThreshold) {
-    int ret = 0;
-
-    if (!setStartThresholdNoCommit(info, useThreshold)) {
-        ret = -1;
-    }
-    if (ret == 0) {
-        // commit it
-        ret = snd_pcm_sw_params(info->handle, info->swParams);
-        if (ret < 0) {
-            ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        }
-    }
-    return (ret == 0)?TRUE:FALSE;
-}
-
-
-// returns TRUE if successful
-int setHWParams(AlsaPcmInfo* info,
-                float sampleRate,
-                int channels,
-                int bufferSizeInFrames,
-                snd_pcm_format_t format) {
-    unsigned int rrate, periodTime, periods;
-    int ret, dir;
-    snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
-
-    /* choose all parameters */
-    ret = snd_pcm_hw_params_any(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Broken configuration: no configurations available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the interleaved read/write format */
-    ret = snd_pcm_hw_params_set_access(info->handle, info->hwParams, SND_PCM_ACCESS_RW_INTERLEAVED);
-    if (ret < 0) {
-        ERROR1("SND_PCM_ACCESS_RW_INTERLEAVED access type not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the sample format */
-    ret = snd_pcm_hw_params_set_format(info->handle, info->hwParams, format);
-    if (ret < 0) {
-        ERROR1("Sample format not available: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the count of channels */
-    ret = snd_pcm_hw_params_set_channels(info->handle, info->hwParams, channels);
-    if (ret < 0) {
-        ERROR2("Channels count (%d) not available: %s\n", channels, snd_strerror(ret));
-        return FALSE;
-    }
-    /* set the stream rate */
-    rrate = (int) (sampleRate + 0.5f);
-    dir = 0;
-    ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
-    if (ret < 0) {
-        ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
-        return FALSE;
-    }
-    if ((rrate-sampleRate > 2) || (rrate-sampleRate < - 2)) {
-        ERROR2("Rate doesn't match (requested %2.2fHz, got %dHz)\n", sampleRate, rrate);
-        return FALSE;
-    }
-    /* set the buffer time */
-    ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
-    if (ret < 0) {
-        ERROR2("Unable to set buffer size to %d frames: %s\n",
-               (int) alsaBufferSizeInFrames, snd_strerror(ret));
-        return FALSE;
-    }
-    bufferSizeInFrames = (int) alsaBufferSizeInFrames;
-    /* set the period time */
-    if (bufferSizeInFrames > 1024) {
-        dir = 0;
-        periodTime = DEFAULT_PERIOD_TIME;
-        ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
-            return FALSE;
-        }
-    } else {
-        /* set the period count for very small buffer sizes to 2 */
-        dir = 0;
-        periods = 2;
-        ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
-        if (ret < 0) {
-            ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
-            return FALSE;
-        }
-    }
-    /* write the parameters to device */
-    ret = snd_pcm_hw_params(info->handle, info->hwParams);
-    if (ret < 0) {
-        ERROR1("Unable to set hw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-// returns 1 if successful
-int setSWParams(AlsaPcmInfo* info) {
-    int ret;
-
-    /* get the current swparams */
-    ret = snd_pcm_sw_params_current(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to determine current swparams: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* never start the transfer automatically */
-    if (!setStartThresholdNoCommit(info, FALSE /* don't use threshold */)) {
-        return FALSE;
-    }
-
-    /* allow the transfer when at least period_size samples can be processed */
-    ret = snd_pcm_sw_params_set_avail_min(info->handle, info->swParams, info->periodSize);
-    if (ret < 0) {
-        ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    /* write the parameters to the playback device */
-    ret = snd_pcm_sw_params(info->handle, info->swParams);
-    if (ret < 0) {
-        ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static snd_output_t* ALSA_OUTPUT = NULL;
-
-void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
-                  int encoding, float sampleRate, int sampleSizeInBits,
-                  int frameSize, int channels,
-                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
-    snd_pcm_format_mask_t* formatMask;
-    snd_pcm_format_t format;
-    int dir;
-    int ret = 0;
-    AlsaPcmInfo* info = NULL;
-    /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
-    snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
-
-
-    TRACE0("> DAUDIO_Open\n");
-#ifdef USE_TRACE
-    // for using ALSA debug dump methods
-    if (ALSA_OUTPUT == NULL) {
-        snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
-    }
-#endif
-    if (channels <= 0) {
-        ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
-        return NULL;
-    }
-    info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
-    if (!info) {
-        ERROR0("Out of memory\n");
-        return NULL;
-    }
-    memset(info, 0, sizeof(AlsaPcmInfo));
-    // initial values are: stopped, flushed
-    info->isRunning = 0;
-    info->isFlushed = 1;
-
-    ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/);
-    if (ret == 0) {
-        // set to blocking mode
-        snd_pcm_nonblock(info->handle, 0);
-        ret = snd_pcm_hw_params_malloc(&(info->hwParams));
-        if (ret != 0) {
-            ERROR1("  snd_pcm_hw_params_malloc returned error %d\n", ret);
-        } else {
-            ret = -1;
-            if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits,
-                                        isSigned, isBigEndian, encoding)) {
-                if (setHWParams(info,
-                                sampleRate,
-                                channels,
-                                bufferSizeInBytes / frameSize,
-                                format)) {
-                    info->frameSize = frameSize;
-                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
-                    if (ret < 0) {
-                        ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
-                    }
-                    snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
-                    snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
-                    info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
-                    TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
-                           (int) info->periodSize, info->periods, info->bufferSizeInBytes);
-                }
-            }
-        }
-        if (ret == 0) {
-            // set software parameters
-            ret = snd_pcm_sw_params_malloc(&(info->swParams));
-            if (ret != 0) {
-                ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
-            } else {
-                if (!setSWParams(info)) {
-                    ret = -1;
-                }
-            }
-        }
-        if (ret == 0) {
-            // prepare device
-            ret = snd_pcm_prepare(info->handle);
-            if (ret < 0) {
-                ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-            }
-        }
-
-#ifdef GET_POSITION_METHOD2
-        if (ret == 0) {
-            ret = snd_pcm_status_malloc(&(info->positionStatus));
-            if (ret != 0) {
-                ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret));
-            }
-        }
-#endif
-    }
-    if (ret != 0) {
-        DAUDIO_Close((void*) info, isSource);
-        info = NULL;
-    } else {
-        // set to non-blocking mode
-        snd_pcm_nonblock(info->handle, 1);
-        TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n",
-               (void*) info->handle);
-    }
-    return (void*) info;
-}
-
-#ifdef USE_TRACE
-void printState(snd_pcm_state_t state) {
-    if (state == SND_PCM_STATE_OPEN) {
-        TRACE0("State: SND_PCM_STATE_OPEN\n");
-    }
-    else if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("State: SND_PCM_STATE_SETUP\n");
-    }
-    else if (state == SND_PCM_STATE_PREPARED) {
-        TRACE0("State: SND_PCM_STATE_PREPARED\n");
-    }
-    else if (state == SND_PCM_STATE_RUNNING) {
-        TRACE0("State: SND_PCM_STATE_RUNNING\n");
-    }
-    else if (state == SND_PCM_STATE_XRUN) {
-        TRACE0("State: SND_PCM_STATE_XRUN\n");
-    }
-    else if (state == SND_PCM_STATE_DRAINING) {
-        TRACE0("State: SND_PCM_STATE_DRAINING\n");
-    }
-    else if (state == SND_PCM_STATE_PAUSED) {
-        TRACE0("State: SND_PCM_STATE_PAUSED\n");
-    }
-    else if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("State: SND_PCM_STATE_SUSPENDED\n");
-    }
-}
-#endif
-
-int DAUDIO_Start(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    snd_pcm_state_t state;
-
-    TRACE0("> DAUDIO_Start\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    // set start mode so that it always starts as soon as data is there
-    setStartThreshold(info, TRUE /* use threshold */);
-    state = snd_pcm_state(info->handle);
-    if (state == SND_PCM_STATE_PAUSED) {
-        // in case it was stopped previously
-        TRACE0("  Un-pausing...\n");
-        ret = snd_pcm_pause(info->handle, FALSE);
-        if (ret != 0) {
-            ERROR2("  NOTE: error in snd_pcm_pause:%d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    if (state == SND_PCM_STATE_SUSPENDED) {
-        TRACE0("  Resuming...\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if ((ret != -EAGAIN) && (ret != -ENOSYS)) {
-                ERROR2("  ERROR: error in snd_pcm_resume:%d: %s\n", ret, snd_strerror(ret));
-            }
-        }
-    }
-    if (state == SND_PCM_STATE_SETUP) {
-        TRACE0("need to call prepare again...\n");
-        // prepare device
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
-        }
-    }
-    // in case there is still data in the buffers
-    ret = snd_pcm_start(info->handle);
-    if (ret != 0) {
-        if (ret != -EPIPE) {
-            ERROR2("  NOTE: error in snd_pcm_start: %d: %s\n", ret, snd_strerror(ret));
-        }
-    }
-    // set to non-blocking mode
-    ret = snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("  ERROR in snd_pcm_nonblock: %s\n", snd_strerror(ret));
-    }
-    state = snd_pcm_state(info->handle);
-#ifdef USE_TRACE
-    printState(state);
-#endif
-    ret = (state == SND_PCM_STATE_PREPARED)
-        || (state == SND_PCM_STATE_RUNNING)
-        || (state == SND_PCM_STATE_XRUN)
-        || (state == SND_PCM_STATE_SUSPENDED);
-    if (ret) {
-        info->isRunning = 1;
-        // source line should keep isFlushed value until Write() is called;
-        // for target data line reset it right now.
-        if (!isSource) {
-            info->isFlushed = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Start %s\n", ret?"success":"error");
-    return ret?TRUE:FALSE;
-}
-
-int DAUDIO_Stop(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("> DAUDIO_Stop\n");
-    // set to blocking mode
-    snd_pcm_nonblock(info->handle, 0);
-    setStartThreshold(info, FALSE /* don't use threshold */); // device will not start after buffer xrun
-    ret = snd_pcm_pause(info->handle, 1);
-    // set to non-blocking mode
-    snd_pcm_nonblock(info->handle, 1);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-    info->isRunning = 0;
-    TRACE0("< DAUDIO_Stop success\n");
-    return TRUE;
-}
-
-void DAUDIO_Close(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    TRACE0("DAUDIO_Close\n");
-    if (info != NULL) {
-        if (info->handle != NULL) {
-            snd_pcm_close(info->handle);
-        }
-        if (info->hwParams) {
-            snd_pcm_hw_params_free(info->hwParams);
-        }
-        if (info->swParams) {
-            snd_pcm_sw_params_free(info->swParams);
-        }
-#ifdef GET_POSITION_METHOD2
-        if (info->positionStatus) {
-            snd_pcm_status_free(info->positionStatus);
-        }
-#endif
-        free(info);
-    }
-}
-
-/*
- * Underrun and suspend recovery
- * returns
- * 0:  exit native and return 0
- * 1:  try again to write/read
- * -1: error - exit native with return value -1
- */
-int xrun_recovery(AlsaPcmInfo* info, int err) {
-    int ret;
-
-    if (err == -EPIPE) {    /* underrun / overflow */
-        TRACE0("xrun_recovery: underrun/overflow.\n");
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -ESTRPIPE) {
-        TRACE0("xrun_recovery: suspended.\n");
-        ret = snd_pcm_resume(info->handle);
-        if (ret < 0) {
-            if (ret == -EAGAIN) {
-                return 0; /* wait until the suspend flag is released */
-            }
-            return -1;
-        }
-        ret = snd_pcm_prepare(info->handle);
-        if (ret < 0) {
-            ERROR1("Can't recover from underrun/overflow, prepare failed: %s\n", snd_strerror(ret));
-            return -1;
-        }
-        return 1;
-    } else if (err == -EAGAIN) {
-        TRACE0("xrun_recovery: EAGAIN try again flag.\n");
-        return 0;
-    }
-
-    TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err));
-    return -1;
-}
-
-// returns -1 on error
-int DAUDIO_Write(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, writtenFrames;
-
-    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
-
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Write: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Write returning -1\n");
-        return -1;
-    }
-
-    count = 2; // maximum number of trials to recover from underrun
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        writtenFrames = snd_pcm_writei(info->handle, (const void*) data, (snd_pcm_uframes_t) frameSize);
-
-        if (writtenFrames < 0) {
-            ret = xrun_recovery(info, (int) writtenFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Write: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Write: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, writtenFrames);
-
-    if (writtenFrames > 0) {
-        // reset "flushed" flag
-        info->isFlushed = 0;
-    }
-
-    ret =  (int) (writtenFrames * info->frameSize);
-    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
-    return ret;
-}
-
-// returns -1 on error
-int DAUDIO_Read(void* id, char* data, int byteSize) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret, count;
-    snd_pcm_sframes_t frameSize, readFrames;
-
-    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
-    /*TRACE3("  info=%p, data=%p, byteSize=%d\n",
-      (void*) info, (void*) data, (int) byteSize);
-      TRACE2("  info->frameSize=%d, info->handle=%p\n",
-      (int) info->frameSize, (void*) info->handle);
-    */
-    /* sanity */
-    if (byteSize <= 0 || info->frameSize <= 0) {
-        ERROR2(" DAUDIO_Read: byteSize=%d, frameSize=%d!\n",
-               (int) byteSize, (int) info->frameSize);
-        TRACE0("< DAUDIO_Read returning -1\n");
-        return -1;
-    }
-    if (!info->isRunning && info->isFlushed) {
-        // PCM has nothing to read
-        return 0;
-    }
-
-    count = 2; // maximum number of trials to recover from error
-    //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize);
-    frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize);
-    do {
-        readFrames = snd_pcm_readi(info->handle, (void*) data, (snd_pcm_uframes_t) frameSize);
-        if (readFrames < 0) {
-            ret = xrun_recovery(info, (int) readFrames);
-            if (ret <= 0) {
-                TRACE1("DAUDIO_Read: xrun recovery returned %d -> return.\n", ret);
-                return ret;
-            }
-            if (count-- <= 0) {
-                ERROR0("DAUDIO_Read: too many attempts to recover from xrun/suspend\n");
-                return -1;
-            }
-        } else {
-            break;
-        }
-    } while (TRUE);
-    //ret =  snd_pcm_frames_to_bytes(info->handle, readFrames);
-    ret =  (int) (readFrames * info->frameSize);
-    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
-    return ret;
-}
-
-
-int DAUDIO_GetBufferSize(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-
-    return info->bufferSizeInBytes;
-}
-
-int DAUDIO_StillDraining(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_state_t state;
-
-    state = snd_pcm_state(info->handle);
-    //printState(state);
-    //TRACE1("Still draining: %s\n", (state != SND_PCM_STATE_XRUN)?"TRUE":"FALSE");
-    return (state == SND_PCM_STATE_RUNNING)?TRUE:FALSE;
-}
-
-
-int DAUDIO_Flush(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-
-    TRACE0("DAUDIO_Flush\n");
-
-    if (info->isFlushed) {
-        // nothing to drop
-        return 1;
-    }
-
-    ret = snd_pcm_drop(info->handle);
-    if (ret != 0) {
-        ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret));
-        return FALSE;
-    }
-
-    info->isFlushed = 1;
-    if (info->isRunning) {
-        ret = DAUDIO_Start(id, isSource);
-    }
-    return ret;
-}
-
-int DAUDIO_GetAvailable(void* id, int isSource) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    snd_pcm_sframes_t availableInFrames;
-    snd_pcm_state_t state;
-    int ret;
-
-    state = snd_pcm_state(info->handle);
-    if (info->isFlushed || state == SND_PCM_STATE_XRUN) {
-        // if in xrun state then we have the entire buffer available,
-        // not 0 as alsa reports
-        ret = info->bufferSizeInBytes;
-    } else {
-        availableInFrames = snd_pcm_avail_update(info->handle);
-        if (availableInFrames < 0) {
-            ret = 0;
-        } else {
-            //ret = snd_pcm_frames_to_bytes(info->handle, availableInFrames);
-            ret = (int) (availableInFrames * info->frameSize);
-        }
-    }
-    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
-    return ret;
-}
-
-INT64 estimatePositionFromAvail(AlsaPcmInfo* info, int isSource, INT64 javaBytePos, int availInBytes) {
-    // estimate the current position with the buffer size and
-    // the available bytes to read or write in the buffer.
-    // not an elegant solution - bytePos will stop on xruns,
-    // and in race conditions it may jump backwards
-    // Advantage is that it is indeed based on the samples that go through
-    // the system (rather than time-based methods)
-    if (isSource) {
-        // javaBytePos is the position that is reached when the current
-        // buffer is played completely
-        return (INT64) (javaBytePos - info->bufferSizeInBytes + availInBytes);
-    } else {
-        // javaBytePos is the position that was when the current buffer was empty
-        return (INT64) (javaBytePos + availInBytes);
-    }
-}
-
-INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    AlsaPcmInfo* info = (AlsaPcmInfo*) id;
-    int ret;
-    INT64 result = javaBytePos;
-    snd_pcm_state_t state;
-    state = snd_pcm_state(info->handle);
-
-    if (!info->isFlushed && state != SND_PCM_STATE_XRUN) {
-#ifdef GET_POSITION_METHOD2
-        snd_timestamp_t* ts;
-        snd_pcm_uframes_t framesAvail;
-
-        // note: slight race condition if this is called simultaneously from 2 threads
-        ret = snd_pcm_status(info->handle, info->positionStatus);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_status: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            // calculate from time value, or from available bytes
-            framesAvail = snd_pcm_status_get_avail(info->positionStatus);
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD3
-        snd_pcm_uframes_t framesAvail;
-        ret = snd_pcm_avail(info->handle, &framesAvail);
-        if (ret != 0) {
-            ERROR1("ERROR in snd_pcm_avail: %s\n", snd_strerror(ret));
-            result = javaBytePos;
-        } else {
-            result = estimatePositionFromAvail(info, isSource, javaBytePos, framesAvail * info->frameSize);
-        }
-#endif
-#ifdef GET_POSITION_METHOD1
-        result = estimatePositionFromAvail(info, isSource, javaBytePos, DAUDIO_GetAvailable(id, isSource));
-#endif
-    }
-    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
-    return result;
-}
-
-
-
-void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    /* save to ignore, since GetBytePosition
-     * takes the javaBytePos param into account
-     */
-}
-
-int DAUDIO_RequiresServicing(void* id, int isSource) {
-    // never need servicing on Linux
-    return FALSE;
-}
-
-void DAUDIO_Service(void* id, int isSource) {
-    // never need servicing on Linux
-}
-
-
-#endif // USE_DAUDIO
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 USE_ERROR
-//#define USE_TRACE
-
-#include "PLATFORM_API_LinuxOS_ALSA_PCMUtils.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-
-
-
-// callback for iteration through devices
-// returns TRUE if iteration should continue
-// NOTE: cardinfo may be NULL (for "default" device)
-typedef int (*DeviceIteratorPtr)(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                             snd_ctl_card_info_t* cardinfo, void *userData);
-
-// for each ALSA device, call iterator. userData is passed to the iterator
-// returns total number of iterations
-int iteratePCMDevices(DeviceIteratorPtr iterator, void* userData) {
-    int count = 0;
-    int subdeviceCount;
-    int card, dev, subDev;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_pcm_t *pcm;
-    snd_pcm_info_t* pcminfo;
-    snd_ctl_card_info_t *cardinfo, *defcardinfo = NULL;
-    UINT32 deviceID;
-    int doContinue = TRUE;
-
-    snd_pcm_info_malloc(&pcminfo);
-    snd_ctl_card_info_malloc(&cardinfo);
-
-    // 1st try "default" device
-    err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                       SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
-    if (err < 0) {
-        // try with the other direction
-        err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
-                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
-    }
-    if (err < 0) {
-        ERROR1("ERROR: snd_pcm_open (\"default\"): %s\n", snd_strerror(err));
-    } else {
-        err = snd_pcm_info(pcm, pcminfo);
-        snd_pcm_close(pcm);
-        if (err < 0) {
-            ERROR1("ERROR: snd_pcm_info (\"default\"): %s\n",
-                    snd_strerror(err));
-        } else {
-            // try to get card info
-            card = snd_pcm_info_get_card(pcminfo);
-            if (card >= 0) {
-                sprintf(devname, ALSA_HARDWARE_CARD, card);
-                if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) {
-                    if (snd_ctl_card_info(handle, cardinfo) >= 0) {
-                        defcardinfo = cardinfo;
-                    }
-                    snd_ctl_close(handle);
-                }
-            }
-            // call callback function for the device
-            if (iterator != NULL) {
-                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, pcminfo,
-                                         defcardinfo, userData);
-            }
-            count++;
-        }
-    }
-
-    // iterate cards
-    card = -1;
-    while (doContinue) {
-        if (snd_card_next(&card) < 0) {
-            break;
-        }
-        if (card < 0) {
-            break;
-        }
-        sprintf(devname, ALSA_HARDWARE_CARD, card);
-        TRACE1("Opening alsa device \"%s\"...\n", devname);
-        err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK);
-        if (err < 0) {
-            ERROR2("ERROR: snd_ctl_open, card=%d: %s\n",
-                    card, snd_strerror(err));
-        } else {
-            err = snd_ctl_card_info(handle, cardinfo);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n",
-                        card, snd_strerror(err));
-            } else {
-                dev = -1;
-                while (doContinue) {
-                    if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
-                        ERROR0("snd_ctl_pcm_next_device\n");
-                    }
-                    if (dev < 0) {
-                        break;
-                    }
-                    snd_pcm_info_set_device(pcminfo, dev);
-                    snd_pcm_info_set_subdevice(pcminfo, 0);
-                    snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
-                    err = snd_ctl_pcm_info(handle, pcminfo);
-                    if (err == -ENOENT) {
-                        // try with the other direction
-                        snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
-                        err = snd_ctl_pcm_info(handle, pcminfo);
-                    }
-                    if (err < 0) {
-                        if (err != -ENOENT) {
-                            ERROR2("ERROR: snd_ctl_pcm_info, card=%d: %s",
-                                    card, snd_strerror(err));
-                        }
-                    } else {
-                        subdeviceCount = needEnumerateSubdevices(ALSA_PCM) ?
-                            snd_pcm_info_get_subdevices_count(pcminfo) : 1;
-                        if (iterator!=NULL) {
-                            for (subDev = 0; subDev < subdeviceCount; subDev++) {
-                                deviceID = encodeDeviceID(card, dev, subDev);
-                                doContinue = (*iterator)(deviceID, pcminfo,
-                                                         cardinfo, userData);
-                                count++;
-                                if (!doContinue) {
-                                    break;
-                                }
-                            }
-                        } else {
-                            count += subdeviceCount;
-                        }
-                    }
-                } // of while(doContinue)
-            }
-            snd_ctl_close(handle);
-        }
-    }
-    snd_ctl_card_info_free(cardinfo);
-    snd_pcm_info_free(pcminfo);
-    return count;
-}
-
-int getAudioDeviceCount() {
-    initAlsaSupport();
-    return iteratePCMDevices(NULL, NULL);
-}
-
-int deviceInfoIterator(UINT32 deviceID, snd_pcm_info_t* pcminfo,
-                       snd_ctl_card_info_t* cardinfo, void* userData) {
-    char buffer[300];
-    ALSA_AudioDeviceDescription* desc = (ALSA_AudioDeviceDescription*)userData;
-#ifdef ALSA_PCM_USE_PLUGHW
-    int usePlugHw = 1;
-#else
-    int usePlugHw = 0;
-#endif
-
-    initAlsaSupport();
-    if (desc->index == 0) {
-        // we found the device with correct index
-        *(desc->maxSimultaneousLines) = needEnumerateSubdevices(ALSA_PCM) ?
-                1 : snd_pcm_info_get_subdevices_count(pcminfo);
-        *desc->deviceID = deviceID;
-        buffer[0]=' '; buffer[1]='[';
-        // buffer[300] is enough to store the actual device string w/o overrun
-        getDeviceStringFromDeviceID(&buffer[2], deviceID, usePlugHw, ALSA_PCM);
-        strncat(buffer, "]", sizeof(buffer) - strlen(buffer) - 1);
-        strncpy(desc->name,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_id(cardinfo)
-                    : snd_pcm_info_get_id(pcminfo),
-                desc->strLen - strlen(buffer));
-        strncat(desc->name, buffer, desc->strLen - strlen(desc->name));
-        strncpy(desc->vendor, "ALSA (http://www.alsa-project.org)", desc->strLen);
-        strncpy(desc->description,
-                (cardinfo != NULL)
-                    ? snd_ctl_card_info_get_name(cardinfo)
-                    : snd_pcm_info_get_name(pcminfo),
-                desc->strLen);
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_id(pcminfo), desc->strLen - strlen(desc->description));
-        strncat(desc->description, ", ", desc->strLen - strlen(desc->description));
-        strncat(desc->description, snd_pcm_info_get_name(pcminfo), desc->strLen - strlen(desc->description));
-        getALSAVersion(desc->version, desc->strLen);
-        TRACE4("Returning %s, %s, %s, %s\n", desc->name, desc->vendor, desc->description, desc->version);
-        return FALSE; // do not continue iteration
-    }
-    desc->index--;
-    return TRUE;
-}
-
-// returns 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware) {
-    char buffer[200];
-    int ret;
-
-    initAlsaSupport();
-    getDeviceStringFromDeviceID(buffer, deviceID, !hardware, ALSA_PCM);
-
-    TRACE1("Opening ALSA device %s\n", buffer);
-    ret = snd_pcm_open(handle, buffer,
-                       isSource?SND_PCM_STREAM_PLAYBACK:SND_PCM_STREAM_CAPTURE,
-                       SND_PCM_NONBLOCK);
-    if (ret != 0) {
-        ERROR1("snd_pcm_open returned error code %d \n", ret);
-        *handle = NULL;
-    }
-    return ret;
-}
-
-
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc) {
-    initAlsaSupport();
-    TRACE1(" getAudioDeviceDescriptionByIndex(mixerIndex = %d\n", desc->index);
-    iteratePCMDevices(&deviceInfoIterator, desc);
-    return (desc->index == 0)?TRUE:FALSE;
-}
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc) {
-
-    *sampleSizeInBytes = (snd_pcm_format_physical_width(alsaFormat) + 7) / 8;
-    *significantBits = snd_pcm_format_width(alsaFormat);
-
-    // defaults
-    *enc = 0; // PCM
-    *isSigned = (snd_pcm_format_signed(alsaFormat) > 0);
-    *isBigEndian = (snd_pcm_format_big_endian(alsaFormat) > 0);
-
-    // non-PCM formats
-    if (alsaFormat == SND_PCM_FORMAT_MU_LAW) { // Mu-Law
-        *sampleSizeInBytes = 8; *enc = 1; *significantBits = *sampleSizeInBytes;
-    }
-    else if (alsaFormat == SND_PCM_FORMAT_A_LAW) {     // A-Law
-        *sampleSizeInBytes = 8; *enc = 2; *significantBits = *sampleSizeInBytes;
-    }
-    else if (snd_pcm_format_linear(alsaFormat) < 1) {
-        return 0;
-    }
-    return (*sampleSizeInBytes > 0);
-}
-
-// returns 1 if successful
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc) {
-    *alsaFormat = SND_PCM_FORMAT_UNKNOWN;
-
-    if (enc == 0) {
-        *alsaFormat = snd_pcm_build_linear_format(significantBits,
-                                                  sampleSizeInBytes * 8,
-                                                  isSigned?0:1,
-                                                  isBigEndian?1:0);
-    }
-    else if ((sampleSizeInBytes == 1) && (significantBits == 8)) {
-        if (enc == 1) { // ULAW
-            *alsaFormat = SND_PCM_FORMAT_MU_LAW;
-        }
-        else if (enc == 2) { // ALAW
-            *alsaFormat = SND_PCM_FORMAT_A_LAW;
-        }
-    }
-    return (*alsaFormat == SND_PCM_FORMAT_UNKNOWN)?0:1;
-}
-
-
-/* end */
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, 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 this with a later version of ALSA than 0.9.0rc3
-// (starting from 1.0.0 it became default behaviour)
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#include <alsa/asoundlib.h>
-#include "Utilities.h"
-
-#ifndef PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
-#define PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
-
-// if this is defined, use plughw: devices
-#define ALSA_PCM_USE_PLUGHW
-//#undef ALSA_PCM_USE_PLUGHW
-
-
-// maximum number of channels that is listed in the formats. If more, than
-// just -1 for channel count is used.
-#define MAXIMUM_LISTED_CHANNELS 32
-
-typedef struct tag_ALSA_AudioDeviceDescription {
-    int index;          // in
-    int strLen;         // in
-    INT32* deviceID;    // out
-    int* maxSimultaneousLines; // out
-    char* name;         // out
-    char* vendor;       // out
-    char* description;  // out
-    char* version;      // out
-} ALSA_AudioDeviceDescription;
-
-
-
-int getAudioDeviceCount();
-int getAudioDeviceDescriptionByIndex(ALSA_AudioDeviceDescription* desc);
-
-// returns ALSA error code, or 0 if successful
-int openPCMfromDeviceID(int deviceID, snd_pcm_t** handle, int isSource, int hardware);
-
-// returns 1 if successful
-// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
-int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
-                            int* sampleSizeInBytes, int* significantBits,
-                            int* isSigned, int* isBigEndian, int* enc);
-
-int getAlsaFormatFromFormat(snd_pcm_format_t* alsaFormat,
-                            int sampleSizeInBytes, int significantBits,
-                            int isSigned, int isBigEndian, int enc);
-
-#endif // PLATFORM_API_LINUXOS_ALSA_PCMUTILS_H_INCLUDED
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,724 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-#define USE_ERROR
-//#define USE_TRACE
-
-#include "Ports.h"
-#include "PLATFORM_API_LinuxOS_ALSA_CommonUtils.h"
-#include <alsa/asoundlib.h>
-
-#if USE_PORTS == TRUE
-
-#define MAX_ELEMS (300)
-#define MAX_CONTROLS (MAX_ELEMS * 4)
-
-#define CHANNELS_MONO (SND_MIXER_SCHN_LAST + 1)
-#define CHANNELS_STEREO (SND_MIXER_SCHN_LAST + 2)
-
-typedef struct {
-    snd_mixer_elem_t* elem;
-    INT32 portType; /* one of PORT_XXX_xx */
-    char* controlType; /* one of CONTROL_TYPE_xx */
-    /* Values: either SND_MIXER_SCHN_FRONT_xx, CHANNELS_MONO or CHANNELS_STEREO.
-       For SND_MIXER_SCHN_FRONT_xx, exactly this channel is set/retrieved directly.
-       For CHANNELS_MONO, ALSA channel SND_MIXER_SCHN_MONO is set/retrieved directly.
-       For CHANNELS_STEREO, ALSA channels SND_MIXER_SCHN_FRONT_LEFT and SND_MIXER_SCHN_FRONT_RIGHT
-       are set after a calculation that takes balance into account. Retrieved? Average of both
-       channels? (Using a cached value is not a good idea since the value in the HW may have been
-       altered.) */
-    INT32 channel;
-} PortControl;
-
-
-typedef struct tag_PortMixer {
-    snd_mixer_t* mixer_handle;
-    /* Number of array elements used in elems and types. */
-    int numElems;
-    snd_mixer_elem_t** elems;
-    /* Array of port types (PORT_SRC_UNKNOWN etc.). Indices are the same as in elems. */
-    INT32* types;
-    /* Number of array elements used in controls. */
-    int numControls;
-    PortControl* controls;
-} PortMixer;
-
-
-///// implemented functions of Ports.h
-
-INT32 PORT_GetPortMixerCount() {
-    INT32 mixerCount;
-    int card;
-    char devname[16];
-    int err;
-    snd_ctl_t *handle;
-    snd_ctl_card_info_t* info;
-
-    TRACE0("> PORT_GetPortMixerCount\n");
-
-    initAlsaSupport();
-
-    snd_ctl_card_info_malloc(&info);
-    card = -1;
-    mixerCount = 0;
-    if (snd_card_next(&card) >= 0) {
-        while (card >= 0) {
-            sprintf(devname, ALSA_HARDWARE_CARD, card);
-            TRACE1("PORT_GetPortMixerCount: Opening alsa device \"%s\"...\n", devname);
-            err = snd_ctl_open(&handle, devname, 0);
-            if (err < 0) {
-                ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err));
-            } else {
-                mixerCount++;
-                snd_ctl_close(handle);
-            }
-            if (snd_card_next(&card) < 0) {
-                break;
-            }
-        }
-    }
-    snd_ctl_card_info_free(info);
-    TRACE0("< PORT_GetPortMixerCount\n");
-    return mixerCount;
-}
-
-
-INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
-    snd_ctl_t* handle;
-    snd_ctl_card_info_t* card_info;
-    char devname[16];
-    int err;
-    char buffer[100];
-
-    TRACE0("> PORT_GetPortMixerDescription\n");
-    snd_ctl_card_info_malloc(&card_info);
-
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    TRACE1("Opening alsa device \"%s\"...\n", devname);
-    err = snd_ctl_open(&handle, devname, 0);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-        return FALSE;
-    }
-    err = snd_ctl_card_info(handle, card_info);
-    if (err < 0) {
-        ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", (int) mixerIndex, snd_strerror(err));
-    }
-    strncpy(description->name, snd_ctl_card_info_get_id(card_info), PORT_STRING_LENGTH - 1);
-    sprintf(buffer, " [%s]", devname);
-    strncat(description->name, buffer, PORT_STRING_LENGTH - 1 - strlen(description->name));
-    strncpy(description->vendor, "ALSA (http://www.alsa-project.org)", PORT_STRING_LENGTH - 1);
-    strncpy(description->description, snd_ctl_card_info_get_name(card_info), PORT_STRING_LENGTH - 1);
-    strncat(description->description, ", ", PORT_STRING_LENGTH - 1 - strlen(description->description));
-    strncat(description->description, snd_ctl_card_info_get_mixername(card_info), PORT_STRING_LENGTH - 1 - strlen(description->description));
-    getALSAVersion(description->version, PORT_STRING_LENGTH - 1);
-
-    snd_ctl_close(handle);
-    snd_ctl_card_info_free(card_info);
-    TRACE0("< PORT_GetPortMixerDescription\n");
-    return TRUE;
-}
-
-
-void* PORT_Open(INT32 mixerIndex) {
-    char devname[16];
-    snd_mixer_t* mixer_handle;
-    int err;
-    PortMixer* handle;
-
-    TRACE0("> PORT_Open\n");
-    sprintf(devname, ALSA_HARDWARE_CARD, (int) mixerIndex);
-    if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) {
-        ERROR2("Mixer %s open error: %s", devname, snd_strerror(err));
-        return NULL;
-    }
-    if ((err = snd_mixer_attach(mixer_handle, devname)) < 0) {
-        ERROR2("Mixer attach %s error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0) {
-        ERROR1("Mixer register error: %s", snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    err = snd_mixer_load(mixer_handle);
-    if (err < 0) {
-        ERROR2("Mixer %s load error: %s", devname, snd_strerror(err));
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle = (PortMixer*) calloc(1, sizeof(PortMixer));
-    if (handle == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        return NULL;
-    }
-    handle->numElems = 0;
-    handle->elems = (snd_mixer_elem_t**) calloc(MAX_ELEMS, sizeof(snd_mixer_elem_t*));
-    if (handle->elems == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle);
-        return NULL;
-    }
-    handle->types = (INT32*) calloc(MAX_ELEMS, sizeof(INT32));
-    if (handle->types == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle);
-        return NULL;
-    }
-    handle->controls = (PortControl*) calloc(MAX_CONTROLS, sizeof(PortControl));
-    if (handle->controls == NULL) {
-        ERROR0("malloc() failed.");
-        snd_mixer_close(mixer_handle);
-        free(handle->elems);
-        free(handle->types);
-        free(handle);
-        return NULL;
-    }
-    handle->mixer_handle = mixer_handle;
-    // necessary to initialize data structures
-    PORT_GetPortCount(handle);
-    TRACE0("< PORT_Open\n");
-    return handle;
-}
-
-
-void PORT_Close(void* id) {
-    TRACE0("> PORT_Close\n");
-    if (id != NULL) {
-        PortMixer* handle = (PortMixer*) id;
-        if (handle->mixer_handle != NULL) {
-            snd_mixer_close(handle->mixer_handle);
-        }
-        if (handle->elems != NULL) {
-            free(handle->elems);
-        }
-        if (handle->types != NULL) {
-            free(handle->types);
-        }
-        if (handle->controls != NULL) {
-            free(handle->controls);
-        }
-        free(handle);
-    }
-    TRACE0("< PORT_Close\n");
-}
-
-
-
-INT32 PORT_GetPortCount(void* id) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t *elem;
-
-    TRACE0("> PORT_GetPortCount\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portMixer->numElems == 0) {
-        for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
-            if (!snd_mixer_selem_is_active(elem))
-                continue;
-            TRACE2("Simple mixer control '%s',%i\n",
-                   snd_mixer_selem_get_name(elem),
-                   snd_mixer_selem_get_index(elem));
-            if (snd_mixer_selem_has_playback_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-            /* If an element has both playback an capture volume, it is put into the arrays
-               twice. */
-            if (snd_mixer_selem_has_capture_volume(elem)) {
-                portMixer->elems[portMixer->numElems] = elem;
-                portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN;
-                portMixer->numElems++;
-            }
-            // to prevent buffer overflow
-            if (portMixer->numElems >= MAX_ELEMS) {
-                break;
-            }
-        }
-    }
-    TRACE0("< PORT_GetPortCount\n");
-    return portMixer->numElems;
-}
-
-
-INT32 PORT_GetPortType(void* id, INT32 portIndex) {
-    PortMixer* portMixer;
-    INT32 type;
-    TRACE0("> PORT_GetPortType\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    type = portMixer->types[portIndex];
-    TRACE0("< PORT_GetPortType\n");
-    return type;
-}
-
-
-INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
-    PortMixer* portMixer;
-    const char* nam;
-
-    TRACE0("> PORT_GetPortName\n");
-    if (id == NULL) {
-        // $$mp: Should become a descriptive error code (invalid handle).
-        return -1;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        // $$mp: Should become a descriptive error code (index out of bounds).
-        return -1;
-    }
-    nam = snd_mixer_selem_get_name(portMixer->elems[portIndex]);
-    strncpy(name, nam, len - 1);
-    name[len - 1] = 0;
-    TRACE0("< PORT_GetPortName\n");
-    return TRUE;
-}
-
-
-static int isPlaybackFunction(INT32 portType) {
-        return (portType & PORT_DST_MASK);
-}
-
-
-/* Sets portControl to a pointer to the next free array element in the PortControl (pointer)
-   array of the passed portMixer. Returns TRUE if successful. May return FALSE if there is no
-   free slot. In this case, portControl is not altered */
-static int getControlSlot(PortMixer* portMixer, PortControl** portControl) {
-    if (portMixer->numControls >= MAX_CONTROLS) {
-        return FALSE;
-    } else {
-        *portControl = &(portMixer->controls[portMixer->numControls]);
-        portMixer->numControls++;
-        return TRUE;
-    }
-}
-
-
-/* Protect against illegal min-max values, preventing divisions by zero.
- */
-inline static long getRange(long min, long max) {
-    if (max > min) {
-        return max - min;
-    } else {
-        return 1;
-    }
-}
-
-
-/* Idea: we may specify that if unit is an empty string, the values are linear and if unit is "dB",
-   the values are logarithmic.
-*/
-static void* createVolumeControl(PortControlCreator* creator,
-                                 PortControl* portControl,
-                                 snd_mixer_elem_t* elem, int isPlayback) {
-    void* control;
-    float precision;
-    long min, max;
-
-    if (isPlayback) {
-        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
-    }
-    /* $$mp: The volume values retrieved with the ALSA API are strongly supposed to be logarithmic.
-       So the following calculation is wrong. However, there is no correct calculation, since
-       for equal-distant logarithmic steps, the precision expressed in linear varies over the
-       scale. */
-    precision = 1.0F / getRange(min, max);
-    control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_VOLUME, 0.0F, +1.0F, precision, "");
-    return control;
-}
-
-
-void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
-    PortMixer* portMixer;
-    snd_mixer_elem_t* elem;
-    void* control;
-    PortControl* portControl;
-    void* controls[10];
-    int numControls;
-    char* portName;
-    int isPlayback = 0;
-    int isMono;
-    int isStereo;
-    char* type;
-    snd_mixer_selem_channel_id_t channel;
-    memset(controls, 0, sizeof(controls));
-
-    TRACE0("> PORT_GetControls\n");
-    if (id == NULL) {
-        ERROR0("Invalid handle!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    portMixer = (PortMixer*) id;
-    if (portIndex < 0 || portIndex >= portMixer->numElems) {
-        ERROR0("Port index out of range!");
-        // $$mp: an error code should be returned.
-        return;
-    }
-    numControls = 0;
-    elem = portMixer->elems[portIndex];
-    if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) {
-        /* Since we've split/duplicated elements with both playback and capture on the recovery
-           of elements, we now can assume that we handle only to deal with either playback or
-           capture. */
-        isPlayback = isPlaybackFunction(portMixer->types[portIndex]);
-        isMono = (isPlayback && snd_mixer_selem_is_playback_mono(elem)) ||
-            (!isPlayback && snd_mixer_selem_is_capture_mono(elem));
-        isStereo = (isPlayback &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) ||
-            (!isPlayback &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
-             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT));
-        // single volume control
-        if (isMono || isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_VOLUME;
-                if (isMono) {
-                    portControl->channel = CHANNELS_MONO;
-                } else {
-                    portControl->channel = CHANNELS_STEREO;
-                }
-                control = createVolumeControl(creator, portControl, elem, isPlayback);
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        } else { // more than two channels, each channels has its own control.
-            for (channel = SND_MIXER_SCHN_FRONT_LEFT; channel <= SND_MIXER_SCHN_LAST; channel++) {
-                if ((isPlayback && snd_mixer_selem_has_playback_channel(elem, channel)) ||
-                    (!isPlayback && snd_mixer_selem_has_capture_channel(elem, channel))) {
-                    if (getControlSlot(portMixer, &portControl)) {
-                        portControl->elem = elem;
-                        portControl->portType = portMixer->types[portIndex];
-                        portControl->controlType = CONTROL_TYPE_VOLUME;
-                        portControl->channel = channel;
-                        control = createVolumeControl(creator, portControl, elem, isPlayback);
-                        // We wrap in a compound control to provide the channel name.
-                        if (control != NULL) {
-                            /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-                               declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-                               to take a const char* parameter. */
-                            control = (creator->newCompoundControl)(creator, (char*) snd_mixer_selem_channel_name(channel), &control, 1);
-                        }
-                        if (control != NULL) {
-                            controls[numControls++] = control;
-                        }
-                    }
-                }
-            }
-        }
-        // BALANCE control
-        if (isStereo) {
-            if (getControlSlot(portMixer, &portControl)) {
-                portControl->elem = elem;
-                portControl->portType = portMixer->types[portIndex];
-                portControl->controlType = CONTROL_TYPE_BALANCE;
-                portControl->channel = CHANNELS_STEREO;
-                /* $$mp: The value for precision is chosen more or less arbitrarily. */
-                control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_BALANCE, -1.0F, 1.0F, 0.01F, "");
-                if (control != NULL) {
-                    controls[numControls++] = control;
-                }
-            }
-        }
-    }
-    if (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_capture_switch(elem)) {
-        if (getControlSlot(portMixer, &portControl)) {
-            type = isPlayback ? CONTROL_TYPE_MUTE : CONTROL_TYPE_SELECT;
-            portControl->elem = elem;
-            portControl->portType = portMixer->types[portIndex];
-            portControl->controlType = type;
-            control = (creator->newBooleanControl)(creator, portControl, type);
-            if (control != NULL) {
-                controls[numControls++] = control;
-            }
-        }
-    }
-    /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
-       declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
-       to take a const char* parameter. */
-    portName = (char*) snd_mixer_selem_get_name(elem);
-    control = (creator->newCompoundControl)(creator, portName, controls, numControls);
-    if (control != NULL) {
-        (creator->addControl)(creator, control);
-    }
-    TRACE0("< PORT_GetControls\n");
-}
-
-
-INT32 PORT_GetIntValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    int value = 0;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        switch (portControl->channel) {
-        case CHANNELS_MONO:
-            channel = SND_MIXER_SCHN_MONO;
-            break;
-
-        case CHANNELS_STEREO:
-            channel = SND_MIXER_SCHN_FRONT_LEFT;
-            break;
-
-        default:
-            channel = portControl->channel;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_get_playback_switch(portControl->elem, channel, &value);
-            } else {
-                snd_mixer_selem_get_capture_switch(portControl->elem, channel, &value);
-            }
-            if (portControl->controlType == CONTROL_TYPE_MUTE) {
-                value = ! value;
-            }
-        } else {
-            ERROR1("PORT_GetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-    return (INT32) value;
-}
-
-
-void PORT_SetIntValue(void* controlIDV, INT32 value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    snd_mixer_selem_channel_id_t channel;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_MUTE) {
-            value = ! value;
-        }
-        if (portControl->controlType == CONTROL_TYPE_MUTE ||
-            portControl->controlType == CONTROL_TYPE_SELECT) {
-            if (isPlaybackFunction(portControl->portType)) {
-                snd_mixer_selem_set_playback_switch_all(portControl->elem, value);
-            } else {
-                snd_mixer_selem_set_capture_switch_all(portControl->elem, value);
-            }
-        } else {
-            ERROR1("PORT_SetIntValue(): inappropriate control type: %s\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-static float scaleVolumeValueToNormalized(long value, long min, long max) {
-    return (float) (value - min) / getRange(min, max);
-}
-
-
-static long scaleVolumeValueToHardware(float value, long min, long max) {
-    return (long)(value * getRange(min, max) + min);
-}
-
-
-float getRealVolume(PortControl* portControl,
-                    snd_mixer_selem_channel_id_t channel) {
-    float fValue;
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        snd_mixer_selem_get_playback_volume(portControl->elem,
-                                            channel, &lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        snd_mixer_selem_get_capture_volume(portControl->elem,
-                                           channel, &lValue);
-    }
-    fValue = scaleVolumeValueToNormalized(lValue, min, max);
-    return fValue;
-}
-
-
-void setRealVolume(PortControl* portControl,
-                   snd_mixer_selem_channel_id_t channel, float value) {
-    long lValue = 0;
-    long min = 0;
-    long max = 0;
-
-    if (isPlaybackFunction(portControl->portType)) {
-        snd_mixer_selem_get_playback_volume_range(portControl->elem,
-                                                  &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_playback_volume(portControl->elem,
-                                            channel, lValue);
-    } else {
-        snd_mixer_selem_get_capture_volume_range(portControl->elem,
-                                                 &min, &max);
-        lValue = scaleVolumeValueToHardware(value, min, max);
-        snd_mixer_selem_set_capture_volume(portControl->elem,
-                                           channel, lValue);
-    }
-}
-
-
-static float getFakeBalance(PortControl* portControl) {
-    float volL, volR;
-
-    // pan is the ratio of left and right
-    volL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    volR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    if (volL > volR) {
-        return -1.0f + (volR / volL);
-    }
-    else if (volR > volL) {
-        return 1.0f - (volL / volR);
-    }
-    return 0.0f;
-}
-
-
-static float getFakeVolume(PortControl* portControl) {
-    float valueL;
-    float valueR;
-    float value;
-
-    valueL = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT);
-    valueR = getRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT);
-    // volume is the greater value of both
-    value = valueL > valueR ? valueL : valueR ;
-    return value;
-}
-
-
-/*
- * sets the unsigned values for left and right volume according to
- * the given volume (0...1) and balance (-1..0..+1)
- */
-static void setFakeVolume(PortControl* portControl, float vol, float bal) {
-    float volumeLeft;
-    float volumeRight;
-
-    if (bal < 0.0f) {
-        volumeLeft = vol;
-        volumeRight = vol * (bal + 1.0f);
-    } else {
-        volumeLeft = vol * (1.0f - bal);
-        volumeRight = vol;
-    }
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_LEFT, volumeLeft);
-    setRealVolume(portControl, SND_MIXER_SCHN_FRONT_RIGHT, volumeRight);
-}
-
-
-float PORT_GetFloatValue(void* controlIDV) {
-    PortControl* portControl = (PortControl*) controlIDV;
-    float value = 0.0F;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                value = getRealVolume(portControl, SND_MIXER_SCHN_MONO);
-                break;
-
-            case CHANNELS_STEREO:
-                value = getFakeVolume(portControl);
-                break;
-
-            default:
-                value = getRealVolume(portControl, portControl->channel);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                value = getFakeBalance(portControl);
-            } else {
-                ERROR0("PORT_GetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_GetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-    return value;
-}
-
-
-void PORT_SetFloatValue(void* controlIDV, float value) {
-    PortControl* portControl = (PortControl*) controlIDV;
-
-    if (portControl != NULL) {
-        if (portControl->controlType == CONTROL_TYPE_VOLUME) {
-            switch (portControl->channel) {
-            case CHANNELS_MONO:
-                setRealVolume(portControl, SND_MIXER_SCHN_MONO, value);
-                break;
-
-            case CHANNELS_STEREO:
-                setFakeVolume(portControl, value, getFakeBalance(portControl));
-                break;
-
-            default:
-                setRealVolume(portControl, portControl->channel, value);
-            }
-        } else if (portControl->controlType == CONTROL_TYPE_BALANCE) {
-            if (portControl->channel == CHANNELS_STEREO) {
-                setFakeVolume(portControl, getFakeVolume(portControl), value);
-            } else {
-                ERROR0("PORT_SetFloatValue(): Balance only allowed for stereo channels!\n");
-            }
-        } else {
-            ERROR1("PORT_SetFloatValue(): inappropriate control type: %s!\n",
-                   portControl->controlType);
-        }
-    }
-}
-
-
-#endif // USE_PORTS
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,626 +0,0 @@
-/*
- * Copyright (c) 2003, 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 USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_SolarisOS_Utils.h"
-#include "DirectAudio.h"
-
-#if USE_DAUDIO == TRUE
-
-
-// The default buffer time
-#define DEFAULT_PERIOD_TIME_MILLIS 50
-
-///// implemented functions of DirectAudio.h
-
-INT32 DAUDIO_GetDirectAudioDeviceCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex,
-                                             DirectAudioDeviceDescription* description) {
-    AudioDeviceDescription desc;
-
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
-        description->maxSimulLines = desc.maxSimulLines;
-        strncpy(description->name, desc.name, DAUDIO_STRING_LENGTH-1);
-        description->name[DAUDIO_STRING_LENGTH-1] = 0;
-        strncpy(description->vendor, desc.vendor, DAUDIO_STRING_LENGTH-1);
-        description->vendor[DAUDIO_STRING_LENGTH-1] = 0;
-        strncpy(description->version, desc.version, DAUDIO_STRING_LENGTH-1);
-        description->version[DAUDIO_STRING_LENGTH-1] = 0;
-        /*strncpy(description->description, desc.description, DAUDIO_STRING_LENGTH-1);*/
-        strncpy(description->description, "Solaris Mixer", DAUDIO_STRING_LENGTH-1);
-        description->description[DAUDIO_STRING_LENGTH-1] = 0;
-        return TRUE;
-    }
-    return FALSE;
-
-}
-
-#define MAX_SAMPLE_RATES   20
-
-void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
-    int fd = -1;
-    AudioDeviceDescription desc;
-    am_sample_rates_t      *sr;
-    /* hardcoded bits and channels */
-    int bits[] = {8, 16};
-    int bitsCount = 2;
-    int channels[] = {1, 2};
-    int channelsCount = 2;
-    /* for querying sample rates */
-    int err;
-    int ch, b, s;
-
-    TRACE2("DAUDIO_GetFormats, mixer %d, isSource=%d\n", mixerIndex, isSource);
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
-        fd = open(desc.pathctl, O_RDONLY);
-    }
-    if (fd < 0) {
-        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
-        return;
-    }
-
-    /* get sample rates */
-    sr = (am_sample_rates_t*) malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(MAX_SAMPLE_RATES));
-    if (sr == NULL) {
-        ERROR1("DAUDIO_GetFormats: out of memory for mixer %d\n", (int) mixerIndex);
-        close(fd);
-        return;
-    }
-
-    sr->num_samp_rates = MAX_SAMPLE_RATES;
-    sr->type = isSource?AUDIO_PLAY:AUDIO_RECORD;
-    sr->samp_rates[0] = -2;
-    err = ioctl(fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr);
-    if (err < 0) {
-        ERROR1("  DAUDIO_GetFormats: AUDIO_MIXER_GET_SAMPLE_RATES failed for mixer %d!\n",
-               (int)mixerIndex);
-        ERROR2(" -> num_sample_rates=%d sample_rates[0] = %d\n",
-               (int) sr->num_samp_rates,
-               (int) sr->samp_rates[0]);
-        /* Some Solaris 8 drivers fail for get sample rates!
-         * Do as if we support all sample rates
-         */
-        sr->flags = MIXER_SR_LIMITS;
-    }
-    if ((sr->flags & MIXER_SR_LIMITS)
-        || (sr->num_samp_rates > MAX_SAMPLE_RATES)) {
-#ifdef USE_TRACE
-        if ((sr->flags & MIXER_SR_LIMITS)) {
-            TRACE1("  DAUDIO_GetFormats: floating sample rate allowed by mixer %d\n",
-                   (int)mixerIndex);
-        }
-        if (sr->num_samp_rates > MAX_SAMPLE_RATES) {
-            TRACE2("  DAUDIO_GetFormats: more than %d formats. Use -1 for sample rates mixer %d\n",
-                   MAX_SAMPLE_RATES, (int)mixerIndex);
-        }
-#endif
-        /*
-         * Fake it to have only one sample rate: -1
-         */
-        sr->num_samp_rates = 1;
-        sr->samp_rates[0] = -1;
-    }
-    close(fd);
-
-    for (ch = 0; ch < channelsCount; ch++) {
-        for (b = 0; b < bitsCount; b++) {
-            for (s = 0; s < sr->num_samp_rates; s++) {
-                DAUDIO_AddAudioFormat(creator,
-                                      bits[b], /* significant bits */
-                                      0, /* frameSize: let it be calculated */
-                                      channels[ch],
-                                      (float) ((int) sr->samp_rates[s]),
-                                      DAUDIO_PCM, /* encoding - let's only do PCM */
-                                      (bits[b] > 8)?TRUE:TRUE, /* isSigned */
-#ifdef _LITTLE_ENDIAN
-                                      FALSE /* little endian */
-#else
-                                      (bits[b] > 8)?TRUE:FALSE  /* big endian */
-#endif
-                                      );
-            }
-        }
-    }
-    free(sr);
-}
-
-
-typedef struct {
-    int fd;
-    audio_info_t info;
-    int bufferSizeInBytes;
-    int frameSize; /* storage size in Bytes */
-    /* how many bytes were written or read */
-    INT32 transferedBytes;
-    /* if transferedBytes exceed 32-bit boundary,
-     * it will be reset and positionOffset will receive
-     * the offset
-     */
-    INT64 positionOffset;
-} SolPcmInfo;
-
-
-void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
-                  int encoding, float sampleRate, int sampleSizeInBits,
-                  int frameSize, int channels,
-                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
-    int err = 0;
-    int openMode;
-    AudioDeviceDescription desc;
-    SolPcmInfo* info;
-
-    TRACE0("> DAUDIO_Open\n");
-    if (encoding != DAUDIO_PCM) {
-        ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
-        return NULL;
-    }
-    if (channels <= 0) {
-        ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
-        return NULL;
-    }
-
-    info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
-    if (!info) {
-        ERROR0("Out of memory\n");
-        return NULL;
-    }
-    memset(info, 0, sizeof(SolPcmInfo));
-    info->frameSize = frameSize;
-    info->fd = -1;
-
-    if (isSource) {
-        openMode = O_WRONLY;
-    } else {
-        openMode = O_RDONLY;
-    }
-
-#ifndef __linux__
-    /* blackdown does not use NONBLOCK */
-    openMode |= O_NONBLOCK;
-#endif
-
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
-        info->fd = open(desc.path, openMode);
-    }
-    if (info->fd < 0) {
-        ERROR1("Couldn't open audio device for mixer %d!\n", mixerIndex);
-        free(info);
-        return NULL;
-    }
-    /* set to multiple open */
-    if (ioctl(info->fd, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
-        TRACE1("DAUDIO_Open: %s set to multiple open\n", desc.path);
-    } else {
-        ERROR1("DAUDIO_Open: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", desc.path);
-    }
-
-    AUDIO_INITINFO(&(info->info));
-    /* need AUDIO_GETINFO ioctl to get this to work on solaris x86  */
-    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
-
-    /* not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO. */
-    AUDIO_INITINFO(&(info->info));
-
-    if (isSource) {
-        info->info.play.sample_rate = sampleRate;
-        info->info.play.precision = sampleSizeInBits;
-        info->info.play.channels = channels;
-        info->info.play.encoding = AUDIO_ENCODING_LINEAR;
-        info->info.play.buffer_size = bufferSizeInBytes;
-        info->info.play.pause = 1;
-    } else {
-        info->info.record.sample_rate = sampleRate;
-        info->info.record.precision = sampleSizeInBits;
-        info->info.record.channels = channels;
-        info->info.record.encoding = AUDIO_ENCODING_LINEAR;
-        info->info.record.buffer_size = bufferSizeInBytes;
-        info->info.record.pause = 1;
-    }
-    err = ioctl(info->fd, AUDIO_SETINFO,  &(info->info));
-    if (err < 0) {
-        ERROR0("DAUDIO_Open: could not set info!\n");
-        DAUDIO_Close((void*) info, isSource);
-        return NULL;
-    }
-    DAUDIO_Flush((void*) info, isSource);
-
-    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
-    if (err >= 0) {
-        if (isSource) {
-            info->bufferSizeInBytes = info->info.play.buffer_size;
-        } else {
-            info->bufferSizeInBytes = info->info.record.buffer_size;
-        }
-        TRACE2("DAUDIO: buffersize in bytes: requested=%d, got %d\n",
-               (int) bufferSizeInBytes,
-               (int) info->bufferSizeInBytes);
-    } else {
-        ERROR0("DAUDIO_Open: cannot get info!\n");
-        DAUDIO_Close((void*) info, isSource);
-        return NULL;
-    }
-    TRACE0("< DAUDIO_Open: Opened device successfully.\n");
-    return (void*) info;
-}
-
-
-int DAUDIO_Start(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int err, modified;
-    audio_info_t audioInfo;
-
-    TRACE0("> DAUDIO_Start\n");
-
-    AUDIO_INITINFO(&audioInfo);
-    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-    if (err >= 0) {
-        // unpause
-        modified = FALSE;
-        if (isSource && audioInfo.play.pause) {
-            audioInfo.play.pause = 0;
-            modified = TRUE;
-        }
-        if (!isSource && audioInfo.record.pause) {
-            audioInfo.record.pause = 0;
-            modified = TRUE;
-        }
-        if (modified) {
-            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
-        }
-    }
-
-    TRACE1("< DAUDIO_Start %s\n", (err>=0)?"success":"error");
-    return (err >= 0)?TRUE:FALSE;
-}
-
-int DAUDIO_Stop(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int err, modified;
-    audio_info_t audioInfo;
-
-    TRACE0("> DAUDIO_Stop\n");
-
-    AUDIO_INITINFO(&audioInfo);
-    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-    if (err >= 0) {
-        // pause
-        modified = FALSE;
-        if (isSource && !audioInfo.play.pause) {
-            audioInfo.play.pause = 1;
-            modified = TRUE;
-        }
-        if (!isSource && !audioInfo.record.pause) {
-            audioInfo.record.pause = 1;
-            modified = TRUE;
-        }
-        if (modified) {
-            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
-        }
-    }
-
-    TRACE1("< DAUDIO_Stop %s\n", (err>=0)?"success":"error");
-    return (err >= 0)?TRUE:FALSE;
-}
-
-void DAUDIO_Close(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-
-    TRACE0("DAUDIO_Close\n");
-    if (info != NULL) {
-        if (info->fd >= 0) {
-            DAUDIO_Flush(id, isSource);
-            close(info->fd);
-        }
-        free(info);
-    }
-}
-
-#ifndef USE_TRACE
-/* close to 2^31 */
-#define POSITION_MAX 2000000000
-#else
-/* for testing */
-#define POSITION_MAX 1000000
-#endif
-
-void resetErrorFlagAndAdjustPosition(SolPcmInfo* info, int isSource, int count) {
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int err;
-    int offset = -1;
-    int underrun = FALSE;
-    int devBytes = 0;
-
-    if (count > 0) {
-        info->transferedBytes += count;
-
-        if (isSource) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        AUDIO_INITINFO(&audioInfo);
-        err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-        if (err >= 0) {
-            underrun = prinfo->error;
-            devBytes = prinfo->samples * info->frameSize;
-        }
-        AUDIO_INITINFO(&audioInfo);
-        if (underrun) {
-            /* if an underrun occurred, reset */
-            ERROR1("DAUDIO_Write/Read: Underrun/overflow: adjusting positionOffset by %d:\n",
-                   (devBytes - info->transferedBytes));
-            ERROR1("    devBytes from %d to 0, ", devBytes);
-            ERROR2(" positionOffset from %d to %d ",
-                   (int) info->positionOffset,
-                   (int) (info->positionOffset + info->transferedBytes));
-            ERROR1(" transferedBytes from %d to 0\n",
-                   (int) info->transferedBytes);
-            prinfo->samples = 0;
-            info->positionOffset += info->transferedBytes;
-            info->transferedBytes = 0;
-        }
-        else if (info->transferedBytes > POSITION_MAX) {
-            /* we will reset transferedBytes and
-             * the samples field in prinfo
-             */
-            offset = devBytes;
-            prinfo->samples = 0;
-        }
-        /* reset error flag */
-        prinfo->error = 0;
-
-        err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
-        if (err >= 0) {
-            if (offset > 0) {
-                /* upon exit of AUDIO_SETINFO, the samples parameter
-                 * was set to the previous value. This is our
-                 * offset.
-                 */
-                TRACE1("Adjust samplePos: offset=%d, ", (int) offset);
-                TRACE2("transferedBytes=%d -> %d, ",
-                       (int) info->transferedBytes,
-                       (int) (info->transferedBytes - offset));
-                TRACE2("positionOffset=%d -> %d\n",
-                       (int) (info->positionOffset),
-                       (int) (((int) info->positionOffset) + offset));
-                info->transferedBytes -= offset;
-                info->positionOffset += offset;
-            }
-        } else {
-            ERROR0("DAUDIO: resetErrorFlagAndAdjustPosition ioctl failed!\n");
-        }
-    }
-}
-
-// returns -1 on error
-int DAUDIO_Write(void* id, char* data, int byteSize) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret = -1;
-
-    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
-    if (info!=NULL) {
-        ret = write(info->fd, data, byteSize);
-        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
-        /* sets ret to -1 if buffer full, no error! */
-        if (ret < 0) {
-            ret = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
-    return ret;
-}
-
-// returns -1 on error
-int DAUDIO_Read(void* id, char* data, int byteSize) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret = -1;
-
-    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
-    if (info != NULL) {
-        ret = read(info->fd, data, byteSize);
-        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
-        /* sets ret to -1 if buffer full, no error! */
-        if (ret < 0) {
-            ret = 0;
-        }
-    }
-    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
-    return ret;
-}
-
-
-int DAUDIO_GetBufferSize(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    if (info) {
-        return info->bufferSizeInBytes;
-    }
-    return 0;
-}
-
-int DAUDIO_StillDraining(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int ret = FALSE;
-
-    if (info!=NULL) {
-        if (isSource) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        /* check error flag */
-        AUDIO_INITINFO(&audioInfo);
-        ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-        ret = (prinfo->error != 0)?FALSE:TRUE;
-    }
-    return ret;
-}
-
-
-int getDevicePosition(SolPcmInfo* info, int isSource) {
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int err;
-
-    if (isSource) {
-        prinfo = &(audioInfo.play);
-    } else {
-        prinfo = &(audioInfo.record);
-    }
-    AUDIO_INITINFO(&audioInfo);
-    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
-    if (err >= 0) {
-        /*TRACE2("---> device paused: %d  eof=%d\n",
-               prinfo->pause, prinfo->eof);
-        */
-        return (int) (prinfo->samples * info->frameSize);
-    }
-    ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n");
-    return -1;
-}
-
-int DAUDIO_Flush(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int err = -1;
-    int pos;
-
-    TRACE0("DAUDIO_Flush\n");
-    if (info) {
-        if (isSource) {
-            err = ioctl(info->fd, I_FLUSH, FLUSHW);
-        } else {
-            err = ioctl(info->fd, I_FLUSH, FLUSHR);
-        }
-        if (err >= 0) {
-            /* resets the transferedBytes parameter to
-             * the current samples count of the device
-             */
-            pos = getDevicePosition(info, isSource);
-            if (pos >= 0) {
-                info->transferedBytes = pos;
-            }
-        }
-    }
-    if (err < 0) {
-        ERROR0("ERROR in DAUDIO_Flush\n");
-    }
-    return (err < 0)?FALSE:TRUE;
-}
-
-int DAUDIO_GetAvailable(void* id, int isSource) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret = 0;
-    int pos;
-
-    if (info) {
-        /* unfortunately, the STREAMS architecture
-         * seems to not have a method for querying
-         * the available bytes to read/write!
-         * estimate it...
-         */
-        pos = getDevicePosition(info, isSource);
-        if (pos >= 0) {
-            if (isSource) {
-                /* we usually have written more bytes
-                 * to the queue than the device position should be
-                 */
-                ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos);
-            } else {
-                /* for record, the device stream should
-                 * be usually ahead of our read actions
-                 */
-                ret = pos - info->transferedBytes;
-            }
-            if (ret > info->bufferSizeInBytes) {
-                ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n",
-                       (int) ret, (int) info->bufferSizeInBytes);
-                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
-                       (int) pos, (int) info->transferedBytes);
-                ret = info->bufferSizeInBytes;
-            }
-            else if (ret < 0) {
-                ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n",
-                       (int) ret);
-                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
-                       (int) pos, (int) info->transferedBytes);
-                ret = 0;
-            }
-        }
-    }
-
-    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
-    return ret;
-}
-
-INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret;
-    int pos;
-    INT64 result = javaBytePos;
-
-    if (info) {
-        pos = getDevicePosition(info, isSource);
-        if (pos >= 0) {
-            result = info->positionOffset + pos;
-        }
-    }
-
-    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
-    return result;
-}
-
-
-void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
-    SolPcmInfo* info = (SolPcmInfo*) id;
-    int ret;
-    int pos;
-
-    if (info) {
-        pos = getDevicePosition(info, isSource);
-        if (pos >= 0) {
-            info->positionOffset = javaBytePos - pos;
-        }
-    }
-}
-
-int DAUDIO_RequiresServicing(void* id, int isSource) {
-    // never need servicing on Solaris
-    return FALSE;
-}
-
-void DAUDIO_Service(void* id, int isSource) {
-    // never need servicing on Solaris
-}
-
-
-#endif // USE_DAUDIO
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Ports.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,600 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- */
-
-#define USE_ERROR
-//#define USE_TRACE
-
-#include "Ports.h"
-#include "PLATFORM_API_SolarisOS_Utils.h"
-
-#if USE_PORTS == TRUE
-
-#define MONITOR_GAIN_STRING "Monitor Gain"
-
-#define ALL_TARGET_PORT_COUNT 6
-
-// define the following to not use audio_prinfo_t.mod_ports
-#define SOLARIS7_COMPATIBLE
-
-// Solaris audio defines
-static int targetPorts[ALL_TARGET_PORT_COUNT] = {
-    AUDIO_SPEAKER,
-    AUDIO_HEADPHONE,
-    AUDIO_LINE_OUT,
-    AUDIO_AUX1_OUT,
-    AUDIO_AUX2_OUT,
-    AUDIO_SPDIF_OUT
-};
-
-static char* targetPortNames[ALL_TARGET_PORT_COUNT] = {
-    "Speaker",
-    "Headphone",
-    "Line Out",
-    "AUX1 Out",
-    "AUX2 Out",
-    "SPDIF Out"
-};
-
-// defined in Ports.h
-static int targetPortJavaSoundMapping[ALL_TARGET_PORT_COUNT] = {
-    PORT_DST_SPEAKER,
-    PORT_DST_HEADPHONE,
-    PORT_DST_LINE_OUT,
-    PORT_DST_UNKNOWN,
-    PORT_DST_UNKNOWN,
-    PORT_DST_UNKNOWN,
-};
-
-#define ALL_SOURCE_PORT_COUNT 7
-
-// Solaris audio defines
-static int sourcePorts[ALL_SOURCE_PORT_COUNT] = {
-    AUDIO_MICROPHONE,
-    AUDIO_LINE_IN,
-    AUDIO_CD,
-    AUDIO_AUX1_IN,
-    AUDIO_AUX2_IN,
-    AUDIO_SPDIF_IN,
-    AUDIO_CODEC_LOOPB_IN
-};
-
-static char* sourcePortNames[ALL_SOURCE_PORT_COUNT] = {
-    "Microphone In",
-    "Line In",
-    "Compact Disc In",
-    "AUX1 In",
-    "AUX2 In",
-    "SPDIF In",
-    "Internal Loopback"
-};
-
-// Ports.h defines
-static int sourcePortJavaSoundMapping[ALL_SOURCE_PORT_COUNT] = {
-    PORT_SRC_MICROPHONE,
-    PORT_SRC_LINE_IN,
-    PORT_SRC_COMPACT_DISC,
-    PORT_SRC_UNKNOWN,
-    PORT_SRC_UNKNOWN,
-    PORT_SRC_UNKNOWN,
-    PORT_SRC_UNKNOWN
-};
-
-struct tag_PortControlID;
-
-typedef struct tag_PortInfo {
-    int fd;                    // file descriptor of the pseudo device
-    audio_info_t audioInfo;
-    // ports
-    int targetPortCount;
-    int sourcePortCount;
-    // indexes to sourcePorts/targetPorts
-    // contains first target ports, then source ports
-    int ports[ALL_TARGET_PORT_COUNT + ALL_SOURCE_PORT_COUNT];
-    // controls
-    int maxControlCount;       // upper bound of number of controls
-    int usedControlIDs;        // number of items already filled in controlIDs
-    struct tag_PortControlID* controlIDs; // the control IDs themselves
-} PortInfo;
-
-#define PORT_CONTROL_TYPE_PLAY          0x4000000
-#define PORT_CONTROL_TYPE_RECORD        0x8000000
-#define PORT_CONTROL_TYPE_SELECT_PORT   1
-#define PORT_CONTROL_TYPE_GAIN          2
-#define PORT_CONTROL_TYPE_BALANCE       3
-#define PORT_CONTROL_TYPE_MONITOR_GAIN  10
-#define PORT_CONTROL_TYPE_OUTPUT_MUTED  11
-#define PORT_CONTROL_TYPE_PLAYRECORD_MASK PORT_CONTROL_TYPE_PLAY | PORT_CONTROL_TYPE_RECORD
-#define PORT_CONTROL_TYPE_MASK 0xFFFFFF
-
-
-typedef struct tag_PortControlID {
-    PortInfo*  portInfo;
-    INT32                 controlType;  // PORT_CONTROL_TYPE_XX
-    uint_t                port;
-} PortControlID;
-
-
-///// implemented functions of Ports.h
-
-INT32 PORT_GetPortMixerCount() {
-    return (INT32) getAudioDeviceCount();
-}
-
-
-INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
-    AudioDeviceDescription desc;
-
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
-        strncpy(description->name, desc.name, PORT_STRING_LENGTH-1);
-        description->name[PORT_STRING_LENGTH-1] = 0;
-        strncpy(description->vendor, desc.vendor, PORT_STRING_LENGTH-1);
-        description->vendor[PORT_STRING_LENGTH-1] = 0;
-        strncpy(description->version, desc.version, PORT_STRING_LENGTH-1);
-        description->version[PORT_STRING_LENGTH-1] = 0;
-        /*strncpy(description->description, desc.description, PORT_STRING_LENGTH-1);*/
-        strncpy(description->description, "Solaris Ports", PORT_STRING_LENGTH-1);
-        description->description[PORT_STRING_LENGTH-1] = 0;
-        return TRUE;
-    }
-    return FALSE;
-}
-
-
-void* PORT_Open(INT32 mixerIndex) {
-    PortInfo* info = NULL;
-    int fd = -1;
-    AudioDeviceDescription desc;
-    int success = FALSE;
-
-    TRACE0("PORT_Open\n");
-    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
-        fd = open(desc.pathctl, O_RDWR);
-    }
-    if (fd < 0) {
-        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
-        return NULL;
-    }
-
-    info = (PortInfo*) malloc(sizeof(PortInfo));
-    if (info != NULL) {
-        memset(info, 0, sizeof(PortInfo));
-        info->fd = fd;
-        success = TRUE;
-    }
-    if (!success) {
-        if (fd >= 0) {
-            close(fd);
-        }
-        PORT_Close((void*) info);
-        info = NULL;
-    }
-    return info;
-}
-
-void PORT_Close(void* id) {
-    TRACE0("PORT_Close\n");
-    if (id != NULL) {
-        PortInfo* info = (PortInfo*) id;
-        if (info->fd >= 0) {
-            close(info->fd);
-            info->fd = -1;
-        }
-        if (info->controlIDs) {
-            free(info->controlIDs);
-            info->controlIDs = NULL;
-        }
-        free(info);
-    }
-}
-
-
-
-INT32 PORT_GetPortCount(void* id) {
-    int ret = 0;
-    PortInfo* info = (PortInfo*) id;
-    if (info != NULL) {
-        if (!info->targetPortCount && !info->sourcePortCount) {
-            int i;
-            AUDIO_INITINFO(&info->audioInfo);
-            if (ioctl(info->fd, AUDIO_GETINFO, &info->audioInfo) >= 0) {
-                for (i = 0; i < ALL_TARGET_PORT_COUNT; i++) {
-                    if (info->audioInfo.play.avail_ports & targetPorts[i]) {
-                        info->ports[info->targetPortCount] = i;
-                        info->targetPortCount++;
-                    }
-#ifdef SOLARIS7_COMPATIBLE
-                    TRACE3("Target %d %s: avail=%d\n", i, targetPortNames[i],
-                           info->audioInfo.play.avail_ports & targetPorts[i]);
-#else
-                    TRACE4("Target %d %s: avail=%d  mod=%d\n", i, targetPortNames[i],
-                           info->audioInfo.play.avail_ports & targetPorts[i],
-                           info->audioInfo.play.mod_ports & targetPorts[i]);
-#endif
-                }
-                for (i = 0; i < ALL_SOURCE_PORT_COUNT; i++) {
-                    if (info->audioInfo.record.avail_ports & sourcePorts[i]) {
-                        info->ports[info->targetPortCount + info->sourcePortCount] = i;
-                        info->sourcePortCount++;
-                    }
-#ifdef SOLARIS7_COMPATIBLE
-                    TRACE3("Source %d %s: avail=%d\n", i, sourcePortNames[i],
-                           info->audioInfo.record.avail_ports & sourcePorts[i]);
-#else
-                    TRACE4("Source %d %s: avail=%d  mod=%d\n", i, sourcePortNames[i],
-                           info->audioInfo.record.avail_ports & sourcePorts[i],
-                           info->audioInfo.record.mod_ports & sourcePorts[i]);
-#endif
-                }
-            }
-        }
-        ret = info->targetPortCount + info->sourcePortCount;
-    }
-    return ret;
-}
-
-int isSourcePort(PortInfo* info, INT32 portIndex) {
-    return (portIndex >= info->targetPortCount);
-}
-
-INT32 PORT_GetPortType(void* id, INT32 portIndex) {
-    PortInfo* info = (PortInfo*) id;
-    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
-        if (isSourcePort(info, portIndex)) {
-            return sourcePortJavaSoundMapping[info->ports[portIndex]];
-        } else {
-            return targetPortJavaSoundMapping[info->ports[portIndex]];
-        }
-    }
-    return 0;
-}
-
-// pre-condition: portIndex must have been verified!
-char* getPortName(PortInfo* info, INT32 portIndex) {
-    char* ret = NULL;
-
-    if (isSourcePort(info, portIndex)) {
-        ret = sourcePortNames[info->ports[portIndex]];
-    } else {
-        ret = targetPortNames[info->ports[portIndex]];
-    }
-    return ret;
-}
-
-INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
-    PortInfo* info = (PortInfo*) id;
-    char* n;
-
-    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
-        n = getPortName(info, portIndex);
-        if (n) {
-            strncpy(name, n, len-1);
-            name[len-1] = 0;
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-void createPortControl(PortInfo* info, PortControlCreator* creator, INT32 portIndex,
-                       INT32 type, void** controlObjects, int* controlCount) {
-    PortControlID* controlID;
-    void* newControl = NULL;
-    int controlIndex;
-    char* jsType = NULL;
-    int isBoolean = FALSE;
-
-    TRACE0(">createPortControl\n");
-
-    // fill the ControlID structure and add this control
-    if (info->usedControlIDs >= info->maxControlCount) {
-        ERROR1("not enough free controlIDs !! maxControlIDs = %d\n", info->maxControlCount);
-        return;
-    }
-    controlID = &(info->controlIDs[info->usedControlIDs]);
-    controlID->portInfo = info;
-    controlID->controlType = type;
-    controlIndex = info->ports[portIndex];
-    if (isSourcePort(info, portIndex)) {
-        controlID->port = sourcePorts[controlIndex];
-    } else {
-        controlID->port = targetPorts[controlIndex];
-    }
-    switch (type & PORT_CONTROL_TYPE_MASK) {
-    case PORT_CONTROL_TYPE_SELECT_PORT:
-        jsType = CONTROL_TYPE_SELECT; isBoolean = TRUE; break;
-    case PORT_CONTROL_TYPE_GAIN:
-        jsType = CONTROL_TYPE_VOLUME;  break;
-    case PORT_CONTROL_TYPE_BALANCE:
-        jsType = CONTROL_TYPE_BALANCE; break;
-    case PORT_CONTROL_TYPE_MONITOR_GAIN:
-        jsType = CONTROL_TYPE_VOLUME; break;
-    case PORT_CONTROL_TYPE_OUTPUT_MUTED:
-        jsType = CONTROL_TYPE_MUTE; isBoolean = TRUE; break;
-    }
-    if (isBoolean) {
-        TRACE0(" PORT_CONTROL_TYPE_BOOLEAN\n");
-        newControl = (creator->newBooleanControl)(creator, controlID, jsType);
-    }
-    else if (jsType == CONTROL_TYPE_BALANCE) {
-        TRACE0(" PORT_CONTROL_TYPE_BALANCE\n");
-        newControl = (creator->newFloatControl)(creator, controlID, jsType,
-                                                -1.0f, 1.0f, 2.0f / 65.0f, "");
-    } else {
-        TRACE0(" PORT_CONTROL_TYPE_FLOAT\n");
-        newControl = (creator->newFloatControl)(creator, controlID, jsType,
-                                                0.0f, 1.0f, 1.0f / 256.0f, "");
-    }
-    if (newControl) {
-        controlObjects[*controlCount] = newControl;
-        (*controlCount)++;
-        info->usedControlIDs++;
-    }
-    TRACE0("<createPortControl\n");
-}
-
-
-void addCompoundControl(PortInfo* info, PortControlCreator* creator, char* name, void** controlObjects, int* controlCount) {
-    void* compControl;
-
-    TRACE1(">addCompoundControl %d controls\n", *controlCount);
-    if (*controlCount) {
-        // create compound control and add it to the vector
-        compControl = (creator->newCompoundControl)(creator, name, controlObjects, *controlCount);
-        if (compControl) {
-            TRACE1(" addCompoundControl: calling addControl %p\n", compControl);
-            (creator->addControl)(creator, compControl);
-        }
-        *controlCount = 0;
-    }
-    TRACE0("<addCompoundControl\n");
-}
-
-void addAllControls(PortInfo* info, PortControlCreator* creator, void** controlObjects, int* controlCount) {
-    int i = 0;
-
-    TRACE0(">addAllControl\n");
-    // go through all controls and add them to the vector
-    for (i = 0; i < *controlCount; i++) {
-        (creator->addControl)(creator, controlObjects[i]);
-    }
-    *controlCount = 0;
-    TRACE0("<addAllControl\n");
-}
-
-void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
-    PortInfo* info = (PortInfo*) id;
-    int portCount = PORT_GetPortCount(id);
-    void* controls[4];
-    int controlCount = 0;
-    INT32 type;
-    int selectable = 1;
-    memset(controls, 0, sizeof(controls));
-
-    TRACE4(">PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n",
-           id, portIndex, info->controlIDs, info->maxControlCount);
-    if ((portIndex >= 0) && (portIndex < portCount)) {
-        // if the memory isn't reserved for the control structures, allocate it
-        if (!info->controlIDs) {
-            int maxCount = 0;
-            TRACE0("getControl: allocate mem\n");
-            // get a maximum number of controls:
-            // each port has a select, balance, and volume control.
-            maxCount = 3 * portCount;
-            // then there is monitorGain and outputMuted
-            maxCount += (2 * info->targetPortCount);
-            info->maxControlCount = maxCount;
-            info->controlIDs = (PortControlID*) malloc(sizeof(PortControlID) * maxCount);
-        }
-        if (!isSourcePort(info, portIndex)) {
-            type = PORT_CONTROL_TYPE_PLAY;
-            // add master mute control
-            createPortControl(info, creator, portIndex,
-                              type | PORT_CONTROL_TYPE_OUTPUT_MUTED,
-                              controls, &controlCount);
-            addAllControls(info, creator, controls, &controlCount);
-#ifdef SOLARIS7_COMPATIBLE
-            selectable = info->audioInfo.play.avail_ports & targetPorts[info->ports[portIndex]];
-#else
-            selectable = info->audioInfo.play.mod_ports & targetPorts[info->ports[portIndex]];
-#endif
-        } else {
-            type = PORT_CONTROL_TYPE_RECORD;
-#ifdef SOLARIS7_COMPATIBLE
-            selectable = info->audioInfo.record.avail_ports & sourcePorts[info->ports[portIndex]];
-#else
-            selectable = info->audioInfo.record.mod_ports & sourcePorts[info->ports[portIndex]];
-#endif
-        }
-        // add a mixer strip with volume, ...
-        createPortControl(info, creator, portIndex,
-                          type | PORT_CONTROL_TYPE_GAIN,
-                          controls, &controlCount);
-        // ... balance, ...
-        createPortControl(info, creator, portIndex,
-                          type | PORT_CONTROL_TYPE_BALANCE,
-                          controls, &controlCount);
-        // ... and select control (if not always on)...
-        if (selectable) {
-            createPortControl(info, creator, portIndex,
-                              type | PORT_CONTROL_TYPE_SELECT_PORT,
-                              controls, &controlCount);
-        }
-        // ... packaged in a compound control.
-        addCompoundControl(info, creator, getPortName(info, portIndex), controls, &controlCount);
-
-        if (type == PORT_CONTROL_TYPE_PLAY) {
-            // add a single strip for source ports with monitor gain
-            createPortControl(info, creator, portIndex,
-                              type | PORT_CONTROL_TYPE_MONITOR_GAIN,
-                              controls, &controlCount);
-            // also in a compound control
-            addCompoundControl(info, creator, MONITOR_GAIN_STRING, controls, &controlCount);
-        }
-    }
-    TRACE0("< PORT_getControls\n");
-}
-
-INT32 PORT_GetIntValue(void* controlIDV) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-
-    AUDIO_INITINFO(&audioInfo);
-    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
-        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-        case PORT_CONTROL_TYPE_SELECT_PORT:
-            return (prinfo->port & controlID->port)?TRUE:FALSE;
-        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
-            return (audioInfo.output_muted)?TRUE:FALSE;
-        default:
-            ERROR1("PORT_GetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        }
-    }
-    ERROR0("PORT_GetIntValue: Could not ioctl!\n");
-    return 0;
-}
-
-void PORT_SetIntValue(void* controlIDV, INT32 value) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-    int setPort;
-
-    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-        prinfo = &(audioInfo.play);
-    } else {
-        prinfo = &(audioInfo.record);
-    }
-    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-    case PORT_CONTROL_TYPE_SELECT_PORT:
-        // first try to just add this port. if that fails, set ONLY to this port.
-        AUDIO_INITINFO(&audioInfo);
-        if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
-            if (value) {
-                setPort = (prinfo->port | controlID->port);
-            } else {
-                setPort = (prinfo->port - controlID->port);
-            }
-            AUDIO_INITINFO(&audioInfo);
-            prinfo->port = setPort;
-            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-                // didn't work. Either this line doesn't support to select several
-                // ports at once (e.g. record), or a real error
-                if (value) {
-                    // set to ONLY this port (and disable any other currently selected ports)
-                    AUDIO_INITINFO(&audioInfo);
-                    prinfo->port = controlID->port;
-                    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-                        ERROR2("Error setting output select port %d to port %d!\n", controlID->port, controlID->port);
-                    }
-                } else {
-                    // assume it's an error
-                    ERROR2("Error setting output select port %d to port %d!\n", controlID->port, setPort);
-                }
-            }
-            break;
-        case PORT_CONTROL_TYPE_OUTPUT_MUTED:
-            AUDIO_INITINFO(&audioInfo);
-            audioInfo.output_muted = (value?TRUE:FALSE);
-            if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-                ERROR2("Error setting output muted on port %d to %d!\n", controlID->port, value);
-            }
-            break;
-        default:
-            ERROR1("PORT_SetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        }
-    }
-}
-
-float PORT_GetFloatValue(void* controlIDV) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-
-    AUDIO_INITINFO(&audioInfo);
-    if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) {
-        if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-            prinfo = &(audioInfo.play);
-        } else {
-            prinfo = &(audioInfo.record);
-        }
-        switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-        case PORT_CONTROL_TYPE_GAIN:
-            return ((float) (prinfo->gain - AUDIO_MIN_GAIN))
-                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
-        case PORT_CONTROL_TYPE_BALANCE:
-            return ((float) ((prinfo->balance - AUDIO_LEFT_BALANCE - AUDIO_MID_BALANCE) << 1))
-                / ((float) (AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE));
-        case PORT_CONTROL_TYPE_MONITOR_GAIN:
-            return ((float) (audioInfo.monitor_gain - AUDIO_MIN_GAIN))
-                / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN));
-        default:
-            ERROR1("PORT_GetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        }
-    }
-    ERROR0("PORT_GetFloatValue: Could not ioctl!\n");
-    return 0.0f;
-}
-
-void PORT_SetFloatValue(void* controlIDV, float value) {
-    PortControlID* controlID = (PortControlID*) controlIDV;
-    audio_info_t audioInfo;
-    audio_prinfo_t* prinfo;
-
-    AUDIO_INITINFO(&audioInfo);
-
-    if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) {
-        prinfo = &(audioInfo.play);
-    } else {
-        prinfo = &(audioInfo.record);
-    }
-    switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) {
-    case PORT_CONTROL_TYPE_GAIN:
-        prinfo->gain = AUDIO_MIN_GAIN
-            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
-        break;
-    case PORT_CONTROL_TYPE_BALANCE:
-        prinfo->balance =  AUDIO_LEFT_BALANCE + AUDIO_MID_BALANCE
-            + ((int) (value * ((float) ((AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE) >> 1))) + 0.5f);
-        break;
-    case PORT_CONTROL_TYPE_MONITOR_GAIN:
-        audioInfo.monitor_gain = AUDIO_MIN_GAIN
-            + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f);
-        break;
-    default:
-        ERROR1("PORT_SetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK);
-        return;
-    }
-    if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) {
-        ERROR0("PORT_SetFloatValue: Could not ioctl!\n");
-    }
-}
-
-#endif // USE_PORTS
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.c	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2002, 2007, 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 USE_ERROR
-#define USE_TRACE
-
-#include "PLATFORM_API_SolarisOS_Utils.h"
-
-#define MAX_AUDIO_DEVICES 20
-
-// not thread safe...
-static AudioDevicePath globalADPaths[MAX_AUDIO_DEVICES];
-static int globalADCount = -1;
-static int globalADCacheTime = -1;
-/* how many seconds do we cache devices */
-#define AD_CACHE_TIME 30
-
-// return seconds
-long getTimeInSeconds() {
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec;
-}
-
-
-int getAudioDeviceCount() {
-    int count = MAX_AUDIO_DEVICES;
-
-    getAudioDevices(globalADPaths, &count);
-    return count;
-}
-
-/* returns TRUE if the path exists at all */
-int addAudioDevice(char* path, AudioDevicePath* adPath, int* count) {
-    int i;
-    int found = 0;
-    int fileExists = 0;
-    // not thread safe...
-    static struct stat statBuf;
-
-    // get stats on the file
-    if (stat(path, &statBuf) == 0) {
-        // file exists.
-        fileExists = 1;
-        // If it is not yet in the adPath array, add it to the array
-        for (i = 0; i < *count; i++) {
-            if (adPath[i].st_ino == statBuf.st_ino
-                && adPath[i].st_dev == statBuf.st_dev) {
-                found = 1;
-                break;
-            }
-        }
-        if (!found) {
-            adPath[*count].st_ino = statBuf.st_ino;
-            adPath[*count].st_dev = statBuf.st_dev;
-            strncpy(adPath[*count].path, path, MAX_NAME_LENGTH);
-            adPath[*count].path[MAX_NAME_LENGTH - 1] = 0;
-            (*count)++;
-            TRACE1("Added audio device %s\n", path);
-        }
-    }
-    return fileExists;
-}
-
-
-void getAudioDevices(AudioDevicePath* adPath, int* count) {
-    int maxCount = *count;
-    char* audiodev;
-    char devsound[15];
-    int i;
-    long timeInSeconds = getTimeInSeconds();
-
-    if (globalADCount < 0
-        || (getTimeInSeconds() - globalADCacheTime) > AD_CACHE_TIME
-        || (adPath != globalADPaths)) {
-        *count = 0;
-        // first device, if set, is AUDIODEV variable
-        audiodev = getenv("AUDIODEV");
-        if (audiodev != NULL && audiodev[0] != 0) {
-            addAudioDevice(audiodev, adPath, count);
-        }
-        // then try /dev/audio
-        addAudioDevice("/dev/audio", adPath, count);
-        // then go through all of the /dev/sound/? devices
-        for (i = 0; i < 100; i++) {
-            sprintf(devsound, "/dev/sound/%d", i);
-            if (!addAudioDevice(devsound, adPath, count)) {
-                break;
-            }
-        }
-        if (adPath == globalADPaths) {
-            /* commit cache */
-            globalADCount = *count;
-            /* set cache time */
-            globalADCacheTime = timeInSeconds;
-        }
-    } else {
-        /* return cache */
-        *count = globalADCount;
-    }
-    // that's it
-}
-
-int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames) {
-    int count = MAX_AUDIO_DEVICES;
-    int ret = 0;
-
-    getAudioDevices(globalADPaths, &count);
-    if (index>=0 && index < count) {
-        ret = getAudioDeviceDescription(globalADPaths[index].path, adDesc, getNames);
-    }
-    return ret;
-}
-
-int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames) {
-    int fd;
-    int mixerMode;
-    int len;
-    audio_info_t info;
-    audio_device_t deviceInfo;
-
-    strncpy(adDesc->path, path, MAX_NAME_LENGTH);
-    adDesc->path[MAX_NAME_LENGTH] = 0;
-    strcpy(adDesc->pathctl, adDesc->path);
-    strcat(adDesc->pathctl, "ctl");
-    strcpy(adDesc->name, adDesc->path);
-    adDesc->vendor[0] = 0;
-    adDesc->version[0] = 0;
-    adDesc->description[0] = 0;
-    adDesc->maxSimulLines = 1;
-
-    // try to open the pseudo device and get more information
-    fd = open(adDesc->pathctl, O_WRONLY | O_NONBLOCK);
-    if (fd >= 0) {
-        close(fd);
-        if (getNames) {
-            fd = open(adDesc->pathctl, O_RDONLY);
-            if (fd >= 0) {
-                if (ioctl(fd, AUDIO_GETDEV, &deviceInfo) >= 0) {
-                    strncpy(adDesc->vendor, deviceInfo.name, MAX_AUDIO_DEV_LEN);
-                    adDesc->vendor[MAX_AUDIO_DEV_LEN] = 0;
-                    strncpy(adDesc->version, deviceInfo.version, MAX_AUDIO_DEV_LEN);
-                    adDesc->version[MAX_AUDIO_DEV_LEN] = 0;
-                    /* add config string to the dev name
-                     * creates a string like "/dev/audio (onboard1)"
-                     */
-                    len = strlen(adDesc->name) + 1;
-                    if (MAX_NAME_LENGTH - len > 3) {
-                        strcat(adDesc->name, " (");
-                        strncat(adDesc->name, deviceInfo.config, MAX_NAME_LENGTH - len);
-                        strcat(adDesc->name, ")");
-                    }
-                    adDesc->name[MAX_NAME_LENGTH-1] = 0;
-                }
-                if (ioctl(fd, AUDIO_MIXERCTL_GET_MODE, &mixerMode) >= 0) {
-                    if (mixerMode == AM_MIXER_MODE) {
-                        TRACE1(" getAudioDeviceDescription: %s is in mixer mode\n", adDesc->path);
-                        adDesc->maxSimulLines = -1;
-                    }
-                } else {
-                    ERROR1("ioctl AUDIO_MIXERCTL_GET_MODE failed on %s!\n", adDesc->path);
-                }
-                close(fd);
-            } else {
-                ERROR1("could not open %s!\n", adDesc->pathctl);
-            }
-        }
-        return 1;
-    }
-    return 0;
-}
--- a/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.h	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- */
-
-#include <Utilities.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-/* does not work on Solaris 2.7 */
-#include <sys/audio.h>
-#include <sys/mixer.h>
-#include <sys/types.h>
-#ifndef __linux__
-#include <stropts.h>
-#endif
-#include <sys/conf.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#ifndef PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
-#define PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
-
-/* defines for Solaris 2.7
-   #ifndef AUDIO_AUX1_OUT
-   #define AUDIO_AUX1_OUT   (0x08)  // output to aux1 out
-   #define AUDIO_AUX2_OUT   (0x10)  // output to aux2 out
-   #define AUDIO_SPDIF_OUT  (0x20)  // output to SPDIF port
-   #define AUDIO_AUX1_IN    (0x08)    // input from aux1 in
-   #define AUDIO_AUX2_IN    (0x10)    // input from aux2 in
-   #define AUDIO_SPDIF_IN   (0x20)    // input from SPDIF port
-   #endif
-*/
-
-/* input from Codec inter. loopback */
-#ifndef AUDIO_CODEC_LOOPB_IN
-#define AUDIO_CODEC_LOOPB_IN       (0x40)
-#endif
-
-
-#define MAX_NAME_LENGTH 300
-
-typedef struct tag_AudioDevicePath {
-    char path[MAX_NAME_LENGTH];
-    ino_t st_ino; // inode number to detect duplicate devices
-    dev_t st_dev; // device ID to detect duplicate audio devices
-} AudioDevicePath;
-
-typedef struct tag_AudioDeviceDescription {
-    INT32 maxSimulLines;
-    char path[MAX_NAME_LENGTH+1];
-    char pathctl[MAX_NAME_LENGTH+4];
-    char name[MAX_NAME_LENGTH+1];
-    char vendor[MAX_NAME_LENGTH+1];
-    char version[MAX_NAME_LENGTH+1];
-    char description[MAX_NAME_LENGTH+1];
-} AudioDeviceDescription;
-
-int getAudioDeviceCount();
-
-/*
- * adPath is an array of AudioDevicePath structures
- * count contains initially the number of elements in adPath
- *       and will be set to the returned number of paths.
- */
-void getAudioDevices(AudioDevicePath* adPath, int* count);
-
-/*
- * fills adDesc from the audio device given in path
- * returns 0 if an error occurred
- * if getNames is 0, only path and pathctl are filled
- */
-int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames);
-int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames);
-
-
-#endif // PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED
--- a/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c	Thu Mar 22 14:10:30 2018 -0700
+++ b/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -231,7 +231,7 @@
     int table_size = sizeof(error_messages) / sizeof(error_messages[0]);
     int i;
 
-    for (i=0; i<table_size; i++) {
+    for (i = 0; i < table_size; i++) {
         if (err == error_messages[i].err) {
             return error_messages[i].msg;
         }
@@ -293,7 +293,7 @@
      */
     arg_count = (*env)->GetArrayLength(env, args);
 
-    for (i=0; i<arg_count; i++) {
+    for (i = 0; i < arg_count; i++) {
         jobject obj = (*env)->GetObjectArrayElement(env, args, i);
         if (obj != NULL) {
             cstr = JNU_GetStringPlatformChars(env, obj, &isCopy);
@@ -314,6 +314,15 @@
                     return -1;
                 }
             }
+        } else {
+            char* newbuf = (char*)realloc(buf, size + 1);
+            if (newbuf == NULL) {
+                free(buf);
+                JNU_ThrowOutOfMemoryError(env, "realloc failed");
+                return -1;
+            }
+            buf = newbuf;
+            buf[size++] = 0;
         }
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
--- a/test/hotspot/jtreg/ProblemList.txt	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/hotspot/jtreg/ProblemList.txt	Fri Mar 23 08:49:58 2018 -0700
@@ -44,6 +44,7 @@
 compiler/codecache/stress/OverloadCompileQueueTest.java 8166554 generic-all
 compiler/codegen/Test6896617.java 8193479 generic-all
 compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8140405 generic-all
+compiler/jvmci/compilerToVM/GetExceptionTableTest.java 8200135 generic-all
 compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java 8158860 generic-all
 compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 8163894 generic-all
 compiler/tiered/LevelTransitionTest.java 8067651 generic-all
--- a/test/jdk/java/nio/channels/DatagramChannel/Connect.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/jdk/java/nio/channels/DatagramChannel/Connect.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, 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
@@ -102,7 +102,7 @@
                 try {
                     dc.send(bb, bogus);
                     throw new RuntimeException("Allowed bogus send while connected");
-                } catch (IllegalArgumentException iae) {
+                } catch (AlreadyConnectedException ace) {
                     // Correct behavior
                 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/ConnectExceptions.java	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8198753
+ * @summary Test DatagramChannel connect exceptions
+ * @library ..
+ * @run testng ConnectExceptions
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.nio.channels.*;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class ConnectExceptions {
+    static DatagramChannel sndChannel;
+    static DatagramChannel rcvChannel;
+    static InetSocketAddress sender;
+    static InetSocketAddress receiver;
+
+    @BeforeTest
+    public static void setup() throws Exception {
+        sndChannel = DatagramChannel.open();
+        sndChannel.bind(null);
+        InetAddress address = InetAddress.getLocalHost();
+        if (address.isLoopbackAddress()) {
+            address = InetAddress.getLoopbackAddress();
+        }
+        sender = new InetSocketAddress(address,
+            sndChannel.socket().getLocalPort());
+
+        rcvChannel = DatagramChannel.open();
+        rcvChannel.bind(null);
+        receiver = new InetSocketAddress(address,
+            rcvChannel.socket().getLocalPort());
+    }
+
+    @Test(expectedExceptions = UnsupportedAddressTypeException.class)
+    public static void unsupportedAddressTypeException() throws Exception {
+        rcvChannel.connect(sender);
+        sndChannel.connect(new SocketAddress() {});
+    }
+
+    @Test(expectedExceptions = UnresolvedAddressException.class)
+    public static void unresolvedAddressException() throws Exception {
+        String host = TestUtil.UNRESOLVABLE_HOST;
+        InetSocketAddress unresolvable = new InetSocketAddress (host, 37);
+        sndChannel.connect(unresolvable);
+    }
+
+    @Test(expectedExceptions = AlreadyConnectedException.class)
+    public static void alreadyConnectedException() throws Exception {
+        sndChannel.connect(receiver);
+        InetSocketAddress random = new InetSocketAddress(0);
+        sndChannel.connect(random);
+    }
+
+    @AfterTest
+    public static void cleanup() throws Exception {
+        rcvChannel.close();
+        sndChannel.close();
+    }
+}
--- a/test/jdk/java/nio/channels/DatagramChannel/ConnectedSend.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/jdk/java/nio/channels/DatagramChannel/ConnectedSend.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -24,6 +24,8 @@
 /* @test
  * @bug 4849277 7183800
  * @summary Test DatagramChannel send while connected
+ * @library ..
+ * @run testng ConnectedSend
  * @author Mike McCloskey
  */
 
@@ -32,20 +34,16 @@
 import java.nio.*;
 import java.nio.channels.*;
 import java.nio.charset.*;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
 
 public class ConnectedSend {
-
-    public static void main(String[] args) throws Exception {
-        test1();
-        test2();
-    }
-
     // Check if DatagramChannel.send while connected can include
     // address without throwing
-    private static void test1() throws Exception {
-
+    @Test
+    public static void sendToConnectedAddress() throws Exception {
         DatagramChannel sndChannel = DatagramChannel.open();
-        sndChannel.socket().bind(null);
+        sndChannel.bind(null);
         InetAddress address = InetAddress.getLocalHost();
         if (address.isLoopbackAddress()) {
             address = InetAddress.getLoopbackAddress();
@@ -55,7 +53,7 @@
             sndChannel.socket().getLocalPort());
 
         DatagramChannel rcvChannel = DatagramChannel.open();
-        rcvChannel.socket().bind(null);
+        rcvChannel.bind(null);
         InetSocketAddress receiver = new InetSocketAddress(
             address,
             rcvChannel.socket().getLocalPort());
@@ -71,8 +69,7 @@
         rcvChannel.receive(bb);
         bb.flip();
         CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
-        if (!cb.toString().startsWith("h"))
-            throw new RuntimeException("Test failed");
+        assertTrue(cb.toString().startsWith("h"), "Unexpected message content");
 
         rcvChannel.close();
         sndChannel.close();
@@ -81,9 +78,10 @@
     // Check if the datagramsocket adaptor can send with a packet
     // that has not been initialized with an address; the legacy
     // datagram socket will send in this case
-    private static void test2() throws Exception {
+    @Test
+    public static void sendAddressedPacket() throws Exception {
         DatagramChannel sndChannel = DatagramChannel.open();
-        sndChannel.socket().bind(null);
+        sndChannel.bind(null);
         InetAddress address = InetAddress.getLocalHost();
         if (address.isLoopbackAddress()) {
             address = InetAddress.getLoopbackAddress();
@@ -93,7 +91,7 @@
             sndChannel.socket().getLocalPort());
 
         DatagramChannel rcvChannel = DatagramChannel.open();
-        rcvChannel.socket().bind(null);
+        rcvChannel.bind(null);
         InetSocketAddress receiver = new InetSocketAddress(
             address,
             rcvChannel.socket().getLocalPort());
@@ -109,13 +107,12 @@
         rcvChannel.receive(bb);
         bb.flip();
         CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
-        if (!cb.toString().startsWith("h"))
-            throw new RuntimeException("Test failed");
+        assertTrue(cb.toString().startsWith("h"), "Unexpected message content");
 
         // Check that the pkt got set with the target address;
         // This is legacy behavior
-        if (!pkt.getSocketAddress().equals(receiver))
-            throw new RuntimeException("Test failed");
+        assertEquals(pkt.getSocketAddress(), receiver,
+            "Unexpected address set on packet");
 
         rcvChannel.close();
         sndChannel.close();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/SendExceptions.java	Fri Mar 23 08:49:58 2018 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 4675045 8198753
+ * @summary Test DatagramChannel send exceptions
+ * @library ..
+ * @run testng SendExceptions
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.nio.channels.*;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class SendExceptions {
+    static DatagramChannel sndChannel;
+    static DatagramChannel rcvChannel;
+    static InetSocketAddress sender;
+    static InetSocketAddress receiver;
+    static ByteBuffer buf = ByteBuffer.allocate(17);
+
+    @BeforeTest
+    public static void setup() throws Exception {
+        sndChannel = DatagramChannel.open();
+        sndChannel.bind(null);
+        InetAddress address = InetAddress.getLocalHost();
+        if (address.isLoopbackAddress()) {
+            address = InetAddress.getLoopbackAddress();
+        }
+        sender = new InetSocketAddress(address,
+            sndChannel.socket().getLocalPort());
+
+        rcvChannel = DatagramChannel.open();
+        rcvChannel.bind(null);
+        receiver = new InetSocketAddress(address,
+            rcvChannel.socket().getLocalPort());
+    }
+
+    @Test(expectedExceptions = UnsupportedAddressTypeException.class)
+    public static void unsupportedAddressTypeException() throws Exception {
+        rcvChannel.connect(sender);
+        sndChannel.send(buf, new SocketAddress() {});
+    }
+
+    @Test(expectedExceptions = UnresolvedAddressException.class)
+    public static void unresolvedAddressException() throws Exception {
+        String host = TestUtil.UNRESOLVABLE_HOST;
+        InetSocketAddress unresolvable = new InetSocketAddress (host, 37);
+        sndChannel.send(buf, unresolvable);
+    }
+
+    @Test(expectedExceptions = AlreadyConnectedException.class)
+    public static void alreadyConnectedException() throws Exception {
+        sndChannel.connect(receiver);
+        InetSocketAddress random = new InetSocketAddress(0);
+        sndChannel.send(buf, random);
+    }
+
+    @AfterTest
+    public static void cleanup() throws Exception {
+        rcvChannel.close();
+        sndChannel.close();
+    }
+}
--- a/test/jdk/java/nio/channels/DatagramChannel/SendToUnresolved.java	Thu Mar 22 14:10:30 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- * 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.
- */
-
-/* @test
- * @bug 4675045
- * @summary Test DatagramChannel send to unresolved address
- * @library ..
- */
-
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
-
-public class SendToUnresolved {
-    public static void main(String [] argv) throws Exception {
-        String host = TestUtil.UNRESOLVABLE_HOST;
-        DatagramChannel dc = DatagramChannel.open();
-        ByteBuffer bb = ByteBuffer.allocate(4);
-        InetSocketAddress sa = new InetSocketAddress (host, 37);
-        InetAddress inetaddr = sa.getAddress();
-        try {
-            dc.send(bb, sa);
-            throw new RuntimeException("Expected exception not thrown");
-        } catch (IOException | UnresolvedAddressException e) {
-            // Correct result
-        }
-        dc.close();
-    }
-}
--- a/test/jdk/java/nio/channels/Selector/CloseWhenKeyIdle.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/jdk/java/nio/channels/Selector/CloseWhenKeyIdle.java	Fri Mar 23 08:49:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -62,22 +62,6 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Skip test on pre-2.6 kernels until the poll SelectorProvider
-        // is updated
-        String osname = System.getProperty("os.name");
-        if (osname.equals("Linux")) {
-            String[] ver = System.getProperty("os.version").split("\\.", 0);
-            if (ver.length >=2 ) {
-                int major = Integer.parseInt(ver[0]);
-                int minor = Integer.parseInt(ver[1]);
-                if (major < 2 || (major == 2 && minor < 6)) {
-                    System.out.println("Test passing on pre-2.6 kernel");
-                    return;
-                }
-            }
-        }
-
-
         // establish loopback connection
 
         ServerSocketChannel ssc = ServerSocketChannel.open();
--- a/test/jdk/java/util/Collection/MOAT.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/jdk/java/util/Collection/MOAT.java	Fri Mar 23 08:49:58 2018 -0700
@@ -26,7 +26,7 @@
  * @bug     6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464
  *          4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753
  *          6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215
- *          4802647 7123424 8024709
+ *          4802647 7123424 8024709 8193128
  * @summary Run many tests on many Collection and Map implementations
  * @author  Martin Buchholz
  * @modules java.base/java.util:open
@@ -212,8 +212,11 @@
 
         // Immutable List
         testEmptyList(List.of());
+        testEmptyList(List.of().subList(0,0));
         testListMutatorsAlwaysThrow(List.of());
+        testListMutatorsAlwaysThrow(List.<Integer>of().subList(0,0));
         testEmptyListMutatorsAlwaysThrow(List.of());
+        testEmptyListMutatorsAlwaysThrow(List.<Integer>of().subList(0,0));
         for (List<Integer> list : Arrays.asList(
                 List.<Integer>of(),
                 List.of(1),
@@ -230,6 +233,17 @@
             testCollection(list);
             testImmutableList(list);
             testListMutatorsAlwaysThrow(list);
+            if (list.size() >= 1) {
+                // test subLists
+                List<Integer> headList = list.subList(0, list.size() - 1);
+                List<Integer> tailList = list.subList(1, list.size());
+                testCollection(headList);
+                testCollection(tailList);
+                testImmutableList(headList);
+                testImmutableList(tailList);
+                testListMutatorsAlwaysThrow(headList);
+                testListMutatorsAlwaysThrow(tailList);
+            }
         }
 
         List<Integer> listCopy = List.copyOf(Arrays.asList(1, 2, 3));
@@ -243,6 +257,44 @@
         testImmutableList(listCollected);
         testListMutatorsAlwaysThrow(listCollected);
 
+        // List indexOf / lastIndexOf
+
+        // 0 element
+        System.out.println("testListIndexOf size 0");
+        testListIndexOf(-1, -1);
+
+        System.out.println("testListIndexOf size 1");
+        testListIndexOf(-1, -1, 0);
+        testListIndexOf(0, 0, 1);
+
+        System.out.println("testListIndexOf size 2");
+        testListIndexOf(-1, -1, 0, 0);
+        testListIndexOf(0, 0, 1, 0);
+        testListIndexOf(0, 1, 1, 1);
+        testListIndexOf(1, 1, 0, 1);
+
+
+        System.out.println("testListIndexOf size 3");
+        testListIndexOf(-1, -1, 0, 0, 0);
+        testListIndexOf(0, 0, 1, 0, 0);
+        testListIndexOf(0, 1, 1, 1, 0);
+        testListIndexOf(1, 2, 0, 1, 1);
+        testListIndexOf(2, 2, 0, 0, 1);
+
+        System.out.println("testListIndexOf size N");
+        testListIndexOf(-1, -1, 0, 0, 0, 0, 0, 0, 0);
+        testListIndexOf(2, 6, 0, 0, 1, 0, 1, 0, 1);
+        testListIndexOf(4, 4, 0, 0, 0, 0, 1, 0, 0);
+        testListIndexOf(0, 6, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 7, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(0, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+        testListIndexOf(12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
+        testListIndexOf(-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
         // Immutable Set
         testEmptySet(Set.of());
         testCollMutatorsAlwaysThrow(Set.of());
@@ -963,6 +1015,37 @@
         equal(it.next(), 4);
     }
 
+    // for any array of integer values, check that the result of lastIndexOf(1)
+    // and indexOf(1) match assumptions for all types of List<Integer> we can
+    // construct
+    private static void testListIndexOf(final int index,
+                                        final int lastIndex,
+                                        final Integer ... values) {
+        if (values.length == 0) {
+            checkListIndexOf(emptyList(), index, lastIndex);
+        } else if (values.length == 1) {
+            checkListIndexOf(singletonList(values[0]), index, lastIndex);
+            checkListIndexOf(nCopies(25, values[0]), index, lastIndex == 0 ? 24 : -1);
+        }
+        List<Integer> l = List.of(values);
+        checkListIndexOf(l, index, lastIndex);
+        checkListIndexOf(Arrays.asList(values), index, lastIndex);
+        checkListIndexOf(new ArrayList(l), index, lastIndex);
+        checkListIndexOf(new LinkedList(l), index, lastIndex);
+        checkListIndexOf(new Vector(l), index, lastIndex);
+        checkListIndexOf(new CopyOnWriteArrayList(l), index, lastIndex);
+    }
+
+    private static void checkListIndexOf(final List<Integer> list,
+                                         final int index,
+                                         final int lastIndex) {
+        String msg = list.getClass().toString();
+        equal(list.indexOf(1), index, msg);
+        equal(list.lastIndexOf(1), lastIndex, msg);
+        equal(list.subList(0, list.size()).indexOf(1), index, msg);
+        equal(list.subList(0, list.size()).lastIndexOf(1), lastIndex, msg);
+    }
+
     private static void testList(final List<Integer> l) {
         //----------------------------------------------------------------
         // 4802633: (coll) AbstractList.addAll(-1,emptyCollection)
@@ -1629,6 +1712,9 @@
     static void equal(Object x, Object y) {
         if (x == null ? y == null : x.equals(y)) pass();
         else {System.out.println(x + " not equal to " + y); fail();}}
+    static void equal(Object x, Object y, String msg) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else {System.out.println(x + " not equal to " + y + " : " + msg); fail();}}
     static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}
     public static void main(String[] args) throws Throwable {
         try { realMain(args); } catch (Throwable t) { unexpected(t); }
--- a/test/jdk/java/util/Collection/SetFactories.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/jdk/java/util/Collection/SetFactories.java	Fri Mar 23 08:49:58 2018 -0700
@@ -266,6 +266,11 @@
         Set.of((Object[])null);
     }
 
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsNullShouldThrowNPE(Set<String> act, Set<String> exp) {
+        act.contains(null);
+    }
+
     @Test(dataProvider="all")
     public void serialEquality(Set<String> act, Set<String> exp) {
         // assume that act.equals(exp) tested elsewhere
--- a/test/jdk/java/util/List/ListFactories.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/jdk/java/util/List/ListFactories.java	Fri Mar 23 08:49:58 2018 -0700
@@ -26,6 +26,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -72,7 +73,7 @@
     @DataProvider(name="empty")
     public Iterator<Object[]> empty() {
         return Collections.singletonList(
-            a(List.of(), Collections.emptyList())
+            a(List.of(), asList())
         ).iterator();
     }
 
@@ -104,11 +105,50 @@
         ).iterator();
     }
 
+    @DataProvider(name="sublists")
+    public Iterator<Object[]> sublists() {
+        return asList(
+            a(List.<String>of().subList(0,0),
+               asList()),
+            a(List.of("a").subList(0,0),
+               asList("a").subList(0,0)),
+            a(List.of("a", "b").subList(0,1),
+               asList("a", "b").subList(0,1)),
+            a(List.of("a", "b", "c").subList(1,3),
+               asList("a", "b", "c").subList(1,3)),
+            a(List.of("a", "b", "c", "d").subList(0,4),
+               asList("a", "b", "c", "d").subList(0,4)),
+            a(List.of("a", "b", "c", "d", "e").subList(0,3),
+               asList("a", "b", "c", "d", "e").subList(0,3)),
+            a(List.of("a", "b", "c", "d", "e", "f").subList(3, 5),
+               asList("a", "b", "c", "d", "e", "f").subList(3, 5)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g").subList(0, 7),
+               asList("a", "b", "c", "d", "e", "f", "g").subList(0, 7)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0),
+               asList("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10)),
+            a(List.of(stringArray).subList(5, NUM_STRINGS),
+               asList(Arrays.copyOfRange(stringArray, 5, NUM_STRINGS)))
+                ).iterator();
+    }
+
     @DataProvider(name="all")
     public Iterator<Object[]> all() {
         List<Object[]> all = new ArrayList<>();
         empty().forEachRemaining(all::add);
         nonempty().forEachRemaining(all::add);
+        sublists().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @DataProvider(name="nonsublists")
+    public Iterator<Object[]> nonsublists() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
         return all.iterator();
     }
 
@@ -212,7 +252,29 @@
         assertEquals(list, Arrays.asList(stringArray));
     }
 
-    @Test(dataProvider="all")
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsNullShouldThrowNPE(List<String> act, List<String> exp) {
+        act.contains(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void indexOfNullShouldThrowNPE(List<String> act, List<String> exp) {
+        act.indexOf(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void lastIndexOfNullShouldThrowNPE(List<String> act, List<String> exp) {
+        act.lastIndexOf(null);
+    }
+
+    // List.of().subList views should not be Serializable
+    @Test(dataProvider="sublists")
+    public void isNotSerializable(List<String> act, List<String> exp) {
+        assertFalse(act instanceof Serializable);
+    }
+
+    // ... but List.of() should be
+    @Test(dataProvider="nonsublists")
     public void serialEquality(List<String> act, List<String> exp) {
         // assume that act.equals(exp) tested elsewhere
         List<String> copy = serialClone(act);
--- a/test/jdk/java/util/Map/MapFactories.java	Thu Mar 22 14:10:30 2018 -0700
+++ b/test/jdk/java/util/Map/MapFactories.java	Fri Mar 23 08:49:58 2018 -0700
@@ -376,6 +376,16 @@
         Map.ofEntries((Map.Entry<?,?>[])null);
     }
 
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsValueNullShouldThrowNPE(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.containsValue(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsKeyNullShouldThrowNPE(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.containsKey(null);
+    }
+
     @Test(dataProvider="all")
     public void serialEquality(Map<Integer, String> act, Map<Integer, String> exp) {
         // assume that act.equals(exp) tested elsewhere