From f895426c1885729f4a4a20b1eb543a92915aed85 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Sep 2009 15:41:43 +0200 Subject: initial changes for win port --- include/zmq.h | 5 +- msvc/libzmq/libzmq.vcproj | 520 ++++++++++++++++++++++++++++++++++++++++++++++ msvc/msvc.sln | 20 ++ msvc/platform.hpp | 59 ++++++ src/app_thread.cpp | 2 + src/fd_signaler.cpp | 1 + src/options.hpp | 2 + src/pipe.cpp | 4 +- src/tcp_connecter.cpp | 75 ++++++- src/tcp_listener.cpp | 1 - src/tcp_socket.cpp | 74 ++++++- src/uuid.cpp | 13 +- src/uuid.hpp | 11 +- src/zmq_connecter.cpp | 2 +- 14 files changed, 764 insertions(+), 25 deletions(-) create mode 100644 msvc/libzmq/libzmq.vcproj create mode 100644 msvc/msvc.sln create mode 100644 msvc/platform.hpp diff --git a/include/zmq.h b/include/zmq.h index f321fa9..a8394ed 100644 --- a/include/zmq.h +++ b/include/zmq.h @@ -25,7 +25,6 @@ extern "C" { #endif #include -#include #if defined MSC_VER && defined ZMQ_BUILDING_LIBZMQ #define ZMQ_EXPORT __declspec(dllexport) @@ -35,6 +34,8 @@ extern "C" { // Maximal size of "Very Small Message". VSMs are passed by value // to avoid excessive memory allocation/deallocation. +// If VMSs larger than 255 bytes are required, type of 'vsm_size' +// field in zmq_msg_t structure should be modified accordingly. #define ZMQ_MAX_VSM_SIZE 30 // Message & notification types. @@ -98,7 +99,7 @@ struct zmq_msg_t { void *content; unsigned char shared; - uint16_t vsm_size; + unsigned char vsm_size; unsigned char vsm_data [ZMQ_MAX_VSM_SIZE]; }; diff --git a/msvc/libzmq/libzmq.vcproj b/msvc/libzmq/libzmq.vcproj new file mode 100644 index 0000000..e1d69d7 --- /dev/null +++ b/msvc/libzmq/libzmq.vcproj @@ -0,0 +1,520 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/msvc.sln b/msvc/msvc.sln new file mode 100644 index 0000000..e023863 --- /dev/null +++ b/msvc/msvc.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzmq", "libzmq\libzmq.vcproj", "{641C5F36-32EE-4323-B740-992B651CF9D6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {641C5F36-32EE-4323-B740-992B651CF9D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {641C5F36-32EE-4323-B740-992B651CF9D6}.Debug|Win32.Build.0 = Debug|Win32 + {641C5F36-32EE-4323-B740-992B651CF9D6}.Release|Win32.ActiveCfg = Release|Win32 + {641C5F36-32EE-4323-B740-992B651CF9D6}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc/platform.hpp b/msvc/platform.hpp new file mode 100644 index 0000000..0555fa3 --- /dev/null +++ b/msvc/platform.hpp @@ -0,0 +1,59 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __ZMQ_PLATFORM_HPP_INCLUDED__ +#define __ZMQ_PLATFORM_HPP_INCLUDED__ + +// This is the platform definition for the Windows platform. +// As a first step of the build process it is copied to +// zmq directory to take place of platform.hpp generated from +// platform.hpp.in on platforms supported by GNU autotools. + +#define ZMQ_HAVE_WINDOWS +#define _WINSOCKAPI_ +#define NOMINMAX +#define _CRT_SECURE_NO_WARNINGS + +// Turn on only the items zmq needs on the Windows platform. + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMCX // No Modem Configuration Extensions. +#define NOMCX +#endif +#ifndef NOIME // No Input Method Editor. +#define NOIME +#endif +#ifndef NOSOUND // No Sound driver routines. +#define NOSOUND +#endif + +#include +#include + +// Enable winsock (not included when WIN32_LEAN_AND_MEAN is defined). +#if(_WIN32_WINNT >= 0x0400) +#include +#include +#else +#include +#endif + +#endif diff --git a/src/app_thread.cpp b/src/app_thread.cpp index 58fe19d..847fcc1 100644 --- a/src/app_thread.cpp +++ b/src/app_thread.cpp @@ -21,6 +21,8 @@ #include "../include/zmq.h" +#include "platform.hpp" + #if defined ZMQ_HAVE_WINDOWS #include "windows.hpp" #else diff --git a/src/fd_signaler.cpp b/src/fd_signaler.cpp index 771094b..3f433b8 100644 --- a/src/fd_signaler.cpp +++ b/src/fd_signaler.cpp @@ -21,6 +21,7 @@ #include "platform.hpp" #include "err.hpp" #include "fd.hpp" +#include "ip.hpp" #if defined ZMQ_HAVE_OPENVMS #include diff --git a/src/options.hpp b/src/options.hpp index 7d78da2..faf21b8 100644 --- a/src/options.hpp +++ b/src/options.hpp @@ -22,6 +22,8 @@ #include +#include "stdint.hpp" + namespace zmq { diff --git a/src/pipe.cpp b/src/pipe.cpp index 3748ae9..392d380 100644 --- a/src/pipe.cpp +++ b/src/pipe.cpp @@ -17,9 +17,7 @@ along with this program. If not, see . */ -#include - -#include <../include/zmq.h> +#include "../include/zmq.h" #include "pipe.hpp" diff --git a/src/tcp_connecter.cpp b/src/tcp_connecter.cpp index 23f3741..fa99538 100644 --- a/src/tcp_connecter.cpp +++ b/src/tcp_connecter.cpp @@ -26,8 +26,79 @@ #ifdef ZMQ_HAVE_WINDOWS -#include "windows.hpp" -#error +zmq::tcp_connecter_t::tcp_connecter_t () : + s (retired_fd) +{ + memset (&addr, 0, sizeof (addr)); +} + +zmq::tcp_connecter_t::~tcp_connecter_t () +{ + if (s != retired_fd) + close (); +} + +int zmq::tcp_connecter_t::set_address (const char *addr_) +{ + // Convert the hostname into sockaddr_in structure. + return resolve_ip_hostname (&addr, addr_); +} + +int zmq::tcp_connecter_t::open () +{ + zmq_assert (s == retired_fd); + + // Create the socket. + s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + // TODO: Convert error to errno. + wsa_assert (s != INVALID_SOCKET); + + // Set to non-blocking mode. + unsigned long argp = 1; + int rc = ioctlsocket (s, FIONBIO, &argp); + wsa_assert (rc != SOCKET_ERROR); + + // Disable Nagle's algorithm. + int flag = 1; + rc = setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, + sizeof (int)); + wsa_assert (rc != SOCKET_ERROR); + + // Connect to the remote peer. + rc = ::connect (s, (sockaddr*) &addr, sizeof addr); + + // Connect was successfull immediately. + if (rc == 0) + return 0; + + // Asynchronous connect was launched. + if (rc == SOCKET_ERROR && (WSAGetLastError () == WSAEINPROGRESS || + WSAGetLastError () == WSAEWOULDBLOCK)) { + errno = EAGAIN; + return -1; + } + + // TODO: Convert error to errno. + wsa_assert (rc == 0); + + return -1; +} + +int zmq::tcp_connecter_t::close () +{ + zmq_assert (s != retired_fd); + int rc = closesocket (s); + wsa_assert (rc != SOCKET_ERROR); + s = retired_fd; + return 0; +} + +zmq::fd_t zmq::tcp_connecter_t::get_fd () +{ + return s; +} + +// connect #else diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index de62879..22d47ca 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -27,7 +27,6 @@ #ifdef ZMQ_HAVE_WINDOWS -#include "windows.hpp" #error #else diff --git a/src/tcp_socket.cpp b/src/tcp_socket.cpp index 4472fa6..21f60f9 100644 --- a/src/tcp_socket.cpp +++ b/src/tcp_socket.cpp @@ -23,8 +23,75 @@ #ifdef ZMQ_HAVE_WINDOWS -#include "windows.hpp" -#error +zmq::tcp_socket_t::tcp_socket_t () : + s (retired_fd) +{ +} + +zmq::tcp_socket_t::~tcp_socket_t () +{ + if (s != retired_fd) + close (); +} + +int zmq::tcp_socket_t::open (fd_t fd_) +{ + zmq_assert (s == retired_fd); + s = fd_; + return 0; +} + +int zmq::tcp_socket_t::close () +{ + zmq_assert (s != retired_fd); + int rc = closesocket (s); + wsa_assert (rc != SOCKET_ERROR); + s = retired_fd; + return 0; +} + +int zmq::tcp_socket_t::write (const void *data, int size) +{ + int nbytes = send (s, (char*) data, size, 0); + + // If not a single byte can be written to the socket in non-blocking mode + // we'll get an error (this may happen during the speculative write). + if (nbytes == SOCKET_ERROR && WSAGetLastError () == WSAEWOULDBLOCK) + return 0; + + // Signalise peer failure. + if (nbytes == SOCKET_ERROR && WSAGetLastError () == WSAECONNRESET) + return -1; + + wsa_assert (nbytes != SOCKET_ERROR); + + return (size_t) nbytes; +} + +int zmq::tcp_socket_t::read (void *data, int size) +{ + int nbytes = recv (s, (char*) data, size, 0); + + // If not a single byte can be read from the socket in non-blocking mode + // we'll get an error (this may happen during the speculative read). + if (nbytes == SOCKET_ERROR && WSAGetLastError () == WSAEWOULDBLOCK) + return 0; + + // Connection failure. + if (nbytes == -1 && ( + WSAGetLastError () == WSAECONNRESET || + WSAGetLastError () == WSAECONNREFUSED || + WSAGetLastError () == WSAENOTCONN)) + return -1; + + wsa_assert (nbytes != SOCKET_ERROR); + + // Orderly shutdown by the other peer. + if (nbytes == 0) + return -1; + + return (size_t) nbytes; +} #else @@ -112,5 +179,4 @@ int zmq::tcp_socket_t::read (void *data, int size) return (size_t) nbytes; } -#endif - +#endif \ No newline at end of file diff --git a/src/uuid.cpp b/src/uuid.cpp index 10db3bc..6abc41d 100644 --- a/src/uuid.cpp +++ b/src/uuid.cpp @@ -23,25 +23,28 @@ #if defined ZMQ_HAVE_WINDOWS -#include - zmq::uuid_t::uuid_t () { RPC_STATUS ret = UuidCreate (&uuid); zmq_assert (ret == RPC_S_OK); ret = UuidToString (&uuid, &uuid_str); zmq_assert (ret == RPC_S_OK); + + /* + HRESULT hr = CoCreateGUID (&uuid); + zmq_assert (hr == S_OK); + int rc = StringFromGUID2 (uuid, uuid_str, 40); + zmq_assert (rc != 0); + */ } zmq::uuid_t::~uuid_t () { - RPC_STATUS ret = RpcStringFree(&uuid_str); - assert (ret == RPC_S_OK); } const char *zmq::uuid_t::to_string () { - return uuid_str; + return (char*) uuid_str; } #elif defined ZMQ_HAVE_FREEBSD diff --git a/src/uuid.hpp b/src/uuid.hpp index 79a9620..81e41a3 100644 --- a/src/uuid.hpp +++ b/src/uuid.hpp @@ -21,15 +21,12 @@ #define __ZMQ_UUID_HPP_INCLUDED__ #include "platform.hpp" +#include "stdint.hpp" -#if defined ZMQ_HAVE_WINDOWS -#include -#elif defined ZMQ_HAVE_FREEBSD +#if defined ZMQ_HAVE_FREEBSD #include #elif defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OSX #include -#else -#include #endif namespace zmq @@ -56,8 +53,8 @@ namespace zmq enum { uuid_string_len = 36 }; #if defined ZMQ_HAVE_WINDOWS - ::UUID uuid; - char *uuid_str; + ::UUID uuid; + RPC_CSTR uuid_str; #elif defined ZMQ_HAVE_FREEBSD ::uuid_t uuid; char *uuid_str; diff --git a/src/zmq_connecter.cpp b/src/zmq_connecter.cpp index e4e7eea..d15566a 100644 --- a/src/zmq_connecter.cpp +++ b/src/zmq_connecter.cpp @@ -106,7 +106,7 @@ void zmq::zmq_connecter_t::start_connecting () } // Connection establishment may be dealyed. Poll for its completion. - else if (rc == -1 && errno == EINPROGRESS) { + else if (rc == -1 && errno == EAGAIN) { handle = add_fd (tcp_connecter.get_fd ()); handle_valid = true; set_pollout (handle); -- cgit v1.2.3