예제 #1
0
  public int write(int fd, byte[] buffer, int length) {
    Port port = getPort(fd);
    if (port == null) return -1;

    synchronized (port.m_WrBuffer) {
      try {
        if (port.m_WritePending > 0) {
          while (true) {
            int res = WaitForSingleObject(port.m_WrOVL.hEvent, INFINITE);
            if (res == WAIT_TIMEOUT) {
              clearCommErrors(port);
              log =
                  log
                      && log(
                          1,
                          "write pending, cbInQue %d cbOutQue %d\n",
                          port.m_COMSTAT.cbInQue,
                          port.m_COMSTAT.cbOutQue);
              continue;
            }
            if (!GetOverlappedResult(port.m_Comm, port.m_WrOVL, port.m_WrN, false)) port.fail();
            if (port.m_WrN[0]
                != port.m_WritePending) // I exptect this is never going to happen, if it does
            new RuntimeException(
                  "Windows OVERLAPPED WriteFile failed to write all, tried to write "
                      + port.m_WritePending
                      + " but got "
                      + port.m_WrN[0]);
            break;
          }
          port.m_WritePending = 0;
        }
        if ((port.m_OpenFlags & O_NONBLOCK) != 0) {
          if (!ClearCommError(port.m_Comm, port.m_WrErr, port.m_WrStat)) port.fail();
          int room = (int) port.m_WrBuffer.size() - port.m_WrStat.cbOutQue;
          if (length > room) length = room;
        }

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

        if (length > port.m_WrBuffer.size()) length = (int) port.m_WrBuffer.size();
        port.m_WrBuffer.write(0, buffer, 0, length); // copy from buffer to Memory
        boolean ok = WriteFile(port.m_Comm, port.m_WrBuffer, length, port.m_WrN, port.m_WrOVL);

        if (!ok) {
          if (GetLastError() != ERROR_IO_PENDING) port.fail();
          port.m_WritePending = length;
        }
        //
        return length; // port.m_WrN[0];
      } catch (Fail f) {
        return -1;
      }
    }
  }