loop through addresses for TCP connect or listen
svn: r1232
This commit is contained in:
parent
0dd1f6a2ab
commit
1fc7c09a67
|
@ -3006,36 +3006,34 @@ int mark_print_params_FIXUP(void *p) {
|
||||||
#ifdef MARKS_FOR_NETWORK_C
|
#ifdef MARKS_FOR_NETWORK_C
|
||||||
|
|
||||||
int mark_listener_SIZE(void *p) {
|
int mark_listener_SIZE(void *p) {
|
||||||
|
listener_t *l = (listener_t *)p;
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(listener_t));
|
gcBYTES_TO_WORDS(sizeof(listener_t) + ((l->count - 1) * sizeof(tcp_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int mark_listener_MARK(void *p) {
|
int mark_listener_MARK(void *p) {
|
||||||
listener_t *l = (listener_t *)p;
|
listener_t *l = (listener_t *)p;
|
||||||
|
|
||||||
|
|
||||||
gcMARK(l->mref);
|
gcMARK(l->mref);
|
||||||
#ifdef USE_MAC_TCP
|
|
||||||
gcMARK(l->datas);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(listener_t));
|
gcBYTES_TO_WORDS(sizeof(listener_t) + ((l->count - 1) * sizeof(tcp_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int mark_listener_FIXUP(void *p) {
|
int mark_listener_FIXUP(void *p) {
|
||||||
listener_t *l = (listener_t *)p;
|
listener_t *l = (listener_t *)p;
|
||||||
|
|
||||||
|
|
||||||
gcFIXUP(l->mref);
|
gcFIXUP(l->mref);
|
||||||
#ifdef USE_MAC_TCP
|
|
||||||
gcFIXUP(l->datas);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(listener_t));
|
gcBYTES_TO_WORDS(sizeof(listener_t) + ((l->count - 1) * sizeof(tcp_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define mark_listener_IS_ATOMIC 0
|
#define mark_listener_IS_ATOMIC 0
|
||||||
#define mark_listener_IS_CONST_SIZE 1
|
#define mark_listener_IS_CONST_SIZE 0
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TCP
|
#ifdef USE_TCP
|
||||||
|
@ -3049,10 +3047,6 @@ int mark_tcp_MARK(void *p) {
|
||||||
|
|
||||||
gcMARK(tcp->b.buffer);
|
gcMARK(tcp->b.buffer);
|
||||||
gcMARK(tcp->b.out_buffer);
|
gcMARK(tcp->b.out_buffer);
|
||||||
# ifdef USE_MAC_TCP
|
|
||||||
gcMARK(tcp->tcp);
|
|
||||||
gcMARK(tcp->activeRcv);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Tcp));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Tcp));
|
||||||
|
@ -3063,10 +3057,6 @@ int mark_tcp_FIXUP(void *p) {
|
||||||
|
|
||||||
gcFIXUP(tcp->b.buffer);
|
gcFIXUP(tcp->b.buffer);
|
||||||
gcFIXUP(tcp->b.out_buffer);
|
gcFIXUP(tcp->b.out_buffer);
|
||||||
# ifdef USE_MAC_TCP
|
|
||||||
gcFIXUP(tcp->tcp);
|
|
||||||
gcFIXUP(tcp->activeRcv);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Tcp));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Tcp));
|
||||||
|
@ -3076,35 +3066,6 @@ int mark_tcp_FIXUP(void *p) {
|
||||||
#define mark_tcp_IS_CONST_SIZE 1
|
#define mark_tcp_IS_CONST_SIZE 1
|
||||||
|
|
||||||
|
|
||||||
# ifdef USE_MAC_TCP
|
|
||||||
int mark_write_data_SIZE(void *p) {
|
|
||||||
return
|
|
||||||
gcBYTES_TO_WORDS(sizeof(WriteData));
|
|
||||||
}
|
|
||||||
|
|
||||||
int mark_write_data_MARK(void *p) {
|
|
||||||
WriteData *d = (WriteData *)p;
|
|
||||||
|
|
||||||
gcMARK(d->xpb);
|
|
||||||
|
|
||||||
return
|
|
||||||
gcBYTES_TO_WORDS(sizeof(WriteData));
|
|
||||||
}
|
|
||||||
|
|
||||||
int mark_write_data_FIXUP(void *p) {
|
|
||||||
WriteData *d = (WriteData *)p;
|
|
||||||
|
|
||||||
gcFIXUP(d->xpb);
|
|
||||||
|
|
||||||
return
|
|
||||||
gcBYTES_TO_WORDS(sizeof(WriteData));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define mark_write_data_IS_ATOMIC 0
|
|
||||||
#define mark_write_data_IS_CONST_SIZE 1
|
|
||||||
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef UDP_IS_SUPPORTED
|
# ifdef UDP_IS_SUPPORTED
|
||||||
int mark_udp_SIZE(void *p) {
|
int mark_udp_SIZE(void *p) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -1204,16 +1204,14 @@ END print;
|
||||||
START network;
|
START network;
|
||||||
|
|
||||||
mark_listener {
|
mark_listener {
|
||||||
mark:
|
|
||||||
listener_t *l = (listener_t *)p;
|
listener_t *l = (listener_t *)p;
|
||||||
|
|
||||||
|
mark:
|
||||||
|
|
||||||
gcMARK(l->mref);
|
gcMARK(l->mref);
|
||||||
#ifdef USE_MAC_TCP
|
|
||||||
gcMARK(l->datas);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size:
|
size:
|
||||||
gcBYTES_TO_WORDS(sizeof(listener_t));
|
gcBYTES_TO_WORDS(sizeof(listener_t) + ((l->count - 1) * sizeof(tcp_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_TCP
|
#ifdef USE_TCP
|
||||||
|
@ -1223,27 +1221,11 @@ mark_tcp {
|
||||||
|
|
||||||
gcMARK(tcp->b.buffer);
|
gcMARK(tcp->b.buffer);
|
||||||
gcMARK(tcp->b.out_buffer);
|
gcMARK(tcp->b.out_buffer);
|
||||||
# ifdef USE_MAC_TCP
|
|
||||||
gcMARK(tcp->tcp);
|
|
||||||
gcMARK(tcp->activeRcv);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
size:
|
size:
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Tcp));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Tcp));
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef USE_MAC_TCP
|
|
||||||
mark_write_data {
|
|
||||||
mark:
|
|
||||||
WriteData *d = (WriteData *)p;
|
|
||||||
|
|
||||||
gcMARK(d->xpb);
|
|
||||||
|
|
||||||
size:
|
|
||||||
gcBYTES_TO_WORDS(sizeof(WriteData));
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef UDP_IS_SUPPORTED
|
# ifdef UDP_IS_SUPPORTED
|
||||||
mark_udp {
|
mark_udp {
|
||||||
mark:
|
mark:
|
||||||
|
|
|
@ -111,8 +111,9 @@ typedef SOCKET tcp_t;
|
||||||
#ifdef USE_SOCKETS_TCP
|
#ifdef USE_SOCKETS_TCP
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Scheme_Object so;
|
Scheme_Object so;
|
||||||
tcp_t s;
|
|
||||||
Scheme_Custodian_Reference *mref;
|
Scheme_Custodian_Reference *mref;
|
||||||
|
int count;
|
||||||
|
tcp_t s[1];
|
||||||
} listener_t;
|
} listener_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -834,7 +835,7 @@ static void TCP_INIT(char *name)
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
|
|
||||||
#ifdef USE_SOCKETS_TCP
|
#ifdef USE_SOCKETS_TCP
|
||||||
#define LISTENER_WAS_CLOSED(x) (((listener_t *)(x))->s == INVALID_SOCKET)
|
#define LISTENER_WAS_CLOSED(x) (((listener_t *)(x))->s[0] == INVALID_SOCKET)
|
||||||
#endif
|
#endif
|
||||||
#ifndef LISTENER_WAS_CLOSED
|
#ifndef LISTENER_WAS_CLOSED
|
||||||
#define LISTENER_WAS_CLOSED(x) 0
|
#define LISTENER_WAS_CLOSED(x) 0
|
||||||
|
@ -843,14 +844,15 @@ static void TCP_INIT(char *name)
|
||||||
/* Forward declaration */
|
/* Forward declaration */
|
||||||
static int stop_listener(Scheme_Object *o);
|
static int stop_listener(Scheme_Object *o);
|
||||||
|
|
||||||
static int tcp_check_accept(Scheme_Object *listener)
|
static int tcp_check_accept(Scheme_Object *_listener)
|
||||||
{
|
{
|
||||||
#ifdef USE_SOCKETS_TCP
|
#ifdef USE_SOCKETS_TCP
|
||||||
tcp_t s;
|
tcp_t s, mx;
|
||||||
|
listener_t *listener = (listener_t *)_listener;
|
||||||
DECL_FDSET(readfds, 1);
|
DECL_FDSET(readfds, 1);
|
||||||
DECL_FDSET(exnfds, 1);
|
DECL_FDSET(exnfds, 1);
|
||||||
struct timeval time = {0, 0};
|
struct timeval time = {0, 0};
|
||||||
int sr;
|
int sr, i;
|
||||||
|
|
||||||
INIT_DECL_FDSET(readfds, 1);
|
INIT_DECL_FDSET(readfds, 1);
|
||||||
INIT_DECL_FDSET(exnfds, 1);
|
INIT_DECL_FDSET(exnfds, 1);
|
||||||
|
@ -858,33 +860,52 @@ static int tcp_check_accept(Scheme_Object *listener)
|
||||||
if (LISTENER_WAS_CLOSED(listener))
|
if (LISTENER_WAS_CLOSED(listener))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
s = ((listener_t *)listener)->s;
|
|
||||||
|
|
||||||
MZ_FD_ZERO(readfds);
|
MZ_FD_ZERO(readfds);
|
||||||
MZ_FD_ZERO(exnfds);
|
MZ_FD_ZERO(exnfds);
|
||||||
|
|
||||||
|
mx = 0;
|
||||||
|
for (i = 0; i < listener->count; i++) {
|
||||||
|
s = listener->s[i];
|
||||||
MZ_FD_SET(s, readfds);
|
MZ_FD_SET(s, readfds);
|
||||||
MZ_FD_SET(s, exnfds);
|
MZ_FD_SET(s, exnfds);
|
||||||
|
if (s > mx)
|
||||||
|
mx = s;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
sr = select(s + 1, readfds, NULL, exnfds, &time);
|
sr = select(mx + 1, readfds, NULL, exnfds, &time);
|
||||||
} while ((sr == -1) && (NOT_WINSOCK(errno) == EINTR));
|
} while ((sr == -1) && (NOT_WINSOCK(errno) == EINTR));
|
||||||
|
|
||||||
|
if (sr) {
|
||||||
|
for (i = 0; i < listener->count; i++) {
|
||||||
|
s = listener->s[i];
|
||||||
|
if (FD_ISSET(s, readfds)
|
||||||
|
|| FD_ISSET(s, exnfds))
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sr;
|
return sr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcp_accept_needs_wakeup(Scheme_Object *listener, void *fds)
|
static void tcp_accept_needs_wakeup(Scheme_Object *_listener, void *fds)
|
||||||
{
|
{
|
||||||
#ifdef USE_SOCKETS_TCP
|
#ifdef USE_SOCKETS_TCP
|
||||||
if (!LISTENER_WAS_CLOSED(listener)) {
|
if (!LISTENER_WAS_CLOSED(_listener)) {
|
||||||
tcp_t s = ((listener_t *)listener)->s;
|
listener_t *listener = (listener_t *)_listener;
|
||||||
|
int i;
|
||||||
|
tcp_t s;
|
||||||
void *fds2;
|
void *fds2;
|
||||||
|
|
||||||
fds2 = MZ_GET_FDSET(fds, 2);
|
fds2 = MZ_GET_FDSET(fds, 2);
|
||||||
|
|
||||||
|
for (i = 0; i < listener->count; i++) {
|
||||||
|
s = listener->s[i];
|
||||||
MZ_FD_SET(s, (fd_set *)fds);
|
MZ_FD_SET(s, (fd_set *)fds);
|
||||||
MZ_FD_SET(s, (fd_set *)fds2);
|
MZ_FD_SET(s, (fd_set *)fds2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,8 +924,9 @@ static int tcp_check_connect(Scheme_Object *connector_p)
|
||||||
s = *(tcp_t *)connector_p;
|
s = *(tcp_t *)connector_p;
|
||||||
|
|
||||||
MZ_FD_ZERO(writefds);
|
MZ_FD_ZERO(writefds);
|
||||||
MZ_FD_SET(s, writefds);
|
|
||||||
MZ_FD_ZERO(exnfds);
|
MZ_FD_ZERO(exnfds);
|
||||||
|
|
||||||
|
MZ_FD_SET(s, writefds);
|
||||||
MZ_FD_SET(s, exnfds);
|
MZ_FD_SET(s, exnfds);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -1493,9 +1515,17 @@ make_tcp_output_port(void *data, const char *name)
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
|
|
||||||
#ifdef USE_SOCKETS_TCP
|
#ifdef USE_SOCKETS_TCP
|
||||||
static void closesocket_w_decrement(tcp_t s)
|
typedef struct Close_Socket_Data {
|
||||||
|
tcp_t s;
|
||||||
|
struct addrinfo *src_addr, *dest_addr;
|
||||||
|
} Close_Socket_Data;
|
||||||
|
|
||||||
|
static void closesocket_w_decrement(Close_Socket_Data *csd)
|
||||||
{
|
{
|
||||||
closesocket(s);
|
closesocket(csd->s);
|
||||||
|
if (csd->src_addr)
|
||||||
|
freeaddrinfo(csd->src_addr);
|
||||||
|
freeaddrinfo(csd->dest_addr);
|
||||||
--scheme_file_open_count;
|
--scheme_file_open_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1576,10 +1606,10 @@ static Scheme_Object *tcp_connect(int argc, Scheme_Object *argv[])
|
||||||
else
|
else
|
||||||
tcp_connect_src = scheme_get_host_address(src_address, src_id, &errid, -1, 1, 1);
|
tcp_connect_src = scheme_get_host_address(src_address, src_id, &errid, -1, 1, 1);
|
||||||
if (no_local_spec || tcp_connect_src) {
|
if (no_local_spec || tcp_connect_src) {
|
||||||
|
GC_CAN_IGNORE struct addrinfo *addr;
|
||||||
|
for (addr = tcp_connect_dest; addr; addr = addr->ai_next) {
|
||||||
tcp_t s;
|
tcp_t s;
|
||||||
s = socket(tcp_connect_dest->ai_family,
|
s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||||
tcp_connect_dest->ai_socktype,
|
|
||||||
tcp_connect_dest->ai_protocol);
|
|
||||||
if (s != INVALID_SOCKET) {
|
if (s != INVALID_SOCKET) {
|
||||||
int status, inprogress;
|
int status, inprogress;
|
||||||
if (no_local_spec
|
if (no_local_spec
|
||||||
|
@ -1594,7 +1624,7 @@ static Scheme_Object *tcp_connect(int argc, Scheme_Object *argv[])
|
||||||
setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof(int));
|
setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof(int));
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
status = connect(s, tcp_connect_dest->ai_addr, tcp_connect_dest->ai_addrlen);
|
status = connect(s, addr->ai_addr, addr->ai_addrlen);
|
||||||
#ifdef USE_UNIX_SOCKETS_TCP
|
#ifdef USE_UNIX_SOCKETS_TCP
|
||||||
if (status)
|
if (status)
|
||||||
status = errno;
|
status = errno;
|
||||||
|
@ -1613,20 +1643,19 @@ static Scheme_Object *tcp_connect(int argc, Scheme_Object *argv[])
|
||||||
|
|
||||||
scheme_file_open_count++;
|
scheme_file_open_count++;
|
||||||
|
|
||||||
if (tcp_connect_src) {
|
|
||||||
// freeaddrinfo(tcp_connect_src);
|
|
||||||
tcp_connect_src = NULL;
|
|
||||||
}
|
|
||||||
// freeaddrinfo(tcp_connect_dest);
|
|
||||||
tcp_connect_dest = NULL;
|
|
||||||
|
|
||||||
if (inprogress) {
|
if (inprogress) {
|
||||||
tcp_t *sptr;
|
tcp_t *sptr;
|
||||||
|
Close_Socket_Data *csd;
|
||||||
|
|
||||||
sptr = (tcp_t *)scheme_malloc_atomic(sizeof(tcp_t));
|
sptr = (tcp_t *)scheme_malloc_atomic(sizeof(tcp_t));
|
||||||
*sptr = s;
|
*sptr = s;
|
||||||
|
|
||||||
BEGIN_ESCAPEABLE(closesocket_w_decrement, s);
|
csd = (Close_Socket_Data *)scheme_malloc_atomic(sizeof(Close_Socket_Data));
|
||||||
|
csd->s = s;
|
||||||
|
csd->src_addr = tcp_connect_src;
|
||||||
|
csd->dest_addr = tcp_connect_dest;
|
||||||
|
|
||||||
|
BEGIN_ESCAPEABLE(closesocket_w_decrement, csd);
|
||||||
scheme_block_until(tcp_check_connect, tcp_connect_needs_wakeup, (void *)sptr, (float)0.0);
|
scheme_block_until(tcp_check_connect, tcp_connect_needs_wakeup, (void *)sptr, (float)0.0);
|
||||||
END_ESCAPEABLE();
|
END_ESCAPEABLE();
|
||||||
|
|
||||||
|
@ -1657,6 +1686,10 @@ static Scheme_Object *tcp_connect(int argc, Scheme_Object *argv[])
|
||||||
Scheme_Object *v[2];
|
Scheme_Object *v[2];
|
||||||
Scheme_Tcp *tcp;
|
Scheme_Tcp *tcp;
|
||||||
|
|
||||||
|
if (tcp_connect_src)
|
||||||
|
freeaddrinfo(tcp_connect_src);
|
||||||
|
freeaddrinfo(tcp_connect_dest);
|
||||||
|
|
||||||
tcp = make_tcp_port_data(s, 2);
|
tcp = make_tcp_port_data(s, 2);
|
||||||
|
|
||||||
v[0] = make_tcp_input_port(tcp, address);
|
v[0] = make_tcp_input_port(tcp, address);
|
||||||
|
@ -1679,6 +1712,7 @@ static Scheme_Object *tcp_connect(int argc, Scheme_Object *argv[])
|
||||||
errpart = 4;
|
errpart = 4;
|
||||||
errid = SOCK_ERRNO();
|
errid = SOCK_ERRNO();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (tcp_connect_src)
|
if (tcp_connect_src)
|
||||||
freeaddrinfo(tcp_connect_src);
|
freeaddrinfo(tcp_connect_src);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1758,19 +1792,22 @@ tcp_listen(int argc, Scheme_Object *argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
GC_CAN_IGNORE struct addrinfo *tcp_listen_addr;
|
GC_CAN_IGNORE struct addrinfo *tcp_listen_addr, *addr;
|
||||||
int err;
|
int err, count = 0, pos = 0, i;
|
||||||
|
listener_t *l = NULL;
|
||||||
|
|
||||||
tcp_listen_addr = scheme_get_host_address(address, id, &err,
|
tcp_listen_addr = scheme_get_host_address(address, id, &err, -1, 1, 1);
|
||||||
!address ? MZ_PF_INET : -1,
|
|
||||||
1, 1);
|
for (addr = tcp_listen_addr; addr; addr = addr->ai_next) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
if (tcp_listen_addr) {
|
if (tcp_listen_addr) {
|
||||||
tcp_t s;
|
tcp_t s;
|
||||||
|
|
||||||
s = socket(tcp_listen_addr->ai_family,
|
errid = 0;
|
||||||
tcp_listen_addr->ai_socktype,
|
for (addr = tcp_listen_addr; addr; addr = addr->ai_next) {
|
||||||
tcp_listen_addr->ai_protocol);
|
s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||||
|
|
||||||
if (s != INVALID_SOCKET) {
|
if (s != INVALID_SOCKET) {
|
||||||
#ifdef USE_WINSOCK_TCP
|
#ifdef USE_WINSOCK_TCP
|
||||||
|
@ -1784,13 +1821,12 @@ tcp_listen(int argc, Scheme_Object *argv[])
|
||||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)(&reuse), sizeof(int));
|
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)(&reuse), sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bind(s, tcp_listen_addr->ai_addr, tcp_listen_addr->ai_addrlen)) {
|
if (!bind(s, addr->ai_addr, addr->ai_addrlen)) {
|
||||||
if (!listen(s, backlog)) {
|
if (!listen(s, backlog)) {
|
||||||
listener_t *l;
|
if (!pos) {
|
||||||
|
l = scheme_malloc_tagged(sizeof(listener_t) + ((count - 1) * sizeof(tcp_t)));
|
||||||
l = MALLOC_ONE_TAGGED(listener_t);
|
|
||||||
l->so.type = scheme_listener_type;
|
l->so.type = scheme_listener_type;
|
||||||
l->s = s;
|
l->count = count;
|
||||||
{
|
{
|
||||||
Scheme_Custodian_Reference *mref;
|
Scheme_Custodian_Reference *mref;
|
||||||
mref = scheme_add_managed(NULL,
|
mref = scheme_add_managed(NULL,
|
||||||
|
@ -1800,21 +1836,40 @@ tcp_listen(int argc, Scheme_Object *argv[])
|
||||||
1);
|
1);
|
||||||
l->mref = mref;
|
l->mref = mref;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
l->s[pos++] = s;
|
||||||
|
|
||||||
scheme_file_open_count++;
|
scheme_file_open_count++;
|
||||||
REGISTER_SOCKET(s);
|
REGISTER_SOCKET(s);
|
||||||
|
|
||||||
|
if (pos == count) {
|
||||||
freeaddrinfo(tcp_listen_addr);
|
freeaddrinfo(tcp_listen_addr);
|
||||||
|
|
||||||
return (Scheme_Object *)l;
|
return (Scheme_Object *)l;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
errid = SOCK_ERRNO();
|
||||||
|
closesocket(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errid = SOCK_ERRNO();
|
||||||
|
closesocket(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errid = SOCK_ERRNO();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errid = SOCK_ERRNO();
|
for (i = 0; i < pos; i++) {
|
||||||
|
s = l->s[i];
|
||||||
|
UNREGISTER_SOCKET(s);
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
} else
|
--scheme_file_open_count;
|
||||||
errid = SOCK_ERRNO();
|
}
|
||||||
|
|
||||||
freeaddrinfo(tcp_listen_addr);
|
freeaddrinfo(tcp_listen_addr);
|
||||||
} else {
|
} else {
|
||||||
scheme_raise_exn(MZEXN_FAIL_NETWORK,
|
scheme_raise_exn(MZEXN_FAIL_NETWORK,
|
||||||
|
@ -1843,20 +1898,25 @@ static int stop_listener(Scheme_Object *o)
|
||||||
|
|
||||||
#ifdef USE_SOCKETS_TCP
|
#ifdef USE_SOCKETS_TCP
|
||||||
{
|
{
|
||||||
tcp_t s = ((listener_t *)o)->s;
|
listener_t *listener = (listener_t *)o;
|
||||||
|
int i;
|
||||||
|
tcp_t s;
|
||||||
|
s = listener->s[0];
|
||||||
if (s == INVALID_SOCKET)
|
if (s == INVALID_SOCKET)
|
||||||
was_closed = 1;
|
was_closed = 1;
|
||||||
else {
|
else {
|
||||||
|
for (i = 0; i < listener->count; i++) {
|
||||||
|
s = listener->s[i];
|
||||||
UNREGISTER_SOCKET(s);
|
UNREGISTER_SOCKET(s);
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
((listener_t *)o)->s = INVALID_SOCKET;
|
listener->s[i] = INVALID_SOCKET;
|
||||||
--scheme_file_open_count;
|
--scheme_file_open_count;
|
||||||
|
}
|
||||||
scheme_remove_managed(((listener_t *)o)->mref, o);
|
scheme_remove_managed(((listener_t *)o)->mref, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return was_closed;
|
return was_closed;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1917,7 +1977,7 @@ static Scheme_Object *
|
||||||
tcp_accept(int argc, Scheme_Object *argv[])
|
tcp_accept(int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
#ifdef USE_TCP
|
#ifdef USE_TCP
|
||||||
int was_closed = 0, errid;
|
int was_closed = 0, errid, ready_pos;
|
||||||
Scheme_Object *listener;
|
Scheme_Object *listener;
|
||||||
# ifdef USE_SOCKETS_TCP
|
# ifdef USE_SOCKETS_TCP
|
||||||
tcp_t s;
|
tcp_t s;
|
||||||
|
@ -1935,11 +1995,14 @@ tcp_accept(int argc, Scheme_Object *argv[])
|
||||||
was_closed = LISTENER_WAS_CLOSED(listener);
|
was_closed = LISTENER_WAS_CLOSED(listener);
|
||||||
|
|
||||||
if (!was_closed) {
|
if (!was_closed) {
|
||||||
if (!tcp_check_accept(listener)) {
|
ready_pos = tcp_check_accept(listener);
|
||||||
|
if (!ready_pos) {
|
||||||
scheme_block_until(tcp_check_accept, tcp_accept_needs_wakeup, listener, 0.0);
|
scheme_block_until(tcp_check_accept, tcp_accept_needs_wakeup, listener, 0.0);
|
||||||
|
ready_pos = tcp_check_accept(listener);
|
||||||
}
|
}
|
||||||
was_closed = LISTENER_WAS_CLOSED(listener);
|
was_closed = LISTENER_WAS_CLOSED(listener);
|
||||||
}
|
} else
|
||||||
|
ready_pos = 0;
|
||||||
|
|
||||||
if (was_closed) {
|
if (was_closed) {
|
||||||
scheme_raise_exn(MZEXN_FAIL_NETWORK,
|
scheme_raise_exn(MZEXN_FAIL_NETWORK,
|
||||||
|
@ -1950,7 +2013,7 @@ tcp_accept(int argc, Scheme_Object *argv[])
|
||||||
scheme_custodian_check_available(NULL, "tcp-accept", "network");
|
scheme_custodian_check_available(NULL, "tcp-accept", "network");
|
||||||
|
|
||||||
# ifdef USE_SOCKETS_TCP
|
# ifdef USE_SOCKETS_TCP
|
||||||
s = ((listener_t *)listener)->s;
|
s = ((listener_t *)listener)->s[ready_pos-1];
|
||||||
|
|
||||||
l = sizeof(tcp_accept_addr);
|
l = sizeof(tcp_accept_addr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user