Browse thread
Ocaml debugger under Windows
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Dmitry Bely <dmitry.bely@g...> |
| Subject: | Re: [Caml-list] Ocaml debugger under Windows |
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