mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-05 16:08:40 +00:00
asio sync
This commit is contained in:
parent
4d4b30700a
commit
2d27cede5f
11 changed files with 94 additions and 23 deletions
|
@ -35,11 +35,16 @@ public:
|
||||||
FD_ZERO(&fd_set_);
|
FD_ZERO(&fd_set_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(socket_type descriptor)
|
bool set(socket_type descriptor)
|
||||||
{
|
{
|
||||||
if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_)
|
if (descriptor < (socket_type)FD_SETSIZE)
|
||||||
max_descriptor_ = descriptor;
|
{
|
||||||
FD_SET(descriptor, &fd_set_);
|
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
|
bool is_set(socket_type descriptor) const
|
||||||
|
|
|
@ -173,8 +173,13 @@ public:
|
||||||
typename operation_map::iterator i = operations_.begin();
|
typename operation_map::iterator i = operations_.begin();
|
||||||
while (i != operations_.end())
|
while (i != operations_.end())
|
||||||
{
|
{
|
||||||
descriptors.set(i->first);
|
Descriptor descriptor = i->first;
|
||||||
++i;
|
++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)
|
inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
|
||||||
|
strcpy_s(target, max_size, source);
|
||||||
|
#else
|
||||||
*target = 0;
|
*target = 0;
|
||||||
strncat(target, source, max_size);
|
strncat(target, source, max_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { gai_clone_flag = 1 << 30 };
|
enum { gai_clone_flag = 1 << 30 };
|
||||||
|
@ -1658,7 +1662,11 @@ inline asio::error_code getnameinfo_emulation(
|
||||||
{
|
{
|
||||||
return ec = asio::error::no_buffer_space;
|
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));
|
sprintf(serv, "%u", ntohs(port));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1677,7 +1685,11 @@ inline asio::error_code getnameinfo_emulation(
|
||||||
{
|
{
|
||||||
return ec = asio::error::no_buffer_space;
|
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));
|
sprintf(serv, "%u", ntohs(port));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
|
#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
|
||||||
::pthread_mutex_unlock(&mutex);
|
::pthread_mutex_unlock(&mutex);
|
||||||
|
|
|
@ -92,7 +92,11 @@
|
||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
# include <sys/poll.h>
|
# include <sys/poll.h>
|
||||||
# include <sys/types.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/socket.h>
|
||||||
# include <sys/uio.h>
|
# include <sys/uio.h>
|
||||||
# include <netinet/in.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;
|
const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
|
||||||
typedef sockaddr socket_addr_type;
|
typedef sockaddr socket_addr_type;
|
||||||
typedef in_addr in4_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;
|
typedef ip_mreq in4_mreq_type;
|
||||||
|
# endif
|
||||||
typedef sockaddr_in sockaddr_in4_type;
|
typedef sockaddr_in sockaddr_in4_type;
|
||||||
typedef in6_addr in6_addr_type;
|
typedef in6_addr in6_addr_type;
|
||||||
typedef ipv6_mreq in6_mreq_type;
|
typedef ipv6_mreq in6_mreq_type;
|
||||||
|
|
|
@ -36,13 +36,17 @@ public:
|
||||||
fd_set_.fd_count = 0;
|
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)
|
for (u_int i = 0; i < fd_set_.fd_count; ++i)
|
||||||
if (fd_set_.fd_array[i] == descriptor)
|
if (fd_set_.fd_array[i] == descriptor)
|
||||||
return;
|
return true;
|
||||||
if (fd_set_.fd_count < win_fd_set_size)
|
if (fd_set_.fd_count < win_fd_set_size)
|
||||||
|
{
|
||||||
fd_set_.fd_array[fd_set_.fd_count++] = descriptor;
|
fd_set_.fd_array[fd_set_.fd_count++] = descriptor;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_set(socket_type descriptor) const
|
bool is_set(socket_type descriptor) const
|
||||||
|
|
|
@ -194,7 +194,10 @@ enum misc_errors
|
||||||
eof,
|
eof,
|
||||||
|
|
||||||
/// Element not found.
|
/// 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
|
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 returns non-null if there is a non-success error code.
|
||||||
operator unspecified_bool_type() const
|
operator unspecified_bool_type() const
|
||||||
|
@ -120,7 +124,7 @@ public:
|
||||||
if (value_ == 0)
|
if (value_ == 0)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return reinterpret_cast<unspecified_bool_type>(1);
|
return &error_code::unspecified_bool_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Operator to test if the error represents success.
|
/// Operator to test if the error represents success.
|
||||||
|
|
|
@ -35,6 +35,8 @@ inline std::string error_code::message() const
|
||||||
return "Already open.";
|
return "Already open.";
|
||||||
if (*this == error::not_found)
|
if (*this == error::not_found)
|
||||||
return "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())
|
if (category_ == error::get_ssl_category())
|
||||||
return "SSL error.";
|
return "SSL error.";
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
|
|
@ -100,6 +100,10 @@ public:
|
||||||
&openssl_operation::do_async_write,
|
&openssl_operation::do_async_write,
|
||||||
this, boost::arg<1>(), boost::arg<2>()
|
this, boost::arg<1>(), boost::arg<2>()
|
||||||
);
|
);
|
||||||
|
read_ = boost::bind(
|
||||||
|
&openssl_operation::do_async_read,
|
||||||
|
this
|
||||||
|
);
|
||||||
handler_= boost::bind(
|
handler_= boost::bind(
|
||||||
&openssl_operation::async_user_handler,
|
&openssl_operation::async_user_handler,
|
||||||
this, boost::arg<1>(), boost::arg<2>()
|
this, boost::arg<1>(), boost::arg<2>()
|
||||||
|
@ -122,6 +126,10 @@ public:
|
||||||
&openssl_operation::do_sync_write,
|
&openssl_operation::do_sync_write,
|
||||||
this, boost::arg<1>(), boost::arg<2>()
|
this, boost::arg<1>(), boost::arg<2>()
|
||||||
);
|
);
|
||||||
|
read_ = boost::bind(
|
||||||
|
&openssl_operation::do_sync_read,
|
||||||
|
this
|
||||||
|
);
|
||||||
handler_ = boost::bind(
|
handler_ = boost::bind(
|
||||||
&openssl_operation::sync_user_handler,
|
&openssl_operation::sync_user_handler,
|
||||||
this, boost::arg<1>(), boost::arg<2>()
|
this, boost::arg<1>(), boost::arg<2>()
|
||||||
|
@ -134,7 +142,7 @@ public:
|
||||||
int start()
|
int start()
|
||||||
{
|
{
|
||||||
int rc = primitive_( session_ );
|
int rc = primitive_( session_ );
|
||||||
int sys_error_code = ERR_get_error();
|
|
||||||
bool is_operation_done = (rc > 0);
|
bool is_operation_done = (rc > 0);
|
||||||
// For connect/accept/shutdown, the operation
|
// For connect/accept/shutdown, the operation
|
||||||
// is done, when return code is 1
|
// is done, when return code is 1
|
||||||
|
@ -144,6 +152,8 @@ public:
|
||||||
int error_code = !is_operation_done ?
|
int error_code = !is_operation_done ?
|
||||||
::SSL_get_error( session_, rc ) :
|
::SSL_get_error( session_, rc ) :
|
||||||
0;
|
0;
|
||||||
|
int sys_error_code = ERR_get_error();
|
||||||
|
|
||||||
bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
|
bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
|
||||||
bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
|
bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
|
||||||
::BIO_ctrl_pending( ssl_bio_ ));
|
::BIO_ctrl_pending( ssl_bio_ ));
|
||||||
|
@ -211,6 +221,10 @@ public:
|
||||||
|
|
||||||
return start();
|
return start();
|
||||||
}
|
}
|
||||||
|
else if (is_read_needed)
|
||||||
|
{
|
||||||
|
return read_();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue with operation, flush any SSL data out to network...
|
// Continue with operation, flush any SSL data out to network...
|
||||||
|
@ -222,10 +236,12 @@ private:
|
||||||
typedef boost::function<int (const asio::error_code&, int)>
|
typedef boost::function<int (const asio::error_code&, int)>
|
||||||
int_handler_func;
|
int_handler_func;
|
||||||
typedef boost::function<int (bool, int)> write_func;
|
typedef boost::function<int (bool, int)> write_func;
|
||||||
|
typedef boost::function<int ()> read_func;
|
||||||
|
|
||||||
ssl_primitive_func primitive_;
|
ssl_primitive_func primitive_;
|
||||||
user_handler_func user_handler_;
|
user_handler_func user_handler_;
|
||||||
write_func write_;
|
write_func write_;
|
||||||
|
read_func read_;
|
||||||
int_handler_func handler_;
|
int_handler_func handler_;
|
||||||
|
|
||||||
net_buffer send_buf_; // buffers for network IO
|
net_buffer send_buf_; // buffers for network IO
|
||||||
|
@ -249,8 +265,15 @@ private:
|
||||||
throw asio::system_error(error);
|
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);
|
user_handler_(error, rc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -315,8 +338,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// OPeration is not done and writing to net has been made...
|
// OPeration is not done and writing to net has been made...
|
||||||
// start reading...
|
// start operation again
|
||||||
do_async_read();
|
start();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -339,7 +362,7 @@ private:
|
||||||
handler_(error, rc);
|
handler_(error, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_async_read()
|
int do_async_read()
|
||||||
{
|
{
|
||||||
// Wait for new data
|
// Wait for new data
|
||||||
socket_.async_read_some
|
socket_.async_read_some
|
||||||
|
@ -354,6 +377,7 @@ private:
|
||||||
asio::placeholders::bytes_transferred
|
asio::placeholders::bytes_transferred
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void async_read_handler(const asio::error_code& error,
|
void async_read_handler(const asio::error_code& error,
|
||||||
|
@ -432,8 +456,8 @@ private:
|
||||||
// Finish the operation, with success
|
// Finish the operation, with success
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
// Operation is not finished, read data from net...
|
// Operation is not finished, start again.
|
||||||
return do_sync_read();
|
return start();
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_sync_read()
|
int do_sync_read()
|
||||||
|
|
|
@ -44,16 +44,15 @@ namespace ssl {
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
* @par Example
|
* @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
|
* @code
|
||||||
* asio::io_service io_service;
|
* asio::io_service io_service;
|
||||||
* asio::ssl::context context(io_service, asio::ssl::context::sslv23);
|
* 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
|
* @endcode
|
||||||
*
|
*
|
||||||
* @par Concepts:
|
* @par Concepts:
|
||||||
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
|
* AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream.
|
||||||
* Sync_Read_Stream, Sync_Write_Stream.
|
|
||||||
*/
|
*/
|
||||||
template <typename Stream, typename Service = stream_service>
|
template <typename Stream, typename Service = stream_service>
|
||||||
class stream
|
class stream
|
||||||
|
|
|
@ -18,6 +18,6 @@
|
||||||
// ASIO_VERSION % 100 is the sub-minor version
|
// ASIO_VERSION % 100 is the sub-minor version
|
||||||
// ASIO_VERSION / 100 % 1000 is the minor version
|
// ASIO_VERSION / 100 % 1000 is the minor version
|
||||||
// ASIO_VERSION / 100000 is the major 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
|
#endif // ASIO_VERSION_HPP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue