diff options
author | mturk <mturk@13f79535-47bb-0310-9956-ffa450edef68> | 2010-08-26 16:05:40 +0000 |
---|---|---|
committer | mturk <mturk@13f79535-47bb-0310-9956-ffa450edef68> | 2010-08-26 16:05:40 +0000 |
commit | d0aa7c6111c39ad7f532ca6c135ca5775498857d (patch) | |
tree | aab6fb541da7567bf7243676323b547cee966c4d | |
parent | edeffda94094090307efac831d62517707b9e3bb (diff) | |
download | libapr-d0aa7c6111c39ad7f532ca6c135ca5775498857d.tar.gz |
Backport Win32 part of poll provider for Vista+
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/1.5.x@989795 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | apr.dsp | 4 | ||||
-rw-r--r-- | file_io/win32/pipe.c | 36 | ||||
-rw-r--r-- | include/arch/win32/apr_arch_misc.h | 56 | ||||
-rw-r--r-- | libapr.dsp | 4 |
4 files changed, 90 insertions, 10 deletions
@@ -416,6 +416,10 @@ SOURCE=.\passwd\apr_getpass.c # PROP Default_Filter "" # Begin Source File +SOURCE=.\poll\unix\poll.c +# End Source File +# Begin Source File + SOURCE=.\poll\unix\pollcb.c # End Source File # Begin Source File diff --git a/file_io/win32/pipe.c b/file_io/win32/pipe.c index 4ee629d9f..aaf07f70e 100644 --- a/file_io/win32/pipe.c +++ b/file_io/win32/pipe.c @@ -229,8 +229,9 @@ APR_DECLARE(apr_status_t) apr_os_pipe_put(apr_file_t **file, static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr) { static int id = 0; - + FD_SET rs; SOCKET ls; + struct timeval socktm; struct sockaddr_in pa; struct sockaddr_in la; struct sockaddr_in ca; @@ -238,7 +239,7 @@ static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr) apr_status_t rv = APR_SUCCESS; int ll = sizeof(la); int lc = sizeof(ca); - int bm = 1; + unsigned long bm = 1; int uid[2]; int iid[2]; @@ -290,17 +291,41 @@ static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr) goto cleanup; } for (;;) { + int ns; + int nc = 0; /* Listening socket is nonblocking by now. - * The accept must create the socket - * immediatelly because we connected already. + * The accept should create the socket + * immediatelly because we are connected already. + * However on buys systems this can take a while + * until winsock gets a chance to handle the events. */ + FD_ZERO(&rs); + FD_SET(ls, &rs); + + socktm.tv_sec = 1; + socktm.tv_usec = 0; + if ((ns = select(0, &rs, NULL, NULL, &socktm)) == SOCKET_ERROR) { + /* Accept still not signaled */ + Sleep(100); + continue; + } + if (ns == 0) { + /* No connections in the last second */ + continue; + } if ((*rd = accept(ls, (SOCKADDR *)&ca, &lc)) == INVALID_SOCKET) { rv = apr_get_netos_error(); goto cleanup; } /* Verify the connection by reading the send identification. */ - nrd = recv(*rd, (char *)iid, sizeof(iid), 0); + do { + if (nc++) + Sleep(1); + nrd = recv(*rd, (char *)iid, sizeof(iid), 0); + rv = nrd == SOCKET_ERROR ? apr_get_netos_error() : APR_SUCCESS; + } while (APR_STATUS_IS_EAGAIN(rv)); + if (nrd == sizeof(iid)) { if (memcmp(uid, iid, sizeof(uid)) == 0) { /* Wow, we recived what we send. @@ -316,7 +341,6 @@ static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr) } } else if (nrd == SOCKET_ERROR) { - rv = apr_get_netos_error(); goto cleanup; } closesocket(*rd); diff --git a/include/arch/win32/apr_arch_misc.h b/include/arch/win32/apr_arch_misc.h index 1de496ed6..6c2b30991 100644 --- a/include/arch/win32/apr_arch_misc.h +++ b/include/arch/win32/apr_arch_misc.h @@ -186,18 +186,24 @@ FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char *fnName, int ordinal); /* The apr_load_dll_func call WILL return 0 set error to * ERROR_INVALID_FUNCTION if the function cannot be loaded */ - #define APR_DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args, names) \ typedef rettype (calltype *apr_winapi_fpt_##fn) args; \ static apr_winapi_fpt_##fn apr_winapi_pfn_##fn = NULL; \ - static APR_INLINE rettype apr_winapi_##fn args \ - { if (!apr_winapi_pfn_##fn) \ + static int apr_winapi_chk_##fn = 0; \ + static APR_INLINE int apr_winapi_ld_##fn(void) \ + { if (apr_winapi_pfn_##fn) return 1; \ + if (apr_winapi_chk_##fn ++) return 0; \ + if (!apr_winapi_pfn_##fn) \ apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \ apr_load_dll_func(lib, #fn, ord); \ - if (apr_winapi_pfn_##fn) \ + if (apr_winapi_pfn_##fn) return 1; else return 0; }; \ + static APR_INLINE rettype apr_winapi_##fn args \ + { if (apr_winapi_ld_##fn()) \ return (*(apr_winapi_pfn_##fn)) names; \ else { SetLastError(ERROR_INVALID_FUNCTION); return 0;} }; \ +#define APR_HAVE_LATE_DLL_FUNC(fn) apr_winapi_ld_##fn() + /* Provide late bound declarations of every API function missing from * one or more supported releases of the Win32 API * @@ -432,6 +438,48 @@ APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, Process32NextW, 0, ( (hSnapshot, lppe)); #define Process32NextW apr_winapi_Process32NextW +#if !defined(POLLERR) +/* Event flag definitions for WSAPoll(). */ +#define POLLRDNORM 0x0100 +#define POLLRDBAND 0x0200 +#define POLLIN (POLLRDNORM | POLLRDBAND) +#define POLLPRI 0x0400 + +#define POLLWRNORM 0x0010 +#define POLLOUT (POLLWRNORM) +#define POLLWRBAND 0x0020 + +#define POLLERR 0x0001 +#define POLLHUP 0x0002 +#define POLLNVAL 0x0004 + +typedef struct pollfd { + SOCKET fd; + SHORT events; + SHORT revents; + +} WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD; + +#endif /* !defined(POLLERR) */ +#ifdef WSAPoll +#undef WSAPoll +#endif +APR_DECLARE_LATE_DLL_FUNC(DLL_WINSOCK2API, int, WSAAPI, WSAPoll, 0, ( + IN OUT LPWSAPOLLFD fdArray, + IN ULONG fds, + IN INT timeout), + (fdArray, fds, timeout)); +#define WSAPoll apr_winapi_WSAPoll +#define HAVE_POLL 1 + +#ifdef SetDllDirectoryW +#undef SetDllDirectoryW +#endif +APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, SetDllDirectoryW, 0, ( + IN LPCWSTR lpPathName), + (lpPathName)); +#define SetDllDirectoryW apr_winapi_SetDllDirectoryW + #endif /* !defined(_WIN32_WCE) */ #endif /* ! MISC_H */ diff --git a/libapr.dsp b/libapr.dsp index b8b199f87..a4aeff3d8 100644 --- a/libapr.dsp +++ b/libapr.dsp @@ -468,6 +468,10 @@ SOURCE=.\passwd\apr_getpass.c # PROP Default_Filter "" # Begin Source File +SOURCE=.\poll\unix\poll.c +# End Source File +# Begin Source File + SOURCE=.\poll\unix\pollcb.c # End Source File # Begin Source File |