Problem: socket returned by ZMQ_FD cannot be used with CreateIoCompletionPort

Solution: add WSA_FLAG_OVERLAPPED socket flag
This commit is contained in:
Simon Giesecke 2019-03-26 18:18:33 +01:00
parent 25bb43c33a
commit 42e27b7d0d
2 changed files with 39 additions and 2 deletions

View File

@ -84,8 +84,9 @@ zmq::fd_t zmq::open_socket (int domain_, int type_, int protocol_)
#if defined ZMQ_HAVE_WINDOWS && defined WSA_FLAG_NO_HANDLE_INHERIT
// if supported, create socket with WSA_FLAG_NO_HANDLE_INHERIT, such that
// the race condition in making it non-inheritable later is avoided
const fd_t s = WSASocket (domain_, type_, protocol_, NULL, 0,
WSA_FLAG_NO_HANDLE_INHERIT);
const fd_t s =
WSASocket (domain_, type_, protocol_, NULL, 0,
WSA_FLAG_OVERLAPPED || WSA_FLAG_NO_HANDLE_INHERIT);
#else
const fd_t s = socket (domain_, type_, protocol_);
#endif

View File

@ -32,6 +32,10 @@
#include <string.h>
#if defined _WIN32
#include "../src/windows.hpp"
#endif
SETUP_TEARDOWN_TESTCONTEXT
typedef void (*extra_func_t) (void *socket_);
@ -110,6 +114,35 @@ void test_pair_tcp_fastpath ()
}
#endif
#ifdef _WIN32
void test_io_completion_port ()
{
void *const s = test_context_socket (ZMQ_PAIR);
SOCKET fd;
size_t fd_size = sizeof fd;
TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (s, ZMQ_FD, &fd, &fd_size));
::WSAPROTOCOL_INFO pi;
TEST_ASSERT_SUCCESS_RAW_ERRNO (
::WSADuplicateSocket (fd, ::GetCurrentProcessId (), &pi));
const SOCKET socket = ::WSASocket (pi.iAddressFamily /*AF_INET*/,
pi.iSocketType /*SOCK_STREAM*/,
pi.iProtocol /*IPPROTO_TCP*/, &pi, 0, 0);
const HANDLE iocp =
::CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0);
TEST_ASSERT_NOT_EQUAL (NULL, iocp);
const HANDLE res =
::CreateIoCompletionPort (reinterpret_cast<HANDLE> (socket), iocp, 0, 0);
TEST_ASSERT_NOT_EQUAL (NULL, res);
TEST_ASSERT_SUCCESS_RAW_ERRNO (closesocket (socket));
TEST_ASSERT_TRUE (CloseHandle (iocp));
test_context_socket_close (s);
}
#endif
int main ()
{
setup_test_environment ();
@ -120,6 +153,9 @@ int main ()
#ifdef ZMQ_BUILD_DRAFT
RUN_TEST (test_pair_tcp_fastpath);
#endif
#ifdef _WIN32
RUN_TEST (test_io_completion_port);
#endif
return UNITY_END ();
}