Revu la construction des listes resultats, plus efficace si FD_SETSIZE est grand (PR#738)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@4774 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02master
parent
f4961db472
commit
7d3b7ee427
|
@ -31,25 +31,28 @@
|
|||
|
||||
typedef fd_set file_descr_set;
|
||||
|
||||
static void fdlist_to_fdset(value fdlist, file_descr_set *fdset)
|
||||
static void fdlist_to_fdset(value fdlist, fd_set *fdset, int *maxfd)
|
||||
{
|
||||
value l;
|
||||
FD_ZERO(fdset);
|
||||
for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
|
||||
FD_SET(Int_val(Field(l, 0)), fdset);
|
||||
int fd = Int_val(Field(l, 0));
|
||||
FD_SET(fd, fdset);
|
||||
if (fd > *maxfd) *maxfd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
static value fdset_to_fdlist(file_descr_set *fdset)
|
||||
static value fdset_to_fdlist(value fdlist, fd_set *fdset)
|
||||
{
|
||||
int i;
|
||||
value l;
|
||||
value res = Val_int(0);
|
||||
|
||||
Begin_root(res);
|
||||
for (i = FD_SETSIZE - 1; i >= 0; i--) {
|
||||
if (FD_ISSET(i, fdset)) {
|
||||
Begin_roots2(l, res);
|
||||
for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
|
||||
int fd = Int_val(Field(l, 0));
|
||||
if (FD_ISSET(fd, fdset)) {
|
||||
value newres = alloc_small(2, 0);
|
||||
Field(newres, 0) = Val_int(i);
|
||||
Field(newres, 0) = Val_int(fd);
|
||||
Field(newres, 1) = res;
|
||||
res = newres;
|
||||
}
|
||||
|
@ -58,46 +61,49 @@ static value fdset_to_fdlist(file_descr_set *fdset)
|
|||
return res;
|
||||
}
|
||||
|
||||
CAMLprim value unix_select(value readfds, value writefds, value exceptfds, value timeout)
|
||||
CAMLprim value unix_select(value readfds, value writefds, value exceptfds,
|
||||
value timeout)
|
||||
{
|
||||
file_descr_set read, write, except;
|
||||
fd_set read, write, except;
|
||||
int maxfd;
|
||||
double tm;
|
||||
struct timeval tv;
|
||||
struct timeval * tvp;
|
||||
int retcode;
|
||||
value res;
|
||||
value read_list = Val_unit, write_list = Val_unit, except_list = Val_unit;
|
||||
|
||||
Begin_roots3 (read_list, write_list, except_list);
|
||||
fdlist_to_fdset(readfds, &read);
|
||||
fdlist_to_fdset(writefds, &write);
|
||||
fdlist_to_fdset(exceptfds, &except);
|
||||
Begin_roots3 (readfds, writefds, exceptfds);
|
||||
maxfd = 0;
|
||||
fdlist_to_fdset(readfds, &read, &maxfd);
|
||||
fdlist_to_fdset(writefds, &write, &maxfd);
|
||||
fdlist_to_fdset(exceptfds, &except, &maxfd);
|
||||
tm = Double_val(timeout);
|
||||
if (tm < 0.0)
|
||||
tvp = (struct timeval *) NULL;
|
||||
else {
|
||||
tv.tv_sec = (int) tm;
|
||||
tv.tv_usec = (int) (1e6 * (tm - (int) tm));
|
||||
tv.tv_usec = (int) (1e6 * (tm - tv.tv_sec));
|
||||
tvp = &tv;
|
||||
}
|
||||
enter_blocking_section();
|
||||
retcode = select(FD_SETSIZE, &read, &write, &except, tvp);
|
||||
retcode = select(maxfd, &read, &write, &except, tvp);
|
||||
leave_blocking_section();
|
||||
if (retcode == -1) uerror("select", Nothing);
|
||||
read_list = fdset_to_fdlist(&read);
|
||||
write_list = fdset_to_fdlist(&write);
|
||||
except_list = fdset_to_fdlist(&except);
|
||||
readfds = fdset_to_fdlist(readfds, &read);
|
||||
writefds = fdset_to_fdlist(writefds, &write);
|
||||
exceptfds = fdset_to_fdlist(exceptfds, &except);
|
||||
res = alloc_small(3, 0);
|
||||
Field(res, 0) = read_list;
|
||||
Field(res, 1) = write_list;
|
||||
Field(res, 2) = except_list;
|
||||
Field(res, 0) = readfds;
|
||||
Field(res, 1) = writefds;
|
||||
Field(res, 2) = exceptfds;
|
||||
End_roots();
|
||||
return res;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CAMLprim value unix_select(value readfds, value writefds, value exceptfds, value timeout)
|
||||
CAMLprim value unix_select(value readfds, value writefds, value exceptfds,
|
||||
value timeout)
|
||||
{ invalid_argument("select not implemented"); }
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue