This is the mail archive of the cygwin@sources.redhat.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Serial I/O Multi-thread safe - FIX


Here is a fix for the problem I posted back on January 12th. The
problem lies in fhandler_serial.cc

The problem is that both the raw_read() and raw_write() functions use
the same io_status structure. My fix below
creates a local structure called osWrite in the raw_write function. This
may not be the best way to solve the
problem, but it works. I have built cygwin1.dll, tested it, and the problem 
is solved. Serial I/O seems solid now.

I have a document from Microsoft that explains: "A common mistake in
overlapped I/O is to reuse an OVERLAPPED structure
before the previous overlapped operation is completed". In my
application, one thread was blocked on a read while another
thread issued a write on the same handle.

My hope is that this fix or something similar will find its
way into an upcoming release.

Thanks

- Bill

----- Cut here ------

/* Cover function to WriteFile to provide Posix interface and semantics
   (as much as possible).  */
int
fhandler_serial::raw_write (const void *ptr, size_t len)
{
  DWORD bytes_written;
  OVERLAPPED osWrite;

  memset (&osWrite, 0, sizeof (osWrite));
  osWrite.hEvent = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
  ProtectHandle (osWrite.hEvent);

  if (overlapped_armed)
    PurgeComm (get_handle (), PURGE_TXABORT | PURGE_RXABORT);

  for (;;)
    {
      overlapped_armed = TRUE;
      if (WriteFile (get_handle(), ptr, len, &bytes_written, &osWrite))
        break;

      switch (GetLastError ())
        {
          case ERROR_OPERATION_ABORTED:
            continue;
          case ERROR_IO_PENDING:
            break;
          default:
            goto err;
        }

      if (!GetOverlappedResult (get_handle (), &osWrite, &bytes_written,
TRUE))
        goto err;

      break;
    }

  CloseHandle(osWrite.hEvent);
 
  overlapped_armed = FALSE;
  return bytes_written;

err:
  CloseHandle(osWrite.hEvent);
  __seterrno ();
  return -1;
}


--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]