caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Dmitry Bely" <dmitry.bely@gmail.com>
To: "Alain Frisch" <alain@frisch.fr>
Cc: ocaml <caml-list@inria.fr>
Subject: Re: [Caml-list] Ocaml debugger under Windows
Date: Wed, 6 Feb 2008 11:56:43 +0300	[thread overview]
Message-ID: <90823c940802060056i6afd360did9cbef43c9664bf@mail.gmail.com> (raw)
In-Reply-To: <47A8CE81.5040905@frisch.fr>

On Feb 6, 2008 12:00 AM, Alain Frisch <alain@frisch.fr> wrote:
> > I don't think it would work on Windows. You cannot select() on
> > arbitrary Unix.file_descr - only socket-associated descriptor can be
> > used.
>
> Do you know how Cygwin emulate the desired behavior?  Does it use threads?

It surely use WaitForMultipleObjects() instead of select(). The
implementation is quite complicated; GDB's one seems to be better
showing an idea (see below).

But frankly speaking I don't like to add any C code here - in fact it
means altering win32unix library that is unlikely to happen. Can it be
solved on Caml level? Anyone? Is select() with small timeout is
acceptable?

/* Wrapper for select.  On Windows systems, where the select interface
   only works for sockets, this uses the GDB serial abstraction to
   handle sockets, consoles, pipes, and serial ports.

   The arguments to this function are the same as the traditional
   arguments to select on POSIX platforms.  */

int
gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	    struct timeval *timeout)
{
  static HANDLE never_handle;
  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
  HANDLE h;
  DWORD event;
  DWORD num_handles;
  int fd;
  int num_ready;
  int indx;

  num_ready = 0;
  num_handles = 0;
  for (fd = 0; fd < n; ++fd)
    {
      HANDLE read = NULL, except = NULL;
      struct serial *scb;

      /* There is no support yet for WRITEFDS.  At present, this isn't
	 used by GDB -- but we do not want to silently ignore WRITEFDS
	 if something starts using it.  */
      gdb_assert (!writefds || !FD_ISSET (fd, writefds));

      if ((!readfds || !FD_ISSET (fd, readfds))
	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
	continue;
      h = (HANDLE) _get_osfhandle (fd);

      scb = serial_for_fd (fd);
      if (scb)
	serial_wait_handle (scb, &read, &except);

      if (read == NULL)
	read = h;
      if (except == NULL)
	{
	  if (!never_handle)
	    never_handle = CreateEvent (0, FALSE, FALSE, 0);

	  except = never_handle;
	}

      if (readfds && FD_ISSET (fd, readfds))
	{
	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
	  handles[num_handles++] = read;
	}

      if (exceptfds && FD_ISSET (fd, exceptfds))
	{
	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
	  handles[num_handles++] = except;
	}
    }
  /* If we don't need to wait for any handles, we are done.  */
  if (!num_handles)
    {
      if (timeout)
	Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);

      return 0;
    }

  event = WaitForMultipleObjects (num_handles,
				  handles,
				  FALSE,
				  timeout
				  ? (timeout->tv_sec * 1000
				     + timeout->tv_usec / 1000)
				  : INFINITE);
  /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
     HANDLES included an abandoned mutex.  Since GDB doesn't use
     mutexes, that should never occur.  */
  gdb_assert (!(WAIT_ABANDONED_0 <= event
		&& event < WAIT_ABANDONED_0 + num_handles));
  if (event == WAIT_FAILED)
    return -1;
  if (event == WAIT_TIMEOUT)
    return 0;
  /* Run through the READFDS, clearing bits corresponding to descriptors
     for which input is unavailable.  */
  h = handles[event - WAIT_OBJECT_0];
  for (fd = 0, indx = 0; fd < n; ++fd)
    {
      HANDLE fd_h;
      struct serial *scb;

      if ((!readfds || !FD_ISSET (fd, readfds))
	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
	continue;

      if (readfds && FD_ISSET (fd, readfds))
	{
	  fd_h = handles[indx++];
	  /* This handle might be ready, even though it wasn't the handle
	     returned by WaitForMultipleObjects.  */
	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
	    FD_CLR (fd, readfds);
	  else
	    num_ready++;
	}

      if (exceptfds && FD_ISSET (fd, exceptfds))
	{
	  fd_h = handles[indx++];
	  /* This handle might be ready, even though it wasn't the handle
	     returned by WaitForMultipleObjects.  */
	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
	    FD_CLR (fd, exceptfds);
	  else
	    num_ready++;
	}

      /* We created at least one event handle for this fd.  Let the
	 device know we are finished with it.  */
      scb = serial_for_fd (fd);
      if (scb)
	serial_done_wait_handle (scb);
    }

  return num_ready;
}

- Dmitry Bely


  reply	other threads:[~2008-02-06  8:56 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-05  9:46 Dmitry Bely
2008-02-05  9:54 ` [Caml-list] " Alain Frisch
2008-02-05 17:23   ` Dmitry Bely
2008-02-05 17:40     ` Benedikt Grundmann
2008-02-05 19:39       ` Dmitry Bely
2008-02-05 21:00         ` Alain Frisch
2008-02-06  8:56           ` Dmitry Bely [this message]
2008-02-06 17:12     ` Xavier Leroy
2008-02-06 18:22       ` Dmitry Bely
2008-05-03 18:39       ` Dmitry Bely
2008-02-08 13:27     ` Kuba Ober
2008-02-08 16:33       ` Dmitry Bely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=90823c940802060056i6afd360did9cbef43c9664bf@mail.gmail.com \
    --to=dmitry.bely@gmail.com \
    --cc=alain@frisch.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).