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

waitForCardAbsent(0) and waitForCardPresent(0) block terminal instance

    XMLWordPrintable

Details

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Linux vs OSX

      A DESCRIPTION OF THE PROBLEM :
      waitForCardAbsent and waitForCardPresent with indefinite as their parameter (pass in 0), block the terminal instance completely until the event that it is waiting for occurs. This is expected behavior, but other threads should still be able to talk with the terminal instance while another thread is waiting. This seems like only an issue on Linux, as the desired behavior works properly on OSX.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Call either of those methods on a CardTerminal instance in a thread, and when its waiting indefinitely, try interacting with the same card terminal in another thread. In my experience, you will be blocked from sending APDUs to the terminal in the other thread.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The desired behavior can be experienced on OSX. The threads listening for events are alive and well, but you are able to communicate with the terminal instance in another thread still as they are not being blocked.
      ACTUAL -
      Card terminal blocked until it returns back from the event, even in other threads

      ---------- BEGIN SOURCE ----------
      final TerminalFactory tf = TerminalFactory.getDefault();
              final List<CardTerminal> list = tf.terminals().list();
              for(final CardTerminal term : list) {
                  new Thread(() -> {
                      while(true) {
                          try {
                              if(term.isCardPresent()) {
                                  term.waitForCardAbsent(0);
                                  // do something now that card is missing
                              } else {
                                  term.waitForCardPresent(0);
                                  // do something now that card is gone
                              }
                          } catch(final CardException e) {
                              // oof
                          }
                      }
                  }).start();
              }

              for(final CardTerminal term : list) {
                  // send some APDUs to the terms
              }

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

      CUSTOMER SUBMITTED WORKAROUND :
      The only current workaround is to use an actual timeout value that's not indefinite, and keep asking for it over and over again. This seems to chew CPU % depending on how often it is being polled like that. My current new thread logic for that is:

      new Thread(() -> {
                      try {
                          boolean previous = terminal.isCardPresent();
                          while(true) {
                              terminal.waitForCardPresent(50);
                              if(terminal.isCardPresent()) {
                                  if(!previous) {
                                      previous = true;
                                  }
                              } else {
                                  if(previous) {
                                      previous = false;
                                  }
                              }
                          }
                      } catch(final CardException e) {
                         // oof
                      }
                  }).start();

      FREQUENCY : always


      Attachments

        Activity

          People

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: