asio sync

This commit is contained in:
Marcos Pinto 2007-12-31 07:11:07 +00:00
parent 4d4b30700a
commit 2d27cede5f
11 changed files with 94 additions and 23 deletions

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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__)

View File

@ -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()

View File

@ -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

View File

@ -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