예제 #1
0
  public List<String> getPortList() {
    Pattern p = JTermios.getPortNamePattern(this);
    char[] buffer;
    int size = 0;
    for (size = 16 * 1024; size < 256 * 1024; size *= 2) {
      buffer = new char[size];
      int res = QueryDosDeviceW(null, buffer, buffer.length);
      if (res > 0) { //
        LinkedList<String> list = new LinkedList<String>();
        int offset = 0;
        String port;
        while ((port = getString(buffer, offset)).length() > 0) {
          if (p.matcher(port).matches()) list.add(port);

          offset += port.length() + 1;
        }
        return list;
      } else {
        int err = GetLastError();
        if (err != ERROR_INSUFFICIENT_BUFFER) {
          log = log && log(1, "QueryDosDeviceW() failed with GetLastError() = %d\n", err);
          return null;
        }
      }
    }
    log = log && log(1, "Repeated QueryDosDeviceW() calls failed up to buffer size %d\n", size);
    return null;
  }
예제 #2
0
  public int select(int n, FDSet readfds, FDSet writefds, FDSet exceptfds, TimeVal timeout) {
    // long T0 = System.currentTimeMillis();
    int ready = 0;
    LinkedList<Port> locked = new LinkedList<Port>();
    try {
      try {
        LinkedList<Port> waiting = new LinkedList<Port>();
        for (int fd = 0; fd < n; fd++) {
          boolean rd = FD_ISSET(fd, readfds);
          boolean wr = FD_ISSET(fd, writefds);
          FD_CLR(fd, readfds);
          FD_CLR(fd, writefds);
          if (rd || wr) {
            Port port = getPort(fd);
            if (port == null) return -1;
            try {
              port.lock();
              locked.add(port);
              clearCommErrors(port);

              // check if there is data to be read, as WaitCommEvent
              // does check for only *new* data that and thus
              // might wait indefinitely if select() is called twice
              // without first reading away all data

              if (rd && port.m_COMSTAT.cbInQue > 0) {
                FD_SET(fd, readfds);
                ready++;
              }

              if (wr && port.m_COMSTAT.cbOutQue == 0) {
                FD_SET(fd, writefds);
                ready++;
              }

              if (!ResetEvent(port.m_SelOVL.hEvent)) port.fail();

              int flags = 0;
              if (rd) flags |= EV_RXCHAR;
              if (wr) flags |= EV_TXEMPTY;
              if (!SetCommMask(port.m_Comm, flags)) port.fail();
              if (WaitCommEvent(port.m_Comm, port.m_EventFlags, port.m_SelOVL)) {
                if (!GetOverlappedResult(port.m_Comm, port.m_SelOVL, port.m_SelN, false))
                  port.fail();
                // actually it seems that overlapped
                // WaitCommEvent never returns true so we never get here
                ready = maskToFDSets(port, readfds, writefds, exceptfds, ready);
              } else {
                // FIXME if the port dies on us what happens
                if (GetLastError() != ERROR_IO_PENDING) port.fail();
                waiting.add(port);
              }
            } catch (InterruptedException ie) {
              m_ErrNo = EINTR;
              return -1;
            }
          }
        }
        if (ready == 0) {
          int waitn = waiting.size();
          if (waitn > 0) {
            HANDLE[] wobj = new HANDLE[waiting.size() * 2];
            int i = 0;
            for (Port port : waiting) {
              wobj[i++] = port.m_SelOVL.hEvent;
              wobj[i++] = port.m_CancelWaitSema4;
            }
            int tout =
                timeout != null ? (int) (timeout.tv_sec * 1000 + timeout.tv_usec / 1000) : INFINITE;
            // int res = WaitForSingleObject(wobj[0], tout);
            int res = WaitForMultipleObjects(waitn * 2, wobj, false, tout);

            if (res == WAIT_TIMEOUT) {
              // work around the fact that sometimes we miss
              // events
              for (Port port : waiting) {
                clearCommErrors(port);
                int[] mask = {0};

                if (!GetCommMask(port.m_Comm, mask)) port.fail();
                if (port.m_COMSTAT.cbInQue > 0 && ((mask[0] & EV_RXCHAR) != 0)) {
                  FD_SET(port.m_FD, readfds);
                  log = log && log(1, "missed EV_RXCHAR event\n");
                  return 1;
                }
                if (port.m_COMSTAT.cbOutQue == 0 && ((mask[0] & EV_TXEMPTY) != 0)) {
                  FD_SET(port.m_FD, writefds);
                  log = log && log(1, "missed EV_TXEMPTY event\n");
                  return 1;
                }
              }
            }
            if (res != WAIT_TIMEOUT) {
              i = (res - WAIT_OBJECT_0) / 2;
              if (i < 0 || i >= waitn) throw new Fail();

              Port port = waiting.get(i);
              if (!GetOverlappedResult(port.m_Comm, port.m_SelOVL, port.m_SelN, false)) port.fail();

              ready = maskToFDSets(port, readfds, writefds, exceptfds, ready);
            }
          } else {
            if (timeout != null) nanoSleep(timeout.tv_sec * 1000000000L + timeout.tv_usec * 1000);
            else {
              m_ErrNo = EINVAL;
              return -1;
            }
            return 0;
          }
        }
      } catch (Fail f) {
        return -1;
      }
    } finally {
      for (Port port : locked) port.unlock();
    }
    // long T1 = System.currentTimeMillis();
    // System.err.println("select() " + (T1 - T0));

    return ready;
  }