asio sync
This commit is contained in:
parent
4d4b30700a
commit
2d27cede5f
|
@ -35,11 +35,16 @@ public:
|
|||
FD_ZERO(&fd_set_);
|
||||
}
|
||||
|
||||
void set(socket_type descriptor)
|
||||
bool set(socket_type descriptor)
|
||||
{
|
||||
if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_)
|
||||
max_descriptor_ = descriptor;
|
||||
FD_SET(descriptor, &fd_set_);
|
||||
if (descriptor < (socket_type)FD_SETSIZE)
|
||||
{
|
||||
if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_)
|
||||
max_descriptor_ = descriptor;
|
||||
FD_SET(descriptor, &fd_set_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_set(socket_type descriptor) const
|
||||
|
|
|
@ -173,8 +173,13 @@ public:
|
|||
typename operation_map::iterator i = operations_.begin();
|
||||
while (i != operations_.end())
|
||||
{
|
||||
descriptors.set(i->first);
|
||||
Descriptor descriptor = i->first;
|
||||
++i;
|
||||
if (!descriptors.set(descriptor))
|
||||
{
|
||||
asio::error_code ec(error::fd_set_failure);
|
||||
dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1124,8 +1124,12 @@ inline void gai_free(void* p)
|
|||
inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
|
||||
{
|
||||
using namespace std;
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
|
||||
strcpy_s(target, max_size, source);
|
||||
#else
|
||||
*target = 0;
|
||||
strncat(target, source, max_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
enum { gai_clone_flag = 1 << 30 };
|
||||
|
@ -1658,7 +1662,11 @@ inline asio::error_code getnameinfo_emulation(
|
|||
{
|
||||
return ec = asio::error::no_buffer_space;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
|
||||
sprintf_s(serv, servlen, "%u", ntohs(port));
|
||||
#else
|
||||
sprintf(serv, "%u", ntohs(port));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1677,7 +1685,11 @@ inline asio::error_code getnameinfo_emulation(
|
|||
{
|
||||
return ec = asio::error::no_buffer_space;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
|
||||
sprintf_s(serv, servlen, "%u", ntohs(port));
|
||||
#else
|
||||
sprintf(serv, "%u", ntohs(port));
|
||||
#endif
|
||||
}
|
||||
#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
|
||||
::pthread_mutex_unlock(&mutex);
|
||||
|
|
|
@ -92,7 +92,11 @@
|
|||
# include <sys/ioctl.h>
|
||||
# include <sys/poll.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/select.h>
|
||||
# if defined(__hpux)
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
# include <sys/socket.h>
|
||||
# include <sys/uio.h>
|
||||
# include <netinet/in.h>
|
||||
|
@ -156,7 +160,16 @@ const int max_addr_v4_str_len = INET_ADDRSTRLEN;
|
|||
const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
|
||||
typedef sockaddr socket_addr_type;
|
||||
typedef in_addr in4_addr_type;
|
||||
# if defined(__hpux)
|
||||
// HP-UX doesn't provide ip_mreq when _XOPEN_SOURCE_EXTENDED is defined.
|
||||
struct in4_mreq_type
|
||||
{
|
||||
struct in_addr imr_multiaddr;
|
||||
struct in_addr imr_interface;
|
||||
};
|
||||
# else
|
||||
typedef ip_mreq in4_mreq_type;
|
||||
# endif
|
||||
typedef sockaddr_in sockaddr_in4_type;
|
||||
typedef in6_addr in6_addr_type;
|
||||
typedef ipv6_mreq in6_mreq_type;
|
||||
|
|
|
@ -36,13 +36,17 @@ public:
|
|||
fd_set_.fd_count = 0;
|
||||
}
|
||||
|
||||
void set(socket_type descriptor)
|
||||
bool set(socket_type descriptor)
|
||||
{
|
||||
for (u_int i = 0; i < fd_set_.fd_count; ++i)
|
||||
if (fd_set_.fd_array[i] == descriptor)
|
||||
return;
|
||||
return true;
|
||||
if (fd_set_.fd_count < win_fd_set_size)
|
||||
{
|
||||
fd_set_.fd_array[fd_set_.fd_count++] = descriptor;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_set(socket_type descriptor) const
|
||||
|
|
|
@ -194,7 +194,10 @@ enum misc_errors
|
|||
eof,
|
||||
|
||||
/// Element not found.
|
||||
not_found
|
||||
not_found,
|
||||
|
||||
/// The descriptor cannot fit into the select system call's fd_set.
|
||||
fd_set_failure
|
||||
};
|
||||
|
||||
enum ssl_errors
|
||||
|
|
|
@ -112,7 +112,11 @@ public:
|
|||
{
|
||||
};
|
||||
|
||||
typedef unspecified_bool_type_t* unspecified_bool_type;
|
||||
typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
|
||||
|
||||
static void unspecified_bool_true(unspecified_bool_type_t)
|
||||
{
|
||||
}
|
||||
|
||||
/// Operator returns non-null if there is a non-success error code.
|
||||
operator unspecified_bool_type() const
|
||||
|
@ -120,7 +124,7 @@ public:
|
|||
if (value_ == 0)
|
||||
return 0;
|
||||
else
|
||||
return reinterpret_cast<unspecified_bool_type>(1);
|
||||
return &error_code::unspecified_bool_true;
|
||||
}
|
||||
|
||||
/// Operator to test if the error represents success.
|
||||
|
|
|
@ -35,6 +35,8 @@ inline std::string error_code::message() const
|
|||
return "Already open.";
|
||||
if (*this == error::not_found)
|
||||
return "Not found.";
|
||||
if (*this == error::fd_set_failure)
|
||||
return "The descriptor does not fit into the select call's fd_set.";
|
||||
if (category_ == error::get_ssl_category())
|
||||
return "SSL error.";
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
|
|
|
@ -100,6 +100,10 @@ public:
|
|||
&openssl_operation::do_async_write,
|
||||
this, boost::arg<1>(), boost::arg<2>()
|
||||
);
|
||||
read_ = boost::bind(
|
||||
&openssl_operation::do_async_read,
|
||||
this
|
||||
);
|
||||
handler_= boost::bind(
|
||||
&openssl_operation::async_user_handler,
|
||||
this, boost::arg<1>(), boost::arg<2>()
|
||||
|
@ -122,6 +126,10 @@ public:
|
|||
&openssl_operation::do_sync_write,
|
||||
this, boost::arg<1>(), boost::arg<2>()
|
||||
);
|
||||
read_ = boost::bind(
|
||||
&openssl_operation::do_sync_read,
|
||||
this
|
||||
);
|
||||
handler_ = boost::bind(
|
||||
&openssl_operation::sync_user_handler,
|
||||
this, boost::arg<1>(), boost::arg<2>()
|
||||
|
@ -134,7 +142,7 @@ public:
|
|||
int start()
|
||||
{
|
||||
int rc = primitive_( session_ );
|
||||
int sys_error_code = ERR_get_error();
|
||||
|
||||
bool is_operation_done = (rc > 0);
|
||||
// For connect/accept/shutdown, the operation
|
||||
// is done, when return code is 1
|
||||
|
@ -144,6 +152,8 @@ public:
|
|||
int error_code = !is_operation_done ?
|
||||
::SSL_get_error( session_, rc ) :
|
||||
0;
|
||||
int sys_error_code = ERR_get_error();
|
||||
|
||||
bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
|
||||
bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
|
||||
::BIO_ctrl_pending( ssl_bio_ ));
|
||||
|
@ -211,6 +221,10 @@ public:
|
|||
|
||||
return start();
|
||||
}
|
||||
else if (is_read_needed)
|
||||
{
|
||||
return read_();
|
||||
}
|
||||
}
|
||||
|
||||
// Continue with operation, flush any SSL data out to network...
|
||||
|
@ -222,10 +236,12 @@ private:
|
|||
typedef boost::function<int (const asio::error_code&, int)>
|
||||
int_handler_func;
|
||||
typedef boost::function<int (bool, int)> write_func;
|
||||
typedef boost::function<int ()> read_func;
|
||||
|
||||
ssl_primitive_func primitive_;
|
||||
user_handler_func user_handler_;
|
||||
write_func write_;
|
||||
read_func read_;
|
||||
int_handler_func handler_;
|
||||
|
||||
net_buffer send_buf_; // buffers for network IO
|
||||
|
@ -249,8 +265,15 @@ private:
|
|||
throw asio::system_error(error);
|
||||
}
|
||||
|
||||
int async_user_handler(const asio::error_code& error, int rc)
|
||||
int async_user_handler(asio::error_code error, int rc)
|
||||
{
|
||||
if (rc < 0)
|
||||
{
|
||||
if (!error)
|
||||
error = asio::error::no_recovery;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
user_handler_(error, rc);
|
||||
return 0;
|
||||
}
|
||||
|
@ -315,8 +338,8 @@ private:
|
|||
}
|
||||
|
||||
// OPeration is not done and writing to net has been made...
|
||||
// start reading...
|
||||
do_async_read();
|
||||
// start operation again
|
||||
start();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -339,7 +362,7 @@ private:
|
|||
handler_(error, rc);
|
||||
}
|
||||
|
||||
void do_async_read()
|
||||
int do_async_read()
|
||||
{
|
||||
// Wait for new data
|
||||
socket_.async_read_some
|
||||
|
@ -354,6 +377,7 @@ private:
|
|||
asio::placeholders::bytes_transferred
|
||||
)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void async_read_handler(const asio::error_code& error,
|
||||
|
@ -432,8 +456,8 @@ private:
|
|||
// Finish the operation, with success
|
||||
return rc;
|
||||
|
||||
// Operation is not finished, read data from net...
|
||||
return do_sync_read();
|
||||
// Operation is not finished, start again.
|
||||
return start();
|
||||
}
|
||||
|
||||
int do_sync_read()
|
||||
|
|
|
@ -44,16 +44,15 @@ namespace ssl {
|
|||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Example
|
||||
* To use the SSL stream template with a stream_socket, you would write:
|
||||
* To use the SSL stream template with an ip::tcp::socket, you would write:
|
||||
* @code
|
||||
* asio::io_service io_service;
|
||||
* asio::ssl::context context(io_service, asio::ssl::context::sslv23);
|
||||
* asio::ssl::stream<asio::stream_socket> sock(io_service, context);
|
||||
* asio::ssl::stream<asio::ip::tcp::socket> sock(io_service, context);
|
||||
* @endcode
|
||||
*
|
||||
* @par Concepts:
|
||||
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
|
||||
* Sync_Read_Stream, Sync_Write_Stream.
|
||||
* AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream.
|
||||
*/
|
||||
template <typename Stream, typename Service = stream_service>
|
||||
class stream
|
||||
|
|
|
@ -18,6 +18,6 @@
|
|||
// ASIO_VERSION % 100 is the sub-minor version
|
||||
// ASIO_VERSION / 100 % 1000 is the minor version
|
||||
// ASIO_VERSION / 100000 is the major version
|
||||
#define ASIO_VERSION 308 // 0.3.8
|
||||
#define ASIO_VERSION 309 // 0.3.9
|
||||
|
||||
#endif // ASIO_VERSION_HPP
|
||||
|
|
Loading…
Reference in New Issue