2
0
mirror of https://github.com/boostorg/asio.git synced 2026-02-26 02:42:08 +00:00

Some changes to enable support for WinCE.

[SVN r40759]
This commit is contained in:
Christopher Kohlhoff
2007-11-04 21:25:49 +00:00
parent 9db4bb6bc0
commit 6e1a010a72
8 changed files with 298 additions and 29 deletions

View File

@@ -101,6 +101,10 @@ inline socket_type accept(socket_type s, socket_addr_type* addr,
}
#endif
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
clear_error(ec);
#endif
return new_s;
}
@@ -115,14 +119,25 @@ inline int bind(socket_type s, const socket_addr_type* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_bind(&msghdr::msg_namelen, s, addr, addrlen), ec);
int result = error_wrapper(call_bind(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
inline int close(socket_type s, boost::system::error_code& ec)
{
clear_error(ec);
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::closesocket(s), ec);
int result = error_wrapper(::closesocket(s), ec);
# if defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::close(s), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -131,7 +146,12 @@ inline int close(socket_type s, boost::system::error_code& ec)
inline int shutdown(socket_type s, int what, boost::system::error_code& ec)
{
clear_error(ec);
return error_wrapper(::shutdown(s, what), ec);
int result = error_wrapper(::shutdown(s, what), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
template <typename SockLenType>
@@ -145,14 +165,24 @@ inline int connect(socket_type s, const socket_addr_type* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_connect(
int result = error_wrapper(call_connect(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
inline int listen(socket_type s, int backlog, boost::system::error_code& ec)
{
clear_error(ec);
return error_wrapper(::listen(s, backlog), ec);
int result = error_wrapper(::listen(s, backlog), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -218,6 +248,9 @@ inline int recv(socket_type s, buf* bufs, size_t count, int flags,
recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@@ -243,6 +276,9 @@ inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
*addrlen = (std::size_t)tmp_addrlen;
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@@ -269,6 +305,9 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@@ -291,9 +330,13 @@ inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
DWORD send_buf_count = static_cast<DWORD>(count);
DWORD bytes_transferred = 0;
int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
send_buf_count, &bytes_transferred, flags, addr, addrlen, 0, 0), ec);
send_buf_count, &bytes_transferred, flags, addr,
static_cast<int>(addrlen), 0, 0), ec);
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@@ -328,6 +371,10 @@ inline socket_type socket(int af, int type, int protocol,
reinterpret_cast<const char*>(&optval), sizeof(optval));
}
# if defined(UNDER_CE)
clear_error(ec);
# endif
return s;
#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
socket_type s = error_wrapper(::socket(af, type, protocol), ec);
@@ -386,8 +433,13 @@ inline int setsockopt(socket_type s, int level, int optname,
return -1;
#else // defined(__BORLANDC__)
clear_error(ec);
return error_wrapper(call_setsockopt(&msghdr::msg_namelen,
int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen), ec);
# if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#endif // defined(__BORLANDC__)
}
@@ -456,6 +508,10 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
*static_cast<DWORD*>(optval) = 1;
clear_error(ec);
}
# if defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
@@ -491,8 +547,13 @@ inline int getpeername(socket_type s, socket_addr_type* addr,
std::size_t* addrlen, boost::system::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_getpeername(
int result = error_wrapper(call_getpeername(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
template <typename SockLenType>
@@ -509,8 +570,13 @@ inline int getsockname(socket_type s, socket_addr_type* addr,
std::size_t* addrlen, boost::system::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_getsockname(
int result = error_wrapper(call_getsockname(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
@@ -518,7 +584,12 @@ inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
{
clear_error(ec);
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::ioctlsocket(s, cmd, arg), ec);
int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);
# if defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::ioctl(s, cmd, arg), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -557,8 +628,13 @@ inline int select(int nfds, fd_set* readfds, fd_set* writefds,
return error_wrapper(::pselect(nfds, readfds,
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
#else
return error_wrapper(::select(nfds, readfds,
int result = error_wrapper(::select(nfds, readfds,
writefds, exceptfds, timeout), ec);
# if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result >= 0)
clear_error(ec);
# endif
return result;
#endif
}
@@ -569,7 +645,12 @@ inline int poll_read(socket_type s, boost::system::error_code& ec)
FD_ZERO(&fds);
FD_SET(s, &fds);
clear_error(ec);
return error_wrapper(::select(s, &fds, 0, 0, 0), ec);
int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec);
# if defined(UNDER_CE)
if (result >= 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
pollfd fds;
fds.fd = s;
@@ -587,7 +668,12 @@ inline int poll_write(socket_type s, boost::system::error_code& ec)
FD_ZERO(&fds);
FD_SET(s, &fds);
clear_error(ec);
return error_wrapper(::select(s, 0, &fds, 0, 0), ec);
int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec);
# if defined(UNDER_CE)
if (result >= 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
pollfd fds;
fds.fd = s;
@@ -635,9 +721,17 @@ inline const char* inet_ntop(int af, const void* src, char* dest, size_t length,
}
DWORD string_length = static_cast<DWORD>(length);
#if defined(BOOST_NO_ANSI_APIS)
LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));
int result = error_wrapper(::WSAAddressToStringW(
reinterpret_cast<sockaddr*>(&address),
address_length, 0, string_buffer, &string_length), ec);
::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0);
#else
int result = error_wrapper(::WSAAddressToStringA(
reinterpret_cast<sockaddr*>(&address),
address_length, 0, dest, &string_length), ec);
#endif
// Windows may set error code on success.
if (result != socket_error_retval)
@@ -681,10 +775,20 @@ inline int inet_pton(int af, const char* src, void* dest,
sockaddr_storage_type address;
int address_length = sizeof(sockaddr_storage_type);
#if defined(BOOST_NO_ANSI_APIS)
int num_wide_chars = strlen(src) + 1;
LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR));
::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars);
int result = error_wrapper(::WSAStringToAddressW(
wide_buffer, af, 0,
reinterpret_cast<sockaddr*>(&address),
&address_length), ec);
#else
int result = error_wrapper(::WSAStringToAddressA(
const_cast<char*>(src), af, 0,
reinterpret_cast<sockaddr*>(&address),
&address_length), ec);
#endif
if (af == AF_INET)
{
@@ -718,6 +822,11 @@ inline int inet_pton(int af, const char* src, void* dest,
if (result == socket_error_retval && !ec)
ec = boost::asio::error::invalid_argument;
#if defined(UNDER_CE)
if (result != socket_error_retval)
clear_error(ec);
#endif
return result == socket_error_retval ? -1 : 1;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
int result = error_wrapper(::inet_pton(af, src, dest), ec);
@@ -744,7 +853,12 @@ inline int inet_pton(int af, const char* src, void* dest,
inline int gethostname(char* name, int namelen, boost::system::error_code& ec)
{
clear_error(ec);
return error_wrapper(::gethostname(name, namelen), ec);
int result = error_wrapper(::gethostname(name, namelen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \
@@ -783,6 +897,9 @@ inline hostent* gethostbyaddr(const char* addr, int length, int af,
hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
if (!retval)
return 0;
# if defined(UNDER_CE)
clear_error(ec);
# endif
*result = *retval;
return retval;
#elif defined(__sun) || defined(__QNX__)
@@ -831,6 +948,9 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result,
hostent* retval = error_wrapper(::gethostbyname(name), ec);
if (!retval)
return 0;
# if defined(UNDER_CE)
clear_error(ec);
# endif
*result = *retval;
return result;
#elif defined(__sun) || defined(__QNX__)
@@ -1616,7 +1736,7 @@ inline boost::system::error_code getaddrinfo(const char* host,
{
clear_error(ec);
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
// Building for Windows XP, Windows Server 2003, or later.
int error = ::getaddrinfo(host, service, hints, result);
return ec = translate_addrinfo_error(error);
@@ -1647,7 +1767,7 @@ inline boost::system::error_code getaddrinfo(const char* host,
inline void freeaddrinfo(addrinfo_type* ai)
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
// Building for Windows XP, Windows Server 2003, or later.
::freeaddrinfo(ai);
# else
@@ -1675,7 +1795,7 @@ inline boost::system::error_code getnameinfo(const socket_addr_type* addr,
char* serv, std::size_t servlen, int flags, boost::system::error_code& ec)
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
// Building for Windows XP, Windows Server 2003, or later.
clear_error(ec);
int error = ::getnameinfo(addr, addrlen, host, static_cast<DWORD>(hostlen),
@@ -1739,8 +1859,6 @@ inline u_short_type host_to_network_short(u_short_type value)
} // namespace asio
} // namespace boost
#undef BOOST_ASIO_SOCKET_CALL
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_HPP

View File

@@ -80,7 +80,9 @@
# undef BOOST_ASIO_WSPIAPI_H_DEFINED
# endif // defined(BOOST_ASIO_WSPIAPI_H_DEFINED)
# if !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS)
# if defined(_MSC_VER) || defined(__BORLANDC__)
# if defined(UNDER_CE)
# pragma comment(lib, "ws2.lib")
# elif defined(_MSC_VER) || defined(__BORLANDC__)
# pragma comment(lib, "ws2_32.lib")
# pragma comment(lib, "mswsock.lib")
# endif // defined(_MSC_VER) || defined(__BORLANDC__)

View File

@@ -24,7 +24,11 @@
#if !defined(BOOST_HAS_THREADS)
# include <boost/asio/detail/null_thread.hpp>
#elif defined(BOOST_WINDOWS)
# include <boost/asio/detail/win_thread.hpp>
# if defined(UNDER_CE)
# include <boost/asio/detail/wince_thread.hpp>
# else
# include <boost/asio/detail/win_thread.hpp>
# endif
#elif defined(BOOST_HAS_PTHREADS)
# include <boost/asio/detail/posix_thread.hpp>
#else
@@ -38,7 +42,11 @@ namespace detail {
#if !defined(BOOST_HAS_THREADS)
typedef null_thread thread;
#elif defined(BOOST_WINDOWS)
# if defined(UNDER_CE)
typedef wince_thread thread;
# else
typedef win_thread thread;
# endif
#elif defined(BOOST_HAS_PTHREADS)
typedef posix_thread thread;
#endif

View File

@@ -27,6 +27,7 @@
#if !defined(BOOST_ASIO_DISABLE_IOCP)
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
#if !defined(UNDER_CE)
// Define this to indicate that IOCP is supported on the target platform.
#define BOOST_ASIO_HAS_IOCP 1
@@ -41,6 +42,7 @@ class win_iocp_io_service;
} // namespace asio
} // namespace boost
#endif // !defined(UNDER_CE)
#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#endif // !defined(BOOST_ASIO_DISABLE_IOCP)

View File

@@ -22,7 +22,7 @@
#include <boost/system/system_error.hpp>
#include <boost/asio/detail/pop_options.hpp>
#if defined(BOOST_WINDOWS)
#if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
#include <boost/asio/error.hpp>
#include <boost/asio/detail/noncopyable.hpp>
@@ -120,7 +120,7 @@ inline unsigned int __stdcall win_thread_function(void* arg)
} // namespace asio
} // namespace boost
#endif // defined(BOOST_WINDOWS)
#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
#include <boost/asio/detail/pop_options.hpp>

View File

@@ -41,11 +41,17 @@ class win_tss_ptr
: private noncopyable
{
public:
#if defined(UNDER_CE)
enum { out_of_indexes = 0xFFFFFFFF };
#else
enum { out_of_indexes = TLS_OUT_OF_INDEXES };
#endif
// Constructor.
win_tss_ptr()
{
tss_key_ = ::TlsAlloc();
if (tss_key_ == TLS_OUT_OF_INDEXES)
if (tss_key_ == out_of_indexes)
{
DWORD last_error = ::GetLastError();
boost::system::system_error e(

View File

@@ -0,0 +1,126 @@
//
// wince_thread.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_DETAIL_WINCE_THREAD_HPP
#define BOOST_ASIO_DETAIL_WINCE_THREAD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/push_options.hpp>
#include <boost/asio/detail/push_options.hpp>
#include <boost/config.hpp>
#include <boost/system/system_error.hpp>
#include <boost/asio/detail/pop_options.hpp>
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
#include <boost/asio/error.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/socket_types.hpp>
#include <boost/asio/detail/push_options.hpp>
#include <boost/throw_exception.hpp>
#include <memory>
#include <boost/asio/detail/pop_options.hpp>
namespace boost {
namespace asio {
namespace detail {
DWORD WINAPI wince_thread_function(LPVOID arg);
class wince_thread
: private noncopyable
{
public:
// Constructor.
template <typename Function>
wince_thread(Function f)
{
std::auto_ptr<func_base> arg(new func<Function>(f));
DWORD thread_id = 0;
thread_ = ::CreateThread(0, 0, wince_thread_function,
arg.get(), 0, &thread_id);
if (!thread_)
{
DWORD last_error = ::GetLastError();
boost::system::system_error e(
boost::system::error_code(last_error,
boost::asio::error::system_category),
"thread");
boost::throw_exception(e);
}
arg.release();
}
// Destructor.
~wince_thread()
{
::CloseHandle(thread_);
}
// Wait for the thread to exit.
void join()
{
::WaitForSingleObject(thread_, INFINITE);
}
private:
friend DWORD WINAPI wince_thread_function(LPVOID arg);
class func_base
{
public:
virtual ~func_base() {}
virtual void run() = 0;
};
template <typename Function>
class func
: public func_base
{
public:
func(Function f)
: f_(f)
{
}
virtual void run()
{
f_();
}
private:
Function f_;
};
::HANDLE thread_;
};
inline DWORD WINAPI wince_thread_function(LPVOID arg)
{
std::auto_ptr<wince_thread::func_base> func(
static_cast<wince_thread::func_base*>(arg));
func->run();
return 0;
}
} // namespace detail
} // namespace asio
} // namespace boost
#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE)
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_DETAIL_WINCE_THREAD_HPP

View File

@@ -253,6 +253,13 @@ template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name>
class multicast_hops
{
public:
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
typedef int ipv4_value_type;
#else
typedef unsigned char ipv4_value_type;
#endif
typedef int ipv6_value_type;
// Default constructor.
multicast_hops()
: ipv4_value_(0),
@@ -265,7 +272,7 @@ public:
{
if (v < 0 || v > 255)
throw std::out_of_range("multicast hops value out of range");
ipv4_value_ = static_cast<unsigned char>(v);
ipv4_value_ = (ipv4_value_type)v;
ipv6_value_ = v;
}
@@ -274,7 +281,7 @@ public:
{
if (v < 0 || v > 255)
throw std::out_of_range("multicast hops value out of range");
ipv4_value_ = static_cast<unsigned char>(v);
ipv4_value_ = (ipv4_value_type)v;
ipv6_value_ = v;
return *this;
}
@@ -343,7 +350,7 @@ public:
else if (ipv6_value_ > 255)
ipv4_value_ = 255;
else
ipv4_value_ = static_cast<unsigned char>(ipv6_value_);
ipv4_value_ = (ipv4_value_type)ipv6_value_;
}
else
{
@@ -354,8 +361,8 @@ public:
}
private:
unsigned char ipv4_value_;
int ipv6_value_;
ipv4_value_type ipv4_value_;
ipv6_value_type ipv6_value_;
};
// Helper template for implementing ip_mreq-based options.