rktio: fix network problems
This commit is contained in:
parent
3065773b31
commit
6e1d519711
|
@ -796,7 +796,7 @@ struct mz_addrinfo *scheme_get_host_address(const char *address, int id, int *er
|
|||
|
||||
ok = MZ_GETADDRINFO(address, service, &hints, &r);
|
||||
*err = ok;
|
||||
|
||||
|
||||
if (!ok)
|
||||
return r;
|
||||
else
|
||||
|
|
|
@ -16,8 +16,11 @@ OBJS = rktio_filesystem.o \
|
|||
|
||||
all: $(OBJS)
|
||||
|
||||
demo: $(OBJS) main.o demo_fifo
|
||||
$(CC) -o demo $(CFLAGS) $(LDFLAGS) main.o $(OBJS)
|
||||
demo: rktio_demo
|
||||
./rktio_demo
|
||||
|
||||
rktio_demo: $(OBJS) demo.o demo_fifo
|
||||
$(CC) -o rktio_demo $(CFLAGS) $(LDFLAGS) demo.o $(OBJS)
|
||||
|
||||
demo_fifo:
|
||||
mkfifo demo_fifo
|
||||
|
@ -43,5 +46,5 @@ rktio_error.o: $(srcdir)/rktio_error.c $(RKTIO_HEADERS)
|
|||
rktio_main.o: $(srcdir)/rktio_main.c $(RKTIO_HEADERS)
|
||||
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_main.o -c $(srcdir)/rktio_main.c
|
||||
|
||||
main.o: $(srcdir)/main.c $(RKTIO_HEADERS)
|
||||
$(CC) $(CFLAGS) -I$(srcdir) -I. -o main.o -c $(srcdir)/main.c
|
||||
demo.o: $(srcdir)/demo.c $(RKTIO_HEADERS)
|
||||
$(CC) $(CFLAGS) -I$(srcdir) -I. -o demo.o -c $(srcdir)/demo.c
|
||||
|
|
68
racket/src/rktio/configure
vendored
68
racket/src/rktio/configure
vendored
|
@ -3104,6 +3104,52 @@ case "$host_os" in
|
|||
*mingw*)
|
||||
use_flag_pthread=no
|
||||
skip_iconv_check=yes
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lwinpthread" >&5
|
||||
$as_echo_n "checking for pthread_create in -lwinpthread... " >&6; }
|
||||
if ${ac_cv_lib_winpthread_pthread_create+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lwinpthread $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pthread_create ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pthread_create ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_winpthread_pthread_create=yes
|
||||
else
|
||||
ac_cv_lib_winpthread_pthread_create=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_winpthread_pthread_create" >&5
|
||||
$as_echo "$ac_cv_lib_winpthread_pthread_create" >&6; }
|
||||
if test "x$ac_cv_lib_winpthread_pthread_create" = xyes; then :
|
||||
has_winpthread=yes
|
||||
else
|
||||
has_winpthread=no
|
||||
fi
|
||||
|
||||
if test "${has_winpthread}" = "yes" ; then
|
||||
LIBS="${LIBS} -Wl,-Bstatic -lwinpthread"
|
||||
fi
|
||||
;;
|
||||
cygwin*)
|
||||
;;
|
||||
|
@ -3111,6 +3157,7 @@ case "$host_os" in
|
|||
;;
|
||||
darwin*)
|
||||
PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT"
|
||||
enable_pthread_by_default=yes
|
||||
try_kqueue_syscall=yes
|
||||
|
||||
# Although select() generally works as well as poll() on OS X,
|
||||
|
@ -3886,6 +3933,27 @@ if test "${LFS_CFLAGS}" != "" && test "${LFS_CFLAGS}" != "undefined"; then
|
|||
CFLAGS="${CFLAGS} ${LFS_CFLAGS}"
|
||||
fi
|
||||
|
||||
############### pthread ###################
|
||||
|
||||
if test "${enable_pthread}" = "" ; then
|
||||
if test "${enable_pthread_by_default}" = "yes" ; then
|
||||
enable_pthread=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${enable_pthread}" = "yes" ; then
|
||||
if test "${use_flag_pthread}" = "yes" ; then
|
||||
PREFLAGS="$PREFLAGS -pthread"
|
||||
LDFLAGS="$LDFLAGS -pthread"
|
||||
fi
|
||||
if test "${use_flag_posix_pthread}" = "yes" ; then
|
||||
PREFLAGS="$PREFLAGS -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT"
|
||||
fi
|
||||
|
||||
$as_echo "#define RKTIO_USE_PTHREADS 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
############## final output ################
|
||||
|
||||
|
||||
|
|
|
@ -59,6 +59,11 @@ case "$host_os" in
|
|||
*mingw*)
|
||||
use_flag_pthread=no
|
||||
skip_iconv_check=yes
|
||||
|
||||
AC_CHECK_LIB(winpthread, pthread_create, has_winpthread=yes, has_winpthread=no)
|
||||
if test "${has_winpthread}" = "yes" ; then
|
||||
LIBS="${LIBS} -Wl,-Bstatic -lwinpthread"
|
||||
fi
|
||||
;;
|
||||
cygwin*)
|
||||
;;
|
||||
|
@ -66,6 +71,7 @@ case "$host_os" in
|
|||
;;
|
||||
darwin*)
|
||||
PREFLAGS="$PREFLAGS -DOS_X -D_DARWIN_UNLIMITED_SELECT"
|
||||
enable_pthread_by_default=yes
|
||||
try_kqueue_syscall=yes
|
||||
|
||||
# Although select() generally works as well as poll() on OS X,
|
||||
|
@ -245,6 +251,25 @@ if test "${LFS_CFLAGS}" != "" && test "${LFS_CFLAGS}" != "undefined"; then
|
|||
CFLAGS="${CFLAGS} ${LFS_CFLAGS}"
|
||||
fi
|
||||
|
||||
############### pthread ###################
|
||||
|
||||
if test "${enable_pthread}" = "" ; then
|
||||
if test "${enable_pthread_by_default}" = "yes" ; then
|
||||
enable_pthread=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${enable_pthread}" = "yes" ; then
|
||||
if test "${use_flag_pthread}" = "yes" ; then
|
||||
PREFLAGS="$PREFLAGS -pthread"
|
||||
LDFLAGS="$LDFLAGS -pthread"
|
||||
fi
|
||||
if test "${use_flag_posix_pthread}" = "yes" ; then
|
||||
PREFLAGS="$PREFLAGS -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT"
|
||||
fi
|
||||
AC_DEFINE(RKTIO_USE_PTHREADS, 1, [Pthread enabled])
|
||||
fi
|
||||
|
||||
############## final output ################
|
||||
|
||||
AC_SUBST(CC)
|
||||
|
|
|
@ -274,6 +274,49 @@ static void check_read_write_pair(rktio_t *rktio, rktio_fd_t *fd, rktio_fd_t *fd
|
|||
check_valid(rktio_close(rktio, fd2));
|
||||
}
|
||||
|
||||
void check_many_lookup(rktio_t *rktio)
|
||||
{
|
||||
# define LOOKUPS_N 10
|
||||
int i, j;
|
||||
rktio_addrinfo_lookup_t *lookup[LOOKUPS_N];
|
||||
rktio_addrinfo_t *addr;
|
||||
rktio_poll_set_t *ps;
|
||||
|
||||
for (i = 0; i < LOOKUPS_N; i++) {
|
||||
if (i & 1)
|
||||
lookup[i] = rktio_start_addrinfo_lookup(rktio, "localhost", 50+i, -1, 0, 1);
|
||||
else
|
||||
lookup[i] = rktio_start_addrinfo_lookup(rktio, "racket-lang.org", 50+i, -1, 0, 1);
|
||||
check_valid(lookup[i]);
|
||||
}
|
||||
|
||||
for (j = 0; j < LOOKUPS_N; j++) {
|
||||
ps = rktio_make_poll_set(rktio);
|
||||
check_valid(ps);
|
||||
|
||||
for (i = 0; i < LOOKUPS_N; i++) {
|
||||
if (lookup[i])
|
||||
rktio_poll_add_addrinfo_lookup(rktio, lookup[i], ps);
|
||||
}
|
||||
|
||||
rktio_sleep(rktio, 0, ps, NULL);
|
||||
rktio_poll_set_close(rktio, ps);
|
||||
|
||||
for (i = 0; i < LOOKUPS_N; i++) {
|
||||
if (lookup[i] && (rktio_poll_addrinfo_lookup_ready(rktio, lookup[i]) == RKTIO_POLL_READY)) {
|
||||
if ((i % 3) == 2)
|
||||
rktio_addrinfo_lookup_stop(rktio, lookup[i]);
|
||||
else {
|
||||
addr = rktio_addrinfo_lookup_get(rktio, lookup[i]);
|
||||
check_valid(addr);
|
||||
rktio_free_addrinfo(rktio, addr);
|
||||
}
|
||||
lookup[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rktio_addrinfo_t *lookup_loop(rktio_t *rktio,
|
||||
const char *hostname, int portno,
|
||||
|
@ -288,7 +331,7 @@ rktio_addrinfo_t *lookup_loop(rktio_t *rktio,
|
|||
|
||||
lookup = rktio_start_addrinfo_lookup(rktio, hostname, portno, family, passive, tcp);
|
||||
check_valid(lookup);
|
||||
|
||||
|
||||
rktio_poll_add_addrinfo_lookup(rktio, lookup, ps);
|
||||
rktio_sleep(rktio, 0, ps, NULL);
|
||||
rktio_poll_set_close(rktio, ps);
|
||||
|
@ -493,8 +536,10 @@ int main()
|
|||
{
|
||||
rktio_addrinfo_t *addr;
|
||||
rktio_listener_t *lnr;
|
||||
|
||||
check_many_lookup(rktio);
|
||||
|
||||
addr = lookup_loop(rktio, "localhost", 4536, -1, 1, 1);
|
||||
addr = lookup_loop(rktio, NULL, 4536, -1, 1, 1);
|
||||
|
||||
lnr = rktio_listen(rktio, addr, 5, 1);
|
||||
check_valid(lnr);
|
|
@ -14,8 +14,14 @@ typedef long intptr_t;
|
|||
typedef unsigned long uintptr_t;
|
||||
#endif
|
||||
|
||||
/* Whether pthread is available */
|
||||
#undef RKTIO_USE_PTHREADS
|
||||
|
||||
/* When poll(), epoll(), kqueue(), etc. is available: */
|
||||
#undef HAVE_POLL_SYSCALL
|
||||
#undef HAVE_EPOLL_SYSCALL
|
||||
#undef HAVE_INOTIFY_SYSCALL
|
||||
#undef HAVE_KQUEUE_SYSCALL
|
||||
|
||||
/* Whether getaddrinfo() is available: */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
|
|
@ -92,7 +92,7 @@ rktio_ltps_t *rktio_open_ltps(rktio_t *rktio)
|
|||
#if defined(HAVE_KQUEUE_SYSCALL) || defined(HAVE_EPOLL_SYSCALL)
|
||||
lt->fd = -1;
|
||||
#else
|
||||
lt->fd_set = rktio_alloc_fdset_array(3);
|
||||
lt->fd_set = rktio_make_poll_set(rktio);
|
||||
#endif
|
||||
|
||||
lt->signaled = NULL;
|
||||
|
@ -133,7 +133,7 @@ int rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt)
|
|||
}
|
||||
free(lt);
|
||||
#else
|
||||
rktio_free_fdset_array(lt->fd_set, 3);
|
||||
rktio_poll_set_close(rktio, lt->fd_set);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -41,6 +41,21 @@ typedef struct sockaddr_in rktio_unspec_address;
|
|||
#define REGISTER_SOCKET(s) /**/
|
||||
#define UNREGISTER_SOCKET(s) /**/
|
||||
|
||||
# if defined(__linux__) || defined(OS_X)
|
||||
/* RKTIO_TCP_LISTEN_IPV6_ONLY_SOCKOPT uses IPV6_V6ONLY for IPv6
|
||||
listeners when the same listener has an IPv4 address, which means
|
||||
that the IpV6 listener accepts only IPv6 connections. This is used
|
||||
with Linux, for example, because a port cannot have both an IPv4
|
||||
and IPv6 listener if the IPv6 one doesn't use IPV6_V6ONLY. (The
|
||||
two listeners might be for different interfaces, in which case
|
||||
IPV6_V6ONLY is not necessary, but we must err on the side of being
|
||||
too restrictive. If IPV6_V6ONLY is not #defined or if setting the
|
||||
option doesn't work, then the IPv6 addresses are silently ignored
|
||||
when creating the listener (but only where there is at least once
|
||||
IPv4 address). */
|
||||
# define RKTIO_TCP_LISTEN_IPV6_ONLY_SOCKOPT
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CANT_SET_SOCKET_BUFSIZE
|
||||
|
@ -147,10 +162,6 @@ struct rktio_udp_t {
|
|||
/* Host address lookup, including asynchronous-lookup support */
|
||||
/*========================================================================*/
|
||||
|
||||
#if defined(OS_X) || defined(USE_PTHREAD_THREAD_TIMER)
|
||||
# define PTHREADS_OK_FOR_GHBN
|
||||
#endif
|
||||
|
||||
# ifdef PROTOENT_IS_INT
|
||||
# define PROTO_P_PROTO PROTOENT_IS_INT
|
||||
# else
|
||||
|
@ -168,7 +179,11 @@ static struct protoent *proto;
|
|||
#define RKTIO_SOCK_SVC_NAME_MAX_LEN 32
|
||||
|
||||
#if defined(HAVE_GETADDRINFO) || defined(__MINGW32__)
|
||||
# define rktio_addrinfo_t addrinfo
|
||||
struct rktio_addrinfo_t {
|
||||
struct addrinfo ai;
|
||||
};
|
||||
# define RKTIO_AS_ADDRINFO(x) (&(x)->ai)
|
||||
# define RKTIO_AS_ADDRINFO_PTR(xp) ((struct addrinfo **)(xp))
|
||||
#else
|
||||
struct rktio_addrinfo_t {
|
||||
int ai_flags;
|
||||
|
@ -179,6 +194,8 @@ struct rktio_addrinfo_t {
|
|||
struct sockaddr *ai_addr;
|
||||
struct rktio_addrinfo_t *ai_next;
|
||||
};
|
||||
# define RKTIO_AS_ADDRINFO(x) x
|
||||
# define RKTIO_AS_ADDRINFO_PTR(x) x
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) && !defined(HAVE_GETADDRINFO)
|
||||
|
@ -192,7 +209,7 @@ struct rktio_addrinfo_t {
|
|||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
# define rktio_AI_PASSIVE AI_PASSIVE
|
||||
# define do_getaddrinfo getaddrinfo
|
||||
# define do_getaddrinfo(n, s, h, res) getaddrinfo(n, s, RKTIO_AS_ADDRINFO(h), RKTIO_AS_ADDRINFO_PTR(res))
|
||||
# define do_freeaddrinfo freeaddrinfo
|
||||
# define do_gai_strerror gai_strerror
|
||||
#else
|
||||
|
@ -284,11 +301,13 @@ static void free_lookup(rktio_addrinfo_lookup_t *lookup)
|
|||
{
|
||||
#if defined(RKTIO_SYSTEM_WINDOWS) || defined(RKTIO_USE_PTHREADS)
|
||||
if (lookup->result)
|
||||
do_freeaddrinfo(lookup->result);
|
||||
do_freeaddrinfo(RKTIO_AS_ADDRINFO(lookup->result));
|
||||
#endif
|
||||
|
||||
free(lookup->name);
|
||||
free(lookup->svc);
|
||||
|
||||
if (lookup->name)
|
||||
free(lookup->name);
|
||||
if (lookup->svc)
|
||||
free(lookup->svc);
|
||||
free(lookup->hints);
|
||||
free(lookup);
|
||||
}
|
||||
|
@ -315,7 +334,7 @@ static void init_lookup(rktio_addrinfo_lookup_t *lookup)
|
|||
|
||||
#define GHBN_WAIT 1
|
||||
#define GHBN_DONE 2
|
||||
#define GHBN_ADBANDONED 3
|
||||
#define GHBN_ABANDONED 3
|
||||
|
||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||
|
||||
|
@ -350,27 +369,27 @@ static void ghbn_wait_exit(rktio_t *rktio)
|
|||
|
||||
static void ghbn_lock(rktio_t *rktio)
|
||||
{
|
||||
pthread_mutex_lock(rktio->ghbn_lock);
|
||||
pthread_mutex_lock(&rktio->ghbn_lock);
|
||||
}
|
||||
|
||||
static void ghbn_unlock(rktio_t *rktio)
|
||||
{
|
||||
pthread_mutex_lock(rktio->ghbn_unlock);
|
||||
pthread_mutex_unlock(&rktio->ghbn_lock);
|
||||
}
|
||||
|
||||
static void ghbn_wait(rktio_t *rktio)
|
||||
{
|
||||
pthread_cond_wait(rktio->ghbn_start, rktio->ghbn_lock);
|
||||
pthread_cond_wait(&rktio->ghbn_start, &rktio->ghbn_lock);
|
||||
}
|
||||
|
||||
static void ghbn_signal(rktio_t *rktio)
|
||||
{
|
||||
pthread_cond_signal(rktio->ghbn_start);
|
||||
pthread_cond_signal(&rktio->ghbn_start);
|
||||
}
|
||||
|
||||
static void ghbn_wait_exit(rktio_t *rktio)
|
||||
{
|
||||
pthread_join(rktio->th, NULL);
|
||||
pthread_join(rktio->ghbn_th, NULL);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
@ -386,17 +405,14 @@ static intptr_t getaddrinfo_in_thread(void *_data)
|
|||
while (rktio->ghbn_run) {
|
||||
lookup = rktio->ghbn_requests;
|
||||
if (lookup) {
|
||||
rktio->ghbn->requests = lookup->next;
|
||||
rktio->ghbn_requests = lookup->next;
|
||||
ghbn_unlock(rktio);
|
||||
|
||||
/* Handle one lookup request: */
|
||||
err = do_getaddrinfo(lookup->name,
|
||||
lookup->svc,
|
||||
lookup->hints,
|
||||
&result);
|
||||
request->err = err;
|
||||
err = do_getaddrinfo(lookup->name, lookup->svc, lookup->hints, &result);
|
||||
lookup->err = err;
|
||||
if (!err)
|
||||
request->result = result;
|
||||
lookup->result = result;
|
||||
|
||||
ghbn_lock(rktio);
|
||||
|
||||
|
@ -406,13 +422,13 @@ static intptr_t getaddrinfo_in_thread(void *_data)
|
|||
{
|
||||
long v = 1;
|
||||
do {
|
||||
cr = write(lookup->done_fd[1], &v, sizeof(v));
|
||||
} while ((cr == -1) && (errno == EINTR));
|
||||
err = write(lookup->done_fd[1], &v, sizeof(v));
|
||||
} while ((err == -1) && (errno == EINTR));
|
||||
reliably_close(lookup->done_fd[1]);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (lookup->state == GHBN_ADBANDONED) {
|
||||
if (lookup->mode == GHBN_ABANDONED) {
|
||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||
CloseHandle(data->ready_sema);
|
||||
# else
|
||||
|
@ -472,7 +488,7 @@ static int ghbn_init(rktio_t *rktio)
|
|||
get_posix_error();
|
||||
return 0;
|
||||
}
|
||||
if (pthread_create(&rktio->th, NULL,
|
||||
if (pthread_create(&rktio->ghbn_th, NULL,
|
||||
(RKTIO_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread,
|
||||
rktio)) {
|
||||
return 0;
|
||||
|
@ -495,6 +511,8 @@ void rktio_free_ghbn(rktio_t *rktio)
|
|||
|
||||
static rktio_addrinfo_lookup_t *start_lookup(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup)
|
||||
{
|
||||
lookup->mode = GHBN_WAIT;
|
||||
|
||||
if (!rktio->ghbn_started) {
|
||||
rktio->ghbn_run = 1;
|
||||
if (!ghbn_init(rktio))
|
||||
|
@ -503,40 +521,41 @@ static rktio_addrinfo_lookup_t *start_lookup(rktio_t *rktio, rktio_addrinfo_look
|
|||
}
|
||||
|
||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||
{
|
||||
HANDLE ready_sema;
|
||||
unsigned int id;
|
||||
intptr_t th;
|
||||
{
|
||||
HANDLE ready_sema;
|
||||
unsigned int id;
|
||||
intptr_t th;
|
||||
|
||||
lookup->done_sema = CreateSemaphore(NULL, 0, 1, NULL);
|
||||
if (!lookup->done_sema) {
|
||||
get_windows_error();
|
||||
free_lookup(lookup);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
# else
|
||||
if (pipe(lookup->done_fd)) {
|
||||
get_posix_error();
|
||||
lookup->done_sema = CreateSemaphore(NULL, 0, 1, NULL);
|
||||
if (!lookup->done_sema) {
|
||||
get_windows_error();
|
||||
free_lookup(lookup);
|
||||
return NULL;
|
||||
} else {
|
||||
fcntl(lookup->done_fd[0], F_SETFL, RKTIO_NONBLOCKING);
|
||||
}
|
||||
}
|
||||
# else
|
||||
if (pipe(lookup->done_fd)) {
|
||||
get_posix_error();
|
||||
free_lookup(lookup);
|
||||
return NULL;
|
||||
} else {
|
||||
fcntl(lookup->done_fd[0], F_SETFL, RKTIO_NONBLOCKING);
|
||||
}
|
||||
# endif
|
||||
|
||||
ghbn_lock(rktio);
|
||||
lookup->next = rktio->ghbn_requests;
|
||||
ghbn_requests = lookup;
|
||||
ghbn_signal(rktio);
|
||||
ghbn_unlock(rktio);
|
||||
ghbn_lock(rktio);
|
||||
lookup->next = rktio->ghbn_requests;
|
||||
rktio->ghbn_requests = lookup;
|
||||
ghbn_signal(rktio);
|
||||
ghbn_unlock(rktio);
|
||||
|
||||
return lookup;
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
int rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup)
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
ghbn_lock(rktio);
|
||||
|
||||
if (lookup->mode == GHBN_DONE) {
|
||||
|
@ -545,10 +564,10 @@ int rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lo
|
|||
}
|
||||
|
||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||
if (WaitForSingleObject(lookup->done_sema, 0) == WAIT_OBJECT_0)
|
||||
if (WaitForSingleObject(lookup->done_sema, 0) == WAIT_OBJECT_0) {
|
||||
CloseHandle(lookup->done_sema);
|
||||
else
|
||||
return 0;
|
||||
done = 1;
|
||||
}
|
||||
# else
|
||||
{
|
||||
long v;
|
||||
|
@ -558,19 +577,20 @@ int rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lo
|
|||
} while ((cr == -1) && (errno == EINTR));
|
||||
if (cr > 0) {
|
||||
reliably_close(lookup->done_fd[0]);
|
||||
} else
|
||||
return 0;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
lookup->mode = GHBN_DONE;
|
||||
if (done)
|
||||
lookup->mode = GHBN_DONE;
|
||||
|
||||
ghbn_unlock(rktio);
|
||||
|
||||
return RKTIO_POLL_READY;
|
||||
return (done ? RKTIO_POLL_READY : 0);
|
||||
}
|
||||
|
||||
void rktio_poll_add_addr_lookup(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup, rktio_poll_set_t *fds)
|
||||
void rktio_poll_add_addrinfo_lookup(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup, rktio_poll_set_t *fds)
|
||||
{
|
||||
ghbn_lock(rktio);
|
||||
|
||||
|
@ -586,12 +606,12 @@ void rktio_poll_add_addr_lookup(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup,
|
|||
rktio_poll_set_add_handle(lookup->done_sema, fds, 1);
|
||||
# else
|
||||
{
|
||||
void *fds2;
|
||||
rktio_poll_set_t *fds2;
|
||||
|
||||
fds2 = RKTIO_GET_FDSET(fds, 2);
|
||||
|
||||
RKTIO_FD_SET(lookup->done_fd[0], (fd_set *)fds);
|
||||
RKTIO_FD_SET(lookup->done_fd[0], (fd_set *)fds2);
|
||||
RKTIO_FD_SET(lookup->done_fd[0], fds);
|
||||
RKTIO_FD_SET(lookup->done_fd[0], fds2);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
@ -600,7 +620,7 @@ void rktio_addrinfo_lookup_stop(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup)
|
|||
{
|
||||
ghbn_lock(rktio);
|
||||
if (lookup->mode != GHBN_DONE) {
|
||||
lookup->mode == GHBN_ABANDONED;
|
||||
lookup->mode = GHBN_ABANDONED;
|
||||
ghbn_unlock(rktio);
|
||||
} else {
|
||||
ghbn_unlock(rktio);
|
||||
|
@ -666,7 +686,10 @@ rktio_addrinfo_t *rktio_addrinfo_lookup_get(rktio_t *rktio, rktio_addrinfo_looku
|
|||
|
||||
free_lookup(lookup);
|
||||
|
||||
return result;
|
||||
if (err)
|
||||
return NULL;
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -698,25 +721,25 @@ rktio_addrinfo_lookup_t *rktio_start_addrinfo_lookup(rktio_t *rktio,
|
|||
|
||||
hints = malloc(sizeof(rktio_addrinfo_t));
|
||||
memset(hints, 0, sizeof(struct rktio_addrinfo_t));
|
||||
hints->ai_family = ((family < 0) ? PF_UNSPEC : family);
|
||||
RKTIO_AS_ADDRINFO(hints)->ai_family = ((family < 0) ? PF_UNSPEC : family);
|
||||
if (passive) {
|
||||
hints->ai_flags |= rktio_AI_PASSIVE;
|
||||
RKTIO_AS_ADDRINFO(hints)->ai_flags |= rktio_AI_PASSIVE;
|
||||
}
|
||||
if (tcp) {
|
||||
hints->ai_socktype = SOCK_STREAM;
|
||||
RKTIO_AS_ADDRINFO(hints)->ai_socktype = SOCK_STREAM;
|
||||
# ifndef PROTOENT_IS_INT
|
||||
if (!proto) {
|
||||
proto = getprotobyname("tcp");
|
||||
}
|
||||
# endif
|
||||
hints->ai_protocol= PROTO_P_PROTO;
|
||||
RKTIO_AS_ADDRINFO(hints)->ai_protocol= PROTO_P_PROTO;
|
||||
} else {
|
||||
hints->ai_socktype = SOCK_DGRAM;
|
||||
RKTIO_AS_ADDRINFO(hints)->ai_socktype = SOCK_DGRAM;
|
||||
}
|
||||
|
||||
lookup = malloc(sizeof(rktio_addrinfo_lookup_t));
|
||||
lookup->name = strdup(hostname);
|
||||
lookup->svc = strdup(service);
|
||||
lookup->name = (hostname ? strdup(hostname) : NULL);
|
||||
lookup->svc = (service ? strdup(service) : NULL);
|
||||
lookup->hints = hints;
|
||||
init_lookup(lookup);
|
||||
|
||||
|
@ -725,7 +748,7 @@ rktio_addrinfo_lookup_t *rktio_start_addrinfo_lookup(rktio_t *rktio,
|
|||
|
||||
void rktio_free_addrinfo(rktio_t *rktio, rktio_addrinfo_t *a)
|
||||
{
|
||||
do_freeaddrinfo(a);
|
||||
do_freeaddrinfo(RKTIO_AS_ADDRINFO(a));
|
||||
}
|
||||
|
||||
const char *rktio_gai_strerror(int errnum)
|
||||
|
@ -1042,11 +1065,13 @@ static rktio_connect_t *try_connect(rktio_t *rktio, rktio_connect_t *conn)
|
|||
rktio_socket_t s;
|
||||
|
||||
addr = conn->addr;
|
||||
s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
s = socket(RKTIO_AS_ADDRINFO(addr)->ai_family,
|
||||
RKTIO_AS_ADDRINFO(addr)->ai_socktype,
|
||||
RKTIO_AS_ADDRINFO(addr)->ai_protocol);
|
||||
if (s != INVALID_SOCKET) {
|
||||
int status, inprogress;
|
||||
if (!conn->src
|
||||
|| !bind(s, conn->src->ai_addr, conn->src->ai_addrlen)) {
|
||||
|| !bind(s, RKTIO_AS_ADDRINFO(conn->src)->ai_addr, RKTIO_AS_ADDRINFO(conn->src)->ai_addrlen)) {
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
unsigned long ioarg = 1;
|
||||
ioctlsocket(s, FIONBIO, &ioarg);
|
||||
|
@ -1055,7 +1080,7 @@ static rktio_connect_t *try_connect(rktio_t *rktio, rktio_connect_t *conn)
|
|||
fcntl(s, F_SETFL, RKTIO_NONBLOCKING);
|
||||
RKTIO_WHEN_SET_SOCKBUF_SIZE(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof(int)));
|
||||
#endif
|
||||
status = connect(s, addr->ai_addr, addr->ai_addrlen);
|
||||
status = connect(s, RKTIO_AS_ADDRINFO(addr)->ai_addr, RKTIO_AS_ADDRINFO(addr)->ai_addrlen);
|
||||
#ifdef RKTIO_SYSTEM_UNIX
|
||||
if (status)
|
||||
status = errno;
|
||||
|
@ -1128,9 +1153,9 @@ rktio_fd_t *rktio_connect_finish(rktio_t *rktio, rktio_connect_t *conn)
|
|||
|
||||
if (errid) {
|
||||
rktio_close(rktio, rfd);
|
||||
if (conn->addr->ai_next) {
|
||||
if (RKTIO_AS_ADDRINFO(conn->addr)->ai_next) {
|
||||
/* try the next one */
|
||||
conn->addr = conn->addr->ai_next;
|
||||
conn->addr = (rktio_addrinfo_t *)RKTIO_AS_ADDRINFO(conn->addr)->ai_next;
|
||||
if (try_connect(rktio, conn)) {
|
||||
set_racket_error(RKTIO_ERROR_CONNECT_TRYING_NEXT);
|
||||
return NULL;
|
||||
|
@ -1189,16 +1214,16 @@ rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *src, int backlo
|
|||
int any_v4 = 0, any_v6 = 0;
|
||||
#endif
|
||||
|
||||
for (addr = src; addr; addr = addr->ai_next) {
|
||||
for (addr = src; addr; addr = (rktio_addrinfo_t *)RKTIO_AS_ADDRINFO(addr)->ai_next) {
|
||||
#ifdef RKTIO_TCP_LISTEN_IPV6_ONLY_SOCKOPT
|
||||
if (addr->ai_family == RKTIO_PF_INET)
|
||||
if (RKTIO_AS_ADDRINFO(addr)->ai_family == RKTIO_PF_INET)
|
||||
any_v4 = 1;
|
||||
else if (addr->ai_family == PF_INET6)
|
||||
else if (RKTIO_AS_ADDRINFO(addr)->ai_family == PF_INET6)
|
||||
any_v6 = 1;
|
||||
#endif
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
rktio_socket_t s;
|
||||
#ifdef RKTIO_TCP_LISTEN_IPV6_ONLY_SOCKOPT
|
||||
|
@ -1212,34 +1237,36 @@ rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *src, int backlo
|
|||
|
||||
for (addr = src; addr; ) {
|
||||
#ifdef RKTIO_TCP_LISTEN_IPV6_ONLY_SOCKOPT
|
||||
if ((v6_loop && (addr->ai_family != PF_INET6))
|
||||
|| (skip_v6 && (addr->ai_family == PF_INET6))) {
|
||||
addr = addr->ai_next;
|
||||
if ((v6_loop && (RKTIO_AS_ADDRINFO(addr)->ai_family != PF_INET6))
|
||||
|| (skip_v6 && (RKTIO_AS_ADDRINFO(addr)->ai_family == PF_INET6))) {
|
||||
addr = (rktio_addrinfo_t *)RKTIO_AS_ADDRINFO(addr)->ai_next;
|
||||
if (v6_loop && !addr) {
|
||||
v6_loop = 0;
|
||||
skip_v6 = 1;
|
||||
addr = tcp_listen_addr;
|
||||
addr = src;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
s = socket(RKTIO_AS_ADDRINFO(addr)->ai_family,
|
||||
RKTIO_AS_ADDRINFO(addr)->ai_socktype,
|
||||
RKTIO_AS_ADDRINFO(addr)->ai_protocol);
|
||||
if (s != INVALID_SOCKET)
|
||||
get_socket_error();
|
||||
|
||||
#ifdef RKTIO_TCP_LISTEN_IPV6_ONLY_SOCKOPT
|
||||
if (s == INVALID_SOCKET) {
|
||||
/* Maybe it failed because IPv6 is not available: */
|
||||
if ((addr->ai_family == PF_INET6) && (errno == EAFNOSUPPORT)) {
|
||||
if ((RKTIO_AS_ADDRINFO(addr)->ai_family == PF_INET6) && (errno == EAFNOSUPPORT)) {
|
||||
if (any_v4 && !pos) {
|
||||
/* Let client known that maybe we can make it work with just IPv4. */
|
||||
set_racket_option(RKTIO_ERROR_TRY_AGAIN_WITH_IPV4);
|
||||
set_racket_error(RKTIO_ERROR_TRY_AGAIN_WITH_IPV4);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (s != INVALID_SOCKET) {
|
||||
if (any_v4 && (addr->ai_family == PF_INET6)) {
|
||||
if (any_v4 && (RKTIO_AS_ADDRINFO(addr)->ai_family == PF_INET6)) {
|
||||
int ok;
|
||||
# ifdef IPV6_V6ONLY
|
||||
int on = 1;
|
||||
|
@ -1250,7 +1277,7 @@ rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *src, int backlo
|
|||
if (ok) {
|
||||
if (!pos) {
|
||||
/* IPV6_V6ONLY doesn't work */
|
||||
set_racket_option(RKTIO_ERROR_TRY_AGAIN_WITH_IPV4);
|
||||
set_racket_error(RKTIO_ERROR_TRY_AGAIN_WITH_IPV4);
|
||||
s = INVALID_SOCKET;
|
||||
} else {
|
||||
get_socket_error();
|
||||
|
@ -1275,11 +1302,11 @@ rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *src, int backlo
|
|||
}
|
||||
|
||||
if (first_was_zero) {
|
||||
((struct sockaddr_in *)addr->ai_addr)->sin_port = no_port;
|
||||
((struct sockaddr_in *)RKTIO_AS_ADDRINFO(addr)->ai_addr)->sin_port = no_port;
|
||||
}
|
||||
if (!bind(s, addr->ai_addr, addr->ai_addrlen)) {
|
||||
if (!bind(s, RKTIO_AS_ADDRINFO(addr)->ai_addr, RKTIO_AS_ADDRINFO(addr)->ai_addrlen)) {
|
||||
if (first_time) {
|
||||
if (((struct sockaddr_in *)addr->ai_addr)->sin_port == 0) {
|
||||
if (((struct sockaddr_in *)RKTIO_AS_ADDRINFO(addr)->ai_addr)->sin_port == 0) {
|
||||
no_port = get_no_portno(rktio, s);
|
||||
first_was_zero = 1;
|
||||
if (no_port < 0) {
|
||||
|
@ -1327,7 +1354,7 @@ rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *src, int backlo
|
|||
break;
|
||||
}
|
||||
|
||||
addr = addr->ai_next;
|
||||
addr = (rktio_addrinfo_t *)RKTIO_AS_ADDRINFO(addr)->ai_next;
|
||||
|
||||
#ifdef RKTIO_TCP_LISTEN_IPV6_ONLY_SOCKOPT
|
||||
if (!addr && v6_loop) {
|
||||
|
|
|
@ -733,7 +733,10 @@ void rktio_collapse_win_fd(rktio_poll_set_t *fds)
|
|||
|
||||
static rktio_poll_set_t *alloc_fdset_arrays()
|
||||
{
|
||||
void *p;
|
||||
p = malloc((3 * sizeof(fd_set)) + sizeof(int));
|
||||
*(int *)((char *)p + (3 * sizeof(fd_set))) = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void free_fdset_arrays(rktio_poll_set_t *fds)
|
||||
|
@ -869,7 +872,13 @@ void rktio_free_global_poll_set(rktio_t *rktio) {
|
|||
|
||||
rktio_poll_set_t *rktio_make_poll_set(rktio_t *rktio)
|
||||
{
|
||||
return alloc_fdset_arrays();
|
||||
rktio_poll_set_t *fds = alloc_fdset_arrays();
|
||||
|
||||
RKTIO_FD_ZERO(fds);
|
||||
RKTIO_FD_ZERO(RKTIO_GET_FDSET(fds, 1));
|
||||
RKTIO_FD_ZERO(RKTIO_GET_FDSET(fds, 2));
|
||||
|
||||
return fds;
|
||||
}
|
||||
|
||||
void rktio_poll_set_close(rktio_t *rktio, rktio_poll_set_t *fds)
|
||||
|
|
|
@ -5,10 +5,16 @@
|
|||
# define RKTIO_SYSTEM_UNIX
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__) && !defined(OS_X)
|
||||
# define OS_X
|
||||
#endif
|
||||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#ifdef RKTIO_USE_PTHREADS
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if RKTIO_SYSTEM_WINDOWS
|
||||
# define USE_FAR_RKTIO_FDCALLS
|
||||
|
@ -47,14 +53,14 @@ struct rktio_t {
|
|||
|
||||
#if defined(RKTIO_SYSTEM_WINDOWS) || defined(RKTIO_USE_PTHREADS)
|
||||
int ghbn_started, ghbn_run;
|
||||
struct rktio_addr_lookup_t *ghbn_requests;
|
||||
struct rktio_addrinfo_lookup_t *ghbn_requests;
|
||||
# ifdef RKTIO_USE_PTHREADS
|
||||
HANDLE ghbn_th;
|
||||
pthread_t ghbn_th;
|
||||
pthread_mutex_t ghbn_lock;
|
||||
pthread_cond_t ghbn_start;
|
||||
# endif
|
||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||
pthread_t ghbn_th;
|
||||
HANDLE ghbn_th;
|
||||
HANDLE ghbn_lock;
|
||||
HANDLE ghbn_start;
|
||||
# endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user