Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8232862

MidiInDevice thread stuck after closing device

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 13
    • client-libs

      ADDITIONAL SYSTEM INFORMATION :
      OSX 10.14.6
      openjdk version "13" 2019-09-17
      OpenJDK Runtime Environment (build 13+33)
      OpenJDK 64-Bit Server VM (build 13+33, mixed mode, sharing)

      A DESCRIPTION OF THE PROBLEM :
      When opening a MidiInDevice a new thread is created for listening for midi messages.
      This thread calls a native method (MidiInDevice::nGetMessages
      ) for polling/fetching data.
      On osx this native method is blocking. If the device is now closed using MidiInDevice::close the native call will still block and the listener thread will be open for ever. This causes other side effects such as that the device can never be used again during the JVM runtime.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      0) Run on osx
      1) Open a midi input device (not synthesizer, not sequencer)
      2) Close the input device
      3) The application will now not terminate anymore
      The same code works on windows

      The sample code does the steps listed above with 5 seconds sleep in between

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The application should terminate and no midi thread should be active.
      ACTUAL -
      A midi input thread is still active and the native call is blocking

      ---------- BEGIN SOURCE ----------
      package test;

      import java.util.Arrays;
      import java.util.List;

      import javax.sound.midi.MidiDevice;
      import javax.sound.midi.MidiMessage;
      import javax.sound.midi.MidiSystem;
      import javax.sound.midi.MidiUnavailableException;
      import javax.sound.midi.Receiver;
      import javax.sound.midi.Sequencer;
      import javax.sound.midi.Synthesizer;
      import javax.sound.midi.Transmitter;

      public class MidiTest implements Receiver
      {
      private Transmitter transmitter;
      private MidiDevice device;

      public static void main(String[] args) throws MidiUnavailableException, InterruptedException
      {
      MidiTest test = new MidiTest();
      test.openDevice();
      Thread.sleep(5000);
      test.closeDevice();
      Thread.sleep(5000);
      for (Thread thread : Thread.getAllStackTraces().keySet())
      {
      System.out.println("Active threads: " + thread.getName());
      }
      }

      public void openDevice() throws MidiUnavailableException
      {
      List<MidiDevice.Info> deviceInfo = Arrays.asList(MidiSystem.getMidiDeviceInfo());
      for (MidiDevice.Info info : deviceInfo)
      {
      MidiDevice device = MidiSystem.getMidiDevice(info);
      if (device.getMaxTransmitters() == 0 || device instanceof Sequencer || device instanceof Synthesizer)
      {
      continue;
      }

      // Found an output device
      open(device);
      return;
      }
      }

      private void open(MidiDevice device) throws MidiUnavailableException
      {
      this.device = device;
      device.open();
      transmitter = device.getTransmitter();
      transmitter.setReceiver(this);
      System.out.println("Listening for data...");
      }

      private void closeDevice()
      {
      System.out.println("Closing device...");
      transmitter.close();
      device.close();
      }

      @Override
      public void send(MidiMessage message, long timeStamp)
      {
      System.out.println("Data received: " + message.toString());
      }

      @Override
      public void close()
      {
      // Nothing
      }
      }


      ---------- END SOURCE ----------

      FREQUENCY : always


            skodandarama Suman Rajkumaar Kodandarama (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: