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
next prev parent 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).