Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -105,11 +105,10 @@ }], ac_cv_snprintf_useful_ret="yes", ac_cv_snprintf_useful_ret="no", ac_cv_snprintf_useful_ret="no")]) AC_MSG_RESULT($ac_cv_snprintf_useful_ret)]) - test x"$have_asprintf" != x"yes" -a x"$ac_cv_snprintf_useful_ret" != x"yes" && \ AC_MSG_ERROR(No asprintf and no snprintf returning required space!) AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") @@ -141,14 +140,60 @@ #define _WIN32_WINNT 0x0501 #include #endif], [ struct addrinfo ai; getaddrinfo(NULL, NULL, NULL, NULL); - ], [have_getaddrinfo="yes"], [have_getaddrinfo="no"]) -AC_MSG_RESULT($have_getaddrinfo) -test x"$have_getaddrinfo" = x"yes" && \ + ], [ + AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GETADDRINFO, 1, [Whether we have getaddrinfo]) + + AC_MSG_CHECKING(whether getaddrinfo is thread-safe) + case "$host_os" in + darwin[[12345]].*) + have_threadsafe_getaddrinfo="no" + ;; + darwin*) + have_threadsafe_getaddrinfo="yes" + ;; + freebsd[[1234]].* | freebsd5.[[1234]]*) + have_threadsafe_getaddrinfo="no" + ;; + freebsd*) + have_threadsafe_getaddrinfo="yes" + ;; + netbsd[[123]].*) + have_threadsafe_getaddrinfo="no" + ;; + netbsd*) + have_threadsafe_getaddrinfo="yes" + ;; + solaris*) + have_threadsafe_getaddrinfo="yes" + ;; + *) + have_threadsafe_getaddrinfo="unknown" + ;; + esac + + if test x"$have_threadsafe_getaddrinfo" = x"unknown"; then + AC_EGREP_CPP(yes, [ + #include + #ifdef h_errno + yes + #end + ], + [have_threadsafe_getaddrinfo="yes"], + [have_threadsafe_getaddrinfo="no"]) + fi + + test x"$have_threadsafe_getaddrinfo" = x"yes" && \ + AC_DEFINE(HAVE_THREADSAFE_GETADDRINFO, 1, + [Whether getaddrinfo is thread-safe]) + + AC_MSG_RESULT($have_threadsafe_getaddrinfo) + ], [ + AC_MSG_RESULT(no)]) AC_CHECK_FUNC(madvise, [AC_DEFINE(HAVE_MADVISE, 1, [Whether we have madvise])]) if test x"$GOBJC" = x"yes"; then OBJCFLAGS="$OBJCFLAGS -Werror" Index: m4/buildsys.m4 ================================================================== --- m4/buildsys.m4 +++ m4/buildsys.m4 @@ -30,12 +30,12 @@ ]) AC_DEFUN([BUILDSYS_PROG_IMPLIB], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_MSG_CHECKING(whether we need an implib) - case "$host" in - *-*-cygwin* | *-*-mingw*) + case "$host_os" in + cygwin* | mingw*) AC_MSG_RESULT(yes) PROG_IMPLIB_NEEDED='yes' PROG_IMPLIB_LDFLAGS='-Wl,-export-all-symbols,--out-implib,lib${PROG}.a' ;; *) @@ -50,13 +50,13 @@ ]) AC_DEFUN([BUILDSYS_SHARED_LIB], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_MSG_CHECKING(for shared library system) - case "$host" in - *-apple-*) - AC_MSG_RESULT(Mac OS X) + case "$host_os" in + darwin*) + AC_MSG_RESULT(Darwin) LIB_CPPFLAGS='-DPIC' LIB_CFLAGS='-fPIC' LIB_LDFLAGS='-dynamiclib -flat_namespace' LIB_PREFIX='lib' LIB_SUFFIX='.dylib' @@ -67,11 +67,11 @@ PLUGIN_SUFFIX='.impl' INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' CLEAN_LIB='' ;; - *-*-solaris*) + solaris*) AC_MSG_RESULT(Solaris) LIB_CPPFLAGS='-DPIC' LIB_CFLAGS='-fPIC' LIB_LDFLAGS='-shared -fPIC -Wl,-soname=${LIB}.${LIB_MAJOR}.${LIB_MINOR}' LIB_PREFIX='lib' @@ -83,11 +83,11 @@ PLUGIN_SUFFIX='.so' INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' CLEAN_LIB='' ;; - *-*-openbsd* | *-*-mirbsd*) + openbsd* | mirbsd*) AC_MSG_RESULT(OpenBSD) LIB_CPPFLAGS='-DPIC' LIB_CFLAGS='-fPIC' LIB_LDFLAGS='-shared -fPIC' LIB_PREFIX='lib' @@ -99,11 +99,11 @@ PLUGIN_SUFFIX='.so' INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i' CLEAN_LIB='' ;; - *-*-cygwin* | *-*-mingw*) + cygwin* | mingw*) AC_MSG_RESULT(Win32) LIB_CPPFLAGS='-DPIC' LIB_CFLAGS='' LIB_LDFLAGS='-shared -Wl,--out-implib,${LIB}.a' LIB_PREFIX='lib' Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -27,18 +27,18 @@ #ifndef INVALID_SOCKET #define INVALID_SOCKET -1 #endif -#ifndef HAVE_GETADDRINFO +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_THREADSAFE_GETADDRINFO) #import "OFThread.h" static OFMutex *mutex = nil; #endif @implementation OFTCPSocket -#ifndef HAVE_GETADDRINFO +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_THREADSAFE_GETADDRINFO) + (void)initialize { if (self == [OFTCPSocket class]) mutex = [[OFMutex alloc] init]; } @@ -50,10 +50,14 @@ close(sock); [super dealloc]; } +/* + * FIXME: Maybe we could copy the result of the name lookup and release the + * lock so that we don't keep the lock during connection attemps. + */ - connectToService: (OFString*)service onNode: (OFString*)node { if (sock != INVALID_SOCKET) @throw [OFAlreadyConnectedException newWithClass: isa]; @@ -63,15 +67,23 @@ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo([node cString], [service cString], &hints, &res0)) +#ifndef HAVE_THREADSAFE_GETADDRINFO + [mutex lock]; +#endif + + if (getaddrinfo([node cString], [service cString], &hints, &res0)) { +#ifndef HAVE_THREADSAFE_GETADDRINFO + [mutex unlock]; +#endif @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; + } for (res = res0; res != NULL; res = res->ai_next) { if ((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == INVALID_SOCKET) continue; @@ -84,10 +96,14 @@ break; } freeaddrinfo(res0); + +#ifndef HAVE_THREADSAFE_GETADDRINFO + [mutex unlock]; +#endif #else BOOL connected = NO; struct hostent *he; struct servent *se; struct sockaddr_in addr;