diff --git a/example/allocation/Jamfile b/example/allocation/Jamfile index c1d3f60c..84711cc7 100644 --- a/example/allocation/Jamfile +++ b/example/allocation/Jamfile @@ -21,7 +21,8 @@ if $(UNIX) } exe server - : server.cpp + : @boost/libs/system/build/boost_system + server.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/allocation/server.cpp b/example/allocation/server.cpp index 0d71e3de..085660ca 100644 --- a/example/allocation/server.cpp +++ b/example/allocation/server.cpp @@ -140,7 +140,8 @@ public: boost::asio::placeholders::bytes_transferred))); } - void handle_read(const boost::asio::error& error, size_t bytes_transferred) + void handle_read(const boost::system::error_code& error, + size_t bytes_transferred) { if (!error) { @@ -153,7 +154,7 @@ public: } } - void handle_write(const boost::asio::error& error) + void handle_write(const boost::system::error_code& error) { if (!error) { @@ -192,7 +193,8 @@ public: boost::asio::placeholders::error)); } - void handle_accept(session_ptr new_session, const boost::asio::error& error) + void handle_accept(session_ptr new_session, + const boost::system::error_code& error) { if (!error) { @@ -226,10 +228,6 @@ int main(int argc, char* argv[]) io_service.run(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/buffers/Jamfile b/example/buffers/Jamfile index 5db60966..a2f23be4 100644 --- a/example/buffers/Jamfile +++ b/example/buffers/Jamfile @@ -21,7 +21,8 @@ if $(UNIX) } exe server - : reference_counted.cpp + : @boost/libs/system/build/boost_system + reference_counted.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/buffers/reference_counted.cpp b/example/buffers/reference_counted.cpp index bdcf9e2c..bcd11a16 100644 --- a/example/buffers/reference_counted.cpp +++ b/example/buffers/reference_counted.cpp @@ -85,7 +85,8 @@ public: boost::asio::placeholders::error)); } - void handle_accept(session_ptr new_session, const boost::asio::error& error) + void handle_accept(session_ptr new_session, + const boost::system::error_code& error) { if (!error) { diff --git a/example/chat/Jamfile b/example/chat/Jamfile index 425a1192..13519886 100644 --- a/example/chat/Jamfile +++ b/example/chat/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) exe chat_client : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system chat_client.cpp : $(BOOST_ROOT) ../../../.. @@ -34,6 +35,7 @@ exe chat_client exe chat_server : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system chat_server.cpp : $(BOOST_ROOT) ../../../.. diff --git a/example/chat/chat_client.cpp b/example/chat/chat_client.cpp index 5eb7d96f..081d0bf0 100644 --- a/example/chat/chat_client.cpp +++ b/example/chat/chat_client.cpp @@ -46,7 +46,7 @@ public: private: - void handle_connect(const boost::asio::error& error, + void handle_connect(const boost::system::error_code& error, tcp::resolver::iterator endpoint_iterator) { if (!error) @@ -66,7 +66,7 @@ private: } } - void handle_read_header(const boost::asio::error& error) + void handle_read_header(const boost::system::error_code& error) { if (!error && read_msg_.decode_header()) { @@ -81,7 +81,7 @@ private: } } - void handle_read_body(const boost::asio::error& error) + void handle_read_body(const boost::system::error_code& error) { if (!error) { @@ -112,7 +112,7 @@ private: } } - void handle_write(const boost::asio::error& error) + void handle_write(const boost::system::error_code& error) { if (!error) { @@ -178,10 +178,6 @@ int main(int argc, char* argv[]) c.close(); t.join(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/chat/chat_server.cpp b/example/chat/chat_server.cpp index dd25ca15..e9afb0e4 100644 --- a/example/chat/chat_server.cpp +++ b/example/chat/chat_server.cpp @@ -112,7 +112,7 @@ public: } } - void handle_read_header(const boost::asio::error& error) + void handle_read_header(const boost::system::error_code& error) { if (!error && read_msg_.decode_header()) { @@ -127,7 +127,7 @@ public: } } - void handle_read_body(const boost::asio::error& error) + void handle_read_body(const boost::system::error_code& error) { if (!error) { @@ -143,7 +143,7 @@ public: } } - void handle_write(const boost::asio::error& error) + void handle_write(const boost::system::error_code& error) { if (!error) { @@ -188,7 +188,8 @@ public: boost::asio::placeholders::error)); } - void handle_accept(chat_session_ptr session, const boost::asio::error& error) + void handle_accept(chat_session_ptr session, + const boost::system::error_code& error) { if (!error) { @@ -234,10 +235,6 @@ int main(int argc, char* argv[]) io_service.run(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/echo/Jamfile b/example/echo/Jamfile index c0c4fa2e..e2847e0e 100644 --- a/example/echo/Jamfile +++ b/example/echo/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) template asio_echo_example : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/echo/async_tcp_echo_server.cpp b/example/echo/async_tcp_echo_server.cpp index f370dc0e..4bd73a98 100644 --- a/example/echo/async_tcp_echo_server.cpp +++ b/example/echo/async_tcp_echo_server.cpp @@ -36,7 +36,8 @@ public: boost::asio::placeholders::bytes_transferred)); } - void handle_read(const boost::asio::error& error, size_t bytes_transferred) + void handle_read(const boost::system::error_code& error, + size_t bytes_transferred) { if (!error) { @@ -51,7 +52,7 @@ public: } } - void handle_write(const boost::asio::error& error) + void handle_write(const boost::system::error_code& error) { if (!error) { @@ -85,7 +86,8 @@ public: boost::asio::placeholders::error)); } - void handle_accept(session* new_session, const boost::asio::error& error) + void handle_accept(session* new_session, + const boost::system::error_code& error) { if (!error) { @@ -123,10 +125,6 @@ int main(int argc, char* argv[]) io_service.run(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/echo/async_udp_echo_server.cpp b/example/echo/async_udp_echo_server.cpp index a39c5cb2..0057fd84 100644 --- a/example/echo/async_udp_echo_server.cpp +++ b/example/echo/async_udp_echo_server.cpp @@ -29,7 +29,8 @@ public: boost::asio::placeholders::bytes_transferred)); } - void handle_receive_from(const boost::asio::error& error, size_t bytes_recvd) + void handle_receive_from(const boost::system::error_code& error, + size_t bytes_recvd) { if (!error && bytes_recvd > 0) { @@ -49,7 +50,7 @@ public: } } - void handle_send_to(const boost::asio::error& error, size_t bytes_sent) + void handle_send_to(const boost::system::error_code& error, size_t bytes_sent) { socket_.async_receive_from( boost::asio::buffer(data_, max_length), sender_endpoint_, @@ -83,10 +84,6 @@ int main(int argc, char* argv[]) io_service.run(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/echo/blocking_tcp_echo_client.cpp b/example/echo/blocking_tcp_echo_client.cpp index 7321673d..831a9d0c 100644 --- a/example/echo/blocking_tcp_echo_client.cpp +++ b/example/echo/blocking_tcp_echo_client.cpp @@ -50,10 +50,6 @@ int main(int argc, char* argv[]) std::cout.write(reply, reply_length); std::cout << "\n"; } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/echo/blocking_tcp_echo_server.cpp b/example/echo/blocking_tcp_echo_server.cpp index 82213f45..9c41bb9d 100644 --- a/example/echo/blocking_tcp_echo_server.cpp +++ b/example/echo/blocking_tcp_echo_server.cpp @@ -29,9 +29,8 @@ void session(socket_ptr sock) { char data[max_length]; - boost::asio::error error; - size_t length = sock->read_some( - boost::asio::buffer(data), boost::asio::assign_error(error)); + boost::system::error_code error; + size_t length = sock->read_some(boost::asio::buffer(data), error); if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) @@ -40,10 +39,6 @@ void session(socket_ptr sock) boost::asio::write(*sock, boost::asio::buffer(data, length)); } } - catch (boost::asio::error& e) - { - std::cerr << "Error in thread: " << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception in thread: " << e.what() << "\n"; @@ -76,10 +71,6 @@ int main(int argc, char* argv[]) using namespace std; // For atoi. server(io_service, atoi(argv[1])); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/echo/blocking_udp_echo_client.cpp b/example/echo/blocking_udp_echo_client.cpp index 829e780a..7f6f712e 100644 --- a/example/echo/blocking_udp_echo_client.cpp +++ b/example/echo/blocking_udp_echo_client.cpp @@ -50,10 +50,6 @@ int main(int argc, char* argv[]) std::cout.write(reply, reply_length); std::cout << "\n"; } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/echo/blocking_udp_echo_server.cpp b/example/echo/blocking_udp_echo_server.cpp index b1889d72..10a5c4f9 100644 --- a/example/echo/blocking_udp_echo_server.cpp +++ b/example/echo/blocking_udp_echo_server.cpp @@ -44,10 +44,6 @@ int main(int argc, char* argv[]) using namespace std; // For atoi. server(io_service, atoi(argv[1])); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/http/client/Jamfile b/example/http/client/Jamfile index f0429d51..f4092c6d 100644 --- a/example/http/client/Jamfile +++ b/example/http/client/Jamfile @@ -21,7 +21,8 @@ if $(UNIX) } exe async_client - : async_client.cpp + : @boost/libs/system/build/boost_system + async_client.cpp : $(BOOST_ROOT) ../../../../.. BOOST_ALL_NO_LIB=1 @@ -32,7 +33,8 @@ exe async_client ; exe sync_client - : sync_client.cpp + : @boost/libs/system/build/boost_system + sync_client.cpp : $(BOOST_ROOT) ../../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/http/client/async_client.cpp b/example/http/client/async_client.cpp index 99dc8361..29d182a7 100644 --- a/example/http/client/async_client.cpp +++ b/example/http/client/async_client.cpp @@ -44,7 +44,7 @@ public: } private: - void handle_resolve(const boost::asio::error& err, + void handle_resolve(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator) { if (!err) @@ -62,7 +62,7 @@ private: } } - void handle_connect(const boost::asio::error& err, + void handle_connect(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator) { if (!err) @@ -87,7 +87,7 @@ private: } } - void handle_write_request(const boost::asio::error& err) + void handle_write_request(const boost::system::error_code& err) { if (!err) { @@ -102,7 +102,7 @@ private: } } - void handle_read_status_line(const boost::asio::error& err) + void handle_read_status_line(const boost::system::error_code& err) { if (!err) { @@ -137,7 +137,7 @@ private: } } - void handle_read_headers(const boost::asio::error& err) + void handle_read_headers(const boost::system::error_code& err) { if (!err) { @@ -164,7 +164,7 @@ private: } } - void handle_read_content(const boost::asio::error& err) + void handle_read_content(const boost::system::error_code& err) { if (!err) { diff --git a/example/http/client/sync_client.cpp b/example/http/client/sync_client.cpp index f416cdaf..a90a0a27 100644 --- a/example/http/client/sync_client.cpp +++ b/example/http/client/sync_client.cpp @@ -38,11 +38,11 @@ int main(int argc, char* argv[]) // Try each endpoint until we successfully establish a connection. tcp::socket socket(io_service); - boost::asio::error error = boost::asio::error::host_not_found; + boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpoint_iterator != end) { socket.close(); - socket.connect(*endpoint_iterator++, boost::asio::assign_error(error)); + socket.connect(*endpoint_iterator++, error); } if (error) throw error; @@ -98,8 +98,7 @@ int main(int argc, char* argv[]) // Read until EOF, writing data to output as we go. while (boost::asio::read(socket, response, - boost::asio::transfer_at_least(1), - boost::asio::assign_error(error))) + boost::asio::transfer_at_least(1), error)) std::cout << &response; if (error != boost::asio::error::eof) throw error; diff --git a/example/http/server/Jamfile b/example/http/server/Jamfile index 2b55e128..9019835c 100644 --- a/example/http/server/Jamfile +++ b/example/http/server/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) exe http_server : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system connection.cpp connection_manager.cpp mime_types.cpp diff --git a/example/http/server/connection.cpp b/example/http/server/connection.cpp index 745bcb49..21117d2b 100644 --- a/example/http/server/connection.cpp +++ b/example/http/server/connection.cpp @@ -43,7 +43,7 @@ void connection::stop() socket_.close(); } -void connection::handle_read(const boost::asio::error& e, +void connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred) { if (!e) @@ -80,7 +80,7 @@ void connection::handle_read(const boost::asio::error& e, } } -void connection::handle_write(const boost::asio::error& e) +void connection::handle_write(const boost::system::error_code& e) { if (e != boost::asio::error::operation_aborted) { diff --git a/example/http/server/connection.hpp b/example/http/server/connection.hpp index 3a7b72a7..27733490 100644 --- a/example/http/server/connection.hpp +++ b/example/http/server/connection.hpp @@ -47,10 +47,11 @@ public: private: /// Handle completion of a read operation. - void handle_read(const boost::asio::error& e, std::size_t bytes_transferred); + void handle_read(const boost::system::error_code& e, + std::size_t bytes_transferred); /// Handle completion of a write operation. - void handle_write(const boost::asio::error& e); + void handle_write(const boost::system::error_code& e); /// Socket for the connection. boost::asio::ip::tcp::socket socket_; diff --git a/example/http/server/posix_main.cpp b/example/http/server/posix_main.cpp index 235657ca..2bfb2050 100644 --- a/example/http/server/posix_main.cpp +++ b/example/http/server/posix_main.cpp @@ -62,10 +62,6 @@ int main(int argc, char* argv[]) s.stop(); t.join(); } - catch (boost::asio::error& e) - { - std::cerr << "asio error: " << e << "\n"; - } catch (std::exception& e) { std::cerr << "exception: " << e.what() << "\n"; diff --git a/example/http/server/server.cpp b/example/http/server/server.cpp index ded42556..f5c90fae 100644 --- a/example/http/server/server.cpp +++ b/example/http/server/server.cpp @@ -52,7 +52,7 @@ void server::stop() io_service_.post(boost::bind(&server::handle_stop, this)); } -void server::handle_accept(const boost::asio::error& e) +void server::handle_accept(const boost::system::error_code& e) { if (!e) { diff --git a/example/http/server/server.hpp b/example/http/server/server.hpp index 1cd58a65..852fc4df 100644 --- a/example/http/server/server.hpp +++ b/example/http/server/server.hpp @@ -39,7 +39,7 @@ public: private: /// Handle completion of an asynchronous accept operation. - void handle_accept(const boost::asio::error& e); + void handle_accept(const boost::system::error_code& e); /// Handle a request to stop the server. void handle_stop(); diff --git a/example/http/server/win_main.cpp b/example/http/server/win_main.cpp index 88b03428..e516ed7d 100644 --- a/example/http/server/win_main.cpp +++ b/example/http/server/win_main.cpp @@ -59,10 +59,6 @@ int main(int argc, char* argv[]) // Run the server until stopped. s.run(); } - catch (boost::asio::error& e) - { - std::cerr << "asio error: " << e << "\n"; - } catch (std::exception& e) { std::cerr << "exception: " << e.what() << "\n"; diff --git a/example/iostreams/Jamfile b/example/iostreams/Jamfile index 25536dba..c388d179 100644 --- a/example/iostreams/Jamfile +++ b/example/iostreams/Jamfile @@ -21,7 +21,8 @@ if $(UNIX) } exe daytime_client - : daytime_client.cpp + : @boost/libs/system/build/boost_system + daytime_client.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 @@ -32,7 +33,8 @@ exe daytime_client ; exe daytime_server - : daytime_server.cpp + : @boost/libs/system/build/boost_system + daytime_server.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/iostreams/daytime_client.cpp b/example/iostreams/daytime_client.cpp index cba90d96..e0ddfed4 100644 --- a/example/iostreams/daytime_client.cpp +++ b/example/iostreams/daytime_client.cpp @@ -29,9 +29,9 @@ int main(int argc, char* argv[]) std::getline(s, line); std::cout << line << std::endl; } - catch (boost::asio::error& e) + catch (std::exception& e) { - std::cout << e << std::endl; + std::cout << "Exception: " << e.what() << std::endl; } return 0; diff --git a/example/multicast/Jamfile b/example/multicast/Jamfile index ec4b8dde..70820775 100644 --- a/example/multicast/Jamfile +++ b/example/multicast/Jamfile @@ -21,7 +21,8 @@ if $(UNIX) } exe receiver - : receiver.cpp + : @boost/libs/system/build/boost_system + receiver.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 @@ -32,7 +33,8 @@ exe receiver ; exe sender - : sender.cpp + : @boost/libs/system/build/boost_system + sender.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/multicast/receiver.cpp b/example/multicast/receiver.cpp index 9b1e35aa..6cee4927 100644 --- a/example/multicast/receiver.cpp +++ b/example/multicast/receiver.cpp @@ -41,7 +41,8 @@ public: boost::asio::placeholders::bytes_transferred)); } - void handle_receive_from(const boost::asio::error& error, size_t bytes_recvd) + void handle_receive_from(const boost::system::error_code& error, + size_t bytes_recvd) { if (!error) { diff --git a/example/multicast/sender.cpp b/example/multicast/sender.cpp index ed780d8f..0e83e084 100644 --- a/example/multicast/sender.cpp +++ b/example/multicast/sender.cpp @@ -38,7 +38,7 @@ public: boost::asio::placeholders::error)); } - void handle_send_to(const boost::asio::error& error) + void handle_send_to(const boost::system::error_code& error) { if (!error && message_count_ < max_message_count) { @@ -49,7 +49,7 @@ public: } } - void handle_timeout(const boost::asio::error& error) + void handle_timeout(const boost::system::error_code& error) { if (!error) { @@ -90,10 +90,6 @@ int main(int argc, char* argv[]) sender s(io_service, boost::asio::ip::address::from_string(argv[1])); io_service.run(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/serialization/Jamfile b/example/serialization/Jamfile index 5960d571..3d23d957 100644 --- a/example/serialization/Jamfile +++ b/example/serialization/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) exe client : @boost/libs/serialization/build/boost_serialization + @boost/libs/system/build/boost_system client.cpp : $(BOOST_ROOT) ../../../.. @@ -34,6 +35,7 @@ exe client exe server : @boost/libs/serialization/build/boost_serialization + @boost/libs/system/build/boost_system server.cpp : $(BOOST_ROOT) ../../../.. diff --git a/example/serialization/client.cpp b/example/serialization/client.cpp index 9d8a0502..fa117ca4 100644 --- a/example/serialization/client.cpp +++ b/example/serialization/client.cpp @@ -41,7 +41,7 @@ public: } /// Handle completion of a connect operation. - void handle_connect(const boost::asio::error& e, + void handle_connect(const boost::system::error_code& e, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) { if (!e) @@ -72,7 +72,7 @@ public: } /// Handle completion of a read operation. - void handle_read(const boost::asio::error& e) + void handle_read(const boost::system::error_code& e) { if (!e) { diff --git a/example/serialization/connection.hpp b/example/serialization/connection.hpp index 4f27510c..c04ca0fc 100644 --- a/example/serialization/connection.hpp +++ b/example/serialization/connection.hpp @@ -64,7 +64,7 @@ public: if (!header_stream || header_stream.str().size() != header_length) { // Something went wrong, inform the caller. - boost::asio::error error(boost::asio::error::invalid_argument); + boost::system::error_code error(boost::asio::error::invalid_argument); socket_.io_service().post(boost::bind(handler, error)); return; } @@ -83,7 +83,9 @@ public: void async_read(T& t, Handler handler) { // Issue a read operation to read exactly the number of bytes in a header. - void (connection::*f)(const boost::asio::error&, T&, boost::tuple) + void (connection::*f)( + const boost::system::error_code&, + T&, boost::tuple) = &connection::handle_read_header; boost::asio::async_read(socket_, boost::asio::buffer(inbound_header_), boost::bind(f, @@ -95,8 +97,8 @@ public: /// a tuple since boost::bind seems to have trouble binding a function object /// created using boost::bind as a parameter. template - void handle_read_header(const boost::asio::error& e, T& t, - boost::tuple handler) + void handle_read_header(const boost::system::error_code& e, + T& t, boost::tuple handler) { if (e) { @@ -110,14 +112,16 @@ public: if (!(is >> std::hex >> inbound_data_size)) { // Header doesn't seem to be valid. Inform the caller. - boost::asio::error error(boost::asio::error::invalid_argument); + boost::system::error_code error(boost::asio::error::invalid_argument); boost::get<0>(handler)(error); return; } // Start an asynchronous call to receive the data. inbound_data_.resize(inbound_data_size); - void (connection::*f)(const boost::asio::error&, T&, boost::tuple) + void (connection::*f)( + const boost::system::error_code&, + T&, boost::tuple) = &connection::handle_read_data; boost::asio::async_read(socket_, boost::asio::buffer(inbound_data_), boost::bind(f, this, @@ -127,8 +131,8 @@ public: /// Handle a completed read of message data. template - void handle_read_data(const boost::asio::error& e, T& t, - boost::tuple handler) + void handle_read_data(const boost::system::error_code& e, + T& t, boost::tuple handler) { if (e) { @@ -147,7 +151,7 @@ public: catch (std::exception& e) { // Unable to decode data. - boost::asio::error error(boost::asio::error::invalid_argument); + boost::system::error_code error(boost::asio::error::invalid_argument); boost::get<0>(handler)(error); return; } diff --git a/example/serialization/server.cpp b/example/serialization/server.cpp index d37c4f17..0479a688 100644 --- a/example/serialization/server.cpp +++ b/example/serialization/server.cpp @@ -62,7 +62,7 @@ public: } /// Handle completion of a accept operation. - void handle_accept(const boost::asio::error& e, connection_ptr conn) + void handle_accept(const boost::system::error_code& e, connection_ptr conn) { if (!e) { @@ -89,7 +89,7 @@ public: } /// Handle completion of a write operation. - void handle_write(const boost::asio::error& e, connection_ptr conn) + void handle_write(const boost::system::error_code& e, connection_ptr conn) { // Nothing to do. The socket will be closed automatically when the last // reference to the connection object goes away. diff --git a/example/services/Jamfile b/example/services/Jamfile index 71cab7c2..b30104bf 100644 --- a/example/services/Jamfile +++ b/example/services/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) exe daytime_client : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system daytime_client.cpp : $(BOOST_ROOT) ../../../.. diff --git a/example/services/daytime_client.cpp b/example/services/daytime_client.cpp index b7695eee..ad1d9c75 100644 --- a/example/services/daytime_client.cpp +++ b/example/services/daytime_client.cpp @@ -19,7 +19,7 @@ typedef boost::asio::basic_stream_socket@boost/libs/system/build/boost_system + client.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 @@ -34,7 +35,8 @@ exe client ; exe server - : server.cpp + : @boost/libs/system/build/boost_system + server.cpp : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/ssl/client.cpp b/example/ssl/client.cpp index 64a36322..743727fb 100644 --- a/example/ssl/client.cpp +++ b/example/ssl/client.cpp @@ -29,7 +29,7 @@ public: boost::asio::placeholders::error, ++endpoint_iterator)); } - void handle_connect(const boost::asio::error& error, + void handle_connect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) { if (!error) @@ -52,7 +52,7 @@ public: } } - void handle_handshake(const boost::asio::error& error) + void handle_handshake(const boost::system::error_code& error) { if (!error) { @@ -72,7 +72,8 @@ public: } } - void handle_write(const boost::asio::error& error, size_t bytes_transferred) + void handle_write(const boost::system::error_code& error, + size_t bytes_transferred) { if (!error) { @@ -88,7 +89,8 @@ public: } } - void handle_read(const boost::asio::error& error, size_t bytes_transferred) + void handle_read(const boost::system::error_code& error, + size_t bytes_transferred) { if (!error) { @@ -132,10 +134,6 @@ int main(int argc, char* argv[]) io_service.run(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/ssl/server.cpp b/example/ssl/server.cpp index 22102ddf..37f759c5 100644 --- a/example/ssl/server.cpp +++ b/example/ssl/server.cpp @@ -36,7 +36,7 @@ public: boost::asio::placeholders::error)); } - void handle_handshake(const boost::asio::error& error) + void handle_handshake(const boost::system::error_code& error) { if (!error) { @@ -51,7 +51,8 @@ public: } } - void handle_read(const boost::asio::error& error, size_t bytes_transferred) + void handle_read(const boost::system::error_code& error, + size_t bytes_transferred) { if (!error) { @@ -66,7 +67,7 @@ public: } } - void handle_write(const boost::asio::error& error) + void handle_write(const boost::system::error_code& error) { if (!error) { @@ -116,7 +117,8 @@ public: return "test"; } - void handle_accept(session* new_session, const boost::asio::error& error) + void handle_accept(session* new_session, + const boost::system::error_code& error) { if (!error) { @@ -155,10 +157,6 @@ int main(int argc, char* argv[]) io_service.run(); } - catch (boost::asio::error& e) - { - std::cerr << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/timeouts/Jamfile b/example/timeouts/Jamfile index 710c69b4..f92fd749 100644 --- a/example/timeouts/Jamfile +++ b/example/timeouts/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) template asio_timeouts_example : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/timeouts/accept_timeout.cpp b/example/timeouts/accept_timeout.cpp index 0d90298e..0ba53ed1 100644 --- a/example/timeouts/accept_timeout.cpp +++ b/example/timeouts/accept_timeout.cpp @@ -32,7 +32,7 @@ public: timer_.async_wait(boost::bind(&accept_handler::close, this)); } - void handle_accept(const error& err) + void handle_accept(const boost::system::error_code& err) { if (err) { @@ -64,10 +64,6 @@ int main() accept_handler ah(ios); ios.run(); } - catch (boost::asio::error& e) - { - std::cerr << "Exception: " << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/timeouts/connect_timeout.cpp b/example/timeouts/connect_timeout.cpp index 9980136a..5604293d 100644 --- a/example/timeouts/connect_timeout.cpp +++ b/example/timeouts/connect_timeout.cpp @@ -32,7 +32,7 @@ public: timer_.async_wait(boost::bind(&connect_handler::close, this)); } - void handle_connect(const error& err) + void handle_connect(const boost::system::error_code& err) { if (err) { @@ -75,10 +75,6 @@ int main() ios.run(); } - catch (boost::asio::error& e) - { - std::cerr << "Exception: " << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/timeouts/datagram_receive_timeout.cpp b/example/timeouts/datagram_receive_timeout.cpp index 6c1ffb16..2cfa67ca 100644 --- a/example/timeouts/datagram_receive_timeout.cpp +++ b/example/timeouts/datagram_receive_timeout.cpp @@ -33,7 +33,7 @@ public: timer_.async_wait(boost::bind(&datagram_handler::close, this)); } - void handle_receive_from(const error& err, size_t length) + void handle_receive_from(const boost::system::error_code& err, size_t length) { if (err) { @@ -67,10 +67,6 @@ int main() datagram_handler dh(ios); ios.run(); } - catch (boost::asio::error& e) - { - std::cerr << "Exception: " << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/timeouts/stream_receive_timeout.cpp b/example/timeouts/stream_receive_timeout.cpp index fe2f0d99..1bccc3e4 100644 --- a/example/timeouts/stream_receive_timeout.cpp +++ b/example/timeouts/stream_receive_timeout.cpp @@ -29,7 +29,7 @@ public: boost::asio::placeholders::error)); } - void handle_accept(const error& err) + void handle_accept(const boost::system::error_code& err) { if (err) { @@ -47,7 +47,7 @@ public: } } - void handle_recv(const error& err) + void handle_recv(const boost::system::error_code& err) { if (err) { @@ -91,10 +91,6 @@ int main() ios.run(); } - catch (boost::asio::error& e) - { - std::cerr << "Exception: " << e << "\n"; - } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; diff --git a/example/timers/Jamfile b/example/timers/Jamfile index a6d943f2..fc6f1c0c 100644 --- a/example/timers/Jamfile +++ b/example/timers/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) template asio_timers_example : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/timers/tick_count_timer.cpp b/example/timers/tick_count_timer.cpp index 180f2a33..2ea9fc78 100644 --- a/example/timers/tick_count_timer.cpp +++ b/example/timers/tick_count_timer.cpp @@ -85,7 +85,7 @@ struct tick_count_traits typedef boost::asio::basic_deadline_timer< DWORD, tick_count_traits> tick_count_timer; -void handle_timeout(const boost::asio::error&) +void handle_timeout(const boost::system::error_code&) { std::cout << "handle_timeout\n"; } diff --git a/example/timers/time_t_timer.cpp b/example/timers/time_t_timer.cpp index 5ca32093..e2272407 100644 --- a/example/timers/time_t_timer.cpp +++ b/example/timers/time_t_timer.cpp @@ -60,7 +60,7 @@ struct time_t_traits typedef boost::asio::basic_deadline_timer< std::time_t, time_t_traits> time_t_timer; -void handle_timeout(const boost::asio::error&) +void handle_timeout(const boost::system::error_code&) { std::cout << "handle_timeout\n"; } diff --git a/example/tutorial/Jamfile b/example/tutorial/Jamfile index 9f76df83..a8c23c96 100644 --- a/example/tutorial/Jamfile +++ b/example/tutorial/Jamfile @@ -22,6 +22,7 @@ if $(UNIX) template asio_tutorial : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system : $(BOOST_ROOT) ../../../.. BOOST_ALL_NO_LIB=1 diff --git a/example/tutorial/daytime1/client.cpp b/example/tutorial/daytime1/client.cpp index 53dc68b9..6e92201b 100644 --- a/example/tutorial/daytime1/client.cpp +++ b/example/tutorial/daytime1/client.cpp @@ -32,11 +32,11 @@ int main(int argc, char* argv[]) tcp::resolver::iterator end; tcp::socket socket(io_service); - boost::asio::error error = boost::asio::error::host_not_found; + boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpoint_iterator != end) { socket.close(); - socket.connect(*endpoint_iterator++, boost::asio::assign_error(error)); + socket.connect(*endpoint_iterator++, error); } if (error) throw error; @@ -44,10 +44,9 @@ int main(int argc, char* argv[]) for (;;) { boost::array buf; - boost::asio::error error; + boost::system::error_code error; - size_t len = socket.read_some( - boost::asio::buffer(buf), boost::asio::assign_error(error)); + size_t len = socket.read_some(boost::asio::buffer(buf), error); if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. diff --git a/example/tutorial/daytime2/server.cpp b/example/tutorial/daytime2/server.cpp index abe17d5c..741d335f 100644 --- a/example/tutorial/daytime2/server.cpp +++ b/example/tutorial/daytime2/server.cpp @@ -37,8 +37,9 @@ int main() std::string message = make_daytime_string(); + boost::system::error_code ignored_error; boost::asio::write(socket, boost::asio::buffer(message), - boost::asio::transfer_all(), boost::asio::ignore_error()); + boost::asio::transfer_all(), ignored_error); } } catch (std::exception& e) diff --git a/example/tutorial/daytime3/server.cpp b/example/tutorial/daytime3/server.cpp index 39a0e0b1..d5957fa9 100644 --- a/example/tutorial/daytime3/server.cpp +++ b/example/tutorial/daytime3/server.cpp @@ -57,7 +57,7 @@ private: { } - void handle_write(const boost::asio::error& /*error*/, + void handle_write(const boost::system::error_code& /*error*/, size_t /*bytes_transferred*/) { } @@ -87,7 +87,7 @@ private: } void handle_accept(tcp_connection::pointer new_connection, - const boost::asio::error& error) + const boost::system::error_code& error) { if (!error) { diff --git a/example/tutorial/daytime5/server.cpp b/example/tutorial/daytime5/server.cpp index 3334aa55..9efc1983 100644 --- a/example/tutorial/daytime5/server.cpp +++ b/example/tutorial/daytime5/server.cpp @@ -35,17 +35,18 @@ int main() { boost::array recv_buf; udp::endpoint remote_endpoint; - boost::asio::error error; + boost::system::error_code error; socket.receive_from(boost::asio::buffer(recv_buf), - remote_endpoint, 0, boost::asio::assign_error(error)); + remote_endpoint, 0, error); if (error && error != boost::asio::error::message_size) throw error; std::string message = make_daytime_string(); + boost::system::error_code ignored_error; socket.send_to(boost::asio::buffer(message), - remote_endpoint, 0, boost::asio::ignore_error()); + remote_endpoint, 0, ignored_error); } } catch (std::exception& e) diff --git a/example/tutorial/daytime6/server.cpp b/example/tutorial/daytime6/server.cpp index 46d2a182..ba5fa2f8 100644 --- a/example/tutorial/daytime6/server.cpp +++ b/example/tutorial/daytime6/server.cpp @@ -44,7 +44,7 @@ private: boost::asio::placeholders::bytes_transferred)); } - void handle_receive(const boost::asio::error& error, + void handle_receive(const boost::system::error_code& error, std::size_t /*bytes_transferred*/) { if (!error || error == boost::asio::error::message_size) @@ -62,7 +62,8 @@ private: } void handle_send(boost::shared_ptr /*message*/, - const boost::asio::error& /*error*/, std::size_t /*bytes_transferred*/) + const boost::system::error_code& /*error*/, + std::size_t /*bytes_transferred*/) { } diff --git a/example/tutorial/daytime7/server.cpp b/example/tutorial/daytime7/server.cpp index 9e247af7..d1a5a002 100644 --- a/example/tutorial/daytime7/server.cpp +++ b/example/tutorial/daytime7/server.cpp @@ -86,7 +86,7 @@ private: } void handle_accept(tcp_connection::pointer new_connection, - const boost::asio::error& error) + const boost::system::error_code& error) { if (!error) { @@ -116,7 +116,7 @@ private: boost::asio::placeholders::error)); } - void handle_receive(const boost::asio::error& error) + void handle_receive(const boost::system::error_code& error) { if (!error || error == boost::asio::error::message_size) { diff --git a/example/tutorial/timer2/timer.cpp b/example/tutorial/timer2/timer.cpp index 957b13d3..3d2042b7 100644 --- a/example/tutorial/timer2/timer.cpp +++ b/example/tutorial/timer2/timer.cpp @@ -12,7 +12,7 @@ #include #include -void print(const boost::asio::error& /*e*/) +void print(const boost::system::error_code& /*e*/) { std::cout << "Hello, world!\n"; } diff --git a/example/tutorial/timer3/timer.cpp b/example/tutorial/timer3/timer.cpp index 1e6a85fb..265ad632 100644 --- a/example/tutorial/timer3/timer.cpp +++ b/example/tutorial/timer3/timer.cpp @@ -13,7 +13,7 @@ #include #include -void print(const boost::asio::error& /*e*/, +void print(const boost::system::error_code& /*e*/, boost::asio::deadline_timer* t, int* count) { if (*count < 5) diff --git a/include/boost/asio.hpp b/include/boost/asio.hpp index b530490a..4a21d7ab 100644 --- a/include/boost/asio.hpp +++ b/include/boost/asio.hpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -63,7 +62,6 @@ #include #include #include -#include #include #include diff --git a/include/boost/asio/basic_datagram_socket.hpp b/include/boost/asio/basic_datagram_socket.hpp index ccc0fcb5..9db52c21 100644 --- a/include/boost/asio/basic_datagram_socket.hpp +++ b/include/boost/asio/basic_datagram_socket.hpp @@ -24,7 +24,8 @@ #include #include -#include +#include +#include namespace boost { namespace asio { @@ -39,7 +40,7 @@ namespace asio { * @e Shared @e objects: Unsafe. * * @par Concepts: - * Async_Object, Error_Source. + * Async_Object */ template > @@ -80,7 +81,7 @@ public: * * @param protocol An object specifying protocol parameters to be used. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_datagram_socket(boost::asio::io_service& io_service, const protocol_type& protocol) @@ -102,7 +103,7 @@ public: * @param endpoint An endpoint on the local machine to which the datagram * socket will be bound. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_datagram_socket(boost::asio::io_service& io_service, const endpoint_type& endpoint) @@ -123,7 +124,7 @@ public: * * @param native_socket The new underlying socket implementation. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_datagram_socket(boost::asio::io_service& io_service, const protocol_type& protocol, const native_type& native_socket) @@ -141,7 +142,7 @@ public: * * @returns The number of bytes sent. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected datagram socket. @@ -156,7 +157,10 @@ public: template std::size_t send(const Const_Buffers& buffers) { - return this->service.send(this->implementation, buffers, 0, throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.send(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Send some data on a connected socket. @@ -171,7 +175,7 @@ public: * * @returns The number of bytes sent. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected datagram socket. @@ -180,8 +184,11 @@ public: std::size_t send(const Const_Buffers& buffers, socket_base::message_flags flags) { - return this->service.send(this->implementation, buffers, flags, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Send some data on a connected socket. @@ -194,24 +201,18 @@ public: * * @param flags Flags specifying how the send call is to be made. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. * * @note The send operation can only be used with a connected socket. Use * the send_to function to send data on an unconnected datagram socket. */ - template + template std::size_t send(const Const_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return this->service.send(this->implementation, buffers, flags, - error_handler); + return this->service.send(this->implementation, buffers, flags, ec); } /// Start an asynchronous send on a connected socket. @@ -229,8 +230,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -273,8 +274,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -304,7 +305,7 @@ public: * * @returns The number of bytes sent. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To send a single data buffer use the @ref buffer function as follows: @@ -321,8 +322,11 @@ public: std::size_t send_to(const Const_Buffers& buffers, const endpoint_type& destination) { - return this->service.send_to(this->implementation, buffers, destination, 0, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Send a datagram to the specified endpoint. @@ -339,14 +343,17 @@ public: * * @returns The number of bytes sent. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ template std::size_t send_to(const Const_Buffers& buffers, const endpoint_type& destination, socket_base::message_flags flags) { - return this->service.send_to(this->implementation, buffers, destination, - flags, throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, flags, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Send a datagram to the specified endpoint. @@ -361,22 +368,17 @@ public: * * @param flags Flags specifying how the send call is to be made. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes sent. */ - template + template std::size_t send_to(const Const_Buffers& buffers, const endpoint_type& destination, socket_base::message_flags flags, - Error_Handler error_handler) + boost::system::error_code& ec) { - return this->service.send_to(this->implementation, buffers, destination, - flags, error_handler); + return this->service.send_to(this->implementation, + buffers, destination, flags, ec); } /// Start an asynchronous send. @@ -396,8 +398,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -443,8 +445,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -470,7 +472,7 @@ public: * * @returns The number of bytes received. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected datagram @@ -487,8 +489,11 @@ public: template std::size_t receive(const Mutable_Buffers& buffers) { - return this->service.receive(this->implementation, buffers, 0, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Receive some data on a connected socket. @@ -503,7 +508,7 @@ public: * * @returns The number of bytes received. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The receive operation can only be used with a connected socket. Use * the receive_from function to receive data on an unconnected datagram @@ -513,8 +518,11 @@ public: std::size_t receive(const Mutable_Buffers& buffers, socket_base::message_flags flags) { - return this->service.receive(this->implementation, buffers, flags, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Receive some data on a connected socket. @@ -527,12 +535,7 @@ public: * * @param flags Flags specifying how the receive call is to be made. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. * @@ -540,12 +543,11 @@ public: * the receive_from function to receive data on an unconnected datagram * socket. */ - template + template std::size_t receive(const Mutable_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return this->service.receive(this->implementation, buffers, flags, - error_handler); + return this->service.receive(this->implementation, buffers, flags, ec); } /// Start an asynchronous receive on a connected socket. @@ -562,8 +564,8 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -606,8 +608,8 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -637,7 +639,7 @@ public: * * @returns The number of bytes received. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To receive into a single data buffer use the @ref buffer function as @@ -655,8 +657,11 @@ public: std::size_t receive_from(const Mutable_Buffers& buffers, endpoint_type& sender_endpoint) { - return this->service.receive_from(this->implementation, buffers, - sender_endpoint, 0, throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Receive a datagram with the endpoint of the sender. @@ -673,14 +678,17 @@ public: * * @returns The number of bytes received. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ template std::size_t receive_from(const Mutable_Buffers& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags) { - return this->service.receive_from(this->implementation, buffers, - sender_endpoint, flags, throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, flags, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Receive a datagram with the endpoint of the sender. @@ -695,22 +703,17 @@ public: * * @param flags Flags specifying how the receive call is to be made. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes received. */ - template + template std::size_t receive_from(const Mutable_Buffers& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, - Error_Handler error_handler) + boost::system::error_code& ec) { return this->service.receive_from(this->implementation, buffers, - sender_endpoint, flags, error_handler); + sender_endpoint, flags, ec); } /// Start an asynchronous receive. @@ -732,8 +735,8 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. + * const boost::system::system_error& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -778,8 +781,8 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation diff --git a/include/boost/asio/basic_deadline_timer.hpp b/include/boost/asio/basic_deadline_timer.hpp index e0bc65c8..4ff4b7ce 100644 --- a/include/boost/asio/basic_deadline_timer.hpp +++ b/include/boost/asio/basic_deadline_timer.hpp @@ -40,9 +40,6 @@ namespace asio { * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * - * @par Concepts: - * Async_Object, Error_Source. - * * @sa @ref deadline_timer_reset * * @par Examples: @@ -61,7 +58,7 @@ namespace asio { * @par * Performing an asynchronous wait: * @code - * void handler(const boost::asio::error& error) + * void handler(const boost::system::error_code& error) * { * if (!error) * { @@ -86,9 +83,6 @@ class basic_deadline_timer : public basic_io_object { public: - /// The type used for reporting errors. - typedef boost::asio::error error_type; - /// The time traits type. typedef Time_Traits traits_type; @@ -222,7 +216,7 @@ public: * This function is used to wait for the timer to expire. This function * blocks and does not return until the timer has expired. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void wait() { @@ -246,7 +240,7 @@ public: * will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const boost::asio::error& error // Result of operation + * const boost::system::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -282,7 +276,7 @@ public: * } * } * - * void on_timeout(const boost::asio::error& e) + * void on_timeout(const boost::system::error_code& e) * { * if (e != boost::asio::error::operation_aborted) * { @@ -297,8 +291,8 @@ public: * late and the wait handler has already been executed, or will soon be * executed. If it returns 1 then the wait handler was successfully cancelled. * - * @li If a wait handler is cancelled, the boost::asio::error passed to it - * contains the value boost::asio::error::operation_aborted. + * @li If a wait handler is cancelled, the boost::system::error_code passed to + * it contains the value boost::asio::error::operation_aborted. * * @sa boost::asio::basic_deadline_timer */ diff --git a/include/boost/asio/basic_socket.hpp b/include/boost/asio/basic_socket.hpp index c6c19767..851a9421 100644 --- a/include/boost/asio/basic_socket.hpp +++ b/include/boost/asio/basic_socket.hpp @@ -19,8 +19,8 @@ #include #include -#include #include +#include namespace boost { namespace asio { @@ -35,7 +35,7 @@ namespace asio { * @e Shared @e objects: Unsafe. * * @par Concepts: - * Error_Source, IO_Object. + * IO_Object. */ template class basic_socket @@ -52,9 +52,6 @@ public: /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; - /// The type used for reporting errors. - typedef boost::asio::error error_type; - /// A basic_socket is always the lowest layer. typedef basic_socket lowest_layer_type; @@ -79,13 +76,15 @@ public: * * @param protocol An object specifying protocol parameters to be used. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_socket(boost::asio::io_service& io_service, const protocol_type& protocol) : basic_io_object(io_service) { - this->service.open(this->implementation, protocol, throw_error()); + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); } /// Construct a basic_socket, opening it and binding it to the given local @@ -101,15 +100,17 @@ public: * @param endpoint An endpoint on the local machine to which the socket will * be bound. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_socket(boost::asio::io_service& io_service, const endpoint_type& endpoint) : basic_io_object(io_service) { - this->service.open(this->implementation, endpoint.protocol(), - throw_error()); - this->service.bind(this->implementation, endpoint, throw_error()); + boost::system::error_code ec; + this->service.open(this->implementation, endpoint.protocol(), ec); + boost::asio::detail::throw_error(ec); + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); } /// Construct a basic_socket on an existing native socket. @@ -123,14 +124,15 @@ public: * * @param native_socket A native socket. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_socket(boost::asio::io_service& io_service, const protocol_type& protocol, const native_type& native_socket) : basic_io_object(io_service) { - this->service.assign(this->implementation, protocol, native_socket, - throw_error()); + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_socket, ec); + boost::asio::detail::throw_error(ec); } /// Get a reference to the lowest layer. @@ -153,7 +155,7 @@ public: * * @param protocol An object specifying protocol parameters to be used. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -163,7 +165,9 @@ public: */ void open(const protocol_type& protocol = protocol_type()) { - this->service.open(this->implementation, protocol, throw_error()); + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); } /// Open the socket using the specified protocol. @@ -172,28 +176,23 @@ public: * * @param protocol An object specifying which protocol is to be used. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::socket socket(io_service); - * boost::asio::error error; - * socket.open(boost::asio::ip::tcp::v4(), boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * socket.open(boost::asio::ip::tcp::v4(), ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void open(const protocol_type& protocol, Error_Handler error_handler) + boost::system::error_code open(const protocol_type& protocol, + boost::system::error_code& ec) { - this->service.open(this->implementation, protocol, error_handler); + return this->service.open(this->implementation, protocol, ec); } /// Assign an existing native socket to the socket. @@ -204,12 +203,13 @@ public: * * @param native_socket A native socket. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void assign(const protocol_type& protocol, const native_type& native_socket) { - this->service.assign(this->implementation, protocol, native_socket, - throw_error()); + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_socket, ec); + boost::asio::detail::throw_error(ec); } /// Assign an existing native socket to the socket. @@ -220,19 +220,13 @@ public: * * @param native_socket A native socket. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void assign(const protocol_type& protocol, const native_type& native_socket, - Error_Handler error_handler) + boost::system::error_code assign(const protocol_type& protocol, + const native_type& native_socket, boost::system::error_code& ec) { - this->service.assign(this->implementation, protocol, native_socket, - error_handler); + return this->service.assign(this->implementation, + protocol, native_socket, ec); } /// Close the socket. @@ -241,11 +235,13 @@ public: * or connect operations will be cancelled immediately, and will complete * with the boost::asio::error::operation_aborted error. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void close() { - this->service.close(this->implementation, throw_error()); + boost::system::error_code ec; + this->service.close(this->implementation, ec); + boost::asio::detail::throw_error(ec); } /// Close the socket. @@ -254,29 +250,23 @@ public: * or connect operations will be cancelled immediately, and will complete * with the boost::asio::error::operation_aborted error. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::socket socket(io_service); * ... - * boost::asio::error error; - * socket.close(boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * socket.close(ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void close(Error_Handler error_handler) + boost::system::error_code close(boost::system::error_code& ec) { - this->service.close(this->implementation, error_handler); + return this->service.close(this->implementation, ec); } /// Get the native socket representation. @@ -296,11 +286,13 @@ public: * operations to finish immediately, and the handlers for cancelled operations * will be passed the boost::asio::error::operation_aborted error. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void cancel() { - this->service.cancel(this->implementation, throw_error()); + boost::system::error_code ec; + this->service.cancel(this->implementation, ec); + boost::asio::detail::throw_error(ec); } /// Cancel all asynchronous operations associated with the socket. @@ -309,17 +301,11 @@ public: * operations to finish immediately, and the handlers for cancelled operations * will be passed the boost::asio::error::operation_aborted error. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void cancel(Error_Handler error_handler) + boost::system::error_code cancel(boost::system::error_code& ec) { - this->service.cancel(this->implementation, error_handler); + return this->service.cancel(this->implementation, ec); } /// Bind the socket to the given local endpoint. @@ -330,7 +316,7 @@ public: * @param endpoint An endpoint on the local machine to which the socket will * be bound. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -342,7 +328,9 @@ public: */ void bind(const endpoint_type& endpoint) { - this->service.bind(this->implementation, endpoint, throw_error()); + boost::system::error_code ec; + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); } /// Bind the socket to the given local endpoint. @@ -353,31 +341,25 @@ public: * @param endpoint An endpoint on the local machine to which the socket will * be bound. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::socket socket(io_service); * socket.open(boost::asio::ip::tcp::v4()); - * boost::asio::error error; + * boost::system::error_code ec; * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), - * boost::asio::assign_error(error)); - * if (error) + * boost::asio::ip::tcp::v4(), 12345), ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void bind(const endpoint_type& endpoint, Error_Handler error_handler) + boost::system::error_code bind(const endpoint_type& endpoint, + boost::system::error_code& ec) { - this->service.bind(this->implementation, endpoint, error_handler); + return this->service.bind(this->implementation, endpoint, ec); } /// Connect the socket to the specified endpoint. @@ -393,7 +375,7 @@ public: * @param peer_endpoint The remote endpoint to which the socket will be * connected. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -405,7 +387,9 @@ public: */ void connect(const endpoint_type& peer_endpoint) { - this->service.connect(this->implementation, peer_endpoint, throw_error()); + boost::system::error_code ec; + this->service.connect(this->implementation, peer_endpoint, ec); + boost::asio::detail::throw_error(ec); } /// Connect the socket to the specified endpoint. @@ -421,30 +405,25 @@ public: * @param peer_endpoint The remote endpoint to which the socket will be * connected. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::socket socket(io_service); * boost::asio::ip::tcp::endpoint endpoint( * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::asio::error error; - * socket.connect(endpoint, boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * socket.connect(endpoint, ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void connect(const endpoint_type& peer_endpoint, Error_Handler error_handler) + boost::system::error_code connect(const endpoint_type& peer_endpoint, + boost::system::error_code& ec) { - this->service.connect(this->implementation, peer_endpoint, error_handler); + return this->service.connect(this->implementation, peer_endpoint, ec); } /// Start an asynchronous connect. @@ -463,7 +442,7 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error // Result of operation + * const boost::system::error_code& error // Result of operation * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -472,7 +451,7 @@ public: * * @par Example: * @code - * void connect_handler(const boost::asio::error& error) + * void connect_handler(const boost::system::error_code& error) * { * if (!error) * { @@ -500,7 +479,7 @@ public: * * @param option The new option value to be set on the socket. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @sa Socket_Option @n * boost::asio::socket_base::broadcast @n @@ -531,7 +510,9 @@ public: template void set_option(const Socket_Option& option) { - this->service.set_option(this->implementation, option, throw_error()); + boost::system::error_code ec; + this->service.set_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); } /// Set an option on the socket. @@ -540,12 +521,7 @@ public: * * @param option The new option value to be set on the socket. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @sa Socket_Option @n * boost::asio::socket_base::broadcast @n @@ -570,18 +546,19 @@ public: * boost::asio::ip::tcp::socket socket(io_service); * ... * boost::asio::ip::tcp::no_delay option(true); - * boost::asio::error error; - * socket.set_option(option, boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * socket.set_option(option, ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void set_option(const Socket_Option& option, Error_Handler error_handler) + template + boost::system::error_code set_option(const Socket_Option& option, + boost::system::error_code& ec) { - this->service.set_option(this->implementation, option, error_handler); + return this->service.set_option(this->implementation, option, ec); } /// Get an option from the socket. @@ -590,7 +567,7 @@ public: * * @param option The option value to be obtained from the socket. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @sa Socket_Option @n * boost::asio::socket_base::broadcast @n @@ -622,7 +599,9 @@ public: template void get_option(Socket_Option& option) const { - this->service.get_option(this->implementation, option, throw_error()); + boost::system::error_code ec; + this->service.get_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); } /// Get an option from the socket. @@ -631,12 +610,7 @@ public: * * @param option The option value to be obtained from the socket. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @sa Socket_Option @n * boost::asio::socket_base::broadcast @n @@ -661,19 +635,20 @@ public: * boost::asio::ip::tcp::socket socket(io_service); * ... * boost::asio::ip::tcp::socket::keep_alive option; - * boost::asio::error error; - * socket.get_option(option, boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * socket.get_option(option, ec); + * if (ec) * { * // An error occurred. * } * bool is_set = option.get(); * @endcode */ - template - void get_option(Socket_Option& option, Error_Handler error_handler) const + template + boost::system::error_code get_option(Socket_Option& option, + boost::system::error_code& ec) const { - this->service.get_option(this->implementation, option, error_handler); + return this->service.get_option(this->implementation, option, ec); } /// Perform an IO control command on the socket. @@ -682,7 +657,7 @@ public: * * @param command The IO control command to be performed on the socket. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @sa IO_Control_Command @n * boost::asio::socket_base::bytes_readable @n @@ -701,7 +676,9 @@ public: template void io_control(IO_Control_Command& command) { - this->service.io_control(this->implementation, command, throw_error()); + boost::system::error_code ec; + this->service.io_control(this->implementation, command, ec); + boost::asio::detail::throw_error(ec); } /// Perform an IO control command on the socket. @@ -710,12 +687,7 @@ public: * * @param command The IO control command to be performed on the socket. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @sa IO_Control_Command @n * boost::asio::socket_base::bytes_readable @n @@ -727,19 +699,20 @@ public: * boost::asio::ip::tcp::socket socket(io_service); * ... * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::asio::error error; - * socket.io_control(command, boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * socket.io_control(command, ec); + * if (ec) * { * // An error occurred. * } * std::size_t bytes_readable = command.get(); * @endcode */ - template - void io_control(IO_Control_Command& command, Error_Handler error_handler) + template + boost::system::error_code io_control(IO_Control_Command& command, + boost::system::error_code& ec) { - this->service.io_control(this->implementation, command, error_handler); + return this->service.io_control(this->implementation, command, ec); } /// Get the local endpoint of the socket. @@ -748,7 +721,7 @@ public: * * @returns An object that represents the local endpoint of the socket. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -759,41 +732,36 @@ public: */ endpoint_type local_endpoint() const { - return this->service.local_endpoint(this->implementation, throw_error()); + boost::system::error_code ec; + endpoint_type ep = this->service.local_endpoint(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return ep; } /// Get the local endpoint of the socket. /** * This function is used to obtain the locally bound endpoint of the socket. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. + * Returns a default-constructed endpoint object if an error occurred. * * @par Example: * @code * boost::asio::ip::tcp::socket socket(io_service); * ... - * boost::asio::error error; - * boost::asio::ip::tcp::endpoint endpoint - * = socket.local_endpoint(boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - endpoint_type local_endpoint(Error_Handler error_handler) const + endpoint_type local_endpoint(boost::system::error_code& ec) const { - return this->service.local_endpoint(this->implementation, error_handler); + return this->service.local_endpoint(this->implementation, ec); } /// Get the remote endpoint of the socket. @@ -802,7 +770,7 @@ public: * * @returns An object that represents the remote endpoint of the socket. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -813,41 +781,36 @@ public: */ endpoint_type remote_endpoint() const { - return this->service.remote_endpoint(this->implementation, throw_error()); + boost::system::error_code ec; + endpoint_type ep = this->service.remote_endpoint(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return ep; } /// Get the remote endpoint of the socket. /** * This function is used to obtain the remote endpoint of the socket. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. + * Returns a default-constructed endpoint object if an error occurred. * * @par Example: * @code * boost::asio::ip::tcp::socket socket(io_service); * ... - * boost::asio::error error; - * boost::asio::ip::tcp::endpoint endpoint - * = socket.remote_endpoint(boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - endpoint_type remote_endpoint(Error_Handler error_handler) const + endpoint_type remote_endpoint(boost::system::error_code& ec) const { - return this->service.remote_endpoint(this->implementation, error_handler); + return this->service.remote_endpoint(this->implementation, ec); } /// Disable sends or receives on the socket. @@ -857,7 +820,7 @@ public: * * @param what Determines what types of operation will no longer be allowed. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * Shutting down the send side of the socket: @@ -869,7 +832,9 @@ public: */ void shutdown(shutdown_type what) { - this->service.shutdown(this->implementation, what, throw_error()); + boost::system::error_code ec; + this->service.shutdown(this->implementation, what, ec); + boost::asio::detail::throw_error(ec); } /// Disable sends or receives on the socket. @@ -879,31 +844,25 @@ public: * * @param what Determines what types of operation will no longer be allowed. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * Shutting down the send side of the socket: * @code * boost::asio::ip::tcp::socket socket(io_service); * ... - * boost::asio::error error; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, - * boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void shutdown(shutdown_type what, Error_Handler error_handler) + boost::system::error_code shutdown(shutdown_type what, + boost::system::error_code& ec) { - this->service.shutdown(this->implementation, what, error_handler); + return this->service.shutdown(this->implementation, what, ec); } protected: diff --git a/include/boost/asio/basic_socket_acceptor.hpp b/include/boost/asio/basic_socket_acceptor.hpp index b2ecf6d3..29eca489 100644 --- a/include/boost/asio/basic_socket_acceptor.hpp +++ b/include/boost/asio/basic_socket_acceptor.hpp @@ -20,9 +20,9 @@ #include #include #include -#include #include #include +#include namespace boost { namespace asio { @@ -36,9 +36,6 @@ namespace asio { * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * - * @par Concepts: - * Async_Object, Error_Source. - * * @par Example: * Opening a socket acceptor with the SO_REUSEADDR option enabled: * @code @@ -66,9 +63,6 @@ public: /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; - /// The type used for reporting errors. - typedef boost::asio::error error_type; - /// Construct an acceptor without opening it. /** * This constructor creates an acceptor without opening it to listen for new @@ -94,13 +88,15 @@ public: * * @param protocol An object specifying protocol parameters to be used. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_socket_acceptor(boost::asio::io_service& io_service, const protocol_type& protocol) : basic_io_object(io_service) { - this->service.open(this->implementation, protocol, throw_error()); + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); } /// Construct an acceptor opened on the given endpoint. @@ -118,7 +114,7 @@ public: * @param reuse_addr Whether the constructor should set the socket option * socket_base::reuse_address. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note This constructor is equivalent to the following code: * @code @@ -134,16 +130,20 @@ public: const endpoint_type& endpoint, bool reuse_addr = true) : basic_io_object(io_service) { - this->service.open(this->implementation, endpoint.protocol(), - throw_error()); + boost::system::error_code ec; + this->service.open(this->implementation, endpoint.protocol(), ec); + boost::asio::detail::throw_error(ec); if (reuse_addr) { this->service.set_option(this->implementation, - socket_base::reuse_address(true), throw_error()); + socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec); } - this->service.bind(this->implementation, endpoint, throw_error()); + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); this->service.listen(this->implementation, - socket_base::max_connections, throw_error()); + socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec); } /// Construct a basic_socket_acceptor on an existing native acceptor. @@ -159,14 +159,15 @@ public: * * @param native_acceptor A native acceptor. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_socket_acceptor(boost::asio::io_service& io_service, const protocol_type& protocol, const native_type& native_acceptor) : basic_io_object(io_service) { - this->service.assign(this->implementation, protocol, native_acceptor, - throw_error()); + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_acceptor, ec); + boost::asio::detail::throw_error(ec); } /// Open the acceptor using the specified protocol. @@ -176,6 +177,8 @@ public: * * @param protocol An object specifying which protocol is to be used. * + * @throws boost::system::system_error Thrown on failure. + * * @par Example: * @code * boost::asio::ip::tcp::acceptor acceptor(io_service); @@ -184,7 +187,9 @@ public: */ void open(const protocol_type& protocol = protocol_type()) { - this->service.open(this->implementation, protocol, throw_error()); + boost::system::error_code ec; + this->service.open(this->implementation, protocol, ec); + boost::asio::detail::throw_error(ec); } /// Open the acceptor using the specified protocol. @@ -194,29 +199,23 @@ public: * * @param protocol An object specifying which protocol is to be used. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::asio::error error; - * acceptor.open(boost::asio::ip::tcp::v4(), - * boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.open(boost::asio::ip::tcp::v4(), ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void open(const protocol_type& protocol, Error_Handler error_handler) + boost::system::error_code open(const protocol_type& protocol, + boost::system::error_code& ec) { - this->service.open(this->implementation, protocol, error_handler); + return this->service.open(this->implementation, protocol, ec); } /// Assigns an existing native acceptor to the acceptor. @@ -227,12 +226,13 @@ public: * * @param native_acceptor A native acceptor. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void assign(const protocol_type& protocol, const native_type& native_acceptor) { - this->service.assign(this->implementation, protocol, native_acceptor, - throw_error()); + boost::system::error_code ec; + this->service.assign(this->implementation, protocol, native_acceptor, ec); + boost::asio::detail::throw_error(ec); } /// Assigns an existing native acceptor to the acceptor. @@ -243,19 +243,13 @@ public: * * @param native_acceptor A native acceptor. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void assign(const protocol_type& protocol, const native_type& native_acceptor, - Error_Handler error_handler) + boost::system::error_code assign(const protocol_type& protocol, + const native_type& native_acceptor, boost::system::error_code& ec) { - this->service.assign(this->implementation, protocol, native_acceptor, - error_handler); + return this->service.assign(this->implementation, + protocol, native_acceptor, ec); } /// Bind the acceptor to the given local endpoint. @@ -266,7 +260,7 @@ public: * @param endpoint An endpoint on the local machine to which the socket * acceptor will be bound. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -277,7 +271,9 @@ public: */ void bind(const endpoint_type& endpoint) { - this->service.bind(this->implementation, endpoint, throw_error()); + boost::system::error_code ec; + this->service.bind(this->implementation, endpoint, ec); + boost::asio::detail::throw_error(ec); } /// Bind the acceptor to the given local endpoint. @@ -288,30 +284,24 @@ public: * @param endpoint An endpoint on the local machine to which the socket * acceptor will be bound. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::acceptor acceptor(io_service); * acceptor.open(boost::asio::ip::tcp::v4()); - * boost::asio::error error; - * acceptor.bind(boost::asio::ip::tcp::endpoint(12345), - * boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.bind(boost::asio::ip::tcp::endpoint(12345), ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void bind(const endpoint_type& endpoint, Error_Handler error_handler) + boost::system::error_code bind(const endpoint_type& endpoint, + boost::system::error_code& ec) { - this->service.bind(this->implementation, endpoint, error_handler); + return this->service.bind(this->implementation, endpoint, ec); } /// Place the acceptor into the state where it will listen for new @@ -321,10 +311,14 @@ public: * new connections. * * @param backlog The maximum length of the queue of pending connections. + * + * @throws boost::system::system_error Thrown on failure. */ void listen(int backlog = socket_base::max_connections) { - this->service.listen(this->implementation, backlog, throw_error()); + boost::system::error_code ec; + this->service.listen(this->implementation, backlog, ec); + boost::asio::detail::throw_error(ec); } /// Place the acceptor into the state where it will listen for new @@ -335,30 +329,23 @@ public: * * @param backlog The maximum length of the queue of pending connections. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::acceptor acceptor(io_service); * ... - * boost::asio::error error; - * acceptor.listen(boost::asio::socket_base::max_connections, - * boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.listen(boost::asio::socket_base::max_connections, ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void listen(int backlog, Error_Handler error_handler) + boost::system::error_code listen(int backlog, boost::system::error_code& ec) { - this->service.listen(this->implementation, backlog, error_handler); + return this->service.listen(this->implementation, backlog, ec); } /// Close the acceptor. @@ -369,11 +356,13 @@ public: * A subsequent call to open() is required before the acceptor can again be * used to again perform socket accept operations. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void close() { - this->service.close(this->implementation, throw_error()); + boost::system::error_code ec; + this->service.close(this->implementation, ec); + boost::asio::detail::throw_error(ec); } /// Close the acceptor. @@ -384,29 +373,23 @@ public: * A subsequent call to open() is required before the acceptor can again be * used to again perform socket accept operations. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::acceptor acceptor(io_service); * ... - * boost::asio::error error; - * acceptor.close(boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.close(ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void close(Error_Handler error_handler) + boost::system::error_code close(boost::system::error_code& ec) { - this->service.close(this->implementation, error_handler); + return this->service.close(this->implementation, ec); } /// Get the native acceptor representation. @@ -426,11 +409,13 @@ public: * operations to finish immediately, and the handlers for cancelled operations * will be passed the boost::asio::error::operation_aborted error. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void cancel() { - this->service.cancel(this->implementation, throw_error()); + boost::system::error_code ec; + this->service.cancel(this->implementation, ec); + boost::asio::detail::throw_error(ec); } /// Cancel all asynchronous operations associated with the acceptor. @@ -439,17 +424,11 @@ public: * operations to finish immediately, and the handlers for cancelled operations * will be passed the boost::asio::error::operation_aborted error. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void cancel(Error_Handler error_handler) + boost::system::error_code cancel(boost::system::error_code& ec) { - this->service.cancel(this->implementation, error_handler); + return this->service.cancel(this->implementation, ec); } /// Set an option on the acceptor. @@ -458,7 +437,7 @@ public: * * @param option The new option value to be set on the acceptor. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @sa Socket_Option @n * boost::asio::socket_base::reuse_address @@ -476,7 +455,9 @@ public: template void set_option(const Option& option) { - this->service.set_option(this->implementation, option, throw_error()); + boost::system::error_code ec; + this->service.set_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); } /// Set an option on the acceptor. @@ -485,12 +466,7 @@ public: * * @param option The new option value to be set on the acceptor. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @sa Socket_Option @n * boost::asio::socket_base::reuse_address @@ -502,18 +478,19 @@ public: * boost::asio::ip::tcp::acceptor acceptor(io_service); * ... * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::asio::error error; - * acceptor.set_option(option, boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.set_option(option, ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void set_option(const Option& option, Error_Handler error_handler) + template + boost::system::error_code set_option(const Option& option, + boost::system::error_code& ec) { - this->service.set_option(this->implementation, option, error_handler); + return this->service.set_option(this->implementation, option, ec); } /// Get an option from the acceptor. @@ -523,7 +500,7 @@ public: * * @param option The option value to be obtained from the acceptor. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @sa Socket_Option @n * boost::asio::socket_base::reuse_address @@ -541,7 +518,9 @@ public: template void get_option(Option& option) { - this->service.get_option(this->implementation, option, throw_error()); + boost::system::error_code ec; + this->service.get_option(this->implementation, option, ec); + boost::asio::detail::throw_error(ec); } /// Get an option from the acceptor. @@ -551,12 +530,7 @@ public: * * @param option The option value to be obtained from the acceptor. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @sa Socket_Option @n * boost::asio::socket_base::reuse_address @@ -567,19 +541,20 @@ public: * boost::asio::ip::tcp::acceptor acceptor(io_service); * ... * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::asio::error error; - * acceptor.get_option(option, boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.get_option(option, ec); + * if (ec) * { * // An error occurred. * } * bool is_set = option.get(); * @endcode */ - template - void get_option(Option& option, Error_Handler error_handler) + template + boost::system::error_code get_option(Option& option, + boost::system::error_code& ec) { - this->service.get_option(this->implementation, option, error_handler); + return this->service.get_option(this->implementation, option, ec); } /// Get the local endpoint of the acceptor. @@ -588,7 +563,7 @@ public: * * @returns An object that represents the local endpoint of the acceptor. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -599,19 +574,17 @@ public: */ endpoint_type local_endpoint() const { - return this->service.local_endpoint(this->implementation, throw_error()); + boost::system::error_code ec; + endpoint_type ep = this->service.local_endpoint(this->implementation, ec); + boost::asio::detail::throw_error(ec); + return ep; } /// Get the local endpoint of the acceptor. /** * This function is used to obtain the locally bound endpoint of the acceptor. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns An object that represents the local endpoint of the acceptor. * Returns a default-constructed endpoint object if an error occurred and the @@ -621,19 +594,17 @@ public: * @code * boost::asio::ip::tcp::acceptor acceptor(io_service); * ... - * boost::asio::error error; - * boost::asio::ip::tcp::endpoint endpoint - * = acceptor.local_endpoint(boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - endpoint_type local_endpoint(Error_Handler error_handler) const + endpoint_type local_endpoint(boost::system::error_code& ec) const { - return this->service.local_endpoint(this->implementation, error_handler); + return this->service.local_endpoint(this->implementation, ec); } /// Accept a new connection. @@ -644,7 +615,7 @@ public: * * @param peer The socket into which the new connection will be accepted. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -657,7 +628,9 @@ public: template void accept(basic_socket& peer) { - this->service.accept(this->implementation, peer, throw_error()); + boost::system::error_code ec; + this->service.accept(this->implementation, peer, ec); + boost::asio::detail::throw_error(ec); } /// Accept a new connection. @@ -668,31 +641,27 @@ public: * * @param peer The socket into which the new connection will be accepted. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code * boost::asio::ip::tcp::acceptor acceptor(io_service); * ... * boost::asio::ip::tcp::soocket socket(io_service); - * boost::asio::error error; - * acceptor.accept(socket, boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.accept(socket, ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void accept(basic_socket& peer, - Error_Handler error_handler) + template + boost::system::error_code accept( + basic_socket& peer, + boost::system::error_code& ec) { - this->service.accept(this->implementation, peer, error_handler); + return this->service.accept(this->implementation, peer, ec); } /// Start an asynchronous accept. @@ -708,7 +677,7 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error // Result of operation + * const boost::system::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -717,7 +686,7 @@ public: * * @par Example: * @code - * void accept_handler(const boost::asio::error& error) + * void accept_handler(const boost::system::error_code& error) * { * if (!error) * { @@ -752,7 +721,7 @@ public: * @param peer_endpoint An endpoint object which will receive the endpoint of * the remote peer. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * @code @@ -767,8 +736,10 @@ public: void accept_endpoint(basic_socket& peer, endpoint_type& peer_endpoint) { - this->service.accept_endpoint(this->implementation, peer, peer_endpoint, - throw_error()); + boost::system::error_code ec; + this->service.accept_endpoint( + this->implementation, peer, peer_endpoint, ec); + boost::asio::detail::throw_error(ec); } /// Accept a new connection and obtain the endpoint of the peer @@ -783,12 +754,7 @@ public: * @param peer_endpoint An endpoint object which will receive the endpoint of * the remote peer. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @par Example: * @code @@ -796,21 +762,21 @@ public: * ... * boost::asio::ip::tcp::socket socket(io_service); * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::error error; - * acceptor.accept_endpoint(socket, endpoint, - * boost::asio::assign_error(error)); - * if (error) + * boost::system::error_code ec; + * acceptor.accept_endpoint(socket, endpoint, ec); + * if (ec) * { * // An error occurred. * } * @endcode */ - template - void accept_endpoint(basic_socket& peer, - endpoint_type& peer_endpoint, Error_Handler error_handler) + template + boost::system::error_code accept_endpoint( + basic_socket& peer, + endpoint_type& peer_endpoint, boost::system::error_code& ec) { - this->service.accept_endpoint(this->implementation, peer, peer_endpoint, - error_handler); + return this->service.accept_endpoint( + this->implementation, peer, peer_endpoint, ec); } /// Start an asynchronous accept. @@ -832,7 +798,7 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error // Result of operation + * const boost::system::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation diff --git a/include/boost/asio/basic_socket_iostream.hpp b/include/boost/asio/basic_socket_iostream.hpp index ae735b98..99890c7a 100644 --- a/include/boost/asio/basic_socket_iostream.hpp +++ b/include/boost/asio/basic_socket_iostream.hpp @@ -42,7 +42,7 @@ // { // rdbuf()->connect ( x1, ..., xn ); // } -// catch (boost::asio::error&) +// catch (boost::system::system_error&) // { // this->setstate(std::ios_base::failbit); // if (this->exceptions() & std::ios_base::failbit) @@ -61,7 +61,7 @@ { \ rdbuf()->connect( BOOST_PP_ENUM_PARAMS(n, x) ); \ } \ - catch (boost::asio::error&) \ + catch (boost::system::system_error&) \ { \ this->setstate(std::ios_base::failbit); \ if (this->exceptions() & std::ios_base::failbit) \ @@ -78,7 +78,7 @@ // { // rdbuf()->connect ( x1, ..., xn ); // } -// catch (boost::asio::error&) +// catch (boost::system::system_error&) // { // this->setstate(std::ios_base::failbit); // if (this->exceptions() & std::ios_base::failbit) @@ -95,7 +95,7 @@ { \ rdbuf()->connect( BOOST_PP_ENUM_PARAMS(n, x) ); \ } \ - catch (boost::asio::error&) \ + catch (boost::system::system_error&) \ { \ this->setstate(std::ios_base::failbit); \ if (this->exceptions() & std::ios_base::failbit) \ diff --git a/include/boost/asio/basic_socket_streambuf.hpp b/include/boost/asio/basic_socket_streambuf.hpp index 4179fe79..85f5197b 100644 --- a/include/boost/asio/basic_socket_streambuf.hpp +++ b/include/boost/asio/basic_socket_streambuf.hpp @@ -28,9 +28,9 @@ #include #include -#include #include #include +#include #if !defined(BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY) #define BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY 5 @@ -175,15 +175,15 @@ protected: { if (gptr() == egptr()) { - boost::asio::error error; + boost::system::error_code ec; std::size_t bytes_transferred = this->service.receive( this->implementation, boost::asio::buffer(boost::asio::buffer(get_buffer_) + putback_max), - 0, boost::asio::assign_error(error)); - if (error) + 0, ec); + if (ec) { - if (error != boost::asio::error::eof) - throw error; + if (ec != boost::asio::error::eof) + boost::asio::detail::throw_error(ec); return traits_type::eof(); } setg(get_buffer_.begin(), get_buffer_.begin() + putback_max, @@ -206,9 +206,11 @@ protected: boost::asio::buffer(pbase(), pptr() - pbase()); while (boost::asio::buffer_size(buffer) > 0) { + boost::system::error_code ec; std::size_t bytes_transferred = this->service.send( this->implementation, boost::asio::buffer(buffer), - 0, boost::asio::throw_error()); + 0, ec); + boost::asio::detail::throw_error(ec); buffer = buffer + bytes_transferred; } setp(put_buffer_.begin(), put_buffer_.end()); @@ -228,9 +230,11 @@ protected: boost::asio::buffer(pbase(), pptr() - pbase()); while (boost::asio::buffer_size(buffer) > 0) { + boost::system::error_code ec; std::size_t bytes_transferred = this->service.send( this->implementation, boost::asio::buffer(buffer), - 0, boost::asio::throw_error()); + 0, ec); + boost::asio::detail::throw_error(ec); buffer = buffer + bytes_transferred; } setp(put_buffer_.begin(), put_buffer_.end()); @@ -253,16 +257,14 @@ private: resolver_type resolver( boost::base_from_member::member); iterator_type iterator = resolver.resolve(query); - boost::asio::error error(boost::asio::error::host_not_found); - while (error && iterator != iterator_type()) + boost::system::error_code ec(boost::asio::error::host_not_found); + while (ec && iterator != iterator_type()) { this->basic_socket::close(); - this->basic_socket::connect( - *iterator, boost::asio::assign_error(error)); + this->basic_socket::connect(*iterator, ec); ++iterator; } - if (error) - throw error; + boost::asio::detail::throw_error(ec); } enum { putback_max = 8 }; diff --git a/include/boost/asio/basic_stream_socket.hpp b/include/boost/asio/basic_stream_socket.hpp index 06644005..f461b5d0 100644 --- a/include/boost/asio/basic_stream_socket.hpp +++ b/include/boost/asio/basic_stream_socket.hpp @@ -23,8 +23,9 @@ #include #include -#include +#include #include +#include namespace boost { namespace asio { @@ -39,8 +40,8 @@ namespace asio { * @e Shared @e objects: Unsafe. * * @par Concepts: - * Async_Read_Stream, Async_Write_Stream, Error_Source, IO_Object, Stream, - * Sync_Read_Stream, Sync_Write_Stream. + * Async_Read_Stream, Async_Write_Stream, Stream, Sync_Read_Stream, + * Sync_Write_Stream. */ template > @@ -81,7 +82,7 @@ public: * * @param protocol An object specifying protocol parameters to be used. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_stream_socket(boost::asio::io_service& io_service, const protocol_type& protocol) @@ -102,7 +103,7 @@ public: * @param endpoint An endpoint on the local machine to which the stream * socket will be bound. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_stream_socket(boost::asio::io_service& io_service, const endpoint_type& endpoint) @@ -122,7 +123,7 @@ public: * * @param native_socket The new underlying socket implementation. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ basic_stream_socket(boost::asio::io_service& io_service, const protocol_type& protocol, const native_type& native_socket) @@ -140,7 +141,7 @@ public: * * @returns The number of bytes sent. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref write function if you need to ensure that all data @@ -158,7 +159,11 @@ public: template std::size_t send(const Const_Buffers& buffers) { - return this->service.send(this->implementation, buffers, 0, throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Send some data on the socket. @@ -173,7 +178,7 @@ public: * * @returns The number of bytes sent. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref write function if you need to ensure that all data @@ -192,8 +197,11 @@ public: std::size_t send(const Const_Buffers& buffers, socket_base::message_flags flags) { - return this->service.send(this->implementation, buffers, flags, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Send some data on the socket. @@ -206,27 +214,19 @@ public: * * @param flags Flags specifying how the send call is to be made. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes sent. Returns 0 if an error occurred and the - * error handler did not throw an exception. + * @returns The number of bytes sent. Returns 0 if an error occurred. * * @note The send operation may not transmit all of the data to the peer. * Consider using the @ref write function if you need to ensure that all data * is written before the blocking operation completes. */ - template + template std::size_t send(const Const_Buffers& buffers, - socket_base::message_flags flags, - Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return this->service.send(this->implementation, buffers, flags, - error_handler); + return this->service.send(this->implementation, buffers, flags, ec); } /// Start an asynchronous send. @@ -243,8 +243,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -286,8 +286,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -324,7 +324,7 @@ public: * * @returns The number of bytes received. * - * @throws boost::asio::error Thrown on failure. An error code of + * @throws boost::system::system_error Thrown on failure. An error code of * boost::asio::error::eof indicates that the connection was closed by the * peer. * @@ -345,8 +345,10 @@ public: template std::size_t receive(const Mutable_Buffers& buffers) { - return this->service.receive(this->implementation, buffers, 0, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Receive some data on the socket. @@ -361,7 +363,7 @@ public: * * @returns The number of bytes received. * - * @throws boost::asio::error Thrown on failure. An error code of + * @throws boost::system::system_error Thrown on failure. An error code of * boost::asio::error::eof indicates that the connection was closed by the * peer. * @@ -383,8 +385,11 @@ public: std::size_t receive(const Mutable_Buffers& buffers, socket_base::message_flags flags) { - return this->service.receive(this->implementation, buffers, flags, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, flags, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Receive some data on a connected socket. @@ -397,26 +402,19 @@ public: * * @param flags Flags specifying how the receive call is to be made. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes received. Returns 0 if an error occurred and - * the error handler did not throw an exception. + * @returns The number of bytes received. Returns 0 if an error occurred. * * @note The receive operation may not receive all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. */ - template + template std::size_t receive(const Mutable_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return this->service.receive(this->implementation, buffers, flags, - error_handler); + return this->service.receive(this->implementation, buffers, flags, ec); } /// Start an asynchronous receive. @@ -433,8 +431,8 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -478,8 +476,8 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -518,7 +516,7 @@ public: * * @returns The number of bytes written. * - * @throws boost::asio::error Thrown on failure. An error code of + * @throws boost::system::system_error Thrown on failure. An error code of * boost::asio::error::eof indicates that the connection was closed by the * peer. * @@ -538,7 +536,10 @@ public: template std::size_t write_some(const Const_Buffers& buffers) { - return this->service.send(this->implementation, buffers, 0, throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.send(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Write some data to the socket. @@ -549,25 +550,19 @@ public: * * @param buffers One or more data buffers to be written to the socket. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes written. Returns 0 if an error occurred and - * the error handler did not throw an exception. + * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that * all data is written before the blocking operation completes. */ - template + template std::size_t write_some(const Const_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return this->service.send(this->implementation, buffers, 0, error_handler); + return this->service.send(this->implementation, buffers, 0, ec); } /// Start an asynchronous write. @@ -584,8 +579,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -621,7 +616,7 @@ public: * * @returns The number of bytes read. * - * @throws boost::asio::error Thrown on failure. An error code of + * @throws boost::system::system_error Thrown on failure. An error code of * boost::asio::error::eof indicates that the connection was closed by the * peer. * @@ -642,8 +637,10 @@ public: template std::size_t read_some(const Mutable_Buffers& buffers) { - return this->service.receive(this->implementation, buffers, 0, - throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive(this->implementation, buffers, 0, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Read some data from the socket. @@ -654,27 +651,20 @@ public: * * @param buffers One or more buffers into which the data will be read. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes read. Returns 0 if an error occurred and the - * error handler did not throw an exception. + * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that * the requested amount of data is read before the blocking operation * completes. */ - template + template std::size_t read_some(const Mutable_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return this->service.receive(this->implementation, buffers, 0, - error_handler); + return this->service.receive(this->implementation, buffers, 0, ec); } /// Start an asynchronous read. @@ -691,8 +681,8 @@ public: * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -729,7 +719,7 @@ public: * * @returns The number of bytes read. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To peek using a single data buffer use the @ref buffer function as @@ -742,8 +732,11 @@ public: template std::size_t peek(const Mutable_Buffers& buffers) { - return this->service.receive(this->implementation, buffers, - socket_base::message_peek, throw_error()); + boost::system::error_code ec; + std::size_t s = this->service.receive(this->implementation, buffers, + socket_base::message_peek, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Peek at the incoming data on the stream socket. @@ -754,21 +747,16 @@ public: * * @param buffers One or more buffers into which the data will be read. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes read. Returns 0 if an error occurred and the - * error handler did not throw an exception. + * @returns The number of bytes read. Returns 0 if an error occurred. */ - template - std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler) + template + std::size_t peek(const Mutable_Buffers& buffers, + boost::system::error_code& ec) { return this->service.receive(this->implementation, buffers, - socket_base::message_peek, error_handler); + socket_base::message_peek, ec); } /// Determine the amount of data that may be read without blocking. @@ -778,12 +766,14 @@ public: * * @returns The number of bytes of data that can be read without blocking. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ std::size_t in_avail() { socket_base::bytes_readable command; - this->service.io_control(this->implementation, command, throw_error()); + boost::system::error_code ec; + this->service.io_control(this->implementation, command, ec); + boost::asio::detail::throw_error(ec); return command.get(); } @@ -792,20 +782,14 @@ public: * This function is used to determine the amount of data, in bytes, that may * be read from the stream socket without blocking. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes of data that can be read without blocking. */ - template - std::size_t in_avail(Error_Handler error_handler) + std::size_t in_avail(boost::system::error_code& ec) { socket_base::bytes_readable command; - this->service.io_control(this->implementation, command, error_handler); + this->service.io_control(this->implementation, command, ec); return command.get(); } }; diff --git a/include/boost/asio/buffered_read_stream.hpp b/include/boost/asio/buffered_read_stream.hpp index 401da297..059c58ed 100644 --- a/include/boost/asio/buffered_read_stream.hpp +++ b/include/boost/asio/buffered_read_stream.hpp @@ -46,7 +46,7 @@ namespace asio { * @e Shared @e objects: Unsafe. * * @par Concepts: - * Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream, + * Async_Object, Async_Read_Stream, Async_Write_Stream, Stream, * Sync_Read_Stream, Sync_Write_Stream. */ template @@ -60,9 +60,6 @@ public: /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; - /// The type used for reporting errors. - typedef typename next_layer_type::error_type error_type; - #if defined(GENERATING_DOCUMENTATION) /// The default buffer size. static const std::size_t default_buffer_size = implementation_defined; @@ -111,10 +108,9 @@ public: } /// Close the stream. - template - void close(Error_Handler error_handler) + boost::system::error_code close(boost::system::error_code& ec) { - next_layer_.close(error_handler); + return next_layer_.close(ec); } /// Write the given data to the stream. Returns the number of bytes written. @@ -126,12 +122,12 @@ public: } /// Write the given data to the stream. Returns the number of bytes written, - /// or 0 if an error occurred and the error handler did not throw. - template + /// or 0 if an error occurred. + template std::size_t write_some(const Const_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return next_layer_.write_some(buffers, error_handler); + return next_layer_.write_some(buffers, ec); } /// Start an asynchronous write. The data being written must be valid for the @@ -158,10 +154,8 @@ public: } /// Fill the buffer with some data. Returns the number of bytes placed in the - /// buffer as a result of the operation, or 0 if an error occurred and the - /// error handler did not throw. - template - std::size_t fill(Error_Handler error_handler) + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(boost::system::error_code& ec) { detail::buffer_resize_guard resize_guard(storage_); @@ -170,7 +164,7 @@ public: storage_.resize(previous_size + next_layer_.read_some(buffer( storage_.data() + previous_size, storage_.size() - previous_size), - error_handler)); + ec)); resize_guard.commit(); return storage_.size() - previous_size; } @@ -189,12 +183,12 @@ public: { } - template - void operator()(const Error& e, std::size_t bytes_transferred) + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) { storage_.resize(previous_size_ + bytes_transferred); io_service_.dispatch(detail::bind_handler( - handler_, e, bytes_transferred)); + handler_, ec, bytes_transferred)); } private: @@ -228,12 +222,13 @@ public: } /// Read some data from the stream. Returns the number of bytes read or 0 if - /// an error occurred and the error handler did not throw an exception. - template + /// an error occurred. + template std::size_t read_some(const Mutable_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - if (storage_.empty() && !fill(error_handler)) + ec = boost::system::error_code(); + if (storage_.empty() && !fill(ec)) return 0; return copy(buffers); } @@ -252,12 +247,12 @@ public: { } - void operator()(const error_type& e, std::size_t) + void operator()(const boost::system::error_code& ec, std::size_t) { - if (e || storage_.empty()) + if (ec || storage_.empty()) { std::size_t length = 0; - io_service_.dispatch(detail::bind_handler(handler_, e, length)); + io_service_.dispatch(detail::bind_handler(handler_, ec, length)); } else { @@ -280,7 +275,7 @@ public: } storage_.consume(bytes_copied); - io_service_.dispatch(detail::bind_handler(handler_, e, bytes_copied)); + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); } } @@ -304,7 +299,8 @@ public: else { std::size_t length = copy(buffers); - io_service().post(detail::bind_handler(handler, 0, length)); + io_service().post(detail::bind_handler( + handler, boost::asio::error::success, length)); } } @@ -319,11 +315,13 @@ public: } /// Peek at the incoming data on the stream. Returns the number of bytes read, - /// or 0 if an error occurred and the error handler did not throw. - template - std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler) + /// or 0 if an error occurred. + template + std::size_t peek(const Mutable_Buffers& buffers, + boost::system::error_code& ec) { - if (storage_.empty() && !fill(error_handler)) + ec = boost::system::error_code(); + if (storage_.empty() && !fill(ec)) return 0; return peek_copy(buffers); } @@ -335,9 +333,9 @@ public: } /// Determine the amount of data that may be read without blocking. - template - std::size_t in_avail(Error_Handler error_handler) + std::size_t in_avail(boost::system::error_code& ec) { + ec = boost::system::error_code(); return storage_.size(); } diff --git a/include/boost/asio/buffered_stream.hpp b/include/boost/asio/buffered_stream.hpp index a8380da3..1cf4324e 100644 --- a/include/boost/asio/buffered_stream.hpp +++ b/include/boost/asio/buffered_stream.hpp @@ -42,7 +42,7 @@ namespace asio { * @e Shared @e objects: Unsafe. * * @par Concepts: - * Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream, + * Async_Object, Async_Read_Stream, Async_Write_Stream, Stream, * Sync_Read_Stream, Sync_Write_Stream. */ template @@ -56,9 +56,6 @@ public: /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; - /// The type used for reporting errors. - typedef typename next_layer_type::error_type error_type; - /// Construct, passing the specified argument to initialise the next layer. template explicit buffered_stream(Arg& a) @@ -101,10 +98,9 @@ public: } /// Close the stream. - template - void close(Error_Handler error_handler) + boost::system::error_code close(boost::system::error_code& ec) { - stream_impl_.close(error_handler); + return stream_impl_.close(ec); } /// Flush all data from the buffer to the next layer. Returns the number of @@ -117,11 +113,10 @@ public: /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation, or 0 if an - /// error occurred and the error handler did not throw. - template - std::size_t flush(Error_Handler error_handler) + /// error occurred. + std::size_t flush(boost::system::error_code& ec) { - return stream_impl_.next_layer().flush(error_handler); + return stream_impl_.next_layer().flush(ec); } /// Start an asynchronous flush. @@ -140,12 +135,12 @@ public: } /// Write the given data to the stream. Returns the number of bytes written, - /// or 0 if an error occurred and the error handler did not throw. - template + /// or 0 if an error occurred. + template std::size_t write_some(const Const_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return stream_impl_.write_some(buffers, error_handler); + return stream_impl_.write_some(buffers, ec); } /// Start an asynchronous write. The data being written must be valid for the @@ -164,12 +159,10 @@ public: } /// Fill the buffer with some data. Returns the number of bytes placed in the - /// buffer as a result of the operation, or 0 if an error occurred and the - /// error handler did not throw. - template - std::size_t fill(Error_Handler error_handler) + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(boost::system::error_code& ec) { - return stream_impl_.fill(error_handler); + return stream_impl_.fill(ec); } /// Start an asynchronous fill. @@ -188,12 +181,12 @@ public: } /// Read some data from the stream. Returns the number of bytes read or 0 if - /// an error occurred and the error handler did not throw an exception. - template + /// an error occurred. + template std::size_t read_some(const Mutable_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return stream_impl_.read_some(buffers, error_handler); + return stream_impl_.read_some(buffers, ec); } /// Start an asynchronous read. The buffer into which the data will be read @@ -213,11 +206,12 @@ public: } /// Peek at the incoming data on the stream. Returns the number of bytes read, - /// or 0 if an error occurred and the error handler did not throw. - template - std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler) + /// or 0 if an error occurred. + template + std::size_t peek(const Mutable_Buffers& buffers, + boost::system::error_code& ec) { - return stream_impl_.peek(buffers, error_handler); + return stream_impl_.peek(buffers, ec); } /// Determine the amount of data that may be read without blocking. @@ -227,10 +221,9 @@ public: } /// Determine the amount of data that may be read without blocking. - template - std::size_t in_avail(Error_Handler error_handler) + std::size_t in_avail(boost::system::error_code& ec) { - return stream_impl_.in_avail(error_handler); + return stream_impl_.in_avail(ec); } private: diff --git a/include/boost/asio/buffered_write_stream.hpp b/include/boost/asio/buffered_write_stream.hpp index 4e66a3d9..9a6ecc1b 100644 --- a/include/boost/asio/buffered_write_stream.hpp +++ b/include/boost/asio/buffered_write_stream.hpp @@ -47,8 +47,8 @@ namespace asio { * @e Shared @e objects: Unsafe. * * @par Concepts: - * Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream, - * Sync_Read_Stream, Sync_Write_Stream. + * Async_Read_Stream, Async_Write_Stream, Stream, Sync_Read_Stream, + * Sync_Write_Stream. */ template class buffered_write_stream @@ -61,9 +61,6 @@ public: /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; - /// The type used for reporting errors. - typedef typename next_layer_type::error_type error_type; - #if defined(GENERATING_DOCUMENTATION) /// The default buffer size. static const std::size_t default_buffer_size = implementation_defined; @@ -112,10 +109,9 @@ public: } /// Close the stream. - template - void close(Error_Handler error_handler) + boost::system::error_code close(boost::system::error_code& ec) { - next_layer_.close(error_handler); + return next_layer_.close(ec); } /// Flush all data from the buffer to the next layer. Returns the number of @@ -131,13 +127,12 @@ public: /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation, or 0 if an - /// error occurred and the error handler did not throw. - template - std::size_t flush(Error_Handler error_handler) + /// error occurred. + std::size_t flush(boost::system::error_code& ec) { std::size_t bytes_written = write(next_layer_, buffer(storage_.data(), storage_.size()), - transfer_all(), error_handler); + transfer_all(), ec); storage_.consume(bytes_written); return bytes_written; } @@ -154,10 +149,11 @@ public: { } - void operator()(const error_type& e, std::size_t bytes_written) + void operator()(const boost::system::error_code& ec, + std::size_t bytes_written) { storage_.consume(bytes_written); - io_service_.dispatch(detail::bind_handler(handler_, e, bytes_written)); + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_written)); } private: @@ -186,11 +182,12 @@ public: /// Write the given data to the stream. Returns the number of bytes written, /// or 0 if an error occurred and the error handler did not throw. - template + template std::size_t write_some(const Const_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - if (storage_.size() == storage_.capacity() && !flush(error_handler)) + ec = boost::system::error_code(); + if (storage_.size() == storage_.capacity() && !flush(ec)) return 0; return copy(buffers); } @@ -209,12 +206,12 @@ public: { } - void operator()(const error_type& e, std::size_t) + void operator()(const boost::system::error_code& ec, std::size_t) { - if (e) + if (ec) { std::size_t length = 0; - io_service_.dispatch(detail::bind_handler(handler_, e, length)); + io_service_.dispatch(detail::bind_handler(handler_, ec, length)); } else { @@ -238,7 +235,7 @@ public: space_avail -= length; } - io_service_.dispatch(detail::bind_handler(handler_, e, bytes_copied)); + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); } } @@ -262,7 +259,8 @@ public: else { std::size_t bytes_copied = copy(buffers); - io_service().post(detail::bind_handler(handler, 0, bytes_copied)); + io_service().post(detail::bind_handler( + handler, boost::asio::error::success, bytes_copied)); } } @@ -275,12 +273,12 @@ public: } /// Read some data from the stream. Returns the number of bytes read or 0 if - /// an error occurred and the error handler did not throw an exception. - template + /// an error occurred. + template std::size_t read_some(const Mutable_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return next_layer_.read_some(buffers, error_handler); + return next_layer_.read_some(buffers, ec); } /// Start an asynchronous read. The buffer into which the data will be read @@ -300,11 +298,12 @@ public: } /// Peek at the incoming data on the stream. Returns the number of bytes read, - /// or 0 if an error occurred and the error handler did not throw. - template - std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler) + /// or 0 if an error occurred. + template + std::size_t peek(const Mutable_Buffers& buffers, + boost::system::error_code& ec) { - return next_layer_.peek(buffers, error_handler); + return next_layer_.peek(buffers, ec); } /// Determine the amount of data that may be read without blocking. @@ -314,10 +313,9 @@ public: } /// Determine the amount of data that may be read without blocking. - template - std::size_t in_avail(Error_Handler error_handler) + std::size_t in_avail(boost::system::error_code& ec) { - return next_layer_.in_avail(error_handler); + return next_layer_.in_avail(ec); } private: diff --git a/include/boost/asio/datagram_socket_service.hpp b/include/boost/asio/datagram_socket_service.hpp index 3b35981f..499beac6 100644 --- a/include/boost/asio/datagram_socket_service.hpp +++ b/include/boost/asio/datagram_socket_service.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -99,29 +100,29 @@ public: } // Open a new datagram socket implementation. - template - void open(implementation_type& impl, const protocol_type& protocol, - Error_Handler error_handler) + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) { if (protocol.type() == SOCK_DGRAM) - service_impl_.open(impl, protocol, error_handler); + service_impl_.open(impl, protocol, ec); else - error_handler(boost::asio::error(boost::asio::error::invalid_argument)); + ec = boost::asio::error::invalid_argument; + return ec; } /// Assign an existing native socket to a datagram socket. - template - void assign(implementation_type& impl, const protocol_type& protocol, - const native_type& native_socket, Error_Handler error_handler) + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) { - service_impl_.assign(impl, protocol, native_socket, error_handler); + return service_impl_.assign(impl, protocol, native_socket, ec); } /// Close a datagram socket implementation. - template - void close(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) { - service_impl_.close(impl, error_handler); + return service_impl_.close(impl, ec); } /// Get the native socket implementation. @@ -131,26 +132,24 @@ public: } /// Cancel all asynchronous operations associated with the socket. - template - void cancel(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) { - service_impl_.cancel(impl, error_handler); + return service_impl_.cancel(impl, ec); } // Bind the datagram socket to the specified local endpoint. - template - void bind(implementation_type& impl, const endpoint_type& endpoint, - Error_Handler error_handler) + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) { - service_impl_.bind(impl, endpoint, error_handler); + return service_impl_.bind(impl, endpoint, ec); } /// Connect the datagram socket to the specified endpoint. - template - void connect(implementation_type& impl, const endpoint_type& peer_endpoint, - Error_Handler error_handler) + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) { - service_impl_.connect(impl, peer_endpoint, error_handler); + return service_impl_.connect(impl, peer_endpoint, ec); } /// Start an asynchronous connect. @@ -162,63 +161,56 @@ public: } /// Set a socket option. - template - void set_option(implementation_type& impl, const Option& option, - Error_Handler error_handler) + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) { - service_impl_.set_option(impl, option, error_handler); + return service_impl_.set_option(impl, option, ec); } /// Get a socket option. - template - void get_option(const implementation_type& impl, Option& option, - Error_Handler error_handler) const + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const { - service_impl_.get_option(impl, option, error_handler); + return service_impl_.get_option(impl, option, ec); } /// Perform an IO control command on the socket. - template - void io_control(implementation_type& impl, IO_Control_Command& command, - Error_Handler error_handler) + template + boost::system::error_code io_control(implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) { - service_impl_.io_control(impl, command, error_handler); + return service_impl_.io_control(impl, command, ec); } /// Get the local endpoint. - template endpoint_type local_endpoint(const implementation_type& impl, - Error_Handler error_handler) const + boost::system::error_code& ec) const { - endpoint_type endpoint; - service_impl_.get_local_endpoint(impl, endpoint, error_handler); - return endpoint; + return service_impl_.local_endpoint(impl, ec); } /// Get the remote endpoint. - template endpoint_type remote_endpoint(const implementation_type& impl, - Error_Handler error_handler) const + boost::system::error_code& ec) const { - endpoint_type endpoint; - service_impl_.get_remote_endpoint(impl, endpoint, error_handler); - return endpoint; + return service_impl_.remote_endpoint(impl, ec); } /// Disable sends or receives on the socket. - template - void shutdown(implementation_type& impl, socket_base::shutdown_type what, - Error_Handler error_handler) + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) { - service_impl_.shutdown(impl, what, error_handler); + return service_impl_.shutdown(impl, what, ec); } /// Send the given data to the peer. - template + template std::size_t send(implementation_type& impl, const Const_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return service_impl_.send(impl, buffers, flags, error_handler); + return service_impl_.send(impl, buffers, flags, ec); } /// Start an asynchronous send. @@ -230,13 +222,12 @@ public: } /// Send a datagram to the specified endpoint. - template + template std::size_t send_to(implementation_type& impl, const Const_Buffers& buffers, const endpoint_type& destination, socket_base::message_flags flags, - Error_Handler error_handler) + boost::system::error_code& ec) { - return service_impl_.send_to(impl, buffers, destination, flags, - error_handler); + return service_impl_.send_to(impl, buffers, destination, flags, ec); } /// Start an asynchronous send. @@ -249,11 +240,11 @@ public: } /// Receive some data from the peer. - template + template std::size_t receive(implementation_type& impl, const Mutable_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return service_impl_.receive(impl, buffers, flags, error_handler); + return service_impl_.receive(impl, buffers, flags, ec); } /// Start an asynchronous receive. @@ -265,13 +256,13 @@ public: } /// Receive a datagram with the endpoint of the sender. - template + template std::size_t receive_from(implementation_type& impl, const Mutable_Buffers& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { return service_impl_.receive_from(impl, buffers, sender_endpoint, flags, - error_handler); + ec); } /// Start an asynchronous receive that will get the endpoint of the sender. diff --git a/include/boost/asio/detail/deadline_timer_service.hpp b/include/boost/asio/detail/deadline_timer_service.hpp index 3ce880d0..626b385b 100644 --- a/include/boost/asio/detail/deadline_timer_service.hpp +++ b/include/boost/asio/detail/deadline_timer_service.hpp @@ -136,7 +136,8 @@ public: ::timeval tv; tv.tv_sec = timeout.total_seconds(); tv.tv_usec = timeout.total_microseconds() % 1000000; - socket_ops::select(0, 0, 0, 0, &tv); + boost::system::error_code ec; + socket_ops::select(0, 0, 0, 0, &tv, ec); now = Time_Traits::now(); } } @@ -152,10 +153,9 @@ public: { } - void operator()(int result) + void operator()(const boost::system::error_code& result) { - boost::asio::error e(result); - io_service_.post(detail::bind_handler(handler_, e)); + io_service_.post(detail::bind_handler(handler_, result)); } private: diff --git a/include/boost/asio/detail/epoll_reactor.hpp b/include/boost/asio/detail/epoll_reactor.hpp index 2ce249fd..7106bf47 100644 --- a/include/boost/asio/detail/epoll_reactor.hpp +++ b/include/boost/asio/detail/epoll_reactor.hpp @@ -28,10 +28,11 @@ #include #include #include +#include #include +#include #include -#include #include #include #include @@ -140,7 +141,7 @@ public: return; if (!read_op_queue_.has_operation(descriptor)) - if (handler(0)) + if (handler(boost::asio::error::success)) return; if (read_op_queue_.enqueue_operation(descriptor, handler)) @@ -156,8 +157,8 @@ public: int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); if (result != 0) { - int error = errno; - read_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + read_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -173,7 +174,7 @@ public: return; if (!write_op_queue_.has_operation(descriptor)) - if (handler(0)) + if (handler(boost::asio::error::success)) return; if (write_op_queue_.enqueue_operation(descriptor, handler)) @@ -189,8 +190,8 @@ public: int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); if (result != 0) { - int error = errno; - write_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + write_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -218,8 +219,8 @@ public: int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); if (result != 0) { - int error = errno; - except_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + except_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -249,9 +250,9 @@ public: int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); if (result != 0) { - int error = errno; - write_op_queue_.dispatch_all_operations(descriptor, error); - except_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + write_op_queue_.dispatch_all_operations(descriptor, ec); + except_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -399,9 +400,10 @@ private: { if (events[i].events & (EPOLLERR | EPOLLHUP)) { - except_op_queue_.dispatch_all_operations(descriptor, 0); - read_op_queue_.dispatch_all_operations(descriptor, 0); - write_op_queue_.dispatch_all_operations(descriptor, 0); + boost::system::error_code ec; + except_op_queue_.dispatch_all_operations(descriptor, ec); + read_op_queue_.dispatch_all_operations(descriptor, ec); + write_op_queue_.dispatch_all_operations(descriptor, ec); epoll_event ev = { 0, { 0 } }; ev.events = 0; @@ -413,21 +415,22 @@ private: bool more_reads = false; bool more_writes = false; bool more_except = false; + boost::system::error_code ec; // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. if (events[i].events & EPOLLPRI) - more_except = except_op_queue_.dispatch_operation(descriptor, 0); + more_except = except_op_queue_.dispatch_operation(descriptor, ec); else more_except = except_op_queue_.has_operation(descriptor); if (events[i].events & EPOLLIN) - more_reads = read_op_queue_.dispatch_operation(descriptor, 0); + more_reads = read_op_queue_.dispatch_operation(descriptor, ec); else more_reads = read_op_queue_.has_operation(descriptor); if (events[i].events & EPOLLOUT) - more_writes = write_op_queue_.dispatch_operation(descriptor, 0); + more_writes = write_op_queue_.dispatch_operation(descriptor, ec); else more_writes = write_op_queue_.has_operation(descriptor); @@ -443,10 +446,10 @@ private: int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); if (result != 0) { - int error = errno; - read_op_queue_.dispatch_all_operations(descriptor, error); - write_op_queue_.dispatch_all_operations(descriptor, error); - except_op_queue_.dispatch_all_operations(descriptor, error); + ec = boost::system::error_code(errno, boost::system::native_ecat); + read_op_queue_.dispatch_all_operations(descriptor, ec); + write_op_queue_.dispatch_all_operations(descriptor, ec); + except_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -504,7 +507,9 @@ private: int fd = epoll_create(epoll_size); if (fd == -1) { - system_exception e("epoll", errno); + boost::system::system_error e( + boost::system::error_code(errno, boost::system::native_ecat), + "epoll"); boost::throw_exception(e); } return fd; diff --git a/include/boost/asio/detail/kqueue_reactor.hpp b/include/boost/asio/detail/kqueue_reactor.hpp index d2021457..c4008d67 100644 --- a/include/boost/asio/detail/kqueue_reactor.hpp +++ b/include/boost/asio/detail/kqueue_reactor.hpp @@ -31,10 +31,11 @@ #include #include #include +#include #include +#include #include -#include #include #include #include @@ -139,7 +140,7 @@ public: return; if (!read_op_queue_.has_operation(descriptor)) - if (handler(0)) + if (handler(boost::asio::error::success)) return; if (read_op_queue_.enqueue_operation(descriptor, handler)) @@ -148,8 +149,8 @@ public: EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0); if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) { - int error = errno; - read_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + read_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -165,7 +166,7 @@ public: return; if (!write_op_queue_.has_operation(descriptor)) - if (handler(0)) + if (handler(boost::asio::error::success)) return; if (write_op_queue_.enqueue_operation(descriptor, handler)) @@ -174,8 +175,8 @@ public: EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0); if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) { - int error = errno; - write_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + write_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -199,8 +200,8 @@ public: EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0); if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) { - int error = errno; - except_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + except_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -222,8 +223,8 @@ public: EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0); if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) { - int error = errno; - write_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + write_op_queue_.dispatch_all_operations(descriptor, ec); } } @@ -236,9 +237,9 @@ public: EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0); if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) { - int error = errno; - except_op_queue_.dispatch_all_operations(descriptor, error); - write_op_queue_.dispatch_all_operations(descriptor, error); + boost::system::error_code ec(errno, boost::system::native_ecat); + except_op_queue_.dispatch_all_operations(descriptor, ec); + write_op_queue_.dispatch_all_operations(descriptor, ec); } } } @@ -394,21 +395,24 @@ private: bool more_except = false; if (events[i].flags & EV_ERROR) { - int error = events[i].data; + boost::system::error_code error( + events[i].data, boost::system::native_ecat); except_op_queue_.dispatch_all_operations(descriptor, error); read_op_queue_.dispatch_all_operations(descriptor, error); } else if (events[i].flags & EV_OOBAND) { - more_except = except_op_queue_.dispatch_operation(descriptor, 0); + boost::system::error_code error; + more_except = except_op_queue_.dispatch_operation(descriptor, error); if (events[i].data > 0) - more_reads = read_op_queue_.dispatch_operation(descriptor, 0); + more_reads = read_op_queue_.dispatch_operation(descriptor, error); else more_reads = read_op_queue_.has_operation(descriptor); } else { - more_reads = read_op_queue_.dispatch_operation(descriptor, 0); + boost::system::error_code error; + more_reads = read_op_queue_.dispatch_operation(descriptor, error); more_except = except_op_queue_.has_operation(descriptor); } @@ -422,7 +426,7 @@ private: EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0); if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) { - int error = errno; + boost::system::error_code error(errno, boost::system::native_ecat); except_op_queue_.dispatch_all_operations(descriptor, error); read_op_queue_.dispatch_all_operations(descriptor, error); } @@ -433,12 +437,14 @@ private: bool more_writes = false; if (events[i].flags & EV_ERROR) { - int error = events[i].data; + boost::system::error_code error( + events[i].data, boost::system::native_ecat); write_op_queue_.dispatch_all_operations(descriptor, error); } else { - more_writes = write_op_queue_.dispatch_operation(descriptor, 0); + boost::system::error_code error; + more_writes = write_op_queue_.dispatch_operation(descriptor, error); } // Update the descriptor in the kqueue. @@ -449,7 +455,7 @@ private: EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0); if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) { - int error = errno; + boost::system::error_code error(errno, boost::system::native_ecat); write_op_queue_.dispatch_all_operations(descriptor, error); } } @@ -505,7 +511,9 @@ private: int fd = kqueue(); if (fd == -1) { - system_exception e("kqueue", errno); + boost::system::system_error e( + boost::system::error_code(errno, boost::system::native_ecat), + "kqueue"); boost::throw_exception(e); } return fd; diff --git a/include/boost/asio/detail/null_thread.hpp b/include/boost/asio/detail/null_thread.hpp index 4f5eef81..bc4917d9 100644 --- a/include/boost/asio/detail/null_thread.hpp +++ b/include/boost/asio/detail/null_thread.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #if !defined(BOOST_HAS_THREADS) @@ -28,7 +29,6 @@ #include #include -#include #include namespace boost { @@ -43,7 +43,7 @@ public: template null_thread(Function f) { - system_exception e("thread", boost::asio::error::not_supported); + boost::system::system_error e(boost::asio::error::not_supported, "thread"); boost::throw_exception(e); } diff --git a/include/boost/asio/detail/posix_event.hpp b/include/boost/asio/detail/posix_event.hpp index 9e11a3dc..c5e3f64d 100644 --- a/include/boost/asio/detail/posix_event.hpp +++ b/include/boost/asio/detail/posix_event.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #if defined(BOOST_HAS_PTHREADS) @@ -28,7 +29,6 @@ #include #include -#include #include namespace boost { @@ -46,7 +46,9 @@ public: int error = ::pthread_mutex_init(&mutex_, 0); if (error != 0) { - system_exception e("event", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "event"); boost::throw_exception(e); } @@ -54,7 +56,9 @@ public: if (error != 0) { ::pthread_mutex_destroy(&mutex_); - system_exception e("event", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "event"); boost::throw_exception(e); } } diff --git a/include/boost/asio/detail/posix_mutex.hpp b/include/boost/asio/detail/posix_mutex.hpp index bec51e97..913926a0 100644 --- a/include/boost/asio/detail/posix_mutex.hpp +++ b/include/boost/asio/detail/posix_mutex.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #if defined(BOOST_HAS_PTHREADS) @@ -28,7 +29,6 @@ #include #include -#include #include #include @@ -48,7 +48,9 @@ public: int error = ::pthread_mutex_init(&mutex_, 0); if (error != 0) { - system_exception e("mutex", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "mutex"); boost::throw_exception(e); } } @@ -65,7 +67,9 @@ public: int error = ::pthread_mutex_lock(&mutex_); if (error != 0) { - system_exception e("mutex", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "mutex"); boost::throw_exception(e); } } @@ -76,7 +80,9 @@ public: int error = ::pthread_mutex_unlock(&mutex_); if (error != 0) { - system_exception e("mutex", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "mutex"); boost::throw_exception(e); } } diff --git a/include/boost/asio/detail/posix_thread.hpp b/include/boost/asio/detail/posix_thread.hpp index f50c2a48..cee3c817 100644 --- a/include/boost/asio/detail/posix_thread.hpp +++ b/include/boost/asio/detail/posix_thread.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #if defined(BOOST_HAS_PTHREADS) @@ -29,7 +30,6 @@ #include #include -#include #include namespace boost { @@ -52,7 +52,9 @@ public: asio_detail_posix_thread_function, arg.get()); if (error != 0) { - system_exception e("thread", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "thread"); boost::throw_exception(e); } arg.release(); diff --git a/include/boost/asio/detail/posix_tss_ptr.hpp b/include/boost/asio/detail/posix_tss_ptr.hpp index 2d8540a6..80bc0b18 100644 --- a/include/boost/asio/detail/posix_tss_ptr.hpp +++ b/include/boost/asio/detail/posix_tss_ptr.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #if defined(BOOST_HAS_PTHREADS) @@ -28,7 +29,6 @@ #include #include -#include #include namespace boost { @@ -46,7 +46,9 @@ public: int error = ::pthread_key_create(&tss_key_, 0); if (error != 0) { - system_exception e("tss", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "tss"); boost::throw_exception(e); } } diff --git a/include/boost/asio/detail/reactive_socket_service.hpp b/include/boost/asio/detail/reactive_socket_service.hpp index df268644..5fc32921 100644 --- a/include/boost/asio/detail/reactive_socket_service.hpp +++ b/include/boost/asio/detail/reactive_socket_service.hpp @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -117,7 +116,8 @@ public: if (impl.flags_ & implementation_type::internal_non_blocking) { ioctl_arg_type non_blocking = 0; - socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking); + boost::system::error_code ignored_ec; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); impl.flags_ &= ~implementation_type::internal_non_blocking; } @@ -126,66 +126,67 @@ public: ::linger opt; opt.l_onoff = 0; opt.l_linger = 0; + boost::system::error_code ignored_ec; socket_ops::setsockopt(impl.socket_, - SOL_SOCKET, SO_LINGER, &opt, sizeof(opt)); + SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); } - socket_ops::close(impl.socket_); + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, ignored_ec); + impl.socket_ = invalid_socket; } } // Open a new socket implementation. - template - void open(implementation_type& impl, const protocol_type& protocol, - Error_Handler error_handler) + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) { - close(impl, boost::asio::ignore_error()); + boost::system::error_code ignored_ec; + close(impl, ignored_ec); socket_holder sock(socket_ops::socket(protocol.family(), - protocol.type(), protocol.protocol())); + protocol.type(), protocol.protocol(), ec)); if (sock.get() == invalid_socket) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + return ec; if (int err = reactor_.register_descriptor(sock.get())) { - error_handler(boost::asio::error(err)); - return; + ec = boost::system::error_code(err, boost::system::native_ecat); + return ec; } impl.socket_ = sock.release(); impl.flags_ = 0; impl.protocol_ = protocol; - - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); + return ec; } // Assign a native socket to a socket implementation. - template - void assign(implementation_type& impl, const protocol_type& protocol, - const native_type& native_socket, Error_Handler error_handler) + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) { - close(impl, boost::asio::ignore_error()); + boost::system::error_code ignored_ec; + close(impl, ignored_ec); if (int err = reactor_.register_descriptor(native_socket)) { - error_handler(boost::asio::error(err)); - return; + ec = boost::system::error_code(err, boost::system::native_ecat); + return ec; } impl.socket_ = native_socket; impl.flags_ = 0; impl.protocol_ = protocol; - - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); + return ec; } // Destroy a socket implementation. - template - void close(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) { if (impl.socket_ != invalid_socket) { @@ -194,20 +195,19 @@ public: if (impl.flags_ & implementation_type::internal_non_blocking) { ioctl_arg_type non_blocking = 0; - socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking); + boost::system::error_code ignored_ec; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); impl.flags_ &= ~implementation_type::internal_non_blocking; } - if (socket_ops::close(impl.socket_) == socket_error_retval) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + if (socket_ops::close(impl.socket_, ec) == socket_error_retval) + return ec; impl.socket_ = invalid_socket; } - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); + return ec; } // Get the native socket representation. @@ -217,55 +217,49 @@ public: } // Cancel all operations associated with the socket. - template - void cancel(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - error_handler(error); + ec = boost::asio::error::bad_descriptor; + return ec; } else { reactor_.cancel_ops(impl.socket_); - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; + return ec; } } // Bind the socket to the specified local endpoint. - template - void bind(implementation_type& impl, const endpoint_type& endpoint, - Error_Handler error_handler) + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) { - if (socket_ops::bind(impl.socket_, endpoint.data(), - endpoint.size()) == socket_error_retval) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; } // Place the socket into the state where it will listen for new connections. - template - void listen(implementation_type& impl, int backlog, - Error_Handler error_handler) + boost::system::error_code listen(implementation_type& impl, int backlog, + boost::system::error_code& ec) { - if (socket_ops::listen(impl.socket_, backlog) == socket_error_retval) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::listen(impl.socket_, backlog, ec); + return ec; } // Set a socket option. - template - void set_option(implementation_type& impl, const Option& option, - Error_Handler error_handler) + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) { if (option.level(impl.protocol_) == custom_socket_option_level && option.name(impl.protocol_) == enable_connection_aborted_option) { if (option.size(impl.protocol_) != sizeof(int)) { - error_handler(boost::asio::error(boost::asio::error::invalid_argument)); + ec = boost::asio::error::invalid_argument; } else { @@ -273,8 +267,9 @@ public: impl.flags_ |= implementation_type::enable_connection_aborted; else impl.flags_ &= ~implementation_type::enable_connection_aborted; - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); } + return ec; } else { @@ -284,26 +279,24 @@ public: impl.flags_ |= implementation_type::user_set_linger; } - if (socket_ops::setsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_))) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::setsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; } } // Set a socket option. - template - void get_option(const implementation_type& impl, Option& option, - Error_Handler error_handler) const + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const { if (option.level(impl.protocol_) == custom_socket_option_level && option.name(impl.protocol_) == enable_connection_aborted_option) { if (option.size(impl.protocol_) != sizeof(int)) { - error_handler(boost::asio::error(boost::asio::error::invalid_argument)); + ec = boost::asio::error::invalid_argument; } else { @@ -312,25 +305,24 @@ public: *target = 1; else *target = 0; - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); } + return ec; } else { size_t size = option.size(impl.protocol_); - if (socket_ops::getsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size)) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::getsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + return ec; } } // Perform an IO control command on the socket. - template - void io_control(implementation_type& impl, IO_Control_Command& command, - Error_Handler error_handler) + template + boost::system::error_code io_control(implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) { if (command.name() == static_cast(FIONBIO)) { @@ -338,65 +330,52 @@ public: impl.flags_ |= implementation_type::user_set_non_blocking; else impl.flags_ &= ~implementation_type::user_set_non_blocking; - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); } else { - if (socket_ops::ioctl(impl.socket_, command.name(), - static_cast(command.data()))) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::ioctl(impl.socket_, command.name(), + static_cast(command.data()), ec); } + return ec; } // Get the local endpoint. - template - void get_local_endpoint(const implementation_type& impl, - endpoint_type& endpoint, Error_Handler error_handler) const + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const { + endpoint_type endpoint; socket_addr_len_type addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len)) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } - + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); endpoint.resize(addr_len); - error_handler(boost::asio::error(0)); + return endpoint; } // Get the remote endpoint. - template - void get_remote_endpoint(const implementation_type& impl, - endpoint_type& endpoint, Error_Handler error_handler) const + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const { + endpoint_type endpoint; socket_addr_len_type addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len)) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } - + if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); endpoint.resize(addr_len); - error_handler(boost::asio::error(0)); + return endpoint; } /// Disable sends or receives on the socket. - template - void shutdown(implementation_type& impl, socket_base::shutdown_type what, - Error_Handler error_handler) + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) { - if (socket_ops::shutdown(impl.socket_, what) != 0) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::shutdown(impl.socket_, what, ec); + return ec; } // Send the given data to the peer. - template + template size_t send(implementation_type& impl, const Const_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { // Copy buffers into array. socket_ops::buf bufs[max_buffers]; @@ -416,7 +395,7 @@ public: // A request to receive 0 bytes on a stream socket is a no-op. if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) { - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; return 0; } @@ -424,31 +403,21 @@ public: for (;;) { // Try to complete the operation without blocking. - int bytes_sent = socket_ops::send(impl.socket_, bufs, i, flags); - int error = socket_ops::get_error(); + int bytes_sent = socket_ops::send(impl.socket_, bufs, i, flags, ec); // Check if operation succeeded. if (bytes_sent >= 0) - { - error_handler(boost::asio::error(0)); return bytes_sent; - } // Operation failed. if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (error != boost::asio::error::would_block - && error != boost::asio::error::try_again)) - { - error_handler(boost::asio::error(error)); + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) return 0; - } // Wait for socket to become ready. - if (socket_ops::poll_write(impl.socket_) < 0) - { - error_handler(boost::asio::error(socket_ops::get_error())); + if (socket_ops::poll_write(impl.socket_, ec) < 0) return 0; - } } } @@ -468,13 +437,12 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether the operation was successful. - if (result != 0) + if (result) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error, 0)); + io_service_.post(bind_handler(handler_, result, 0)); return true; } @@ -492,16 +460,15 @@ public: } // Send the data. - int bytes = socket_ops::send(socket_, bufs, i, flags_); - boost::asio::error error(bytes < 0 - ? socket_ops::get_error() : boost::asio::error::success); + boost::system::error_code ec; + int bytes = socket_ops::send(socket_, bufs, i, flags_, ec); // Check if we need to run the operation again. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) return false; - io_service_.post(bind_handler(handler_, error, bytes < 0 ? 0 : bytes)); + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); return true; } @@ -522,8 +489,8 @@ public: { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); } else { @@ -543,8 +510,8 @@ public: // A request to receive 0 bytes on a stream socket is a no-op. if (total_buffer_size == 0) { - boost::asio::error error(boost::asio::error::success); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, + boost::asio::error::success, 0)); return; } } @@ -553,10 +520,10 @@ public: if (!(impl.flags_ & implementation_type::internal_non_blocking)) { ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, ec, 0)); return; } impl.flags_ |= implementation_type::internal_non_blocking; @@ -570,10 +537,10 @@ public: // Send a datagram to the specified endpoint. Returns the number of bytes // sent. - template + template size_t send_to(implementation_type& impl, const Const_Buffers& buffers, const endpoint_type& destination, socket_base::message_flags flags, - Error_Handler error_handler) + boost::system::error_code& ec) { // Copy buffers into array. socket_ops::buf bufs[max_buffers]; @@ -593,31 +560,21 @@ public: { // Try to complete the operation without blocking. int bytes_sent = socket_ops::sendto(impl.socket_, bufs, i, flags, - destination.data(), destination.size()); - int error = socket_ops::get_error(); + destination.data(), destination.size(), ec); // Check if operation succeeded. if (bytes_sent >= 0) - { - error_handler(boost::asio::error(0)); return bytes_sent; - } // Operation failed. if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (error != boost::asio::error::would_block - && error != boost::asio::error::try_again)) - { - error_handler(boost::asio::error(error)); + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) return 0; - } // Wait for socket to become ready. - if (socket_ops::poll_write(impl.socket_) < 0) - { - error_handler(boost::asio::error(socket_ops::get_error())); + if (socket_ops::poll_write(impl.socket_, ec) < 0) return 0; - } } } @@ -638,13 +595,12 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether the operation was successful. - if (result != 0) + if (result) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error, 0)); + io_service_.post(bind_handler(handler_, result, 0)); return true; } @@ -662,17 +618,16 @@ public: } // Send the data. + boost::system::error_code ec; int bytes = socket_ops::sendto(socket_, bufs, i, flags_, - destination_.data(), destination_.size()); - boost::asio::error error(bytes < 0 - ? socket_ops::get_error() : boost::asio::error::success); + destination_.data(), destination_.size(), ec); // Check if we need to run the operation again. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) return false; - io_service_.post(bind_handler(handler_, error, bytes < 0 ? 0 : bytes)); + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); return true; } @@ -695,8 +650,8 @@ public: { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); } else { @@ -704,10 +659,10 @@ public: if (!(impl.flags_ & implementation_type::internal_non_blocking)) { ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, ec, 0)); return; } impl.flags_ |= implementation_type::internal_non_blocking; @@ -720,9 +675,9 @@ public: } // Receive some data from the peer. Returns the number of bytes received. - template + template size_t receive(implementation_type& impl, const Mutable_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { // Copy buffers into array. socket_ops::buf bufs[max_buffers]; @@ -742,7 +697,7 @@ public: // A request to receive 0 bytes on a stream socket is a no-op. if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) { - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; return 0; } @@ -750,38 +705,28 @@ public: for (;;) { // Try to complete the operation without blocking. - int bytes_recvd = socket_ops::recv(impl.socket_, bufs, i, flags); - int error = socket_ops::get_error(); + int bytes_recvd = socket_ops::recv(impl.socket_, bufs, i, flags, ec); // Check if operation succeeded. if (bytes_recvd > 0) - { - error_handler(boost::asio::error(0)); return bytes_recvd; - } // Check for EOF. if (bytes_recvd == 0) { - error_handler(boost::asio::error(boost::asio::error::eof)); + ec = boost::asio::error::eof; return 0; } // Operation failed. if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (error != boost::asio::error::would_block - && error != boost::asio::error::try_again)) - { - error_handler(boost::asio::error(error)); + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) return 0; - } // Wait for socket to become ready. - if (socket_ops::poll_read(impl.socket_) < 0) - { - error_handler(boost::asio::error(socket_ops::get_error())); + if (socket_ops::poll_read(impl.socket_, ec) < 0) return 0; - } } } @@ -801,13 +746,12 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether the operation was successful. - if (result != 0) + if (result) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error, 0)); + io_service_.post(bind_handler(handler_, result, 0)); return true; } @@ -825,20 +769,17 @@ public: } // Receive some data. - int bytes = socket_ops::recv(socket_, bufs, i, flags_); - int error_code = boost::asio::error::success; - if (bytes < 0) - error_code = socket_ops::get_error(); - else if (bytes == 0) - error_code = boost::asio::error::eof; - boost::asio::error error(error_code); + boost::system::error_code ec; + int bytes = socket_ops::recv(socket_, bufs, i, flags_, ec); + if (bytes == 0) + ec = boost::asio::error::eof; // Check if we need to run the operation again. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) return false; - io_service_.post(bind_handler(handler_, error, bytes < 0 ? 0 : bytes)); + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); return true; } @@ -859,8 +800,8 @@ public: { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); } else { @@ -880,8 +821,8 @@ public: // A request to receive 0 bytes on a stream socket is a no-op. if (total_buffer_size == 0) { - boost::asio::error error(boost::asio::error::success); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, + boost::asio::error::success, 0)); return; } } @@ -890,10 +831,10 @@ public: if (!(impl.flags_ & implementation_type::internal_non_blocking)) { ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, ec, 0)); return; } impl.flags_ |= implementation_type::internal_non_blocking; @@ -916,10 +857,10 @@ public: // Receive a datagram with the endpoint of the sender. Returns the number of // bytes received. - template + template size_t receive_from(implementation_type& impl, const Mutable_Buffers& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, - Error_Handler error_handler) + boost::system::error_code& ec) { // Copy buffers into array. socket_ops::buf bufs[max_buffers]; @@ -940,39 +881,31 @@ public: // Try to complete the operation without blocking. socket_addr_len_type addr_len = sender_endpoint.capacity(); int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs, i, flags, - sender_endpoint.data(), &addr_len); - int error = socket_ops::get_error(); + sender_endpoint.data(), &addr_len, ec); // Check if operation succeeded. if (bytes_recvd > 0) { sender_endpoint.resize(addr_len); - error_handler(boost::asio::error(0)); return bytes_recvd; } // Check for EOF. if (bytes_recvd == 0) { - error_handler(boost::asio::error(boost::asio::error::eof)); + ec = boost::asio::error::eof; return 0; } // Operation failed. if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (error != boost::asio::error::would_block - && error != boost::asio::error::try_again)) - { - error_handler(boost::asio::error(error)); + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) return 0; - } // Wait for socket to become ready. - if (socket_ops::poll_read(impl.socket_) < 0) - { - error_handler(boost::asio::error(socket_ops::get_error())); + if (socket_ops::poll_read(impl.socket_, ec) < 0) return 0; - } } } @@ -994,13 +927,12 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether the operation was successful. if (result != 0) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error, 0)); + io_service_.post(bind_handler(handler_, result, 0)); return true; } @@ -1019,22 +951,19 @@ public: // Receive some data. socket_addr_len_type addr_len = sender_endpoint_.capacity(); + boost::system::error_code ec; int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_, - sender_endpoint_.data(), &addr_len); - int error_code = boost::asio::error::success; - if (bytes < 0) - error_code = socket_ops::get_error(); - else if (bytes == 0) - error_code = boost::asio::error::eof; - boost::asio::error error(error_code); + sender_endpoint_.data(), &addr_len, ec); + if (bytes == 0) + ec = boost::asio::error::eof; // Check if we need to run the operation again. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) return false; sender_endpoint_.resize(addr_len); - io_service_.post(bind_handler(handler_, error, bytes < 0 ? 0 : bytes)); + io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes)); return true; } @@ -1058,8 +987,8 @@ public: { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor, 0)); } else { @@ -1067,10 +996,10 @@ public: if (!(impl.flags_ & implementation_type::internal_non_blocking)) { ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error, 0)); + io_service().post(bind_handler(handler, ec, 0)); return; } impl.flags_ |= implementation_type::internal_non_blocking; @@ -1084,87 +1013,65 @@ public: } // Accept a new connection. - template - void accept(implementation_type& impl, Socket& peer, - Error_Handler error_handler) + template + boost::system::error_code accept(implementation_type& impl, Socket& peer, + boost::system::error_code& ec) { // We cannot accept a socket that is already open. if (peer.native() != invalid_socket) { - error_handler(boost::asio::error(boost::asio::error::already_connected)); - return; + ec = boost::asio::error::already_connected; + return ec; } // Accept a socket. for (;;) { // Try to complete the operation without blocking. - socket_holder new_socket(socket_ops::accept(impl.socket_, 0, 0)); - int error = socket_ops::get_error(); + socket_holder new_socket(socket_ops::accept(impl.socket_, 0, 0, ec)); // Check if operation succeeded. if (new_socket.get() >= 0) { - boost::asio::error temp_error; - peer.assign(impl.protocol_, new_socket.get(), - boost::asio::assign_error(temp_error)); - if (temp_error) - { - error_handler(temp_error); - } - else - { + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) new_socket.release(); - error_handler(boost::asio::error(0)); - } - return; + return ec; } // Operation failed. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) { if (impl.flags_ & implementation_type::user_set_non_blocking) - { - error_handler(boost::asio::error(error)); - return; - } + return ec; // Fall through to retry operation. } - else if (error == boost::asio::error::connection_aborted) + else if (ec == boost::asio::error::connection_aborted) { if (impl.flags_ & implementation_type::enable_connection_aborted) - { - error_handler(boost::asio::error(error)); - return; - } + return ec; // Fall through to retry operation. } else - { - error_handler(boost::asio::error(error)); - return; - } + return ec; // Wait for socket to become ready. - if (socket_ops::poll_read(impl.socket_) < 0) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return ec; } } // Accept a new connection. - template - void accept_endpoint(implementation_type& impl, Socket& peer, - endpoint_type& peer_endpoint, Error_Handler error_handler) + template + boost::system::error_code accept_endpoint(implementation_type& impl, + Socket& peer, endpoint_type& peer_endpoint, boost::system::error_code& ec) { // We cannot accept a socket that is already open. if (peer.native() != invalid_socket) { - error_handler(boost::asio::error(boost::asio::error::already_connected)); - return; + ec = boost::asio::error::already_connected; + return ec; } // Accept a socket. @@ -1172,61 +1079,40 @@ public: { // Try to complete the operation without blocking. socket_addr_len_type addr_len = peer_endpoint.capacity(); + boost::system::error_code ec; socket_holder new_socket(socket_ops::accept( - impl.socket_, peer_endpoint.data(), &addr_len)); - int error = socket_ops::get_error(); + impl.socket_, peer_endpoint.data(), &addr_len, ec)); // Check if operation succeeded. if (new_socket.get() >= 0) { peer_endpoint.resize(addr_len); - boost::asio::error temp_error; - peer.assign(impl.protocol_, new_socket.get(), - boost::asio::assign_error(temp_error)); - if (temp_error) - { - error_handler(temp_error); - } - else - { + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) new_socket.release(); - error_handler(boost::asio::error(0)); - } - return; + return ec; } // Operation failed. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) { if (impl.flags_ & implementation_type::user_set_non_blocking) - { - error_handler(boost::asio::error(error)); - return; - } + return ec; // Fall through to retry operation. } - else if (error == boost::asio::error::connection_aborted) + else if (ec == boost::asio::error::connection_aborted) { if (impl.flags_ & implementation_type::enable_connection_aborted) - { - error_handler(boost::asio::error(error)); - return; - } + return ec; // Fall through to retry operation. } else - { - error_handler(boost::asio::error(error)); - return; - } + return ec; // Wait for socket to become ready. - if (socket_ops::poll_read(impl.socket_) < 0) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return ec; } } @@ -1247,39 +1133,36 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether the operation was successful. - if (result != 0) + if (result) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, result)); return true; } // Accept the waiting connection. - socket_holder new_socket(socket_ops::accept(socket_, 0, 0)); - boost::asio::error error(new_socket.get() == invalid_socket - ? socket_ops::get_error() : boost::asio::error::success); + boost::system::error_code ec; + socket_holder new_socket(socket_ops::accept(socket_, 0, 0, ec)); // Check if we need to run the operation again. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) return false; - if (error == boost::asio::error::connection_aborted + if (ec == boost::asio::error::connection_aborted && !enable_connection_aborted_) return false; // Transfer ownership of the new socket to the peer object. - if (!error) + if (!ec) { - peer_.assign(protocol_, new_socket.get(), - boost::asio::assign_error(error)); - if (!error) + peer_.assign(protocol_, new_socket.get(), ec); + if (!ec) new_socket.release(); } - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, ec)); return true; } @@ -1300,13 +1183,13 @@ public: { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); } else if (peer.native() != invalid_socket) { - boost::asio::error error(boost::asio::error::already_connected); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::already_connected)); } else { @@ -1314,10 +1197,10 @@ public: if (!(impl.flags_ & implementation_type::internal_non_blocking)) { ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } impl.flags_ |= implementation_type::internal_non_blocking; @@ -1348,42 +1231,39 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether the operation was successful. - if (result != 0) + if (result) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, result)); return true; } // Accept the waiting connection. socket_addr_len_type addr_len = peer_endpoint_.capacity(); + boost::system::error_code ec; socket_holder new_socket(socket_ops::accept( - socket_, peer_endpoint_.data(), &addr_len)); - boost::asio::error error(new_socket.get() == invalid_socket - ? socket_ops::get_error() : boost::asio::error::success); + socket_, peer_endpoint_.data(), &addr_len, ec)); // Check if we need to run the operation again. - if (error == boost::asio::error::would_block - || error == boost::asio::error::try_again) + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) return false; - if (error == boost::asio::error::connection_aborted + if (ec == boost::asio::error::connection_aborted && !enable_connection_aborted_) return false; // Transfer ownership of the new socket to the peer object. - if (!error) + if (!ec) { peer_endpoint_.resize(addr_len); - peer_.assign(peer_endpoint_.protocol(), new_socket.get(), - boost::asio::assign_error(error)); - if (!error) + peer_.assign(peer_endpoint_.protocol(), new_socket.get(), ec); + if (!ec) new_socket.release(); } - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, ec)); return true; } @@ -1405,13 +1285,13 @@ public: { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); } else if (peer.native() != invalid_socket) { - boost::asio::error error(boost::asio::error::already_connected); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::already_connected)); } else { @@ -1419,10 +1299,10 @@ public: if (!(impl.flags_ & implementation_type::internal_non_blocking)) { ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } impl.flags_ |= implementation_type::internal_non_blocking; @@ -1437,9 +1317,8 @@ public: } // Connect the socket to the specified endpoint. - template - void connect(implementation_type& impl, const endpoint_type& peer_endpoint, - Error_Handler error_handler) + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) { // Open the socket if it is not already open. if (impl.socket_ == invalid_socket) @@ -1450,40 +1329,31 @@ public: int proto = peer_endpoint.protocol().protocol(); // Create a new socket. - impl.socket_ = socket_ops::socket(family, type, proto); + impl.socket_ = socket_ops::socket(family, type, proto, ec); if (impl.socket_ == invalid_socket) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + return ec; // Register the socket with the reactor. if (int err = reactor_.register_descriptor(impl.socket_)) { - socket_ops::close(impl.socket_); - error_handler(boost::asio::error(err)); - return; + socket_ops::close(impl.socket_, ec); + ec = boost::system::error_code(err, boost::system::native_ecat); + return ec; } } else if (impl.flags_ & implementation_type::internal_non_blocking) { // Mark the socket as blocking while we perform the connect. ioctl_arg_type non_blocking = 0; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return ec; impl.flags_ &= ~implementation_type::internal_non_blocking; } // Perform the connect operation. - int result = socket_ops::connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size()); - if (result == socket_error_retval) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + return ec; } template @@ -1501,7 +1371,7 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether a handler has already been called for the connection. // If it has, then we don't want to do anything in this handler. @@ -1513,36 +1383,34 @@ public: reactor_.enqueue_cancel_ops_unlocked(socket_); // Check whether the operation was successful. - if (result != 0) + if (result) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, result)); return true; } // Get the error code from the connect operation. int connect_error = 0; size_t connect_error_len = sizeof(connect_error); + boost::system::error_code ec; if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR, - &connect_error, &connect_error_len) == socket_error_retval) + &connect_error, &connect_error_len, ec) == socket_error_retval) { - boost::asio::error error(socket_ops::get_error()); - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, ec)); return true; } // If connection failed then post the handler with the error code. if (connect_error) { - boost::asio::error error(connect_error); - io_service_.post(bind_handler(handler_, error)); + ec = boost::system::error_code(connect_error, + boost::system::native_ecat); + io_service_.post(bind_handler(handler_, ec)); return true; } // Post the result of the successful connection operation. - boost::asio::error error(boost::asio::error::success); - io_service_.post(bind_handler(handler_, error)); - + io_service_.post(bind_handler(handler_, ec)); return true; } @@ -1569,20 +1437,20 @@ public: int proto = peer_endpoint.protocol().protocol(); // Create a new socket. - impl.socket_ = socket_ops::socket(family, type, proto); + boost::system::error_code ec; + impl.socket_ = socket_ops::socket(family, type, proto, ec); if (impl.socket_ == invalid_socket) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } // Register the socket with the reactor. if (int err = reactor_.register_descriptor(impl.socket_)) { - socket_ops::close(impl.socket_); - boost::asio::error error(err); - io_service().post(bind_handler(handler, error)); + socket_ops::close(impl.socket_, ec); + ec = boost::system::error_code(err, boost::system::native_ecat); + io_service().post(bind_handler(handler, ec)); return; } } @@ -1591,10 +1459,10 @@ public: if (!(impl.flags_ & implementation_type::internal_non_blocking)) { ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } impl.flags_ |= implementation_type::internal_non_blocking; @@ -1602,16 +1470,16 @@ public: // Start the connect operation. The socket is already marked as non-blocking // so the connection will take place asynchronously. + boost::system::error_code ec; if (socket_ops::connect(impl.socket_, peer_endpoint.data(), - peer_endpoint.size()) == 0) + peer_endpoint.size(), ec) == 0) { // The connect operation has finished successfully so we need to post the // handler immediately. - boost::asio::error error(boost::asio::error::success); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, boost::asio::error::success)); } - else if (socket_ops::get_error() == boost::asio::error::in_progress - || socket_ops::get_error() == boost::asio::error::would_block) + else if (ec == boost::asio::error::in_progress + || ec == boost::asio::error::would_block) { // The connection is happening in the background, and we need to wait // until the socket becomes writeable. @@ -1623,8 +1491,7 @@ public: else { // The connect operation has failed, so post the handler immediately. - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); } } diff --git a/include/boost/asio/detail/reactor_op_queue.hpp b/include/boost/asio/detail/reactor_op_queue.hpp index 8d522b45..ecb13ea9 100644 --- a/include/boost/asio/detail/reactor_op_queue.hpp +++ b/include/boost/asio/detail/reactor_op_queue.hpp @@ -101,7 +101,8 @@ public: // Dispatch the first operation corresponding to the descriptor. Returns true // if there are more operations queued for the descriptor. - bool dispatch_operation(Descriptor descriptor, int result) + bool dispatch_operation(Descriptor descriptor, + const boost::system::error_code& result) { typename operation_map::iterator i = operations_.find(descriptor); if (i != operations_.end()) @@ -138,7 +139,8 @@ public: } // Dispatch all operations corresponding to the descriptor. - void dispatch_all_operations(Descriptor descriptor, int result) + void dispatch_all_operations(Descriptor descriptor, + const boost::system::error_code& result) { typename operation_map::iterator i = operations_.find(descriptor); if (i != operations_.end()) @@ -180,7 +182,8 @@ public: // Dispatch the operations corresponding to the ready file descriptors // contained in the given descriptor set. template - void dispatch_descriptors(const Descriptor_Set& descriptors, int result) + void dispatch_descriptors(const Descriptor_Set& descriptors, + const boost::system::error_code& result) { typename operation_map::iterator i = operations_.begin(); while (i != operations_.end()) @@ -283,7 +286,7 @@ private: } // Perform the operation. - bool invoke(int result) + bool invoke(const boost::system::error_code& result) { return invoke_func_(this, result); } @@ -295,7 +298,8 @@ private: } protected: - typedef bool (*invoke_func_type)(op_base*, int); + typedef bool (*invoke_func_type)(op_base*, + const boost::system::error_code&); typedef void (*destroy_func_type)(op_base*); // Construct an operation for the given descriptor. @@ -344,7 +348,8 @@ private: } // Invoke the handler. - static bool invoke_handler(op_base* base, int result) + static bool invoke_handler(op_base* base, + const boost::system::error_code& result) { return static_cast*>(base)->handler_(result); } diff --git a/include/boost/asio/detail/resolver_service.hpp b/include/boost/asio/detail/resolver_service.hpp index a90e3a25..6a0c5e7f 100644 --- a/include/boost/asio/detail/resolver_service.hpp +++ b/include/boost/asio/detail/resolver_service.hpp @@ -133,23 +133,21 @@ public: } // Resolve a query to a list of entries. - template iterator_type resolve(implementation_type&, const query_type& query, - Error_Handler error_handler) + boost::system::error_code& ec) { boost::asio::detail::addrinfo_type* address_info = 0; std::string host_name = query.host_name(); std::string service_name = query.service_name(); boost::asio::detail::addrinfo_type hints = query.hints(); - int result = socket_ops::getaddrinfo( - host_name.length() ? host_name.c_str() : 0, - service_name.c_str(), &hints, &address_info); + socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0, + service_name.c_str(), &hints, &address_info, ec); auto_addrinfo auto_address_info(address_info); - error_handler(boost::asio::error(result)); - if (result != 0) + if (ec) return iterator_type(); + return iterator_type::create(address_info, host_name, service_name); } @@ -174,8 +172,7 @@ public: { iterator_type iterator; io_service_.post(boost::asio::detail::bind_handler(handler_, - boost::asio::error(boost::asio::error::operation_aborted), - iterator)); + boost::asio::error::operation_aborted, iterator)); return; } @@ -184,18 +181,17 @@ public: std::string host_name = query_.host_name(); std::string service_name = query_.service_name(); boost::asio::detail::addrinfo_type hints = query_.hints(); - int result = socket_ops::getaddrinfo( - host_name.length() ? host_name.c_str() : 0, - service_name.c_str(), &hints, &address_info); + boost::system::error_code ec; + socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0, + service_name.c_str(), &hints, &address_info, ec); auto_addrinfo auto_address_info(address_info); // Invoke the handler and pass the result. - boost::asio::error e(result); iterator_type iterator; - if (result == 0) + if (!ec) iterator = iterator_type::create(address_info, host_name, service_name); io_service_.post(boost::asio::detail::bind_handler( - handler_, e, iterator)); + handler_, ec, iterator)); } private: @@ -221,27 +217,26 @@ public: } // Resolve an endpoint to a list of entries. - template iterator_type resolve(implementation_type&, - const endpoint_type& endpoint, Error_Handler error_handler) + const endpoint_type& endpoint, boost::system::error_code& ec) { // First try resolving with the service name. If that fails try resolving // but allow the service to be returned as a number. char host_name[NI_MAXHOST]; char service_name[NI_MAXSERV]; int flags = endpoint.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; - int result = socket_ops::getnameinfo(endpoint.data(), endpoint.size(), - host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags); - if (result) + socket_ops::getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + if (ec) { flags |= NI_NUMERICSERV; - result = socket_ops::getnameinfo(endpoint.data(), endpoint.size(), - host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags); + socket_ops::getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); } - error_handler(boost::asio::error(result)); - if (result != 0) + if (ec) return iterator_type(); + return iterator_type::create(endpoint, host_name, service_name); } @@ -267,8 +262,7 @@ public: { iterator_type iterator; io_service_.post(boost::asio::detail::bind_handler(handler_, - boost::asio::error(boost::asio::error::operation_aborted), - iterator)); + boost::asio::error::operation_aborted, iterator)); return; } @@ -278,22 +272,22 @@ public: char host_name[NI_MAXHOST]; char service_name[NI_MAXSERV]; int flags = endpoint_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; - int result = socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(), - host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags); - if (result) + boost::system::error_code ec; + socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + if (ec) { flags |= NI_NUMERICSERV; - result = socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(), - host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags); + socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); } // Invoke the handler and pass the result. - boost::asio::error e(result); iterator_type iterator; - if (result == 0) + if (!ec) iterator = iterator_type::create(endpoint_, host_name, service_name); io_service_.post(boost::asio::detail::bind_handler( - handler_, e, iterator)); + handler_, ec, iterator)); } private: diff --git a/include/boost/asio/detail/select_reactor.hpp b/include/boost/asio/detail/select_reactor.hpp index d8ae6142..87e0a87c 100644 --- a/include/boost/asio/detail/select_reactor.hpp +++ b/include/boost/asio/detail/select_reactor.hpp @@ -291,8 +291,9 @@ private: timeval* tv = block ? get_timeout(tv_buf) : &tv_buf; select_in_progress_ = true; lock.unlock(); + boost::system::error_code ec; int retval = socket_ops::select(static_cast(max_fd + 1), - read_fds, write_fds, except_fds, tv); + read_fds, write_fds, except_fds, tv, ec); lock.lock(); select_in_progress_ = false; @@ -308,9 +309,12 @@ private: { // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. - except_op_queue_.dispatch_descriptors(except_fds, 0); - read_op_queue_.dispatch_descriptors(read_fds, 0); - write_op_queue_.dispatch_descriptors(write_fds, 0); + except_op_queue_.dispatch_descriptors(except_fds, + boost::asio::error::success); + read_op_queue_.dispatch_descriptors(read_fds, + boost::asio::error::success); + write_op_queue_.dispatch_descriptors(write_fds, + boost::asio::error::success); except_op_queue_.dispatch_cancellations(); read_op_queue_.dispatch_cancellations(); write_op_queue_.dispatch_cancellations(); diff --git a/include/boost/asio/detail/socket_holder.hpp b/include/boost/asio/detail/socket_holder.hpp index f06867cf..464831c0 100644 --- a/include/boost/asio/detail/socket_holder.hpp +++ b/include/boost/asio/detail/socket_holder.hpp @@ -45,7 +45,10 @@ public: ~socket_holder() { if (socket_ != invalid_socket) - socket_ops::close(socket_); + { + boost::system::error_code ec; + socket_ops::close(socket_, ec); + } } // Get the underlying socket. @@ -59,7 +62,8 @@ public: { if (socket_ != invalid_socket) { - socket_ops::close(socket_); + boost::system::error_code ec; + socket_ops::close(socket_, ec); socket_ = invalid_socket; } } diff --git a/include/boost/asio/detail/socket_ops.hpp b/include/boost/asio/detail/socket_ops.hpp index 855e2a9a..db74cab8 100644 --- a/include/boost/asio/detail/socket_ops.hpp +++ b/include/boost/asio/detail/socket_ops.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -37,44 +38,39 @@ namespace asio { namespace detail { namespace socket_ops { -inline int get_error() +inline void clear_error(boost::system::error_code& ec) { + errno = 0; #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return WSAGetLastError(); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return errno; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} - -inline void set_error(int error) -{ - errno = error; -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - WSASetLastError(error); + WSASetLastError(0); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + ec = boost::system::error_code(); } template -inline ReturnType error_wrapper(ReturnType return_value) +inline ReturnType error_wrapper(ReturnType return_value, + boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - errno = WSAGetLastError(); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + ec = boost::system::error_code(WSAGetLastError(), boost::system::native_ecat); +#else + ec = boost::system::error_code(errno, boost::system::native_ecat); +#endif return return_value; } inline socket_type accept(socket_type s, socket_addr_type* addr, - socket_addr_len_type* addrlen) + socket_addr_len_type* addrlen, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(__MACH__) && defined(__APPLE__) - socket_type new_s = error_wrapper(::accept(s, addr, addrlen)); + socket_type new_s = error_wrapper(::accept(s, addr, addrlen), ec); if (new_s == invalid_socket) return new_s; int optval = 1; int result = error_wrapper(::setsockopt(new_s, - SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval))); + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); if (result != 0) { ::close(new_s); @@ -83,44 +79,44 @@ inline socket_type accept(socket_type s, socket_addr_type* addr, return new_s; #else - return error_wrapper(::accept(s, addr, addrlen)); + return error_wrapper(::accept(s, addr, addrlen), ec); #endif } inline int bind(socket_type s, const socket_addr_type* addr, - socket_addr_len_type addrlen) + socket_addr_len_type addrlen, boost::system::error_code& ec) { - set_error(0); - return error_wrapper(::bind(s, addr, addrlen)); + clear_error(ec); + return error_wrapper(::bind(s, addr, addrlen), ec); } -inline int close(socket_type s) +inline int close(socket_type s, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return error_wrapper(::closesocket(s)); + return error_wrapper(::closesocket(s), ec); #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return error_wrapper(::close(s)); + return error_wrapper(::close(s), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } -inline int shutdown(socket_type s, int what) +inline int shutdown(socket_type s, int what, boost::system::error_code& ec) { - set_error(0); - return error_wrapper(::shutdown(s, what)); + clear_error(ec); + return error_wrapper(::shutdown(s, what), ec); } inline int connect(socket_type s, const socket_addr_type* addr, - socket_addr_len_type addrlen) + socket_addr_len_type addrlen, boost::system::error_code& ec) { - set_error(0); - return error_wrapper(::connect(s, addr, addrlen)); + clear_error(ec); + return error_wrapper(::connect(s, addr, addrlen), ec); } -inline int listen(socket_type s, int backlog) +inline int listen(socket_type s, int backlog, boost::system::error_code& ec) { - set_error(0); - return error_wrapper(::listen(s, backlog)); + clear_error(ec); + return error_wrapper(::listen(s, backlog), ec); } #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -151,16 +147,17 @@ inline void init_buf(buf& b, const void* data, size_t size) #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } -inline int recv(socket_type s, buf* bufs, size_t count, int flags) +inline int recv(socket_type s, buf* bufs, size_t count, int flags, + boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast(count); DWORD bytes_transferred = 0; DWORD recv_flags = flags; int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0)); + recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); if (result != 0) return -1; return bytes_transferred; @@ -173,21 +170,22 @@ inline int recv(socket_type s, buf* bufs, size_t count, int flags) msg.msg_control = 0; msg.msg_controllen = 0; msg.msg_flags = 0; - return error_wrapper(::recvmsg(s, &msg, flags)); + return error_wrapper(::recvmsg(s, &msg, flags), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags, - socket_addr_type* addr, socket_addr_len_type* addrlen) + socket_addr_type* addr, socket_addr_len_type* addrlen, + boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast(count); DWORD bytes_transferred = 0; DWORD recv_flags = flags; int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, addrlen, 0, 0)); + &bytes_transferred, &recv_flags, addr, addrlen, 0, 0), ec); if (result != 0) return -1; return bytes_transferred; @@ -205,22 +203,23 @@ inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags, msg.msg_control = 0; msg.msg_controllen = 0; msg.msg_flags = 0; - int result = error_wrapper(::recvmsg(s, &msg, flags)); + int result = error_wrapper(::recvmsg(s, &msg, flags), ec); *addrlen = msg.msg_namelen; return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } -inline int send(socket_type s, const buf* bufs, size_t count, int flags) +inline int send(socket_type s, const buf* bufs, size_t count, int flags, + boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast(count); DWORD bytes_transferred = 0; DWORD send_flags = flags; int result = error_wrapper(::WSASend(s, const_cast(bufs), - send_buf_count, &bytes_transferred, send_flags, 0, 0)); + send_buf_count, &bytes_transferred, send_flags, 0, 0), ec); if (result != 0) return -1; return bytes_transferred; @@ -236,20 +235,21 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags) #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - return error_wrapper(::sendmsg(s, &msg, flags)); + return error_wrapper(::sendmsg(s, &msg, flags), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline int sendto(socket_type s, const buf* bufs, size_t count, int flags, - const socket_addr_type* addr, socket_addr_len_type addrlen) + const socket_addr_type* addr, socket_addr_len_type addrlen, + boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast(count); DWORD bytes_transferred = 0; - int result = ::WSASendTo(s, const_cast(bufs), send_buf_count, - &bytes_transferred, flags, addr, addrlen, 0, 0); + int result = error_wrapper(::WSASendTo(s, const_cast(bufs), + send_buf_count, &bytes_transferred, flags, addr, addrlen, 0, 0), ec); if (result != 0) return -1; return bytes_transferred; @@ -270,24 +270,25 @@ inline int sendto(socket_type s, const buf* bufs, size_t count, int flags, #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - return error_wrapper(::sendmsg(s, &msg, flags)); + return error_wrapper(::sendmsg(s, &msg, flags), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } -inline socket_type socket(int af, int type, int protocol) +inline socket_type socket(int af, int type, int protocol, + boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) return error_wrapper(::WSASocket(af, type, protocol, 0, 0, - WSA_FLAG_OVERLAPPED)); + WSA_FLAG_OVERLAPPED), ec); #elif defined(__MACH__) && defined(__APPLE__) - socket_type s = error_wrapper(::socket(af, type, protocol)); + socket_type s = error_wrapper(::socket(af, type, protocol), ec); if (s == invalid_socket) return s; int optval = 1; int result = error_wrapper(::setsockopt(s, - SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval))); + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); if (result != 0) { ::close(s); @@ -296,70 +297,71 @@ inline socket_type socket(int af, int type, int protocol) return s; #else - return error_wrapper(::socket(af, type, protocol)); + return error_wrapper(::socket(af, type, protocol), ec); #endif } inline int setsockopt(socket_type s, int level, int optname, - const void* optval, size_t optlen) + const void* optval, size_t optlen, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) return error_wrapper(::setsockopt(s, level, optname, - reinterpret_cast(optval), static_cast(optlen))); + reinterpret_cast(optval), static_cast(optlen)), ec); #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) return error_wrapper(::setsockopt(s, level, optname, optval, - static_cast(optlen))); + static_cast(optlen)), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline int getsockopt(socket_type s, int level, int optname, void* optval, - size_t* optlen) + size_t* optlen, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) int tmp_optlen = static_cast(*optlen); int result = error_wrapper(::getsockopt(s, level, optname, - reinterpret_cast(optval), &tmp_optlen)); + reinterpret_cast(optval), &tmp_optlen), ec); *optlen = static_cast(tmp_optlen); return result; #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) socklen_t tmp_optlen = static_cast(*optlen); int result = error_wrapper(::getsockopt(s, level, optname, - optval, &tmp_optlen)); + optval, &tmp_optlen), ec); *optlen = static_cast(tmp_optlen); return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline int getpeername(socket_type s, socket_addr_type* addr, - socket_addr_len_type* addrlen) + socket_addr_len_type* addrlen, boost::system::error_code& ec) { - set_error(0); - return error_wrapper(::getpeername(s, addr, addrlen)); + clear_error(ec); + return error_wrapper(::getpeername(s, addr, addrlen), ec); } inline int getsockname(socket_type s, socket_addr_type* addr, - socket_addr_len_type* addrlen) + socket_addr_len_type* addrlen, boost::system::error_code& ec) { - set_error(0); - return error_wrapper(::getsockname(s, addr, addrlen)); + clear_error(ec); + return error_wrapper(::getsockname(s, addr, addrlen), ec); } -inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg) +inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg, + boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return error_wrapper(::ioctlsocket(s, cmd, arg)); + return error_wrapper(::ioctlsocket(s, cmd, arg), ec); #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return error_wrapper(::ioctl(s, cmd, arg)); + return error_wrapper(::ioctl(s, cmd, arg), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline int select(int nfds, fd_set* readfds, fd_set* writefds, - fd_set* exceptfds, timeval* timeout) + fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) if (!readfds && !writefds && !exceptfds && timeout) { @@ -367,6 +369,7 @@ inline int select(int nfds, fd_set* readfds, fd_set* writefds, if (milliseconds == 0) milliseconds = 1; // Force context switch. ::Sleep(milliseconds); + ec = boost::asio::error::success; return 0; } @@ -380,55 +383,56 @@ inline int select(int nfds, fd_set* readfds, fd_set* writefds, && timeout->tv_usec > 0 && timeout->tv_usec < 1000) timeout->tv_usec = 1000; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return error_wrapper(::select(nfds, readfds, writefds, exceptfds, timeout)); + return error_wrapper(::select(nfds, readfds, + writefds, exceptfds, timeout), ec); } -inline int poll_read(socket_type s) +inline int poll_read(socket_type s, boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) FD_SET fds; FD_ZERO(&fds); FD_SET(s, &fds); - set_error(0); - return error_wrapper(::select(s, &fds, 0, 0, 0)); + clear_error(ec); + return error_wrapper(::select(s, &fds, 0, 0, 0), ec); #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) pollfd fds; fds.fd = s; fds.events = POLLIN; fds.revents = 0; - set_error(0); - return error_wrapper(::poll(&fds, 1, -1)); + clear_error(ec); + return error_wrapper(::poll(&fds, 1, -1), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } -inline int poll_write(socket_type s) +inline int poll_write(socket_type s, boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) FD_SET fds; FD_ZERO(&fds); FD_SET(s, &fds); - set_error(0); - return error_wrapper(::select(s, 0, &fds, 0, 0)); + clear_error(ec); + return error_wrapper(::select(s, 0, &fds, 0, 0), ec); #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) pollfd fds; fds.fd = s; fds.events = POLLOUT; fds.revents = 0; - set_error(0); - return error_wrapper(::poll(&fds, 1, -1)); + clear_error(ec); + return error_wrapper(::poll(&fds, 1, -1), ec); #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline const char* inet_ntop(int af, const void* src, char* dest, size_t length, - unsigned long scope_id = 0) + unsigned long scope_id, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy. if (af != AF_INET && af != AF_INET6) { - set_error(boost::asio::error::address_family_not_supported); + ec = boost::asio::error::address_family_not_supported; return 0; } @@ -458,17 +462,17 @@ inline const char* inet_ntop(int af, const void* src, char* dest, size_t length, DWORD string_length = static_cast(length); int result = error_wrapper(::WSAAddressToStringA( reinterpret_cast(&address), - address_length, 0, dest, &string_length)); + address_length, 0, dest, &string_length), ec); // Windows may not set an error code on failure. - if (result == socket_error_retval && get_error() == 0) - set_error(boost::asio::error::invalid_argument); + if (result == socket_error_retval && !ec) + ec = boost::asio::error::invalid_argument; return result == socket_error_retval ? 0 : dest; #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - const char* result = error_wrapper(::inet_ntop(af, src, dest, length)); - if (result == 0 && get_error() == 0) - set_error(boost::asio::error::invalid_argument); + const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec); + if (result == 0 && !ec) + ec = boost::asio::error::invalid_argument; if (result != 0 && af == AF_INET6 && scope_id != 0) { using namespace std; // For strcat and sprintf. @@ -484,15 +488,15 @@ inline const char* inet_ntop(int af, const void* src, char* dest, size_t length, } inline int inet_pton(int af, const char* src, void* dest, - unsigned long* scope_id = 0) + unsigned long* scope_id, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy and strcmp. if (af != AF_INET && af != AF_INET6) { - set_error(boost::asio::error::address_family_not_supported); + ec = boost::asio::error::address_family_not_supported; return -1; } @@ -501,7 +505,7 @@ inline int inet_pton(int af, const char* src, void* dest, int result = error_wrapper(::WSAStringToAddressA( const_cast(src), af, 0, reinterpret_cast(&address), - &address_length)); + &address_length), ec); if (af == AF_INET) { @@ -529,14 +533,14 @@ inline int inet_pton(int af, const char* src, void* dest, } // Windows may not set an error code on failure. - if (result == socket_error_retval && get_error() == 0) - set_error(boost::asio::error::invalid_argument); + if (result == socket_error_retval && !ec) + ec = boost::asio::error::invalid_argument; return result == socket_error_retval ? -1 : 1; #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - int result = error_wrapper(::inet_pton(af, src, dest)); - if (result <= 0 && get_error() == 0) - set_error(boost::asio::error::invalid_argument); + int result = error_wrapper(::inet_pton(af, src, dest), ec); + if (result <= 0 && !ec) + ec = boost::asio::error::invalid_argument; if (result > 0 && af == AF_INET6 && scope_id) { using namespace std; // For strchr and atoi. @@ -555,10 +559,10 @@ inline int inet_pton(int af, const char* src, void* dest, #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } -inline int gethostname(char* name, int namelen) +inline int gethostname(char* name, int namelen, boost::system::error_code& ec) { - set_error(0); - return error_wrapper(::gethostname(name, namelen)); + clear_error(ec); + return error_wrapper(::gethostname(name, namelen), ec); } #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \ @@ -567,7 +571,7 @@ inline int gethostname(char* name, int namelen) // The following functions are only needed for emulation of getaddrinfo and // getnameinfo. -inline int translate_netdb_error(int error) +inline boost::system::error_code translate_netdb_error(int error) { switch (error) { @@ -583,61 +587,66 @@ inline int translate_netdb_error(int error) return boost::asio::error::no_data; default: BOOST_ASSERT(false); - return get_error(); + return boost::asio::error::invalid_argument; } } inline hostent* gethostbyaddr(const char* addr, int length, int af, - hostent* result, char* buffer, int buflength, int* error) + hostent* result, char* buffer, int buflength, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); - hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af)); - *error = get_error(); + hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); if (!retval) return 0; *result = *retval; return retval; #elif defined(__sun) || defined(__QNX__) + int error = 0; hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result, - buffer, buflength, error)); - *error = translate_netdb_error(*error); + buffer, buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); return retval; #elif defined(__MACH__) && defined(__APPLE__) (void)(buffer); (void)(buflength); - hostent* retval = error_wrapper(::getipnodebyaddr(addr, length, af, error)); - *error = translate_netdb_error(*error); + int error = 0; + hostent* retval = error_wrapper(::getipnodebyaddr( + addr, length, af, &error), ec); + if (error) + ec = translate_netdb_error(error); if (!retval) return 0; *result = *retval; return retval; #else hostent* retval = 0; + int error = 0; error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer, - buflength, &retval, error)); - *error = translate_netdb_error(*error); + buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); return retval; #endif } inline hostent* gethostbyname(const char* name, int af, struct hostent* result, - char* buffer, int buflength, int* error, int ai_flags = 0) + char* buffer, int buflength, int ai_flags, boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); (void)(ai_flags); if (af != AF_INET) { - *error = boost::asio::error::address_family_not_supported; + ec = boost::asio::error::address_family_not_supported; return 0; } - hostent* retval = error_wrapper(::gethostbyname(name)); - *error = get_error(); + hostent* retval = error_wrapper(::gethostbyname(name), ec); if (!retval) return 0; *result = *retval; @@ -646,19 +655,23 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, (void)(ai_flags); if (af != AF_INET) { - *error = boost::asio::error::address_family_not_supported; + ec = boost::asio::error::address_family_not_supported; return 0; } + int error = 0; hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer, - buflength, error)); - *error = translate_netdb_error(*error); + buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); return retval; #elif defined(__MACH__) && defined(__APPLE__) (void)(buffer); (void)(buflength); + int error = 0; hostent* retval = error_wrapper(::getipnodebyname( - name, af, ai_flags, error)); - *error = translate_netdb_error(*error); + name, af, ai_flags, &error), ec); + if (error) + ec = translate_netdb_error(error); if (!retval) return 0; *result = *retval; @@ -667,13 +680,15 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, (void)(ai_flags); if (af != AF_INET) { - *error = boost::asio::error::address_family_not_supported; + ec = boost::asio::error::address_family_not_supported; return 0; } hostent* retval = 0; - error_wrapper(::gethostbyname_r(name, result, buffer, buflength, &retval, - error)); - *error = translate_netdb_error(*error); + int error = 0; + error_wrapper(::gethostbyname_r(name, result, + buffer, buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); return retval; #endif } @@ -1089,7 +1104,8 @@ inline int getaddrinfo_emulation(const char* host, const char* service, { // Check for IPv4 dotted decimal string. in4_addr_type inaddr; - if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr) == 1) + boost::system::error_code ec; + if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1) { if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET) { @@ -1112,7 +1128,7 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Check for IPv6 hex string. in6_addr_type in6addr; - if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr) == 1) + if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1) { if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6) { @@ -1136,9 +1152,8 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Look up hostname. hostent hent; char hbuf[8192] = ""; - int herr = 0; hostent* hptr = socket_ops::gethostbyname(sptr->host, - sptr->family, &hent, hbuf, sizeof(hbuf), &herr, hints.ai_flags); + sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec); if (hptr == 0) { if (search_count == 2) @@ -1148,18 +1163,15 @@ inline int getaddrinfo_emulation(const char* host, const char* service, } freeaddrinfo_emulation(aihead); gai_free(canon); - switch (herr) - { - case HOST_NOT_FOUND: + if (ec == boost::asio::error::host_not_found) return EAI_NONAME; - case TRY_AGAIN: + if (ec == boost::asio::error::host_not_found_try_again) return EAI_AGAIN; - case NO_RECOVERY: + if (ec == boost::asio::error::no_recovery) return EAI_FAIL; - case NO_DATA: - default: + if (ec == boost::asio::error::no_data) return EAI_NONAME; - } + return EAI_NONAME; } // Check for address family mismatch if one was specified. @@ -1245,9 +1257,10 @@ inline int getaddrinfo_emulation(const char* host, const char* service, return 0; } -inline int getnameinfo_emulation(const socket_addr_type* sa, - socket_addr_len_type salen, char* host, std::size_t hostlen, - char* serv, std::size_t servlen, int flags) +inline boost::system::error_code getnameinfo_emulation( + const socket_addr_type* sa, socket_addr_len_type salen, char* host, + std::size_t hostlen, char* serv, std::size_t servlen, int flags, + boost::system::error_code& ec) { using namespace std; @@ -1259,8 +1272,7 @@ inline int getnameinfo_emulation(const socket_addr_type* sa, case AF_INET: if (salen != sizeof(sockaddr_in4_type)) { - set_error(boost::asio::error::invalid_argument); - return 1; + return ec = boost::asio::error::invalid_argument; } addr = reinterpret_cast( &reinterpret_cast(sa)->sin_addr); @@ -1270,8 +1282,7 @@ inline int getnameinfo_emulation(const socket_addr_type* sa, case AF_INET6: if (salen != sizeof(sockaddr_in6_type)) { - set_error(boost::asio::error::invalid_argument); - return 1; + return ec = boost::asio::error::invalid_argument; } addr = reinterpret_cast( &reinterpret_cast(sa)->sin6_addr); @@ -1279,27 +1290,25 @@ inline int getnameinfo_emulation(const socket_addr_type* sa, port = reinterpret_cast(sa)->sin6_port; break; default: - set_error(boost::asio::error::address_family_not_supported); - return 1; + return ec = boost::asio::error::address_family_not_supported; } if (host && hostlen > 0) { if (flags & NI_NUMERICHOST) { - if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen) == 0) + if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0) { - return 1; + return ec; } } else { hostent hent; char hbuf[8192] = ""; - int herr = 0; hostent* hptr = socket_ops::gethostbyaddr(addr, static_cast(addr_len), sa->sa_family, - &hent, hbuf, sizeof(hbuf), &herr); + &hent, hbuf, sizeof(hbuf), ec); if (hptr && hptr->h_name && hptr->h_name[0] != '\0') { if (flags & NI_NOFQDN) @@ -1319,12 +1328,12 @@ inline int getnameinfo_emulation(const socket_addr_type* sa, socket_ops::freehostent(hptr); if (flags & NI_NAMEREQD) { - set_error(boost::asio::error::host_not_found); - return 1; + return ec = boost::asio::error::host_not_found; } - if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen) == 0) + if (socket_ops::inet_ntop(sa->sa_family, + addr, host, hostlen, 0, ec) == 0) { - return 1; + return ec; } } } @@ -1336,8 +1345,7 @@ inline int getnameinfo_emulation(const socket_addr_type* sa, { if (servlen < 6) { - set_error(boost::asio::error::no_buffer_space); - return 1; + return ec = boost::asio::error::no_buffer_space; } sprintf(serv, "%u", ntohs(port)); } @@ -1357,8 +1365,7 @@ inline int getnameinfo_emulation(const socket_addr_type* sa, { if (servlen < 6) { - set_error(boost::asio::error::no_buffer_space); - return 1; + return ec = boost::asio::error::no_buffer_space; } sprintf(serv, "%u", ntohs(port)); } @@ -1368,14 +1375,14 @@ inline int getnameinfo_emulation(const socket_addr_type* sa, } } - set_error(0); - return 0; + clear_error(ec); + return ec; } #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) // || defined(__MACH__) && defined(__APPLE__) -inline int translate_addrinfo_error(int error) +inline boost::system::error_code translate_addrinfo_error(int error) { switch (error) { @@ -1398,19 +1405,26 @@ inline int translate_addrinfo_error(int error) case EAI_SOCKTYPE: return boost::asio::error::socket_type_not_supported; default: // Possibly the non-portable EAI_SYSTEM. - return get_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + return boost::system::error_code( + WSAGetLastError(), boost::system::native_ecat); +#else + return boost::system::error_code( + errno, boost::system::native_ecat); +#endif } } -inline int getaddrinfo(const char* host, const char* service, - const addrinfo_type* hints, addrinfo_type** result) +inline boost::system::error_code getaddrinfo(const char* host, + const char* service, const addrinfo_type* hints, addrinfo_type** result, + boost::system::error_code& ec) { - set_error(0); + clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) // Building for Windows XP, Windows Server 2003, or later. int error = ::getaddrinfo(host, service, hints, result); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); # else // Building for Windows 2000 or earlier. typedef int (WSAAPI *gai_t)(const char*, @@ -1420,18 +1434,18 @@ inline int getaddrinfo(const char* host, const char* service, if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo")) { int error = gai(host, service, hints, result); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); } } int error = getaddrinfo_emulation(host, service, hints, result); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); # endif #elif defined(__MACH__) && defined(__APPLE__) int error = getaddrinfo_emulation(host, service, hints, result); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); #else int error = ::getaddrinfo(host, service, hints, result); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); #endif } @@ -1461,17 +1475,17 @@ inline void freeaddrinfo(addrinfo_type* ai) #endif } -inline int getnameinfo(const socket_addr_type* addr, +inline boost::system::error_code getnameinfo(const socket_addr_type* addr, socket_addr_len_type addrlen, char* host, std::size_t hostlen, - char* serv, std::size_t servlen, int flags) + 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) // Building for Windows XP, Windows Server 2003, or later. - set_error(0); + clear_error(ec); int error = ::getnameinfo(addr, addrlen, host, static_cast(hostlen), serv, static_cast(servlen), flags); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); # else // Building for Windows 2000 or earlier. typedef int (WSAAPI *gni_t)(const socket_addr_type*, @@ -1480,15 +1494,14 @@ inline int getnameinfo(const socket_addr_type* addr, { if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo")) { - set_error(0); + clear_error(ec); int error = gni(addr, addrlen, host, hostlen, serv, servlen, flags); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); } } - set_error(0); - int error = getnameinfo_emulation(addr, addrlen, - host, hostlen, serv, servlen, flags); - return translate_addrinfo_error(error); + clear_error(ec); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); # endif #elif defined(__MACH__) && defined(__APPLE__) using namespace std; // For memcpy. @@ -1496,14 +1509,13 @@ inline int getnameinfo(const socket_addr_type* addr, memcpy(&tmp_addr, addr, addrlen); tmp_addr.ss_len = addrlen; addr = reinterpret_cast(&tmp_addr); - set_error(0); - int error = getnameinfo_emulation(addr, addrlen, - host, hostlen, serv, servlen, flags); - return translate_addrinfo_error(error); + clear_error(ec); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); #else - set_error(0); + clear_error(ec); int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags); - return translate_addrinfo_error(error); + return ec = translate_addrinfo_error(error); #endif } diff --git a/include/boost/asio/detail/socket_select_interrupter.hpp b/include/boost/asio/detail/socket_select_interrupter.hpp index 2cba77c4..3976cca6 100644 --- a/include/boost/asio/detail/socket_select_interrupter.hpp +++ b/include/boost/asio/detail/socket_select_interrupter.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -36,17 +37,18 @@ public: // Constructor. socket_select_interrupter() { - socket_holder acceptor(socket_ops::socket(AF_INET, SOCK_STREAM, - IPPROTO_TCP)); + boost::system::error_code ec; + socket_holder acceptor(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); if (acceptor.get() == invalid_socket) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } int opt = 1; socket_ops::setsockopt(acceptor.get(), - SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec); sockaddr_in4_type addr; socket_addr_len_type addr_len = sizeof(addr); @@ -54,67 +56,69 @@ public: addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = 0; if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr, - addr_len) == socket_error_retval) + addr_len, ec) == socket_error_retval) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } - if (getsockname(acceptor.get(), (socket_addr_type*)&addr, &addr_len) - == socket_error_retval) + if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr, + &addr_len, ec) == socket_error_retval) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } - if (socket_ops::listen(acceptor.get(), SOMAXCONN) == socket_error_retval) + if (socket_ops::listen(acceptor.get(), + SOMAXCONN, ec) == socket_error_retval) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } - socket_holder client(socket_ops::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); + socket_holder client(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); if (client.get() == invalid_socket) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr, - addr_len) == socket_error_retval) + addr_len, ec) == socket_error_retval) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } - socket_holder server(socket_ops::accept(acceptor.get(), 0, 0)); + socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec)); if (server.get() == invalid_socket) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking)) + if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking, ec)) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } opt = 1; socket_ops::setsockopt(client.get(), - IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); non_blocking = 1; - if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking)) + if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking, ec)) { - boost::asio::error e(socket_ops::get_error()); + boost::system::system_error e(ec, "socket_select_interrupter"); boost::throw_exception(e); } opt = 1; socket_ops::setsockopt(server.get(), - IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); read_descriptor_ = server.release(); write_descriptor_ = client.release(); @@ -123,10 +127,11 @@ public: // Destructor. ~socket_select_interrupter() { + boost::system::error_code ec; if (read_descriptor_ != invalid_socket) - socket_ops::close(read_descriptor_); + socket_ops::close(read_descriptor_, ec); if (write_descriptor_ != invalid_socket) - socket_ops::close(write_descriptor_); + socket_ops::close(write_descriptor_, ec); } // Interrupt the select call. @@ -135,7 +140,8 @@ public: char byte = 0; socket_ops::buf b; socket_ops::init_buf(b, &byte, 1); - socket_ops::send(write_descriptor_, &b, 1, 0); + boost::system::error_code ec; + socket_ops::send(write_descriptor_, &b, 1, 0, ec); } // Reset the select interrupt. Returns true if the call was interrupted. @@ -144,10 +150,11 @@ public: char data[1024]; socket_ops::buf b; socket_ops::init_buf(b, data, sizeof(data)); - int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0); + boost::system::error_code ec; + int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); bool was_interrupted = (bytes_read > 0); while (bytes_read == sizeof(data)) - bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0); + bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); return was_interrupted; } diff --git a/include/boost/asio/detail/throw_error.hpp b/include/boost/asio/detail/throw_error.hpp new file mode 100644 index 00000000..0f130e83 --- /dev/null +++ b/include/boost/asio/detail/throw_error.hpp @@ -0,0 +1,46 @@ +// +// throw_error.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2006 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_THROW_ERROR_HPP +#define BOOST_ASIO_DETAIL_THROW_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include + + +namespace boost { +namespace asio { +namespace detail { + +inline void throw_error(const boost::system::error_code& err) +{ + if (err) + { + boost::system::system_error e(err); + boost::throw_exception(e); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_THROW_ERROR_HPP diff --git a/include/boost/asio/detail/timer_queue.hpp b/include/boost/asio/detail/timer_queue.hpp index c34bb9f9..f089a216 100644 --- a/include/boost/asio/detail/timer_queue.hpp +++ b/include/boost/asio/detail/timer_queue.hpp @@ -112,7 +112,7 @@ public: { timer_base* t = heap_[0]; remove_timer(t); - t->invoke(0); + t->invoke(boost::asio::error::success); } } @@ -161,7 +161,7 @@ private: { public: // Perform the timer operation and then destroy. - void invoke(int result) + void invoke(const boost::system::error_code& result) { invoke_func_(this, result); } @@ -173,7 +173,8 @@ private: } protected: - typedef void (*invoke_func_type)(timer_base*, int); + typedef void (*invoke_func_type)(timer_base*, + const boost::system::error_code&); typedef void (*destroy_func_type)(timer_base*); // Constructor. @@ -235,7 +236,8 @@ private: } // Invoke the handler and then destroy it. - static void invoke_handler(timer_base* base, int result) + static void invoke_handler(timer_base* base, + const boost::system::error_code& result) { std::auto_ptr > t(static_cast*>(base)); t->handler_(result); diff --git a/include/boost/asio/detail/win_event.hpp b/include/boost/asio/detail/win_event.hpp index 89860021..bd88b4b3 100644 --- a/include/boost/asio/detail/win_event.hpp +++ b/include/boost/asio/detail/win_event.hpp @@ -19,11 +19,11 @@ #include #include +#include #include #if defined(BOOST_WINDOWS) -#include #include #include @@ -46,7 +46,9 @@ public: if (!event_) { DWORD last_error = ::GetLastError(); - system_exception e("event", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, boost::system::native_ecat), + "event"); boost::throw_exception(e); } } diff --git a/include/boost/asio/detail/win_iocp_io_service.hpp b/include/boost/asio/detail/win_iocp_io_service.hpp index aab47ce6..b00781ea 100644 --- a/include/boost/asio/detail/win_iocp_io_service.hpp +++ b/include/boost/asio/detail/win_iocp_io_service.hpp @@ -24,10 +24,10 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -56,7 +56,9 @@ public: if (!iocp_.handle) { DWORD last_error = ::GetLastError(); - system_exception e("iocp", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, boost::system::native_ecat), + "iocp"); boost::throw_exception(e); } } @@ -153,7 +155,9 @@ public: if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) { DWORD last_error = ::GetLastError(); - system_exception e("pqcs", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, boost::system::native_ecat), + "pqcs"); boost::throw_exception(e); } } @@ -206,7 +210,9 @@ public: if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, ptr.get())) { DWORD last_error = ::GetLastError(); - system_exception e("pqcs", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, boost::system::native_ecat), + "pqcs"); boost::throw_exception(e); } @@ -223,7 +229,9 @@ public: bytes_transferred, op_last_error, op)) { DWORD last_error = ::GetLastError(); - system_exception e("pqcs", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, boost::system::native_ecat), + "pqcs"); boost::throw_exception(e); } } @@ -280,7 +288,10 @@ private: if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) { DWORD last_error = ::GetLastError(); - system_exception e("pqcs", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, + boost::system::native_ecat), + "pqcs"); boost::throw_exception(e); } diff --git a/include/boost/asio/detail/win_iocp_socket_service.hpp b/include/boost/asio/detail/win_iocp_socket_service.hpp index 9c1b243e..a0afb052 100644 --- a/include/boost/asio/detail/win_iocp_socket_service.hpp +++ b/include/boost/asio/detail/win_iocp_socket_service.hpp @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -186,7 +185,8 @@ public: implementation_type* impl = impl_list_; while (impl) { - close(*impl, boost::asio::ignore_error()); + boost::system::error_code ignored_ec; + close(*impl, ignored_ec); impl = impl->next_; } } @@ -226,11 +226,13 @@ public: ::linger opt; opt.l_onoff = 0; opt.l_linger = 0; + boost::system::error_code ignored_ec; socket_ops::setsockopt(impl.socket_, - SOL_SOCKET, SO_LINGER, &opt, sizeof(opt)); + SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); } - socket_ops::close(impl.socket_); + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, ignored_ec); impl.socket_ = invalid_socket; impl.cancel_token_.reset(); impl.safe_cancellation_thread_id_ = 0; @@ -249,48 +251,46 @@ public: } // Open a new socket implementation. - template - void open(implementation_type& impl, const protocol_type& protocol, - Error_Handler error_handler) + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) { - close(impl, boost::asio::ignore_error()); + boost::system::error_code ignored_ec; + close(impl, ignored_ec); socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(), - protocol.protocol())); + protocol.protocol(), ec)); if (sock.get() == invalid_socket) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + return ec; iocp_service_.register_socket(sock.get()); impl.socket_ = sock.release(); impl.cancel_token_.reset(static_cast(0), noop_deleter()); impl.protocol_ = protocol; - - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); + return ec; } // Assign a native socket to a socket implementation. - template - void assign(implementation_type& impl, const protocol_type& protocol, - const native_type& native_socket, Error_Handler error_handler) + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) { - close(impl, boost::asio::ignore_error()); + boost::system::error_code ignored_ec; + close(impl, ignored_ec); iocp_service_.register_socket(native_socket); impl.socket_ = native_socket; impl.cancel_token_.reset(static_cast(0), noop_deleter()); impl.protocol_ = protocol; - - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); + return ec; } // Destroy a socket implementation. - template - void close(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) { if (impl.socket_ != invalid_socket) { @@ -303,20 +303,16 @@ public: if (reactor) reactor->close_descriptor(impl.socket_); - if (socket_ops::close(impl.socket_) == socket_error_retval) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } - else - { - impl.socket_ = invalid_socket; - impl.cancel_token_.reset(); - impl.safe_cancellation_thread_id_ = 0; - } + if (socket_ops::close(impl.socket_, ec) == socket_error_retval) + return ec; + + impl.socket_ = invalid_socket; + impl.cancel_token_.reset(); + impl.safe_cancellation_thread_id_ = 0; } - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); + return ec; } // Get the native socket representation. @@ -326,18 +322,17 @@ public: } // Cancel all operations associated with the socket. - template - void cancel(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) { if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - error_handler(error); + ec = boost::asio::error::bad_descriptor; } else if (impl.safe_cancellation_thread_id_ == 0) { // No operations have been started, so there's nothing to cancel. - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; } else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) { @@ -348,55 +343,50 @@ public: if (!::CancelIo(sock_as_handle)) { DWORD last_error = ::GetLastError(); - error_handler(boost::asio::error(last_error)); + ec = boost::system::error_code(last_error, boost::system::native_ecat); } else { - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; } } else { // Asynchronous operations have been started from more than one thread, // so cancellation is not safe. - error_handler(boost::asio::error(boost::asio::error::not_supported)); + ec = boost::asio::error::not_supported; } + + return ec; } // Bind the socket to the specified local endpoint. - template - void bind(implementation_type& impl, const endpoint_type& endpoint, - Error_Handler error_handler) + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) { - if (socket_ops::bind(impl.socket_, endpoint.data(), - endpoint.size()) == socket_error_retval) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; } // Place the socket into the state where it will listen for new connections. - template - void listen(implementation_type& impl, int backlog, - Error_Handler error_handler) + boost::system::error_code listen(implementation_type& impl, int backlog, + boost::system::error_code& ec) { - if (socket_ops::listen(impl.socket_, backlog) == socket_error_retval) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::listen(impl.socket_, backlog, ec); + return ec; } // Set a socket option. - template - void set_option(implementation_type& impl, const Option& option, - Error_Handler error_handler) + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) { if (option.level(impl.protocol_) == custom_socket_option_level && option.name(impl.protocol_) == enable_connection_aborted_option) { if (option.size(impl.protocol_) != sizeof(int)) { - error_handler(boost::asio::error(boost::asio::error::invalid_argument)); + ec = boost::asio::error::invalid_argument; } else { @@ -404,8 +394,9 @@ public: impl.flags_ |= implementation_type::enable_connection_aborted; else impl.flags_ &= ~implementation_type::enable_connection_aborted; - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); } + return ec; } else { @@ -415,26 +406,24 @@ public: impl.flags_ |= implementation_type::user_set_linger; } - if (socket_ops::setsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_))) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::setsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; } } // Set a socket option. - template - void get_option(const implementation_type& impl, Option& option, - Error_Handler error_handler) const + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const { if (option.level(impl.protocol_) == custom_socket_option_level && option.name(impl.protocol_) == enable_connection_aborted_option) { if (option.size(impl.protocol_) != sizeof(int)) { - error_handler(boost::asio::error(boost::asio::error::invalid_argument)); + ec = boost::asio::error::invalid_argument; } else { @@ -443,53 +432,45 @@ public: *target = 1; else *target = 0; - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); } + return ec; } else { size_t size = option.size(impl.protocol_); - if (socket_ops::getsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size)) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::getsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + return ec; } } // Perform an IO control command on the socket. - template - void io_control(implementation_type& impl, IO_Control_Command& command, - Error_Handler error_handler) + template + boost::system::error_code io_control(implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) { - if (socket_ops::ioctl(impl.socket_, command.name(), - static_cast(command.data()))) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::ioctl(impl.socket_, command.name(), + static_cast(command.data()), ec); + return ec; } // Get the local endpoint. - template - void get_local_endpoint(const implementation_type& impl, - endpoint_type& endpoint, Error_Handler error_handler) const + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const { + endpoint_type endpoint; socket_addr_len_type addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len)) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } - + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); endpoint.resize(addr_len); - error_handler(boost::asio::error(0)); + return endpoint; } // Get the remote endpoint. - template - void get_remote_endpoint(const implementation_type& impl, - endpoint_type& endpoint, Error_Handler error_handler) const + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const { if (impl.socket_.have_remote_endpoint()) { @@ -497,49 +478,42 @@ public: DWORD connect_time = 0; size_t connect_time_len = sizeof(connect_time); if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_CONNECT_TIME, - &connect_time, &connect_time_len) == socket_error_retval) + &connect_time, &connect_time_len, ec) == socket_error_retval) { - error_handler(boost::asio::error(socket_ops::get_error())); - return; + return endpoint_type(); } if (connect_time == 0xFFFFFFFF) { - error_handler(boost::asio::error(boost::asio::error::not_connected)); - return; + ec = boost::asio::error::not_connected; + return endpoint_type(); } - endpoint = impl.socket_.remote_endpoint(); - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; + return impl.socket_.remote_endpoint(); } else { + endpoint_type endpoint; socket_addr_len_type addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len)) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } - + if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); endpoint.resize(addr_len); - error_handler(boost::asio::error(0)); + return endpoint; } } /// Disable sends or receives on the socket. - template - void shutdown(implementation_type& impl, socket_base::shutdown_type what, - Error_Handler error_handler) + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) { - if (socket_ops::shutdown(impl.socket_, what) != 0) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::shutdown(impl.socket_, what, ec); + return ec; } // Send the given data to the peer. Returns the number of bytes sent. - template + template size_t send(implementation_type& impl, const Const_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { // Copy buffers into WSABUF array. ::WSABUF bufs[max_buffers]; @@ -559,7 +533,7 @@ public: // A request to receive 0 bytes on a stream socket is a no-op. if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) { - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; return 0; } @@ -572,11 +546,11 @@ public: DWORD last_error = ::WSAGetLastError(); if (last_error == ERROR_NETNAME_DELETED) last_error = WSAECONNRESET; - error_handler(boost::asio::error(last_error)); + ec = boost::system::error_code(last_error, boost::system::native_ecat); return 0; } - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); return bytes_transferred; } @@ -639,9 +613,9 @@ public: ptr.reset(); // Call the handler. - boost::asio::error error(last_error); + boost::system::error_code ec(last_error, boost::system::native_ecat); asio_handler_invoke_helpers::invoke( - detail::bind_handler(handler, error, bytes_transferred), &handler); + detail::bind_handler(handler, ec, bytes_transferred), &handler); } static void destroy_impl(operation* op) @@ -697,7 +671,7 @@ public: if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) { ptr.reset(); - boost::asio::error error(boost::asio::error::success); + boost::system::error_code error(boost::asio::error::success); iocp_service_.post(bind_handler(handler, error, 0)); return; } @@ -712,8 +686,8 @@ public: if (result != 0 && last_error != WSA_IO_PENDING) { ptr.reset(); - boost::asio::error error(last_error); - iocp_service_.post(bind_handler(handler, error, bytes_transferred)); + boost::system::error_code ec(last_error, boost::system::native_ecat); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); } else { @@ -723,10 +697,10 @@ public: // Send a datagram to the specified endpoint. Returns the number of bytes // sent. - template + template size_t send_to(implementation_type& impl, const Const_Buffers& buffers, const endpoint_type& destination, socket_base::message_flags flags, - Error_Handler error_handler) + boost::system::error_code& ec) { // Copy buffers into WSABUF array. ::WSABUF bufs[max_buffers]; @@ -748,11 +722,11 @@ public: if (result != 0) { DWORD last_error = ::WSAGetLastError(); - error_handler(boost::asio::error(last_error)); + ec = boost::system::error_code(last_error, boost::system::native_ecat); return 0; } - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); return bytes_transferred; } @@ -804,9 +778,9 @@ public: ptr.reset(); // Call the handler. - boost::asio::error error(last_error); + boost::system::error_code ec(last_error, boost::system::native_ecat); asio_handler_invoke_helpers::invoke( - detail::bind_handler(handler, error, bytes_transferred), &handler); + detail::bind_handler(handler, ec, bytes_transferred), &handler); } static void destroy_impl(operation* op) @@ -865,8 +839,8 @@ public: if (result != 0 && last_error != WSA_IO_PENDING) { ptr.reset(); - boost::asio::error error(last_error); - iocp_service_.post(bind_handler(handler, error, bytes_transferred)); + boost::system::error_code ec(last_error, boost::system::native_ecat); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); } else { @@ -875,9 +849,9 @@ public: } // Receive some data from the peer. Returns the number of bytes received. - template + template size_t receive(implementation_type& impl, const Mutable_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { // Copy buffers into WSABUF array. ::WSABUF bufs[max_buffers]; @@ -896,7 +870,7 @@ public: // A request to receive 0 bytes on a stream socket is a no-op. if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) { - error_handler(boost::asio::error(0)); + ec = boost::asio::error::success; return 0; } @@ -910,16 +884,16 @@ public: DWORD last_error = ::WSAGetLastError(); if (last_error == ERROR_NETNAME_DELETED) last_error = WSAECONNRESET; - error_handler(boost::asio::error(last_error)); + ec = boost::system::error_code(last_error, boost::system::native_ecat); return 0; } if (bytes_transferred == 0) { - error_handler(boost::asio::error(boost::asio::error::eof)); + ec = boost::asio::error::eof; return 0; } - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); return bytes_transferred; } @@ -977,7 +951,7 @@ public: // Check for connection closed. else if (last_error == 0 && bytes_transferred == 0) { - last_error = boost::asio::error::eof; + last_error = ERROR_HANDLE_EOF; } // Make a copy of the handler so that the memory can be deallocated before @@ -988,9 +962,9 @@ public: ptr.reset(); // Call the handler. - boost::asio::error error(last_error); + boost::system::error_code ec(last_error, boost::system::native_ecat); asio_handler_invoke_helpers::invoke( - detail::bind_handler(handler, error, bytes_transferred), &handler); + detail::bind_handler(handler, ec, bytes_transferred), &handler); } static void destroy_impl(operation* op) @@ -1045,7 +1019,7 @@ public: if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0) { ptr.reset(); - boost::asio::error error(boost::asio::error::success); + boost::system::error_code error(boost::asio::error::success); iocp_service_.post(bind_handler(handler, error, 0)); return; } @@ -1059,8 +1033,8 @@ public: if (result != 0 && last_error != WSA_IO_PENDING) { ptr.reset(); - boost::asio::error error(last_error); - iocp_service_.post(bind_handler(handler, error, bytes_transferred)); + boost::system::error_code ec(last_error, boost::system::native_ecat); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); } else { @@ -1070,10 +1044,10 @@ public: // Receive a datagram with the endpoint of the sender. Returns the number of // bytes received. - template + template size_t receive_from(implementation_type& impl, const Mutable_Buffers& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags, - Error_Handler error_handler) + boost::system::error_code& ec) { // Copy buffers into WSABUF array. ::WSABUF bufs[max_buffers]; @@ -1096,18 +1070,18 @@ public: if (result != 0) { DWORD last_error = ::WSAGetLastError(); - error_handler(boost::asio::error(last_error)); + ec = boost::system::error_code(last_error, boost::system::native_ecat); return 0; } if (bytes_transferred == 0) { - error_handler(boost::asio::error(boost::asio::error::eof)); + ec = boost::asio::error::eof; return 0; } sender_endpoint.resize(endpoint_size); - error_handler(boost::asio::error(0)); + ec = boost::system::error_code(); return bytes_transferred; } @@ -1162,7 +1136,7 @@ public: // Check for connection closed. if (last_error == 0 && bytes_transferred == 0) { - last_error = boost::asio::error::eof; + last_error = ERROR_HANDLE_EOF; } // Record the size of the endpoint returned by the operation. @@ -1176,9 +1150,9 @@ public: ptr.reset(); // Call the handler. - boost::asio::error error(last_error); + boost::system::error_code ec(last_error, boost::system::native_ecat); asio_handler_invoke_helpers::invoke( - detail::bind_handler(handler, error, bytes_transferred), &handler); + detail::bind_handler(handler, ec, bytes_transferred), &handler); } static void destroy_impl(operation* op) @@ -1240,8 +1214,8 @@ public: if (result != 0 && last_error != WSA_IO_PENDING) { ptr.reset(); - boost::asio::error error(last_error); - iocp_service_.post(bind_handler(handler, error, bytes_transferred)); + boost::system::error_code ec(last_error, boost::system::native_ecat); + iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); } else { @@ -1250,23 +1224,23 @@ public: } // Accept a new connection. - template - void accept(implementation_type& impl, Socket& peer, - Error_Handler error_handler) + template + boost::system::error_code accept(implementation_type& impl, Socket& peer, + boost::system::error_code& ec) { // We cannot accept a socket that is already open. if (peer.native() != invalid_socket) { - error_handler(boost::asio::error(boost::asio::error::already_connected)); - return; + ec = boost::asio::error::already_connected; + return ec; } for (;;) { - socket_holder new_socket(socket_ops::accept(impl.socket_, 0, 0)); - if (int err = socket_ops::get_error()) + socket_holder new_socket(socket_ops::accept(impl.socket_, 0, 0, ec)); + if (ec) { - if (err == boost::asio::error::connection_aborted + if (ec == boost::asio::error::connection_aborted && !(impl.flags_ & implementation_type::enable_connection_aborted)) { // Retry accept operation. @@ -1274,48 +1248,37 @@ public: } else { - error_handler(boost::asio::error(err)); - return; + return ec; } } - boost::asio::error temp_error; - peer.assign(impl.protocol_, new_socket.get(), - boost::asio::assign_error(temp_error)); - if (temp_error) - { - error_handler(temp_error); - return; - } - else - { + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) new_socket.release(); - error_handler(boost::asio::error(0)); - return; - } + return ec; } } // Accept a new connection. - template - void accept_endpoint(implementation_type& impl, Socket& peer, - endpoint_type& peer_endpoint, Error_Handler error_handler) + template + boost::system::error_code accept_endpoint(implementation_type& impl, + Socket& peer, endpoint_type& peer_endpoint, boost::system::error_code& ec) { // We cannot accept a socket that is already open. if (peer.native() != invalid_socket) { - error_handler(boost::asio::error(boost::asio::error::already_connected)); - return; + ec = boost::asio::error::already_connected; + return ec; } for (;;) { socket_addr_len_type addr_len = peer_endpoint.capacity(); socket_holder new_socket(socket_ops::accept( - impl.socket_, peer_endpoint.data(), &addr_len)); - if (int err = socket_ops::get_error()) + impl.socket_, peer_endpoint.data(), &addr_len, ec)); + if (ec) { - if (err == boost::asio::error::connection_aborted + if (ec == boost::asio::error::connection_aborted && !(impl.flags_ & implementation_type::enable_connection_aborted)) { // Retry accept operation. @@ -1323,27 +1286,16 @@ public: } else { - error_handler(boost::asio::error(err)); - return; + return ec; } } peer_endpoint.resize(addr_len); - boost::asio::error temp_error; - peer.assign(impl.protocol_, new_socket.get(), - boost::asio::assign_error(temp_error)); - if (temp_error) - { - error_handler(temp_error); - return; - } - else - { + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) new_socket.release(); - error_handler(boost::asio::error(0)); - return; - } + return ec; } } @@ -1397,12 +1349,12 @@ public: // Map Windows error ERROR_NETNAME_DELETED to connection_aborted. if (last_error == ERROR_NETNAME_DELETED) { - last_error = boost::asio::error::connection_aborted; + last_error = WSAECONNABORTED; } // Restart the accept operation if we got the connection_aborted error // and the enable_connection_aborted socket option is not set. - if (last_error == boost::asio::error::connection_aborted + if (last_error == WSAECONNABORTED && !ptr.get()->enable_connection_aborted_) { // Reset OVERLAPPED structure. @@ -1414,11 +1366,11 @@ public: // Create a new socket for the next connection, since the AcceptEx call // fails with WSAEINVAL if we try to reuse the same socket. + boost::system::error_code ec; ptr.get()->new_socket_.reset(); - ptr.get()->new_socket_.reset( - socket_ops::socket(ptr.get()->protocol_.family(), - ptr.get()->protocol_.type(), ptr.get()->protocol_.protocol())); - last_error = socket_ops::get_error(); + ptr.get()->new_socket_.reset(socket_ops::socket( + ptr.get()->protocol_.family(), ptr.get()->protocol_.type(), + ptr.get()->protocol_.protocol(), ec)); if (ptr.get()->new_socket() != invalid_socket) { // Accept a connection. @@ -1432,7 +1384,7 @@ public: if (!result && last_error != WSA_IO_PENDING) { if (last_error == ERROR_NETNAME_DELETED - || last_error == boost::asio::error::connection_aborted) + || last_error == WSAECONNABORTED) { // Post this handler so that operation will be restarted again. ptr.get()->io_service_.post_completion(ptr.get(), last_error, 0); @@ -1466,7 +1418,7 @@ public: &local_addr, &local_addr_length, &remote_addr, &remote_addr_length); if (remote_addr_length > peer_endpoint.capacity()) { - last_error = boost::asio::error::invalid_argument; + last_error = boost::asio::error::invalid_argument.value(); } else { @@ -1481,11 +1433,12 @@ public: if (last_error == 0) { SOCKET update_ctx_param = handler_op->socket_; + boost::system::error_code ec; if (socket_ops::setsockopt(handler_op->new_socket_.get(), SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, - &update_ctx_param, sizeof(SOCKET)) != 0) + &update_ctx_param, sizeof(SOCKET), ec) != 0) { - last_error = socket_ops::get_error(); + last_error = ec.value(); } } @@ -1493,12 +1446,11 @@ public: // socket to the peer object. if (last_error == 0) { - boost::asio::error temp_error; + boost::system::error_code ec; handler_op->peer_.assign(handler_op->protocol_, - native_type(handler_op->new_socket_.get(), peer_endpoint), - boost::asio::assign_error(temp_error)); - if (temp_error) - last_error = temp_error.code(); + native_type(handler_op->new_socket_.get(), peer_endpoint), ec); + if (ec) + last_error = ec.value(); else handler_op->new_socket_.release(); } @@ -1511,9 +1463,9 @@ public: ptr.reset(); // Call the handler. - boost::asio::error error(last_error); + boost::system::error_code ec(last_error, boost::system::native_ecat); asio_handler_invoke_helpers::invoke( - detail::bind_handler(handler, error), &handler); + detail::bind_handler(handler, ec), &handler); } static void destroy_impl(operation* op) @@ -1550,26 +1502,26 @@ public: // Check whether acceptor has been initialised. if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); return; } // Check that peer socket has not already been connected. if (peer.native() != invalid_socket) { - boost::asio::error error(boost::asio::error::already_connected); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::already_connected)); return; } // Create a new socket for the connection. + boost::system::error_code ec; socket_holder sock(socket_ops::socket(impl.protocol_.family(), - impl.protocol_.type(), impl.protocol_.protocol())); + impl.protocol_.type(), impl.protocol_.protocol(), ec)); if (sock.get() == invalid_socket) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } @@ -1597,7 +1549,7 @@ public: { if (!enable_connection_aborted && (last_error == ERROR_NETNAME_DELETED - || last_error == boost::asio::error::connection_aborted)) + || last_error == WSAECONNABORTED)) { // Post handler so that operation will be restarted again. We do not // perform the AcceptEx again here to avoid the possibility of starving @@ -1608,8 +1560,8 @@ public: else { ptr.reset(); - boost::asio::error error(last_error); - iocp_service_.post(bind_handler(handler, error)); + boost::system::error_code ec(last_error, boost::system::native_ecat); + iocp_service_.post(bind_handler(handler, ec)); } } else @@ -1670,12 +1622,12 @@ public: // Map Windows error ERROR_NETNAME_DELETED to connection_aborted. if (last_error == ERROR_NETNAME_DELETED) { - last_error = boost::asio::error::connection_aborted; + last_error = WSAECONNABORTED; } // Restart the accept operation if we got the connection_aborted error // and the enable_connection_aborted socket option is not set. - if (last_error == boost::asio::error::connection_aborted + if (last_error == WSAECONNABORTED && !ptr.get()->enable_connection_aborted_) { // Reset OVERLAPPED structure. @@ -1687,11 +1639,11 @@ public: // Create a new socket for the next connection, since the AcceptEx call // fails with WSAEINVAL if we try to reuse the same socket. + boost::system::error_code ec; ptr.get()->new_socket_.reset(); - ptr.get()->new_socket_.reset( - socket_ops::socket(ptr.get()->protocol_.family(), - ptr.get()->protocol_.type(), ptr.get()->protocol_.protocol())); - last_error = socket_ops::get_error(); + ptr.get()->new_socket_.reset(socket_ops::socket( + ptr.get()->protocol_.family(), ptr.get()->protocol_.type(), + ptr.get()->protocol_.protocol(), ec)); if (ptr.get()->new_socket() != invalid_socket) { // Accept a connection. @@ -1705,7 +1657,7 @@ public: if (!result && last_error != WSA_IO_PENDING) { if (last_error == ERROR_NETNAME_DELETED - || last_error == boost::asio::error::connection_aborted) + || last_error == WSAECONNABORTED) { // Post this handler so that operation will be restarted again. ptr.get()->io_service_.post_completion(ptr.get(), last_error, 0); @@ -1738,7 +1690,7 @@ public: &local_addr, &local_addr_length, &remote_addr, &remote_addr_length); if (remote_addr_length > handler_op->peer_endpoint_.capacity()) { - last_error = boost::asio::error::invalid_argument; + last_error = WSAEINVAL; } else { @@ -1754,11 +1706,12 @@ public: if (last_error == 0) { SOCKET update_ctx_param = handler_op->socket_; + boost::system::error_code ec; if (socket_ops::setsockopt(handler_op->new_socket_.get(), SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, - &update_ctx_param, sizeof(SOCKET)) != 0) + &update_ctx_param, sizeof(SOCKET), ec) != 0) { - last_error = socket_ops::get_error(); + last_error = ec.value(); } } @@ -1766,13 +1719,12 @@ public: // socket to the peer object. if (last_error == 0) { - boost::asio::error temp_error; + boost::system::error_code ec; handler_op->peer_.assign(handler_op->peer_endpoint_.protocol(), native_type(handler_op->new_socket_.get(), - handler_op->peer_endpoint_), - boost::asio::assign_error(temp_error)); - if (temp_error) - last_error = temp_error.code(); + handler_op->peer_endpoint_), ec); + if (ec) + last_error = ec.value(); else handler_op->new_socket_.release(); } @@ -1785,9 +1737,9 @@ public: ptr.reset(); // Call the handler. - boost::asio::error error(last_error); + boost::system::error_code ec(last_error, boost::system::native_ecat); asio_handler_invoke_helpers::invoke( - detail::bind_handler(handler, error), &handler); + detail::bind_handler(handler, ec), &handler); } static void destroy_impl(operation* op) @@ -1826,26 +1778,26 @@ public: // Check whether acceptor has been initialised. if (impl.socket_ == invalid_socket) { - boost::asio::error error(boost::asio::error::bad_descriptor); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::bad_descriptor)); return; } // Check that peer socket has not already been connected. if (peer.native() != invalid_socket) { - boost::asio::error error(boost::asio::error::already_connected); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, + boost::asio::error::already_connected)); return; } // Create a new socket for the connection. + boost::system::error_code ec; socket_holder sock(socket_ops::socket(impl.protocol_.family(), - impl.protocol_.type(), impl.protocol_.protocol())); + impl.protocol_.type(), impl.protocol_.protocol(), ec)); if (sock.get() == invalid_socket) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } @@ -1873,7 +1825,7 @@ public: { if (!enable_connection_aborted && (last_error == ERROR_NETNAME_DELETED - || last_error == boost::asio::error::connection_aborted)) + || last_error == WSAECONNABORTED)) { // Post handler so that operation will be restarted again. We do not // perform the AcceptEx again here to avoid the possibility of starving @@ -1884,8 +1836,8 @@ public: else { ptr.reset(); - boost::asio::error error(last_error); - iocp_service_.post(bind_handler(handler, error)); + boost::system::error_code ec(last_error, boost::system::native_ecat); + iocp_service_.post(bind_handler(handler, ec)); } } else @@ -1895,9 +1847,8 @@ public: } // Connect the socket to the specified endpoint. - template - void connect(implementation_type& impl, const endpoint_type& peer_endpoint, - Error_Handler error_handler) + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) { // Open the socket if it is not already open. if (impl.socket_ == invalid_socket) @@ -1908,22 +1859,16 @@ public: int proto = peer_endpoint.protocol().protocol(); // Create a new socket. - impl.socket_ = socket_ops::socket(family, type, proto); + impl.socket_ = socket_ops::socket(family, type, proto, ec); if (impl.socket_ == invalid_socket) - { - error_handler(boost::asio::error(socket_ops::get_error())); - return; - } + return ec; iocp_service_.register_socket(impl.socket_); } // Perform the connect operation. - int result = socket_ops::connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size()); - if (result == socket_error_retval) - error_handler(boost::asio::error(socket_ops::get_error())); - else - error_handler(boost::asio::error(0)); + socket_ops::connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + return ec; } template @@ -1943,7 +1888,7 @@ public: { } - bool operator()(int result) + bool operator()(const boost::system::error_code& result) { // Check whether a handler has already been called for the connection. // If it has, then we don't want to do anything in this handler. @@ -1955,44 +1900,43 @@ public: reactor_.enqueue_cancel_ops_unlocked(socket_); // Check whether the operation was successful. - if (result != 0) + if (result) { - boost::asio::error error(result); - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, result)); return true; } // Get the error code from the connect operation. int connect_error = 0; size_t connect_error_len = sizeof(connect_error); + boost::system::error_code ec; if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR, - &connect_error, &connect_error_len) == socket_error_retval) + &connect_error, &connect_error_len, ec) == socket_error_retval) { - boost::asio::error error(socket_ops::get_error()); - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, ec)); return true; } // If connection failed then post the handler with the error code. if (connect_error) { - boost::asio::error error(connect_error); - io_service_.post(bind_handler(handler_, error)); + ec = boost::system::error_code( + connect_error, boost::system::native_ecat); + io_service_.post(bind_handler(handler_, ec)); return true; } // Make the socket blocking again (the default). ioctl_arg_type non_blocking = 0; - if (socket_ops::ioctl(socket_, FIONBIO, &non_blocking)) + if (socket_ops::ioctl(socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service_.post(bind_handler(handler_, error)); + io_service_.post(bind_handler(handler_, ec)); return true; } // Post the result of the successful connection operation. - boost::asio::error error(boost::asio::error::success); - io_service_.post(bind_handler(handler_, error)); + ec = boost::system::error_code(); + io_service_.post(bind_handler(handler_, ec)); return true; } @@ -2036,11 +1980,11 @@ public: int proto = peer_endpoint.protocol().protocol(); // Create a new socket. - impl.socket_ = socket_ops::socket(family, type, proto); + boost::system::error_code ec; + impl.socket_ = socket_ops::socket(family, type, proto, ec); if (impl.socket_ == invalid_socket) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } iocp_service_.register_socket(impl.socket_); @@ -2049,24 +1993,23 @@ public: // Mark the socket as non-blocking so that the connection will take place // asynchronously. ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking)) + boost::system::error_code ec; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) { - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); return; } // Start the connect operation. if (socket_ops::connect(impl.socket_, peer_endpoint.data(), - peer_endpoint.size()) == 0) + peer_endpoint.size(), ec) == 0) { // The connect operation has finished successfully so we need to post the // handler immediately. - boost::asio::error error(boost::asio::error::success); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); } - else if (socket_ops::get_error() == boost::asio::error::in_progress - || socket_ops::get_error() == boost::asio::error::would_block) + else if (ec == boost::asio::error::in_progress + || ec == boost::asio::error::would_block) { // The connection is happening in the background, and we need to wait // until the socket becomes writeable. @@ -2078,8 +2021,7 @@ public: else { // The connect operation has failed, so post the handler immediately. - boost::asio::error error(socket_ops::get_error()); - io_service().post(bind_handler(handler, error)); + io_service().post(bind_handler(handler, ec)); } } diff --git a/include/boost/asio/detail/win_mutex.hpp b/include/boost/asio/detail/win_mutex.hpp index dc078336..f5a4b37b 100644 --- a/include/boost/asio/detail/win_mutex.hpp +++ b/include/boost/asio/detail/win_mutex.hpp @@ -19,11 +19,11 @@ #include #include +#include #include #if defined(BOOST_WINDOWS) -#include #include #include #include @@ -48,7 +48,9 @@ public: int error = do_init(); if (error != 0) { - system_exception e("mutex", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "mutex"); boost::throw_exception(e); } } @@ -65,7 +67,9 @@ public: int error = do_lock(); if (error != 0) { - system_exception e("mutex", error); + boost::system::system_error e( + boost::system::error_code(error, boost::system::native_ecat), + "mutex"); boost::throw_exception(e); } } diff --git a/include/boost/asio/detail/win_thread.hpp b/include/boost/asio/detail/win_thread.hpp index d4db0111..1a73b41f 100644 --- a/include/boost/asio/detail/win_thread.hpp +++ b/include/boost/asio/detail/win_thread.hpp @@ -19,11 +19,11 @@ #include #include +#include #include #if defined(BOOST_WINDOWS) -#include #include #include @@ -54,7 +54,9 @@ public: if (!thread_) { DWORD last_error = ::GetLastError(); - system_exception e("thread", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, boost::system::native_ecat), + "thread"); boost::throw_exception(e); } arg.release(); diff --git a/include/boost/asio/detail/win_tss_ptr.hpp b/include/boost/asio/detail/win_tss_ptr.hpp index fda922d3..b265707c 100644 --- a/include/boost/asio/detail/win_tss_ptr.hpp +++ b/include/boost/asio/detail/win_tss_ptr.hpp @@ -19,11 +19,11 @@ #include #include +#include #include #if defined(BOOST_WINDOWS) -#include #include #include @@ -47,7 +47,9 @@ public: if (tss_key_ == TLS_OUT_OF_INDEXES) { DWORD last_error = ::GetLastError(); - system_exception e("tss", last_error); + boost::system::system_error e( + boost::system::error_code(last_error, boost::system::native_ecat), + "tss"); boost::throw_exception(e); } } diff --git a/include/boost/asio/detail/winsock_init.hpp b/include/boost/asio/detail/winsock_init.hpp index 2eb57c1e..72cdd6c0 100644 --- a/include/boost/asio/detail/winsock_init.hpp +++ b/include/boost/asio/detail/winsock_init.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -28,7 +29,6 @@ #include #include -#include #include #include @@ -85,7 +85,9 @@ public: // catch the exception. if (this != &instance_ && ref_->result() != 0) { - system_exception e("winsock", ref_->result()); + boost::system::system_error e( + boost::system::error_code(ref_->result(), boost::system::native_ecat), + "winsock"); boost::throw_exception(e); } } diff --git a/include/boost/asio/error.hpp b/include/boost/asio/error.hpp index 60a0fb7e..507be308 100644 --- a/include/boost/asio/error.hpp +++ b/include/boost/asio/error.hpp @@ -18,371 +18,481 @@ #include #include -#include -#include #include -#include -#include -#include -#include -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -# include -#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +#include +#include +#include #include -#include #include -namespace boost { -namespace asio { - #if defined(GENERATING_DOCUMENTATION) /// INTERNAL ONLY. +# define BOOST_ASIO_NATIVE_ERROR(e) implementation_defined +/// INTERNAL ONLY. # define BOOST_ASIO_SOCKET_ERROR(e) implementation_defined /// INTERNAL ONLY. # define BOOST_ASIO_NETDB_ERROR(e) implementation_defined /// INTERNAL ONLY. # define BOOST_ASIO_GETADDRINFO_ERROR(e) implementation_defined /// INTERNAL ONLY. -# define BOOST_ASIO_OS_ERROR(e_win, e_posix) implementation_defined +# define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined #elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# define BOOST_ASIO_SOCKET_ERROR(e) WSA ## e -# define BOOST_ASIO_NETDB_ERROR(e) WSA ## e -# define BOOST_ASIO_GETADDRINFO_ERROR(e) e -# define BOOST_ASIO_OS_ERROR(e_win, e_posix) e_win +# define BOOST_ASIO_NATIVE_ERROR(e) \ + boost::system::error_code(e, boost::system::native_ecat) +# define BOOST_ASIO_SOCKET_ERROR(e) \ + boost::system::error_code(WSA ## e, boost::system::native_ecat) +# define BOOST_ASIO_NETDB_ERROR(e) \ + boost::system::error_code(WSA ## e, boost::system::native_ecat) +# define BOOST_ASIO_GETADDRINFO_ERROR(e) \ + boost::system::error_code(WSA ## e, boost::system::native_ecat) +# define BOOST_ASIO_EOF_ERROR(e) \ + boost::system::error_code(e, boost::system::native_ecat) +# define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) e_win #else -# define BOOST_ASIO_SOCKET_ERROR(e) e -# define BOOST_ASIO_NETDB_ERROR(e) 16384 + e -# define BOOST_ASIO_GETADDRINFO_ERROR(e) 32768 + e -# define BOOST_ASIO_OS_ERROR(e_win, e_posix) e_posix +# define BOOST_ASIO_NATIVE_ERROR(e) \ + boost::system::error_code(e, boost::system::native_ecat) +# define BOOST_ASIO_SOCKET_ERROR(e) \ + boost::system::error_code(e, boost::system::native_ecat) +# define BOOST_ASIO_NETDB_ERROR(e) \ + boost::system::error_code(e, boost::asio::error_base::netdb_ecat) +# define BOOST_ASIO_GETADDRINFO_ERROR(e) \ + boost::system::error_code(e, boost::asio::error_base::addrinfo_ecat) +# define BOOST_ASIO_EOF_ERROR(e) \ + boost::system::error_code(e, boost::asio::error_base::eof_ecat) +# define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix #endif -/// The error class is used to encapsulate system error codes. -class error - : public std::exception +namespace boost { +namespace asio { + +/// Hack to keep asio library header-file-only. +template +class error_base { public: - /// Error codes. - enum code_type - { - /// Permission denied. - access_denied = BOOST_ASIO_SOCKET_ERROR(EACCES), +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + static boost::system::error_category netdb_ecat; + static int netdb_ed(const boost::system::error_code& ec); + static std::string netdb_md(const boost::system::error_code& ec); + static boost::system::wstring_t netdb_wmd( + const boost::system::error_code& ec); - /// Address family not supported by protocol. - address_family_not_supported = BOOST_ASIO_SOCKET_ERROR(EAFNOSUPPORT), + static boost::system::error_category addrinfo_ecat; + static int addrinfo_ed(const boost::system::error_code& ec); + static std::string addrinfo_md(const boost::system::error_code& ec); + static boost::system::wstring_t addrinfo_wmd( + const boost::system::error_code& ec); - /// Address already in use. - address_in_use = BOOST_ASIO_SOCKET_ERROR(EADDRINUSE), + static boost::system::error_category eof_ecat; + static int eof_ed(const boost::system::error_code& ec); + static std::string eof_md(const boost::system::error_code& ec); + static boost::system::wstring_t eof_wmd(const boost::system::error_code& ec); +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) - /// Transport endpoint is already connected. - already_connected = BOOST_ASIO_SOCKET_ERROR(EISCONN), + static boost::system::error_category ssl_ecat; + static int ssl_ed(const boost::system::error_code& ec); + static std::string ssl_md(const boost::system::error_code& ec); + static boost::system::wstring_t ssl_wmd(const boost::system::error_code& ec); - /// Operation already in progress. - already_started = BOOST_ASIO_SOCKET_ERROR(EALREADY), + /// Permission denied. + static const boost::system::error_code access_denied; - /// A connection has been aborted. - connection_aborted = BOOST_ASIO_SOCKET_ERROR(ECONNABORTED), + /// Address family not supported by protocol. + static const boost::system::error_code address_family_not_supported; - /// Connection refused. - connection_refused = BOOST_ASIO_SOCKET_ERROR(ECONNREFUSED), + /// Address already in use. + static const boost::system::error_code address_in_use; - /// Connection reset by peer. - connection_reset = BOOST_ASIO_SOCKET_ERROR(ECONNRESET), + /// Transport endpoint is already connected. + static const boost::system::error_code already_connected; - /// Bad file descriptor. - bad_descriptor = BOOST_ASIO_SOCKET_ERROR(EBADF), + /// Operation already in progress. + static const boost::system::error_code already_started; - /// End of file or stream. - eof = BOOST_ASIO_OS_ERROR(ERROR_HANDLE_EOF, -1), + /// A connection has been aborted. + static const boost::system::error_code connection_aborted; - /// Bad address. - fault = BOOST_ASIO_SOCKET_ERROR(EFAULT), + /// Connection refused. + static const boost::system::error_code connection_refused; - /// Host not found (authoritative). - host_not_found = BOOST_ASIO_NETDB_ERROR(HOST_NOT_FOUND), + /// Connection reset by peer. + static const boost::system::error_code connection_reset; - /// Host not found (non-authoritative). - host_not_found_try_again = BOOST_ASIO_NETDB_ERROR(TRY_AGAIN), + /// Bad file descriptor. + static const boost::system::error_code bad_descriptor; - /// No route to host. - host_unreachable = BOOST_ASIO_SOCKET_ERROR(EHOSTUNREACH), + /// End of file or stream. + static const boost::system::error_code eof; - /// Operation now in progress. - in_progress = BOOST_ASIO_SOCKET_ERROR(EINPROGRESS), + /// Bad address. + static const boost::system::error_code fault; - /// Interrupted system call. - interrupted = BOOST_ASIO_SOCKET_ERROR(EINTR), + /// Host not found (authoritative). + static const boost::system::error_code host_not_found; - /// Invalid argument. - invalid_argument = BOOST_ASIO_SOCKET_ERROR(EINVAL), + /// Host not found (non-authoritative). + static const boost::system::error_code host_not_found_try_again; - /// Message too long. - message_size = BOOST_ASIO_SOCKET_ERROR(EMSGSIZE), + /// No route to host. + static const boost::system::error_code host_unreachable; - /// Network is down. - network_down = BOOST_ASIO_SOCKET_ERROR(ENETDOWN), + /// Operation now in progress. + static const boost::system::error_code in_progress; - /// Network dropped connection on reset. - network_reset = BOOST_ASIO_SOCKET_ERROR(ENETRESET), + /// Interrupted system call. + static const boost::system::error_code interrupted; - /// Network is unreachable. - network_unreachable = BOOST_ASIO_SOCKET_ERROR(ENETUNREACH), + /// Invalid argument. + static const boost::system::error_code invalid_argument; - /// Too many open files. - no_descriptors = BOOST_ASIO_SOCKET_ERROR(EMFILE), + /// Message too long. + static const boost::system::error_code message_size; - /// No buffer space available. - no_buffer_space = BOOST_ASIO_SOCKET_ERROR(ENOBUFS), + /// Network is down. + static const boost::system::error_code network_down; - /// The query is valid but does not have associated address data. - no_data = BOOST_ASIO_NETDB_ERROR(NO_DATA), + /// Network dropped connection on reset. + static const boost::system::error_code network_reset; - /// Cannot allocate memory. - no_memory = BOOST_ASIO_OS_ERROR(ERROR_OUTOFMEMORY, ENOMEM), + /// Network is unreachable. + static const boost::system::error_code network_unreachable; - /// Operation not permitted. - no_permission = BOOST_ASIO_OS_ERROR(ERROR_ACCESS_DENIED, EPERM), + /// Too many open files. + static const boost::system::error_code no_descriptors; - /// Protocol not available. - no_protocol_option = BOOST_ASIO_SOCKET_ERROR(ENOPROTOOPT), + /// No buffer space available. + static const boost::system::error_code no_buffer_space; - /// A non-recoverable error occurred. - no_recovery = BOOST_ASIO_NETDB_ERROR(NO_RECOVERY), + /// The query is valid but does not have associated address data. + static const boost::system::error_code no_data; - /// Transport endpoint is not connected. - not_connected = BOOST_ASIO_SOCKET_ERROR(ENOTCONN), + /// Cannot allocate memory. + static const boost::system::error_code no_memory; - /// Socket operation on non-socket. - not_socket = BOOST_ASIO_SOCKET_ERROR(ENOTSOCK), + /// Operation not permitted. + static const boost::system::error_code no_permission; - /// Operation not supported. - not_supported = BOOST_ASIO_SOCKET_ERROR(EOPNOTSUPP), + /// Protocol not available. + static const boost::system::error_code no_protocol_option; - /// Operation cancelled. - operation_aborted = BOOST_ASIO_OS_ERROR(ERROR_OPERATION_ABORTED, ECANCELED), + /// A non-recoverable error occurred. + static const boost::system::error_code no_recovery; - /// The service is not supported for the given socket type. - service_not_found = BOOST_ASIO_OS_ERROR( - WSATYPE_NOT_FOUND, - BOOST_ASIO_GETADDRINFO_ERROR(EAI_SERVICE)), + /// Transport endpoint is not connected. + static const boost::system::error_code not_connected; - /// The socket type is not supported. - socket_type_not_supported = BOOST_ASIO_OS_ERROR( - WSAESOCKTNOSUPPORT, - BOOST_ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE)), + /// Socket operation on non-socket. + static const boost::system::error_code not_socket; - /// Cannot send after transport endpoint shutdown. - shut_down = BOOST_ASIO_SOCKET_ERROR(ESHUTDOWN), + /// Operation not supported. + static const boost::system::error_code not_supported; - /// Success. - success = 0, + /// Operation cancelled. + static const boost::system::error_code operation_aborted; - /// Connection timed out. - timed_out = BOOST_ASIO_SOCKET_ERROR(ETIMEDOUT), + /// The service is not supported for the given socket type. + static const boost::system::error_code service_not_found; - /// Resource temporarily unavailable. - try_again = BOOST_ASIO_OS_ERROR(ERROR_RETRY, EAGAIN), + /// The socket type is not supported. + static const boost::system::error_code socket_type_not_supported; - /// The socket is marked non-blocking and the requested operation would - /// block. - would_block = BOOST_ASIO_SOCKET_ERROR(EWOULDBLOCK) - }; + /// Cannot send after transport endpoint shutdown. + static const boost::system::error_code shut_down; - /// Default constructor. - error() - : code_(success) - { - } + /// Success. + static const boost::system::error_code success; - /// Construct with a specific error code. - error(int code) - : code_(code) - { - } + /// Connection timed out. + static const boost::system::error_code timed_out; - /// Copy constructor. - error(const error& e) - : std::exception(e), - code_(e.code_) - { - } + /// Resource temporarily unavailable. + static const boost::system::error_code try_again; - /// Destructor. - virtual ~error() throw () - { - } - - /// Assignment operator. - error& operator=(const error& e) - { - code_ = e.code_; - what_.reset(); - return *this; - } - - /// Get a string representation of the exception. - virtual const char* what() const throw () - { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - try - { - if (!what_) - { - char* msg = 0; - DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER - | FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS, 0, code_, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); - detail::local_free_on_block_exit local_free_obj(msg); - if (length && msg[length - 1] == '\n') - msg[--length] = '\0'; - if (length && msg[length - 1] == '\r') - msg[--length] = '\0'; - if (length) - what_.reset(new std::string(msg)); - else - return "asio error"; - } - return what_->c_str(); - } - catch (std::exception&) - { - return "asio error"; - } -#else // defined(BOOST_WINDOWS) - switch (code_) - { - case error::eof: - return "End of file."; - case error::host_not_found: - return "Host not found (authoritative)."; - case error::host_not_found_try_again: - return "Host not found (non-authoritative), try again later."; - case error::no_recovery: - return "A non-recoverable error occurred during database lookup."; - case error::no_data: - return "The query is valid, but it does not have associated data."; -#if !defined(__sun) - case error::operation_aborted: - return "Operation aborted."; -#endif // !defined(__sun) - case error::service_not_found: - return "Service not found."; - case error::socket_type_not_supported: - return "Socket type not supported."; - default: -#if defined(__sun) || defined(__QNX__) - return strerror(code_); -#elif defined(__MACH__) && defined(__APPLE__) \ - || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - try - { - char buf[256] = ""; - strerror_r(code_, buf, sizeof(buf)); - what_.reset(new std::string(buf)); - return what_->c_str(); - } - catch (std::exception&) - { - return "asio error"; - } -#else - try - { - char buf[256] = ""; - what_.reset(new std::string(strerror_r(code_, buf, sizeof(buf)))); - return what_->c_str(); - } - catch (std::exception&) - { - return "asio error"; - } -#endif - } -#endif // defined(BOOST_WINDOWS) - } - - /// Get the code associated with the error. - int code() const - { - return code_; - } - - struct unspecified_bool_type_t - { - }; - - typedef unspecified_bool_type_t* unspecified_bool_type; - - /// Operator returns non-null if there is a non-success error code. - operator unspecified_bool_type() const - { - if (code_ == success) - return 0; - else - return reinterpret_cast(1); - } - - /// Operator to test if the error represents success. - bool operator!() const - { - return code_ == success; - } - - /// Equality operator to compare two error objects. - friend bool operator==(const error& e1, const error& e2) - { - return e1.code_ == e2.code_; - } - - /// Inequality operator to compare two error objects. - friend bool operator!=(const error& e1, const error& e2) - { - return e1.code_ != e2.code_; - } + /// The socket is marked non-blocking and the requested operation would block. + static const boost::system::error_code would_block; private: - // The code associated with the error. - int code_; - - // The string representation of the error. - mutable boost::scoped_ptr what_; + error_base(); }; -/// Output the string associated with an error. -/** - * Used to output a human-readable string that is associated with an error. - * - * @param os The output stream to which the string will be written. - * - * @param e The error to be written. - * - * @return The output stream. - * - * @relates boost::asio::error - */ -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -std::ostream& operator<<(std::ostream& os, const error& e) +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +template +boost::system::error_category error_base::netdb_ecat( + boost::system::error_code::new_category(&error_base::netdb_ed, + &error_base::netdb_md, &error_base::netdb_wmd)); + +template +int error_base::netdb_ed(const boost::system::error_code& ec) { - os << e.what(); - return os; + return EOTHER; } -#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -template -Ostream& operator<<(Ostream& os, const error& e) + +template +std::string error_base::netdb_md(const boost::system::error_code& ec) { - os << e.what(); - return os; + if (ec == error_base::host_not_found) + return "Host not found (authoritative)"; + if (ec == error_base::host_not_found_try_again) + return "Host not found (non-authoritative), try again later"; + if (ec == error_base::no_data) + return "The query is valid, but it does not have associated data"; + if (ec == error_base::no_recovery) + return "A non-recoverable error occurred during database lookup"; + return "EINVAL"; } -#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +template +boost::system::wstring_t error_base::netdb_wmd( + const boost::system::error_code& ec) +{ + if (ec == error_base::host_not_found) + return L"Host not found (authoritative)"; + if (ec == error_base::host_not_found_try_again) + return L"Host not found (non-authoritative), try again later"; + if (ec == error_base::no_data) + return L"The query is valid, but it does not have associated data"; + if (ec == error_base::no_recovery) + return L"A non-recoverable error occurred during database lookup"; + return L"EINVAL"; +} + +template +boost::system::error_category error_base::addrinfo_ecat( + boost::system::error_code::new_category(&error_base::addrinfo_ed, + &error_base::addrinfo_md, &error_base::addrinfo_wmd)); + +template +int error_base::addrinfo_ed(const boost::system::error_code& ec) +{ + return EOTHER; +} + +template +std::string error_base::addrinfo_md(const boost::system::error_code& ec) +{ + if (ec == error_base::service_not_found) + return "Service not found"; + if (ec == error_base::socket_type_not_supported) + return "Socket type not supported"; + return "EINVAL"; +} + +template +boost::system::wstring_t error_base::addrinfo_wmd( + const boost::system::error_code& ec) +{ + if (ec == error_base::service_not_found) + return L"Service not found"; + if (ec == error_base::socket_type_not_supported) + return L"Socket type not supported"; + return L"EINVAL"; +} + +template +boost::system::error_category error_base::eof_ecat( + boost::system::error_code::new_category(&error_base::eof_ed, + &error_base::eof_md, &error_base::eof_wmd)); + +template +int error_base::eof_ed(const boost::system::error_code& ec) +{ + return EOTHER; +} + +template +std::string error_base::eof_md(const boost::system::error_code& ec) +{ + if (ec == error_base::eof) + return "End of file"; + return "EINVAL"; +} + +template +boost::system::wstring_t error_base::eof_wmd( + const boost::system::error_code& ec) +{ + if (ec == error_base::eof) + return L"End of file"; + return L"EINVAL"; +} + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +template +boost::system::error_category error_base::ssl_ecat( + boost::system::error_code::new_category(&error_base::ssl_ed, + &error_base::ssl_md, &error_base::ssl_wmd)); + +template +int error_base::ssl_ed(const boost::system::error_code& ec) +{ + return EOTHER; +} + +template +std::string error_base::ssl_md(const boost::system::error_code& ec) +{ + return "SSL error"; +} + +template +boost::system::wstring_t error_base::ssl_wmd( + const boost::system::error_code& ec) +{ + return L"SSL error"; +} + +template const boost::system::error_code +error_base::access_denied = BOOST_ASIO_SOCKET_ERROR(EACCES); + +template const boost::system::error_code +error_base::address_family_not_supported = BOOST_ASIO_SOCKET_ERROR( + EAFNOSUPPORT); + +template const boost::system::error_code +error_base::address_in_use = BOOST_ASIO_SOCKET_ERROR(EADDRINUSE); + +template const boost::system::error_code +error_base::already_connected = BOOST_ASIO_SOCKET_ERROR(EISCONN); + +template const boost::system::error_code +error_base::already_started = BOOST_ASIO_SOCKET_ERROR(EALREADY); + +template const boost::system::error_code +error_base::connection_aborted = BOOST_ASIO_SOCKET_ERROR(ECONNABORTED); + +template const boost::system::error_code +error_base::connection_refused = BOOST_ASIO_SOCKET_ERROR(ECONNREFUSED); + +template const boost::system::error_code +error_base::connection_reset = BOOST_ASIO_SOCKET_ERROR(ECONNRESET); + +template const boost::system::error_code +error_base::bad_descriptor = BOOST_ASIO_SOCKET_ERROR(EBADF); + +template const boost::system::error_code +error_base::eof = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_EOF_ERROR(ERROR_HANDLE_EOF), + BOOST_ASIO_EOF_ERROR(-1)); + +template const boost::system::error_code +error_base::fault = BOOST_ASIO_SOCKET_ERROR(EFAULT); + +template const boost::system::error_code +error_base::host_not_found = BOOST_ASIO_NETDB_ERROR(HOST_NOT_FOUND); + +template const boost::system::error_code +error_base::host_not_found_try_again = BOOST_ASIO_NETDB_ERROR(TRY_AGAIN); + +template const boost::system::error_code +error_base::host_unreachable = BOOST_ASIO_SOCKET_ERROR(EHOSTUNREACH); + +template const boost::system::error_code +error_base::in_progress = BOOST_ASIO_SOCKET_ERROR(EINPROGRESS); + +template const boost::system::error_code +error_base::interrupted = BOOST_ASIO_SOCKET_ERROR(EINTR); + +template const boost::system::error_code +error_base::invalid_argument = BOOST_ASIO_SOCKET_ERROR(EINVAL); + +template const boost::system::error_code +error_base::message_size = BOOST_ASIO_SOCKET_ERROR(EMSGSIZE); + +template const boost::system::error_code +error_base::network_down = BOOST_ASIO_SOCKET_ERROR(ENETDOWN); + +template const boost::system::error_code +error_base::network_reset = BOOST_ASIO_SOCKET_ERROR(ENETRESET); + +template const boost::system::error_code +error_base::network_unreachable = BOOST_ASIO_SOCKET_ERROR(ENETUNREACH); + +template const boost::system::error_code +error_base::no_descriptors = BOOST_ASIO_SOCKET_ERROR(EMFILE); + +template const boost::system::error_code +error_base::no_buffer_space = BOOST_ASIO_SOCKET_ERROR(ENOBUFS); + +template const boost::system::error_code +error_base::no_data = BOOST_ASIO_NETDB_ERROR(NO_DATA); + +template const boost::system::error_code +error_base::no_memory = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY), + BOOST_ASIO_NATIVE_ERROR(ENOMEM)); + +template const boost::system::error_code +error_base::no_permission = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED), + BOOST_ASIO_NATIVE_ERROR(EPERM)); + +template const boost::system::error_code +error_base::no_protocol_option = BOOST_ASIO_SOCKET_ERROR(ENOPROTOOPT); + +template const boost::system::error_code +error_base::no_recovery = BOOST_ASIO_NETDB_ERROR(NO_RECOVERY); + +template const boost::system::error_code +error_base::not_connected = BOOST_ASIO_SOCKET_ERROR(ENOTCONN); + +template const boost::system::error_code +error_base::not_socket = BOOST_ASIO_SOCKET_ERROR(ENOTSOCK); + +template const boost::system::error_code +error_base::not_supported = BOOST_ASIO_SOCKET_ERROR(EOPNOTSUPP); + +template const boost::system::error_code +error_base::operation_aborted = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED), + BOOST_ASIO_NATIVE_ERROR(ECANCELED)); + +template const boost::system::error_code +error_base::service_not_found = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND), + BOOST_ASIO_GETADDRINFO_ERROR(EAI_SERVICE)); + +template const boost::system::error_code +error_base::socket_type_not_supported = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT), + BOOST_ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE)); + +template const boost::system::error_code +error_base::shut_down = BOOST_ASIO_SOCKET_ERROR(ESHUTDOWN); + +template const boost::system::error_code +error_base::success; + +template const boost::system::error_code +error_base::timed_out = BOOST_ASIO_SOCKET_ERROR(ETIMEDOUT); + +template const boost::system::error_code +error_base::try_again = BOOST_ASIO_WIN_OR_POSIX( + BOOST_ASIO_NATIVE_ERROR(ERROR_RETRY), + BOOST_ASIO_NATIVE_ERROR(EAGAIN)); + +template const boost::system::error_code +error_base::would_block = BOOST_ASIO_SOCKET_ERROR(EWOULDBLOCK); + +/// Contains error constants. +class error : public error_base +{ +private: + error(); +}; } // namespace asio } // namespace boost +#undef BOOST_ASIO_NATIVE_ERROR #undef BOOST_ASIO_SOCKET_ERROR #undef BOOST_ASIO_NETDB_ERROR #undef BOOST_ASIO_GETADDRINFO_ERROR -#undef BOOST_ASIO_OS_ERROR +#undef BOOST_ASIO_EOF_ERROR +#undef BOOST_ASIO_WIN_OR_POSIX + #include diff --git a/include/boost/asio/error_handler.hpp b/include/boost/asio/error_handler.hpp deleted file mode 100644 index 5372def3..00000000 --- a/include/boost/asio/error_handler.hpp +++ /dev/null @@ -1,122 +0,0 @@ -// -// error_handler.hpp -// ~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2006 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_ERROR_HANDLER_HPP -#define BOOST_ASIO_ERROR_HANDLER_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -namespace boost { -namespace asio { - -namespace detail { - -class ignore_error_t -{ -public: - typedef void result_type; - - template - void operator()(const Error&) const - { - } -}; - -class throw_error_t -{ -public: - typedef void result_type; - - template - void operator()(const Error& err) const - { - if (err) - boost::throw_exception(err); - } -}; - -template -class assign_error_t -{ -public: - typedef void result_type; - - assign_error_t(Target& target) - : target_(&target) - { - } - - template - void operator()(const Error& err) const - { - *target_ = err; - } - -private: - Target* target_; -}; - -} // namespace detail - -/** - * @defgroup error_handler Error Handler Function Objects - * - * Function objects for custom error handling. - */ -/*@{*/ - -/// Return a function object that always ignores the error. -#if defined(GENERATING_DOCUMENTATION) -unspecified ignore_error(); -#else -inline detail::ignore_error_t ignore_error() -{ - return detail::ignore_error_t(); -} -#endif - -/// Return a function object that always throws the error. -#if defined(GENERATING_DOCUMENTATION) -unspecified throw_error(); -#else -inline detail::throw_error_t throw_error() -{ - return detail::throw_error_t(); -} -#endif - -/// Return a function object that assigns the error to a variable. -#if defined(GENERATING_DOCUMENTATION) -template -unspecified assign_error(Target& target); -#else -template -inline detail::assign_error_t assign_error(Target& target) -{ - return detail::assign_error_t(target); -} -#endif - -/*@}*/ - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_ERROR_HANDLER_HPP diff --git a/include/boost/asio/impl/read.ipp b/include/boost/asio/impl/read.ipp index cfcda8be..d140bfb5 100644 --- a/include/boost/asio/impl/read.ipp +++ b/include/boost/asio/impl/read.ipp @@ -19,44 +19,43 @@ #include #include -#include +#include #include #include #include #include +#include namespace boost { namespace asio { template + typename Completion_Condition> std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers, - Completion_Condition completion_condition, Error_Handler error_handler) + Completion_Condition completion_condition, boost::system::error_code& ec) { boost::asio::detail::consuming_buffers< mutable_buffer, Mutable_Buffers> tmp(buffers); std::size_t total_transferred = 0; while (tmp.begin() != tmp.end()) { - typename Sync_Read_Stream::error_type e; - std::size_t bytes_transferred = s.read_some(tmp, assign_error(e)); + std::size_t bytes_transferred = s.read_some(tmp, ec); tmp.consume(bytes_transferred); total_transferred += bytes_transferred; - if (completion_condition(e, total_transferred)) - { - error_handler(e); + if (completion_condition(ec, total_transferred)) return total_transferred; - } } - typename Sync_Read_Stream::error_type e; - error_handler(e); + ec = boost::system::error_code(); return total_transferred; } template inline std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers) { - return read(s, buffers, transfer_all(), throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } template + typename Completion_Condition> std::size_t read(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, - Completion_Condition completion_condition, Error_Handler error_handler) + Completion_Condition completion_condition, boost::system::error_code& ec) { std::size_t total_transferred = 0; for (;;) { - typename Sync_Read_Stream::error_type e; - std::size_t bytes_transferred = s.read_some( - b.prepare(512), assign_error(e)); + std::size_t bytes_transferred = s.read_some(b.prepare(512), ec); b.commit(bytes_transferred); total_transferred += bytes_transferred; - if (completion_condition(e, total_transferred)) - { - error_handler(e); + if (completion_condition(ec, total_transferred)) return total_transferred; - } } } @@ -93,7 +90,10 @@ template inline std::size_t read(Sync_Read_Stream& s, boost::asio::basic_streambuf& b) { - return read(s, b, transfer_all(), throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = read(s, b, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } template & b, Completion_Condition completion_condition) { - return read(s, b, completion_condition, throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = read(s, b, completion_condition, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } namespace detail @@ -122,15 +125,15 @@ namespace detail { } - void operator()(const typename Async_Read_Stream::error_type& e, + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); - if (completion_condition_(e, total_transferred_) + if (completion_condition_(ec, total_transferred_) || buffers_.begin() == buffers_.end()) { - handler_(e, total_transferred_); + handler_(ec, total_transferred_); } else { @@ -215,14 +218,14 @@ namespace detail { } - void operator()(const typename Async_Read_Stream::error_type& e, + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { total_transferred_ += bytes_transferred; streambuf_.commit(bytes_transferred); - if (completion_condition_(e, total_transferred_)) + if (completion_condition_(ec, total_transferred_)) { - handler_(e, total_transferred_); + handler_(ec, total_transferred_); } else { diff --git a/include/boost/asio/impl/read_until.ipp b/include/boost/asio/impl/read_until.ipp index d48ad959..9cd82f6c 100644 --- a/include/boost/asio/impl/read_until.ipp +++ b/include/boost/asio/impl/read_until.ipp @@ -25,11 +25,11 @@ #include #include -#include #include #include #include #include +#include namespace boost { namespace asio { @@ -38,13 +38,16 @@ template inline std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, char delim) { - return read_until(s, b, delim, throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } -template +template std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, char delim, - Error_Handler error_handler) + boost::system::error_code& ec) { std::size_t next_search_start = 0; for (;;) @@ -63,6 +66,7 @@ std::size_t read_until(Sync_Read_Stream& s, if (iter != end) { // Found a match. We're done. + ec = boost::system::error_code(); return iter.position() + 1; } else @@ -72,13 +76,9 @@ std::size_t read_until(Sync_Read_Stream& s, } // Need more data. - typename Sync_Read_Stream::error_type error; - b.commit(s.read_some(b.prepare(512), boost::asio::assign_error(error))); - if (error) - { - error_handler(error); + b.commit(s.read_some(b.prepare(512), ec)); + if (ec) return 0; - } } } @@ -86,7 +86,10 @@ template inline std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, const std::string& delim) { - return read_until(s, b, delim, throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } namespace detail @@ -124,10 +127,10 @@ namespace detail } } // namespace detail -template +template std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, const std::string& delim, - Error_Handler error_handler) + boost::system::error_code& ec) { std::size_t next_search_start = 0; for (;;) @@ -149,6 +152,7 @@ std::size_t read_until(Sync_Read_Stream& s, if (result.second) { // Full match. We're done. + ec = boost::system::error_code(); return result.first.position() + delim.length(); } else @@ -164,13 +168,9 @@ std::size_t read_until(Sync_Read_Stream& s, } // Need more data. - typename Sync_Read_Stream::error_type error; - b.commit(s.read_some(b.prepare(512), boost::asio::assign_error(error))); - if (error) - { - error_handler(error); + b.commit(s.read_some(b.prepare(512), ec)); + if (ec) return 0; - } } } @@ -178,13 +178,16 @@ template inline std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, const boost::regex& expr) { - return read_until(s, b, expr, throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, expr, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } -template +template std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, const boost::regex& expr, - Error_Handler error_handler) + boost::system::error_code& ec) { std::size_t next_search_start = 0; for (;;) @@ -206,6 +209,7 @@ std::size_t read_until(Sync_Read_Stream& s, if (match_results[0].matched) { // Full match. We're done. + ec = boost::system::error_code(); return match_results[0].second.position(); } else @@ -221,13 +225,9 @@ std::size_t read_until(Sync_Read_Stream& s, } // Need more data. - typename Sync_Read_Stream::error_type error; - b.commit(s.read_some(b.prepare(512), boost::asio::assign_error(error))); - if (error) - { - error_handler(error); + b.commit(s.read_some(b.prepare(512), ec)); + if (ec) return 0; - } } } @@ -248,14 +248,14 @@ namespace detail { } - void operator()(const typename Async_Read_Stream::error_type& e, + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { // Check for errors. - if (e) + if (ec) { std::size_t bytes = 0; - handler_(e, bytes); + handler_(ec, bytes); return; } @@ -277,7 +277,7 @@ namespace detail { // Found a match. We're done. std::size_t bytes = iter.position() + 1; - handler_(e, bytes); + handler_(ec, bytes); return; } @@ -341,9 +341,9 @@ void async_read_until(Async_Read_Stream& s, if (iter != end) { // Found a match. We're done. - typename Async_Read_Stream::error_type error; + boost::system::error_code ec; std::size_t bytes = iter.position() + 1; - s.io_service().post(detail::bind_handler(handler, error, bytes)); + s.io_service().post(detail::bind_handler(handler, ec, bytes)); return; } @@ -371,14 +371,14 @@ namespace detail { } - void operator()(const typename Async_Read_Stream::error_type& e, + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { // Check for errors. - if (e) + if (ec) { std::size_t bytes = 0; - handler_(e, bytes); + handler_(ec, bytes); return; } @@ -403,7 +403,7 @@ namespace detail { // Full match. We're done. std::size_t bytes = result.first.position() + delim_.length(); - handler_(e, bytes); + handler_(ec, bytes); return; } else @@ -482,9 +482,9 @@ void async_read_until(Async_Read_Stream& s, if (result.second) { // Full match. We're done. - typename Async_Read_Stream::error_type error; + boost::system::error_code ec; std::size_t bytes = result.first.position() + delim.length(); - s.io_service().post(detail::bind_handler(handler, error, bytes)); + s.io_service().post(detail::bind_handler(handler, ec, bytes)); return; } else @@ -524,14 +524,14 @@ namespace detail { } - void operator()(const typename Async_Read_Stream::error_type& e, + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { // Check for errors. - if (e) + if (ec) { std::size_t bytes = 0; - handler_(e, bytes); + handler_(ec, bytes); return; } @@ -556,7 +556,7 @@ namespace detail { // Full match. We're done. std::size_t bytes = match_results[0].second.position(); - handler_(e, bytes); + handler_(ec, bytes); return; } else @@ -635,9 +635,9 @@ void async_read_until(Async_Read_Stream& s, if (match_results[0].matched) { // Full match. We're done. - typename Async_Read_Stream::error_type error; + boost::system::error_code ec; std::size_t bytes = match_results[0].second.position(); - s.io_service().post(detail::bind_handler(handler, error, bytes)); + s.io_service().post(detail::bind_handler(handler, ec, bytes)); return; } else diff --git a/include/boost/asio/impl/write.ipp b/include/boost/asio/impl/write.ipp index 0edb64c4..d84c1810 100644 --- a/include/boost/asio/impl/write.ipp +++ b/include/boost/asio/impl/write.ipp @@ -19,44 +19,42 @@ #include #include -#include #include #include #include #include +#include namespace boost { namespace asio { template + typename Completion_Condition> std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers, - Completion_Condition completion_condition, Error_Handler error_handler) + Completion_Condition completion_condition, boost::system::error_code& ec) { boost::asio::detail::consuming_buffers< const_buffer, Const_Buffers> tmp(buffers); std::size_t total_transferred = 0; while (tmp.begin() != tmp.end()) { - typename Sync_Write_Stream::error_type e; - std::size_t bytes_transferred = s.write_some(tmp, assign_error(e)); + std::size_t bytes_transferred = s.write_some(tmp, ec); tmp.consume(bytes_transferred); total_transferred += bytes_transferred; - if (completion_condition(e, total_transferred)) - { - error_handler(e); + if (completion_condition(ec, total_transferred)) return total_transferred; - } } - typename Sync_Write_Stream::error_type e; - error_handler(e); + ec = boost::system::error_code(); return total_transferred; } template inline std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers) { - return write(s, buffers, transfer_all(), throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } template + typename Completion_Condition> std::size_t write(Sync_Write_Stream& s, boost::asio::basic_streambuf& b, - Completion_Condition completion_condition, Error_Handler error_handler) + Completion_Condition completion_condition, boost::system::error_code& ec) { - typename Sync_Write_Stream::error_type error; - std::size_t bytes_transferred = write(s, b.data(), - completion_condition, boost::asio::assign_error(error)); + std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec); b.consume(bytes_transferred); - error_handler(error); return bytes_transferred; } @@ -85,7 +83,10 @@ template inline std::size_t write(Sync_Write_Stream& s, boost::asio::basic_streambuf& b) { - return write(s, b, transfer_all(), throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = write(s, b, transfer_all(), ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } template & b, Completion_Condition completion_condition) { - return write(s, b, completion_condition, throw_error()); + boost::system::error_code ec; + std::size_t bytes_transferred = write(s, b, completion_condition, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; } namespace detail @@ -114,15 +118,15 @@ namespace detail { } - void operator()(const typename Async_Write_Stream::error_type& e, + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); - if (completion_condition_(e, total_transferred_) + if (completion_condition_(ec, total_transferred_) || buffers_.begin() == buffers_.end()) { - handler_(e, total_transferred_); + handler_(ec, total_transferred_); } else { @@ -201,11 +205,11 @@ namespace detail { } - void operator()(const typename Async_Write_Stream::error_type& e, + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { streambuf_.consume(bytes_transferred); - handler_(e, bytes_transferred); + handler_(ec, bytes_transferred); } //private: diff --git a/include/boost/asio/ip/address.hpp b/include/boost/asio/ip/address.hpp index 810ec49a..ce214816 100644 --- a/include/boost/asio/ip/address.hpp +++ b/include/boost/asio/ip/address.hpp @@ -24,9 +24,9 @@ #include #include -#include #include #include +#include namespace boost { namespace asio { @@ -120,9 +120,9 @@ public: { if (type_ != ipv4) { - boost::asio::error error( + boost::system::system_error e( boost::asio::error::address_family_not_supported); - boost::throw_exception(error); + boost::throw_exception(e); } return ipv4_address_; } @@ -132,9 +132,9 @@ public: { if (type_ != ipv6) { - boost::asio::error error( + boost::system::system_error e( boost::asio::error::address_family_not_supported); - boost::throw_exception(error); + boost::throw_exception(e); } return ipv6_address_; } @@ -148,53 +148,47 @@ public: } /// Get the address as a string in dotted decimal format. - template - std::string to_string(Error_Handler error_handler) const + std::string to_string(boost::system::error_code& ec) const { if (type_ == ipv6) - return ipv6_address_.to_string(error_handler); - return ipv4_address_.to_string(error_handler); + return ipv6_address_.to_string(ec); + return ipv4_address_.to_string(ec); } /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. static address from_string(const char* str) { - return from_string(str, boost::asio::throw_error()); + boost::system::error_code ec; + address addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; } /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. - template - static address from_string(const char* str, Error_Handler error_handler) + static address from_string(const char* str, boost::system::error_code& ec) { - boost::asio::error error; boost::asio::ip::address_v6 ipv6_address = - boost::asio::ip::address_v6::from_string(str, - boost::asio::assign_error(error)); - if (!error) + boost::asio::ip::address_v6::from_string(str, ec); + if (!ec) { address tmp; tmp.type_ = ipv6; tmp.ipv6_address_ = ipv6_address; - error_handler(error); return tmp; } - error = boost::asio::error(); boost::asio::ip::address_v4 ipv4_address = - boost::asio::ip::address_v4::from_string(str, - boost::asio::assign_error(error)); - if (!error) + boost::asio::ip::address_v4::from_string(str, ec); + if (!ec) { address tmp; tmp.type_ = ipv4; tmp.ipv4_address_ = ipv4_address; - error_handler(error); return tmp; } - error_handler(error); return address(); } @@ -202,16 +196,15 @@ public: /// or from an IPv6 address in hexadecimal notation. static address from_string(const std::string& str) { - return from_string(str.c_str(), boost::asio::throw_error()); + return from_string(str.c_str()); } /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. - template static address from_string(const std::string& str, - Error_Handler error_handler) + boost::system::error_code& ec) { - return from_string(str.c_str(), error_handler); + return from_string(str.c_str(), ec); } /// Compare two addresses for equality. diff --git a/include/boost/asio/ip/address_v4.hpp b/include/boost/asio/ip/address_v4.hpp index bc683a08..730321da 100644 --- a/include/boost/asio/ip/address_v4.hpp +++ b/include/boost/asio/ip/address_v4.hpp @@ -24,9 +24,9 @@ #include #include -#include #include #include +#include namespace boost { namespace asio { @@ -97,63 +97,54 @@ public: /// Get the address as a string in dotted decimal format. std::string to_string() const { - return to_string(boost::asio::throw_error()); + boost::system::error_code ec; + std::string addr = to_string(ec); + boost::asio::detail::throw_error(ec); + return addr; } /// Get the address as a string in dotted decimal format. - template - std::string to_string(Error_Handler error_handler) const + std::string to_string(boost::system::error_code& ec) const { char addr_str[boost::asio::detail::max_addr_v4_str_len]; const char* addr = boost::asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str, - boost::asio::detail::max_addr_v4_str_len); + boost::asio::detail::max_addr_v4_str_len, 0, ec); if (addr == 0) - { - boost::asio::error e(boost::asio::detail::socket_ops::get_error()); - error_handler(e); return std::string(); - } - boost::asio::error e; - error_handler(e); return addr; } /// Create an address from an IP address string in dotted decimal form. static address_v4 from_string(const char* str) { - return from_string(str, boost::asio::throw_error()); + boost::system::error_code ec; + address_v4 addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; } /// Create an address from an IP address string in dotted decimal form. - template - static address_v4 from_string(const char* str, Error_Handler error_handler) + static address_v4 from_string(const char* str, boost::system::error_code& ec) { address_v4 tmp; if (boost::asio::detail::socket_ops::inet_pton( - AF_INET, str, &tmp.addr_) <= 0) - { - boost::asio::error e(boost::asio::detail::socket_ops::get_error()); - error_handler(e); + AF_INET, str, &tmp.addr_, 0, ec) <= 0) return address_v4(); - } - boost::asio::error e; - error_handler(e); return tmp; } /// Create an address from an IP address string in dotted decimal form. static address_v4 from_string(const std::string& str) { - return from_string(str.c_str(), boost::asio::throw_error()); + return from_string(str.c_str()); } /// Create an address from an IP address string in dotted decimal form. - template static address_v4 from_string(const std::string& str, - Error_Handler error_handler) + boost::system::error_code& ec) { - return from_string(str.c_str(), error_handler); + return from_string(str.c_str(), ec); } /// Determine whether the address is a class A address. @@ -275,9 +266,9 @@ template std::basic_ostream& operator<<( std::basic_ostream& os, const address_v4& addr) { - boost::asio::error e; - std::string s = addr.to_string(boost::asio::assign_error(e)); - if (e) + boost::system::error_code ec; + std::string s = addr.to_string(ec); + if (ec) os.setstate(std::ios_base::failbit); else for (std::string::iterator i = s.begin(); i != s.end(); ++i) diff --git a/include/boost/asio/ip/address_v6.hpp b/include/boost/asio/ip/address_v6.hpp index 31197e70..a796cb99 100644 --- a/include/boost/asio/ip/address_v6.hpp +++ b/include/boost/asio/ip/address_v6.hpp @@ -27,9 +27,9 @@ #include #include -#include #include #include +#include #include namespace boost { @@ -106,63 +106,54 @@ public: /// Get the address as a string. std::string to_string() const { - return to_string(boost::asio::throw_error()); + boost::system::error_code ec; + std::string addr = to_string(ec); + boost::asio::detail::throw_error(ec); + return addr; } /// Get the address as a string. - template - std::string to_string(Error_Handler error_handler) const + std::string to_string(boost::system::error_code& ec) const { char addr_str[boost::asio::detail::max_addr_v6_str_len]; const char* addr = boost::asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str, - boost::asio::detail::max_addr_v6_str_len, scope_id_); + boost::asio::detail::max_addr_v6_str_len, scope_id_, ec); if (addr == 0) - { - boost::asio::error e(boost::asio::detail::socket_ops::get_error()); - error_handler(e); return std::string(); - } - boost::asio::error e; - error_handler(e); return addr; } /// Create an address from an IP address string. static address_v6 from_string(const char* str) { - return from_string(str, boost::asio::throw_error()); + boost::system::error_code ec; + address_v6 addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; } /// Create an address from an IP address string. - template - static address_v6 from_string(const char* str, Error_Handler error_handler) + static address_v6 from_string(const char* str, boost::system::error_code& ec) { address_v6 tmp; if (boost::asio::detail::socket_ops::inet_pton( - AF_INET6, str, &tmp.addr_, &tmp.scope_id_) <= 0) - { - boost::asio::error e(boost::asio::detail::socket_ops::get_error()); - error_handler(e); + AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0) return address_v6(); - } - boost::asio::error e; - error_handler(e); return tmp; } /// Create an address from an IP address string. static address_v6 from_string(const std::string& str) { - return from_string(str.c_str(), boost::asio::throw_error()); + return from_string(str.c_str()); } /// Create an address from an IP address string. - template static address_v6 from_string(const std::string& str, - Error_Handler error_handler) + boost::system::error_code& ec) { - return from_string(str.c_str(), error_handler); + return from_string(str.c_str(), ec); } /// Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. @@ -387,9 +378,9 @@ template std::basic_ostream& operator<<( std::basic_ostream& os, const address_v6& addr) { - boost::asio::error e; - std::string s = addr.to_string(boost::asio::assign_error(e)); - if (e) + boost::system::error_code ec; + std::string s = addr.to_string(ec); + if (ec) os.setstate(std::ios_base::failbit); else for (std::string::iterator i = s.begin(); i != s.end(); ++i) diff --git a/include/boost/asio/ip/basic_endpoint.hpp b/include/boost/asio/ip/basic_endpoint.hpp index 17f82d27..673e04fd 100644 --- a/include/boost/asio/ip/basic_endpoint.hpp +++ b/include/boost/asio/ip/basic_endpoint.hpp @@ -204,7 +204,7 @@ public: { if (size > size_type(sizeof(data_))) { - boost::asio::error e(boost::asio::error::invalid_argument); + boost::system::system_error e(boost::asio::error::invalid_argument); boost::throw_exception(e); } } diff --git a/include/boost/asio/ip/basic_resolver.hpp b/include/boost/asio/ip/basic_resolver.hpp index 60c9326c..f7d30f64 100644 --- a/include/boost/asio/ip/basic_resolver.hpp +++ b/include/boost/asio/ip/basic_resolver.hpp @@ -19,8 +19,8 @@ #include #include -#include #include +#include namespace boost { namespace asio { @@ -34,9 +34,6 @@ namespace ip { * @par Thread Safety: * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * Async_Object, Error_Source. */ template > class basic_resolver @@ -55,9 +52,6 @@ public: /// The iterator type. typedef typename Protocol::resolver_iterator iterator; - /// The type used for reporting errors. - typedef boost::asio::error error_type; - /// Constructor. /** * This constructor creates a basic_resolver. @@ -90,7 +84,7 @@ public: * @returns A forward-only iterator that can be used to traverse the list * of endpoint entries. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note A default constructed iterator represents the end of the list. * @@ -99,7 +93,10 @@ public: */ iterator resolve(const query& q) { - return this->service.resolve(this->implementation, q, throw_error()); + boost::system::error_code ec; + iterator i = this->service.resolve(this->implementation, q, ec); + boost::asio::detail::throw_error(ec); + return i; } /// Resolve a query to a list of entries. @@ -112,22 +109,16 @@ public: * of endpoint entries. Returns a default constructed iterator if an error * occurs. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @note A default constructed iterator represents the end of the list. * * @note A successful call to this function is guaranteed to return at least * one entry. */ - template - iterator resolve(const query& q, Error_Handler error_handler) + iterator resolve(const query& q, boost::system::error_code& ec) { - return this->service.resolve(this->implementation, q, error_handler); + return this->service.resolve(this->implementation, q, ec); } /// Asynchronously resolve a query to a list of entries. @@ -141,9 +132,10 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * resolver::iterator iterator // Forward-only iterator that can be used to - * // traverse the list of endpoint entries. + * const boost::system::error_code& error, // Result of operation. + * resolver::iterator iterator // Forward-only iterator that can + * // be used to traverse the list + * // of endpoint entries. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation @@ -172,7 +164,7 @@ public: * @returns A forward-only iterator that can be used to traverse the list * of endpoint entries. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note A default constructed iterator represents the end of the list. * @@ -181,7 +173,10 @@ public: */ iterator resolve(const endpoint_type& e) { - return this->service.resolve(this->implementation, e, throw_error()); + boost::system::error_code ec; + iterator i = this->service.resolve(this->implementation, e, ec); + boost::asio::detail::throw_error(ec); + return i; } /// Resolve an endpoint to a list of entries. @@ -196,22 +191,16 @@ public: * of endpoint entries. Returns a default constructed iterator if an error * occurs. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @note A default constructed iterator represents the end of the list. * * @note A successful call to this function is guaranteed to return at least * one entry. */ - template - iterator resolve(const endpoint_type& e, Error_Handler error_handler) + iterator resolve(const endpoint_type& e, boost::system::error_code& ec) { - return this->service.resolve(this->implementation, e, error_handler); + return this->service.resolve(this->implementation, e, ec); } /// Asynchronously resolve an endpoint to a list of entries. @@ -226,9 +215,10 @@ public: * completes. Copies will be made of the handler as required. The function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * resolver::iterator iterator // Forward-only iterator that can be used to - * // traverse the list of endpoint entries. + * const boost::system::error_code& error, // Result of operation. + * resolver::iterator iterator // Forward-only iterator that can + * // be used to traverse the list + * // of endpoint entries. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation diff --git a/include/boost/asio/ip/host_name.hpp b/include/boost/asio/ip/host_name.hpp index ec5ceac8..610e5aea 100644 --- a/include/boost/asio/ip/host_name.hpp +++ b/include/boost/asio/ip/host_name.hpp @@ -21,8 +21,9 @@ #include #include -#include +#include #include +#include namespace boost { namespace asio { @@ -32,27 +33,28 @@ namespace ip { std::string host_name(); /// Get the current host name. -template -std::string host_name(Error_Handler error_handler); +std::string host_name(boost::system::error_code& ec); inline std::string host_name() -{ - return host_name(boost::asio::throw_error()); -} - -template -std::string host_name(Error_Handler error_handler) { char name[1024]; - if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name)) != 0) + boost::system::error_code ec; + if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) { - boost::asio::error error(boost::asio::detail::socket_ops::get_error()); - error_handler(error); + boost::asio::detail::throw_error(ec); return std::string(); } return std::string(name); } +inline std::string host_name(boost::system::error_code& ec) +{ + char name[1024]; + if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + return std::string(); + return std::string(name); +} + } // namespace ip } // namespace asio } // namespace boost diff --git a/include/boost/asio/ip/resolver_service.hpp b/include/boost/asio/ip/resolver_service.hpp index 7c3bcf89..cebcd87d 100644 --- a/include/boost/asio/ip/resolver_service.hpp +++ b/include/boost/asio/ip/resolver_service.hpp @@ -17,6 +17,7 @@ #include +#include #include #include @@ -85,11 +86,10 @@ public: } /// Resolve a query to a list of entries. - template iterator_type resolve(implementation_type& impl, const query_type& query, - Error_Handler error_handler) + boost::system::error_code& ec) { - return service_impl_.resolve(impl, query, error_handler); + return service_impl_.resolve(impl, query, ec); } /// Asynchronously resolve a query to a list of entries. @@ -101,11 +101,10 @@ public: } /// Resolve an endpoint to a list of entries. - template iterator_type resolve(implementation_type& impl, - const endpoint_type& endpoint, Error_Handler error_handler) + const endpoint_type& endpoint, boost::system::error_code& ec) { - return service_impl_.resolve(impl, endpoint, error_handler); + return service_impl_.resolve(impl, endpoint, ec); } /// Asynchronously resolve an endpoint to a list of entries. diff --git a/include/boost/asio/placeholders.hpp b/include/boost/asio/placeholders.hpp index 42475581..69968753 100644 --- a/include/boost/asio/placeholders.hpp +++ b/include/boost/asio/placeholders.hpp @@ -8,8 +8,8 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_ARG_HPP -#define BOOST_ASIO_ARG_HPP +#ifndef BOOST_ASIO_PLACEHOLDERS_HPP +#define BOOST_ASIO_PLACEHOLDERS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once @@ -19,64 +19,91 @@ #include #include +#include #include namespace boost { namespace asio { - namespace placeholders { -namespace { - -#if defined(__BORLANDC__) - -static inline boost::arg<1> error() -{ - return boost::arg<1>(); -} - -static inline boost::arg<2> bytes_transferred() -{ - return boost::arg<2>(); -} - -static inline boost::arg<2> iterator() -{ - return boost::arg<2>(); -} - -#elif defined(_MSC_VER) && (_MSC_VER < 1400) - -static boost::arg<1> error; -static boost::arg<2> bytes_transferred; -static boost::arg<2> iterator; - -#else +#if defined(GENERATING_DOCUMENTATION) /// An argument placeholder, for use with @ref boost_bind, that corresponds to /// the error argument of a handler for any of the asynchronous functions. -boost::arg<1> error; +unspecified error; /// An argument placeholder, for use with @ref boost_bind, that corresponds to /// the bytes_transferred argument of a handler for asynchronous functions such /// as boost::asio::basic_stream_socket::async_write_some or /// boost::asio::async_write. -boost::arg<2> bytes_transferred; +unspecified bytes_transferred; /// An argument placeholder, for use with @ref boost_bind, that corresponds to /// the iterator argument of a handler for asynchronous functions such as /// boost::asio::basic_resolver::resolve. -boost::arg<2> iterator; +unspecified iterator; + +#elif defined(__BORLANDC__) + +inline boost::arg<1> error() +{ + return boost::arg<1>(); +} + +inline boost::arg<2> bytes_transferred() +{ + return boost::arg<2>(); +} + +inline boost::arg<2> iterator() +{ + return boost::arg<2>(); +} + +#else + +namespace detail +{ + template + struct placeholder + { + static boost::arg& get() + { + static boost::arg result; + return result; + } + }; +} + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +static boost::arg<1>& error + = boost::asio::placeholders::detail::placeholder<1>::get(); +static boost::arg<2>& bytes_transferred + = boost::asio::placeholders::detail::placeholder<2>::get(); +static boost::arg<2>& iterator + = boost::asio::placeholders::detail::placeholder<2>::get(); + +#else + +namespace +{ + boost::arg<1>& error + = boost::asio::placeholders::detail::placeholder<1>::get(); + boost::arg<2>& bytes_transferred + = boost::asio::placeholders::detail::placeholder<2>::get(); + boost::arg<2>& iterator + = boost::asio::placeholders::detail::placeholder<2>::get(); +} // namespace #endif -} // namespace +#endif } // namespace placeholders - } // namespace asio } // namespace boost #include -#endif // BOOST_ASIO_ARG_HPP +#endif // BOOST_ASIO_PLACEHOLDERS_HPP diff --git a/include/boost/asio/read.hpp b/include/boost/asio/read.hpp index ec5f1520..6b3dd4c2 100644 --- a/include/boost/asio/read.hpp +++ b/include/boost/asio/read.hpp @@ -23,6 +23,7 @@ #include #include +#include namespace boost { namespace asio { @@ -54,7 +55,7 @@ namespace asio { * * @returns The number of bytes transferred. * - * @throws Sync_Read_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To read into a single data buffer use the @ref buffer function as follows: @@ -66,8 +67,7 @@ namespace asio { * @note This overload is equivalent to calling: * @code boost::asio::read( * s, buffers, - * boost::asio::transfer_all(), - * boost::asio::throw_error()); @endcode + * boost::asio::transfer_all()); @endcode */ template std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers); @@ -96,18 +96,18 @@ std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers); * whether the read operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Read_Stream::error_type& error, // Result of latest read_some - * // operation. + * const boost::system::error_code& error, // Result of latest read_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the read operation is complete. False * indicates that further calls to the stream's read_some function are required. * * @returns The number of bytes transferred. * - * @throws Sync_Read_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To read into a single data buffer use the @ref buffer function as follows: @@ -116,11 +116,6 @@ std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers); * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. - * - * @note This overload is equivalent to calling: - * @code boost::asio::read( - * s, buffers, completion_condition, - * boost::asio::throw_error()); @endcode */ template @@ -151,32 +146,24 @@ std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers, * whether the read operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Read_Stream::error_type& error, // Result of latest read_some - * // operation. + * const boost::system::error_code& error, // Result of latest read_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the read operation is complete. False * indicates that further calls to the stream's read_some function are required. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const Sync_Read_Stream::error_type& error // Result of operation. - * ); @endcode - * The error handler is only called if the completion_condition indicates that - * the operation is complete. + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes read. If an error occurs, and the error handler - * does not throw an exception, returns the total number of bytes successfully - * transferred prior to the error. + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. */ template + typename Completion_Condition> std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers, - Completion_Condition completion_condition, Error_Handler error_handler); + Completion_Condition completion_condition, boost::system::error_code& ec); /// Attempt to read a certain amount of data from a stream before returning. /** @@ -195,13 +182,12 @@ std::size_t read(Sync_Read_Stream& s, const Mutable_Buffers& buffers, * * @returns The number of bytes transferred. * - * @throws Sync_Read_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code boost::asio::read( * s, b, - * boost::asio::transfer_all(), - * boost::asio::throw_error()); @endcode + * boost::asio::transfer_all()); @endcode */ template std::size_t read(Sync_Read_Stream& s, basic_streambuf& b); @@ -225,23 +211,18 @@ std::size_t read(Sync_Read_Stream& s, basic_streambuf& b); * whether the read operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Read_Stream::error_type& error, // Result of latest read_some - * // operation. + * const boost::system::error_code& error, // Result of latest read_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the read operation is complete. False * indicates that further calls to the stream's read_some function are required. * * @returns The number of bytes transferred. * - * @throws Sync_Read_Stream::error_type Thrown on failure. - * - * @note This overload is equivalent to calling: - * @code boost::asio::read( - * s, b, completion_condition, - * boost::asio::throw_error()); @endcode + * @throws boost::system::system_error Thrown on failure. */ template @@ -267,32 +248,24 @@ std::size_t read(Sync_Read_Stream& s, basic_streambuf& b, * whether the read operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Read_Stream::error_type& error, // Result of latest read_some - * // operation. + * const boost::system::error_code& error, // Result of latest read_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the read operation is complete. False * indicates that further calls to the stream's read_some function are required. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const Sync_Read_Stream::error_type& error // Result of operation. - * ); @endcode - * The error handler is only called if the completion_condition indicates that - * the operation is complete. + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes read. If an error occurs, and the error handler - * does not throw an exception, returns the total number of bytes successfully - * transferred prior to the error. + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. */ template + typename Completion_Condition> std::size_t read(Sync_Read_Stream& s, basic_streambuf& b, - Completion_Condition completion_condition, Error_Handler error_handler); + Completion_Condition completion_condition, boost::system::error_code& ec); /*@}*/ /** @@ -329,14 +302,13 @@ std::size_t read(Sync_Read_Stream& s, basic_streambuf& b, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Read_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes copied into - * // the buffers. If an error - * // occurred, this will be the - * // number of bytes successfully - * // transferred prior to the - * // error. + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -389,11 +361,11 @@ void async_read(Async_Read_Stream& s, const Mutable_Buffers& buffers, * whether the read operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Async_Read_Stream::error_type& error, // Result of latest read_some - * // operation. + * const boost::system::error_code& error, // Result of latest read_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the read operation is complete. False * indicates that further calls to the stream's async_read_some function are @@ -403,14 +375,13 @@ void async_read(Async_Read_Stream& s, const Mutable_Buffers& buffers, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Read_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes copied into - * // the buffers. If an error - * // occurred, this will be the - * // number of bytes successfully - * // transferred prior to the - * // error. + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -456,14 +427,13 @@ void async_read(Async_Read_Stream& s, const Mutable_Buffers& buffers, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Read_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes copied into - * // the buffers. If an error - * // occurred, this will be the - * // number of bytes successfully - * // transferred prior to the - * // error. + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -504,11 +474,11 @@ void async_read(Async_Read_Stream& s, basic_streambuf& b, * whether the read operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Async_Read_Stream::error_type& error, // Result of latest read_some - * // operation. + * const boost::system::error_code& error, // Result of latest read_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the read operation is complete. False * indicates that further calls to the stream's async_read_some function are @@ -518,14 +488,13 @@ void async_read(Async_Read_Stream& s, basic_streambuf& b, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Read_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes copied into - * // the buffers. If an error - * // occurred, this will be the - * // number of bytes successfully - * // transferred prior to the - * // error. + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of diff --git a/include/boost/asio/read_until.hpp b/include/boost/asio/read_until.hpp index b312e7cc..3ebf7ad9 100644 --- a/include/boost/asio/read_until.hpp +++ b/include/boost/asio/read_until.hpp @@ -25,6 +25,7 @@ #include #include +#include namespace boost { namespace asio { @@ -58,7 +59,7 @@ namespace asio { * @returns The number of bytes in the streambuf's get area up to and including * the delimiter. * - * @throws Sync_Read_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To read data into a streambuf until a newline is encountered: @@ -67,11 +68,6 @@ namespace asio { * std::istream is(&b); * std::string line; * std::getline(is, line); @endcode - * - * @note This overload is equivalent to calling: - * @code boost::asio::read_until( - * s, b, delim, - * boost::asio::throw_error()); @endcode */ template std::size_t read_until(Sync_Read_Stream& s, @@ -98,23 +94,15 @@ std::size_t read_until(Sync_Read_Stream& s, * * @param delim The delimiter character. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const Sync_Read_Stream::error_type& error // Result of operation. - * ); @endcode - * The error handler is only called if the completion_condition indicates that - * the operation is complete. + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the streambuf's get area up to and including - * the delimiter. Returns 0 if an error occurred and the error handler did not - * throw an exception. + * the delimiter. Returns 0 if an error occurred. */ -template +template std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, char delim, - Error_Handler error_handler); + boost::system::error_code& ec); /// Read data into a streambuf until a delimiter is encountered. /** @@ -140,7 +128,7 @@ std::size_t read_until(Sync_Read_Stream& s, * @returns The number of bytes in the streambuf's get area up to and including * the delimiter. * - * @throws Sync_Read_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To read data into a streambuf until a newline is encountered: @@ -149,11 +137,6 @@ std::size_t read_until(Sync_Read_Stream& s, * std::istream is(&b); * std::string line; * std::getline(is, line); @endcode - * - * @note This overload is equivalent to calling: - * @code boost::asio::read_until( - * s, b, delim, - * boost::asio::throw_error()); @endcode */ template std::size_t read_until(Sync_Read_Stream& s, @@ -180,23 +163,15 @@ std::size_t read_until(Sync_Read_Stream& s, * * @param delim The delimiter string. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const Sync_Read_Stream::error_type& error // Result of operation. - * ); @endcode - * The error handler is only called if the completion_condition indicates that - * the operation is complete. + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the streambuf's get area up to and including - * the delimiter. Returns 0 if an error occurred and the error handler did not - * throw an exception. + * the delimiter. Returns 0 if an error occurred. */ -template +template std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, const std::string& delim, - Error_Handler error_handler); + boost::system::error_code& ec); /// Read data into a streambuf until a regular expression is located. /** @@ -222,7 +197,7 @@ std::size_t read_until(Sync_Read_Stream& s, * @returns The number of bytes in the streambuf's get area up to and including * the substring that matches the regular expression. * - * @throws Sync_Read_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To read data into a streambuf until a CR-LF sequence is encountered: @@ -231,11 +206,6 @@ std::size_t read_until(Sync_Read_Stream& s, * std::istream is(&b); * std::string line; * std::getline(is, line); @endcode - * - * @note This overload is equivalent to calling: - * @code boost::asio::read_until( - * s, b, expr, - * boost::asio::throw_error()); @endcode */ template std::size_t read_until(Sync_Read_Stream& s, @@ -262,22 +232,16 @@ std::size_t read_until(Sync_Read_Stream& s, * * @param expr The regular expression. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const Sync_Read_Stream::error_type& error // Result of operation. - * ); @endcode - * The error handler is only called if the completion_condition indicates that - * the operation is complete. + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes in the streambuf's get area up to and including -* the substring that matches the regular expression. -*/ -template + * the substring that matches the regular expression. Returns 0 if an error + * occurred. + */ +template std::size_t read_until(Sync_Read_Stream& s, boost::asio::basic_streambuf& b, const boost::regex& expr, - Error_Handler error_handler); + boost::system::error_code& ec); /*@}*/ /** @@ -314,12 +278,12 @@ std::size_t read_until(Sync_Read_Stream& s, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Read_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // The number of bytes in the - * // streambuf's get area up to - * // and including the delimiter. - * // 0 if an error occurred. + * std::size_t bytes_transferred // The number of bytes in the + * // streambuf's get area up to + * // and including the delimiter. + * // 0 if an error occurred. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -330,7 +294,7 @@ std::size_t read_until(Sync_Read_Stream& s, * To asynchronously read data into a streambuf until a newline is encountered: * @code boost::asio::streambuf b; * ... - * void handler(const boost::asio::error& e, std::size_t size) + * void handler(const boost::system::error_code& e, std::size_t size) * { * if (!e) * { @@ -376,12 +340,12 @@ void async_read_until(Async_Read_Stream& s, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Read_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // The number of bytes in the - * // streambuf's get area up to - * // and including the delimiter. - * // 0 if an error occurred. + * std::size_t bytes_transferred // The number of bytes in the + * // streambuf's get area up to + * // and including the delimiter. + * // 0 if an error occurred. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -392,7 +356,7 @@ void async_read_until(Async_Read_Stream& s, * To asynchronously read data into a streambuf until a newline is encountered: * @code boost::asio::streambuf b; * ... - * void handler(const boost::asio::error& e, std::size_t size) + * void handler(const boost::system::error_code& e, std::size_t size) * { * if (!e) * { @@ -440,14 +404,14 @@ void async_read_until(Async_Read_Stream& s, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Read_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // The number of bytes in the - * // streambuf's get area up to - * // and including the substring - * // that matches the regular - * // expression. 0 if an error - * // occurred. + * std::size_t bytes_transferred // The number of bytes in the + * // streambuf's get area up to + * // and including the substring + * // that matches the regular. + * // expression. 0 if an error + * // occurred. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -459,7 +423,7 @@ void async_read_until(Async_Read_Stream& s, * encountered: * @code boost::asio::streambuf b; * ... - * void handler(const boost::asio::error& e, std::size_t size) + * void handler(const boost::system::error_code& e, std::size_t size) * { * if (!e) * { diff --git a/include/boost/asio/socket_acceptor_service.hpp b/include/boost/asio/socket_acceptor_service.hpp index f6bab3eb..d0ae52bf 100644 --- a/include/boost/asio/socket_acceptor_service.hpp +++ b/include/boost/asio/socket_acceptor_service.hpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -95,50 +96,47 @@ public: } /// Open a new socket acceptor implementation. - template - void open(implementation_type& impl, const protocol_type& protocol, - Error_Handler error_handler) + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) { - service_impl_.open(impl, protocol, error_handler); + return service_impl_.open(impl, protocol, ec); } /// Assign an existing native acceptor to a socket acceptor. - template - void assign(implementation_type& impl, const protocol_type& protocol, - const native_type& native_acceptor, Error_Handler error_handler) + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_acceptor, + boost::system::error_code& ec) { - service_impl_.assign(impl, protocol, native_acceptor, error_handler); + return service_impl_.assign(impl, protocol, native_acceptor, ec); } /// Cancel all asynchronous operations associated with the acceptor. - template - void cancel(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) { - service_impl_.cancel(impl, error_handler); + return service_impl_.cancel(impl, ec); } /// Bind the socket acceptor to the specified local endpoint. - template - void bind(implementation_type& impl, const endpoint_type& endpoint, - Error_Handler error_handler) + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) { - service_impl_.bind(impl, endpoint, error_handler); + return service_impl_.bind(impl, endpoint, ec); } /// Place the socket acceptor into the state where it will listen for new /// connections. - template - void listen(implementation_type& impl, int backlog, - Error_Handler error_handler) + boost::system::error_code listen(implementation_type& impl, int backlog, + boost::system::error_code& ec) { - service_impl_.listen(impl, backlog, error_handler); + return service_impl_.listen(impl, backlog, ec); } /// Close a socket acceptor implementation. - template - void close(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) { - service_impl_.close(impl, error_handler); + return service_impl_.close(impl, ec); } /// Get the native acceptor implementation. @@ -148,47 +146,52 @@ public: } /// Set a socket option. - template - void set_option(implementation_type& impl, const Option& option, - Error_Handler error_handler) + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) { - service_impl_.set_option(impl, option, error_handler); + return service_impl_.set_option(impl, option, ec); } - /// Set a socket option. - template - void get_option(implementation_type& impl, Option& option, - Error_Handler error_handler) + /// Get a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const { - service_impl_.get_option(impl, option, error_handler); + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); } /// Get the local endpoint. - template endpoint_type local_endpoint(const implementation_type& impl, - Error_Handler error_handler) const + boost::system::error_code& ec) const { - endpoint_type endpoint; - service_impl_.get_local_endpoint(impl, endpoint, error_handler); - return endpoint; + return service_impl_.local_endpoint(impl, ec); } /// Accept a new connection. - template - void accept(implementation_type& impl, + template + boost::system::error_code accept(implementation_type& impl, basic_socket& peer, - Error_Handler error_handler) + boost::system::error_code& ec) { - service_impl_.accept(impl, peer, error_handler); + return service_impl_.accept(impl, peer, ec); } /// Accept a new connection. - template - void accept_endpoint(implementation_type& impl, + template + boost::system::error_code accept_endpoint(implementation_type& impl, basic_socket& peer, - endpoint_type& peer_endpoint, Error_Handler error_handler) + endpoint_type& peer_endpoint, boost::system::error_code& ec) { - service_impl_.accept_endpoint(impl, peer, peer_endpoint, error_handler); + return service_impl_.accept_endpoint(impl, peer, peer_endpoint, ec); } /// Start an asynchronous accept. diff --git a/include/boost/asio/ssl/basic_context.hpp b/include/boost/asio/ssl/basic_context.hpp index 76e161af..cf25e7be 100644 --- a/include/boost/asio/ssl/basic_context.hpp +++ b/include/boost/asio/ssl/basic_context.hpp @@ -23,9 +23,10 @@ #include #include -#include +#include #include #include +#include namespace boost { namespace asio { @@ -77,11 +78,13 @@ public: * the context_base class. The options are bitwise-ored with any existing * value for the options. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void set_options(options o) { - service_.set_options(impl_, o, throw_error()); + boost::system::error_code ec; + service_.set_options(impl_, o, ec); + boost::asio::detail::throw_error(ec); } /// Set options on the context. @@ -92,17 +95,12 @@ public: * the context_base class. The options are bitwise-ored with any existing * value for the options. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void set_options(options o, Error_Handler error_handler) + boost::system::error_code set_options(options o, + boost::system::error_code& ec) { - service_.set_options(impl_, o, error_handler); + return service_.set_options(impl_, o, ec); } /// Set the peer verification mode. @@ -113,11 +111,13 @@ public: * @param v A bitmask of peer verification modes. The available verify_mode * values are defined in the context_base class. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void set_verify_mode(verify_mode v) { - service_.set_verify_mode(impl_, v, throw_error()); + boost::system::error_code ec; + service_.set_verify_mode(impl_, v, ec); + boost::asio::detail::throw_error(ec); } /// Set the peer verification mode. @@ -128,17 +128,12 @@ public: * @param v A bitmask of peer verification modes. The available verify_mode * values are defined in the context_base class. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void set_verify_mode(verify_mode v, Error_Handler error_handler) + boost::system::error_code set_verify_mode(verify_mode v, + boost::system::error_code& ec) { - service_.set_verify_mode(impl_, v, error_handler); + return service_.set_verify_mode(impl_, v, ec); } /// Load a certification authority file for performing verification. @@ -149,11 +144,13 @@ public: * @param filename The name of a file containing certification authority * certificates in PEM format. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void load_verify_file(const std::string& filename) { - service_.load_verify_file(impl_, filename, throw_error()); + boost::system::error_code ec; + service_.load_verify_file(impl_, filename, ec); + boost::asio::detail::throw_error(ec); } /// Load a certification authority file for performing verification. @@ -164,18 +161,12 @@ public: * @param filename The name of a file containing certification authority * certificates in PEM format. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void load_verify_file(const std::string& filename, - Error_Handler error_handler) + boost::system::error_code load_verify_file(const std::string& filename, + boost::system::error_code& ec) { - service_.load_verify_file(impl_, filename, error_handler); + return service_.load_verify_file(impl_, filename, ec); } /// Add a directory containing certificate authority files to be used for @@ -188,11 +179,13 @@ public: * * @param path The name of a directory containing the certificates. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void add_verify_path(const std::string& path) { - service_.add_verify_path(impl_, path, throw_error()); + boost::system::error_code ec; + service_.add_verify_path(impl_, path, ec); + boost::asio::detail::throw_error(ec); } /// Add a directory containing certificate authority files to be used for @@ -205,17 +198,12 @@ public: * * @param path The name of a directory containing the certificates. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void add_verify_path(const std::string& path, Error_Handler error_handler) + boost::system::error_code add_verify_path(const std::string& path, + boost::system::error_code& ec) { - service_.add_verify_path(impl_, path, error_handler); + return service_.add_verify_path(impl_, path, ec); } /// Use a certificate from a file. @@ -226,11 +214,13 @@ public: * * @param format The file format (ASN.1 or PEM). * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void use_certificate_file(const std::string& filename, file_format format) { - service_.use_certificate_file(impl_, filename, format, throw_error()); + boost::system::error_code ec; + service_.use_certificate_file(impl_, filename, format, ec); + boost::asio::detail::throw_error(ec); } /// Use a certificate from a file. @@ -241,18 +231,12 @@ public: * * @param format The file format (ASN.1 or PEM). * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void use_certificate_file(const std::string& filename, file_format format, - Error_Handler error_handler) + boost::system::error_code use_certificate_file(const std::string& filename, + file_format format, boost::system::error_code& ec) { - service_.use_certificate_file(impl_, filename, format, error_handler); + return service_.use_certificate_file(impl_, filename, format, ec); } /// Use a certificate chain from a file. @@ -263,11 +247,13 @@ public: * @param filename The name of the file containing the certificate. The file * must use the PEM format. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void use_certificate_chain_file(const std::string& filename) { - service_.use_certificate_chain_file(impl_, filename, throw_error()); + boost::system::error_code ec; + service_.use_certificate_chain_file(impl_, filename, ec); + boost::asio::detail::throw_error(ec); } /// Use a certificate chain from a file. @@ -278,18 +264,12 @@ public: * @param filename The name of the file containing the certificate. The file * must use the PEM format. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void use_certificate_chain_file(const std::string& filename, - Error_Handler error_handler) + boost::system::error_code use_certificate_chain_file( + const std::string& filename, boost::system::error_code& ec) { - service_.use_certificate_chain_file(impl_, filename, error_handler); + return service_.use_certificate_chain_file(impl_, filename, ec); } /// Use a private key from a file. @@ -300,11 +280,13 @@ public: * * @param format The file format (ASN.1 or PEM). * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void use_private_key_file(const std::string& filename, file_format format) { - service_.use_private_key_file(impl_, filename, format, throw_error()); + boost::system::error_code ec; + service_.use_private_key_file(impl_, filename, format, ec); + boost::asio::detail::throw_error(ec); } /// Use a private key from a file. @@ -315,18 +297,12 @@ public: * * @param format The file format (ASN.1 or PEM). * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void use_private_key_file(const std::string& filename, file_format format, - Error_Handler error_handler) + boost::system::error_code use_private_key_file(const std::string& filename, + file_format format, boost::system::error_code& ec) { - service_.use_private_key_file(impl_, filename, format, error_handler); + return service_.use_private_key_file(impl_, filename, format, ec); } /// Use an RSA private key from a file. @@ -338,11 +314,13 @@ public: * * @param format The file format (ASN.1 or PEM). * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void use_rsa_private_key_file(const std::string& filename, file_format format) { - service_.use_rsa_private_key_file(impl_, filename, format, throw_error()); + boost::system::error_code ec; + service_.use_rsa_private_key_file(impl_, filename, format, ec); + boost::asio::detail::throw_error(ec); } /// Use an RSA private key from a file. @@ -354,18 +332,13 @@ public: * * @param format The file format (ASN.1 or PEM). * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void use_rsa_private_key_file(const std::string& filename, file_format format, - Error_Handler error_handler) + boost::system::error_code use_rsa_private_key_file( + const std::string& filename, file_format format, + boost::system::error_code& ec) { - service_.use_rsa_private_key_file(impl_, filename, format, error_handler); + return service_.use_rsa_private_key_file(impl_, filename, format, ec); } /// Use the specified file to obtain the temporary Diffie-Hellman parameters. @@ -376,11 +349,13 @@ public: * @param filename The name of the file containing the Diffie-Hellman * parameters. The file must use the PEM format. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void use_tmp_dh_file(const std::string& filename) { - service_.use_tmp_dh_file(impl_, filename, throw_error()); + boost::system::error_code ec; + service_.use_tmp_dh_file(impl_, filename, ec); + boost::asio::detail::throw_error(ec); } /// Use the specified file to obtain the temporary Diffie-Hellman parameters. @@ -391,17 +366,12 @@ public: * @param filename The name of the file containing the Diffie-Hellman * parameters. The file must use the PEM format. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void use_tmp_dh_file(const std::string& filename, Error_Handler error_handler) + boost::system::error_code use_tmp_dh_file(const std::string& filename, + boost::system::error_code& ec) { - service_.use_tmp_dh_file(impl_, filename, error_handler); + return service_.use_tmp_dh_file(impl_, filename, ec); } /// Set the password callback. @@ -417,12 +387,14 @@ public: * ); @endcode * The return value of the callback is a string containing the password. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ template void set_password_callback(Password_Callback callback) { - service_.set_password_callback(impl_, callback, throw_error()); + boost::system::error_code ec; + service_.set_password_callback(impl_, callback, ec); + boost::asio::detail::throw_error(ec); } /// Set the password callback. @@ -438,18 +410,13 @@ public: * ); @endcode * The return value of the callback is a string containing the password. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void set_password_callback(Password_Callback callback, - Error_Handler error_handler) + template + boost::system::error_code set_password_callback(Password_Callback callback, + boost::system::error_code& ec) { - service_.set_password_callback(impl_, callback, error_handler); + return service_.set_password_callback(impl_, callback, ec); } private: diff --git a/include/boost/asio/ssl/context_service.hpp b/include/boost/asio/ssl/context_service.hpp index 6d66fdaa..6d4784bc 100644 --- a/include/boost/asio/ssl/context_service.hpp +++ b/include/boost/asio/ssl/context_service.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -78,85 +79,78 @@ public: } /// Set options on the context. - template - void set_options(impl_type& impl, context_base::options o, - Error_Handler error_handler) + boost::system::error_code set_options(impl_type& impl, + context_base::options o, boost::system::error_code& ec) { - service_impl_.set_options(impl, o, error_handler); + return service_impl_.set_options(impl, o, ec); } /// Set peer verification mode. - template - void set_verify_mode(impl_type& impl, context_base::verify_mode v, - Error_Handler error_handler) + boost::system::error_code set_verify_mode(impl_type& impl, + context_base::verify_mode v, boost::system::error_code& ec) { - service_impl_.set_verify_mode(impl, v, error_handler); + return service_impl_.set_verify_mode(impl, v, ec); } /// Load a certification authority file for performing verification. - template - void load_verify_file(impl_type& impl, const std::string& filename, - Error_Handler error_handler) + boost::system::error_code load_verify_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) { - service_impl_.load_verify_file(impl, filename, error_handler); + return service_impl_.load_verify_file(impl, filename, ec); } /// Add a directory containing certification authority files to be used for /// performing verification. - template - void add_verify_path(impl_type& impl, const std::string& path, - Error_Handler error_handler) + boost::system::error_code add_verify_path(impl_type& impl, + const std::string& path, boost::system::error_code& ec) { - service_impl_.add_verify_path(impl, path, error_handler); + return service_impl_.add_verify_path(impl, path, ec); } /// Use a certificate from a file. - template - void use_certificate_file(impl_type& impl, const std::string& filename, - context_base::file_format format, Error_Handler error_handler) + boost::system::error_code use_certificate_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) { - service_impl_.use_certificate_file(impl, filename, format, error_handler); + return service_impl_.use_certificate_file(impl, filename, format, ec); } /// Use a certificate chain from a file. - template - void use_certificate_chain_file(impl_type& impl, const std::string& filename, - Error_Handler error_handler) + boost::system::error_code use_certificate_chain_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) { - service_impl_.use_certificate_chain_file(impl, filename, error_handler); + return service_impl_.use_certificate_chain_file(impl, filename, ec); } /// Use a private key from a file. - template - void use_private_key_file(impl_type& impl, const std::string& filename, - context_base::file_format format, Error_Handler error_handler) + boost::system::error_code use_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) { - service_impl_.use_private_key_file(impl, filename, format, error_handler); + return service_impl_.use_private_key_file(impl, filename, format, ec); } /// Use an RSA private key from a file. - template - void use_rsa_private_key_file(impl_type& impl, const std::string& filename, - context_base::file_format format, Error_Handler error_handler) + boost::system::error_code use_rsa_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) { - service_impl_.use_rsa_private_key_file(impl, filename, format, - error_handler); + return service_impl_.use_rsa_private_key_file(impl, filename, format, ec); } /// Use the specified file to obtain the temporary Diffie-Hellman parameters. - template - void use_tmp_dh_file(impl_type& impl, const std::string& filename, - Error_Handler error_handler) + boost::system::error_code use_tmp_dh_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) { - service_impl_.use_tmp_dh_file(impl, filename, error_handler); + return service_impl_.use_tmp_dh_file(impl, filename, ec); } /// Set the password callback. - template - void set_password_callback(impl_type& impl, Password_Callback callback, - Error_Handler error_handler) + template + boost::system::error_code set_password_callback(impl_type& impl, + Password_Callback callback, boost::system::error_code& ec) { - service_impl_.set_password_callback(impl, callback, error_handler); + return service_impl_.set_password_callback(impl, callback, ec); } private: diff --git a/include/boost/asio/ssl/detail/openssl_context_service.hpp b/include/boost/asio/ssl/detail/openssl_context_service.hpp index ddad7d1b..9004dbc7 100644 --- a/include/boost/asio/ssl/detail/openssl_context_service.hpp +++ b/include/boost/asio/ssl/detail/openssl_context_service.hpp @@ -131,64 +131,58 @@ public: } // Set options on the context. - template - void set_options(impl_type& impl, context_base::options o, - Error_Handler error_handler) + boost::system::error_code set_options(impl_type& impl, + context_base::options o, boost::system::error_code& ec) { ::SSL_CTX_set_options(impl, o); - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Set peer verification mode. - template - void set_verify_mode(impl_type& impl, context_base::verify_mode v, - Error_Handler error_handler) + boost::system::error_code set_verify_mode(impl_type& impl, + context_base::verify_mode v, boost::system::error_code& ec) { ::SSL_CTX_set_verify(impl, v, 0); - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Load a certification authority file for performing verification. - template - void load_verify_file(impl_type& impl, const std::string& filename, - Error_Handler error_handler) + boost::system::error_code load_verify_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) { if (::SSL_CTX_load_verify_locations(impl, filename.c_str(), 0) != 1) { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Add a directory containing certification authority files to be used for // performing verification. - template - void add_verify_path(impl_type& impl, const std::string& path, - Error_Handler error_handler) + boost::system::error_code add_verify_path(impl_type& impl, + const std::string& path, boost::system::error_code& ec) { if (::SSL_CTX_load_verify_locations(impl, 0, path.c_str()) != 1) { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Use a certificate from a file. - template - void use_certificate_file(impl_type& impl, const std::string& filename, - context_base::file_format format, Error_Handler error_handler) + boost::system::error_code use_certificate_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) { int file_type; switch (format) @@ -201,43 +195,39 @@ public: break; default: { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } } if (::SSL_CTX_use_certificate_file(impl, filename.c_str(), file_type) != 1) { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Use a certificate chain from a file. - template - void use_certificate_chain_file(impl_type& impl, const std::string& filename, - Error_Handler error_handler) + boost::system::error_code use_certificate_chain_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) { if (::SSL_CTX_use_certificate_chain_file(impl, filename.c_str()) != 1) { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Use a private key from a file. - template - void use_private_key_file(impl_type& impl, const std::string& filename, - context_base::file_format format, Error_Handler error_handler) + boost::system::error_code use_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) { int file_type; switch (format) @@ -250,27 +240,25 @@ public: break; default: { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } } if (::SSL_CTX_use_PrivateKey_file(impl, filename.c_str(), file_type) != 1) { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Use an RSA private key from a file. - template - void use_rsa_private_key_file(impl_type& impl, const std::string& filename, - context_base::file_format format, Error_Handler error_handler) + boost::system::error_code use_rsa_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + boost::system::error_code& ec) { int file_type; switch (format) @@ -283,44 +271,39 @@ public: break; default: { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } } if (::SSL_CTX_use_RSAPrivateKey_file( impl, filename.c_str(), file_type) != 1) { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Use the specified file to obtain the temporary Diffie-Hellman parameters. - template - void use_tmp_dh_file(impl_type& impl, const std::string& filename, - Error_Handler error_handler) + boost::system::error_code use_tmp_dh_file(impl_type& impl, + const std::string& filename, boost::system::error_code& ec) { ::BIO* bio = ::BIO_new_file(filename.c_str(), "r"); if (!bio) { - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0); if (!dh) { ::BIO_free(bio); - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } ::BIO_free(bio); @@ -328,13 +311,12 @@ public: if (result != 1) { ::DH_free(dh); - boost::asio::error e(boost::asio::error::invalid_argument); - error_handler(e); - return; + ec = boost::asio::error::invalid_argument; + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } static int password_callback(char* buf, int size, int purpose, void* data) @@ -356,9 +338,9 @@ public: } // Set the password callback. - template - void set_password_callback(impl_type& impl, Password_Callback callback, - Error_Handler error_handler) + template + boost::system::error_code set_password_callback(impl_type& impl, + Password_Callback callback, boost::system::error_code& ec) { // Allocate callback function object if not already present. if (impl->default_passwd_callback_userdata) @@ -379,8 +361,8 @@ public: SSL_CTX_set_default_passwd_cb(impl, &openssl_context_service::password_callback); - boost::asio::error e; - error_handler(e); + ec = boost::asio::error::success; + return ec; } private: diff --git a/include/boost/asio/ssl/detail/openssl_operation.hpp b/include/boost/asio/ssl/detail/openssl_operation.hpp index 056f8667..67be4e47 100644 --- a/include/boost/asio/ssl/detail/openssl_operation.hpp +++ b/include/boost/asio/ssl/detail/openssl_operation.hpp @@ -34,7 +34,8 @@ namespace ssl { namespace detail { typedef boost::function ssl_primitive_func; -typedef boost::function user_handler_func; +typedef boost::function + user_handler_func; // Network send_/recv buffer implementation // @@ -156,15 +157,15 @@ public: if (is_shut_down_sent && is_shut_down_received && is_operation_done) // SSL connection is shut down cleanly - return handler_(boost::asio::error(), 1); + return handler_(boost::asio::error::success, 1); if (is_shut_down_received && !is_write_needed) - return handler_(boost::asio::error(boost::asio::error::eof), 0); + return handler_(boost::asio::error::eof, 0); if (is_shut_down_received) // Shutdown has been requested, while we were reading or writing... // abort our action... - return handler_(boost::asio::error(boost::asio::error::shut_down), 0); + return handler_(boost::asio::error::shut_down, 0); if (!is_operation_done && !is_read_needed && !is_write_needed && !is_shut_down_sent) @@ -172,9 +173,15 @@ public: // The operation has failed... It is not completed and does // not want network communication nor does want to send shutdown out... if (error_code == SSL_ERROR_SYSCALL) - return handler_(boost::asio::error(sys_error_code), rc); + { + return handler_(boost::system::error_code( + sys_error_code, boost::system::native_ecat), rc); + } else - return handler_(boost::asio::error(error_code + 1000000), rc); + { + return handler_(boost::system::error_code( + error_code, boost::asio::error::ssl_ecat), rc); + } } if (!is_operation_done && !is_write_needed) @@ -199,7 +206,7 @@ public: if (!BIO_should_retry(ssl_bio_)) { // Some serios error with BIO.... - return handler_(boost::asio::error(boost::asio::error::no_recovery), 0); + return handler_(boost::asio::error::no_recovery, 0); } } @@ -213,7 +220,7 @@ public: // Private implementation private: - typedef boost::function + typedef boost::function int_handler_func; typedef boost::function write_func; @@ -235,15 +242,15 @@ private: SSL* session_; // - int sync_user_handler(const boost::asio::error& error, int rc) + int sync_user_handler(const boost::system::error_code& error, int rc) { if (!error) return rc; - throw error; + throw boost::system::system_error(error); } - int async_user_handler(const boost::asio::error& error, int rc) + int async_user_handler(const boost::system::error_code& error, int rc) { user_handler_(error, rc); return 0; @@ -296,7 +303,7 @@ private: { // Seems like fatal error // reading from SSL BIO has failed... - handler_(boost::asio::error(boost::asio::error::no_recovery), 0); + handler_(boost::asio::error::no_recovery, 0); return 0; } } @@ -304,7 +311,7 @@ private: if (is_operation_done) { // Finish the operation, with success - handler_(boost::asio::error(), rc); + handler_(boost::asio::error::success, rc); return 0; } @@ -316,7 +323,7 @@ private: } void async_write_handler(bool is_operation_done, int rc, - const boost::asio::error& error, size_t bytes_sent) + const boost::system::error_code& error, size_t bytes_sent) { if (!error) { @@ -324,7 +331,7 @@ private: send_buf_.data_removed(bytes_sent); if (is_operation_done) - handler_(boost::asio::error(), rc); + handler_(boost::asio::error::success, rc); else // Since the operation was not completed, try it again... start(); @@ -350,7 +357,8 @@ private: ); } - void async_read_handler(const boost::asio::error& error, size_t bytes_recvd) + void async_read_handler(const boost::system::error_code& error, + size_t bytes_recvd) { if (!error) { @@ -373,7 +381,7 @@ private: if (!BIO_should_retry(ssl_bio_)) { // Some serios error with BIO.... - handler_(boost::asio::error(boost::asio::error::no_recovery), 0); + handler_(boost::asio::error::no_recovery, 0); return; } } @@ -417,7 +425,7 @@ private: { // Seems like fatal error // reading from SSL BIO has failed... - throw boost::asio::error(boost::asio::error::no_recovery); + throw boost::system::system_error(boost::asio::error::no_recovery); } } @@ -457,7 +465,7 @@ private: if (!BIO_should_retry(ssl_bio_)) { // Some serios error with BIO.... - throw boost::asio::error(boost::asio::error::no_recovery); + throw boost::system::system_error(boost::asio::error::no_recovery); } } diff --git a/include/boost/asio/ssl/detail/openssl_stream_service.hpp b/include/boost/asio/ssl/detail/openssl_stream_service.hpp index 8d40b2fd..72e79c08 100644 --- a/include/boost/asio/ssl/detail/openssl_stream_service.hpp +++ b/include/boost/asio/ssl/detail/openssl_stream_service.hpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -46,7 +47,8 @@ private: class base_handler { public: - typedef boost::function func_t; + typedef boost::function< + void (const boost::system::error_code&, size_t)> func_t; base_handler(boost::asio::io_service& io_service) : op_(NULL) @@ -54,7 +56,7 @@ private: , work_(io_service) {} - void do_func(const boost::asio::error& error, size_t size) + void do_func(const boost::system::error_code& error, size_t size) { func_(error, size); } @@ -91,7 +93,7 @@ private: private: Handler handler_; - void handler_impl(const boost::asio::error& error, size_t size) + void handler_impl(const boost::system::error_code& error, size_t size) { handler_(error, size); delete this; @@ -115,7 +117,7 @@ private: private: Handler handler_; - void handler_impl(const boost::asio::error& error, size_t) + void handler_impl(const boost::system::error_code& error, size_t) { handler_(error); delete this; @@ -140,7 +142,7 @@ private: private: Handler handler_; - void handler_impl(const boost::asio::error& error, size_t) + void handler_impl(const boost::system::error_code& error, size_t) { handler_(error); delete this; @@ -202,9 +204,9 @@ public: } // Perform SSL handshaking. - template - void handshake(impl_type& impl, Stream& next_layer, - stream_base::handshake_type type, Error_Handler error_handler) + template + boost::system::error_code handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, boost::system::error_code& ec) { try { @@ -218,14 +220,14 @@ public: impl->ext_bio); op.start(); } - catch (boost::asio::error& e) + catch (boost::system::system_error& e) { - error_handler(e); - return; + ec = e.code(); + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Start an asynchronous SSL handshake. @@ -261,9 +263,9 @@ public: } // Shut down SSL on the stream. - template - void shutdown(impl_type& impl, Stream& next_layer, - Error_Handler error_handler) + template + boost::system::error_code shutdown(impl_type& impl, Stream& next_layer, + boost::system::error_code& ec) { try { @@ -275,14 +277,14 @@ public: impl->ext_bio); op.start(); } - catch (boost::asio::error& e) + catch (boost::system::system_error& e) { - error_handler(e); - return; + ec = e.code(); + return ec; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); + return ec; } // Asynchronously shut down SSL on the stream. @@ -315,9 +317,9 @@ public: } // Write some data to the stream. - template + template std::size_t write_some(impl_type& impl, Stream& next_layer, - const Const_Buffers& buffers, Error_Handler error_handler) + const Const_Buffers& buffers, boost::system::error_code& ec) { size_t bytes_transferred = 0; try @@ -335,14 +337,13 @@ public: ); bytes_transferred = static_cast(op.start()); } - catch (boost::asio::error& e) + catch (boost::system::system_error& e) { - error_handler(e); + ec = e.code(); return 0; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); return bytes_transferred; } @@ -381,9 +382,9 @@ public: } // Read some data from the stream. - template + template std::size_t read_some(impl_type& impl, Stream& next_layer, - const Mutable_Buffers& buffers, Error_Handler error_handler) + const Mutable_Buffers& buffers, boost::system::error_code& ec) { size_t bytes_transferred = 0; try @@ -401,14 +402,13 @@ public: bytes_transferred = static_cast(op.start()); } - catch (boost::asio::error& e) + catch (boost::system::system_error& e) { - error_handler(e); + ec = e.code(); return 0; } - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); return bytes_transferred; } @@ -447,22 +447,20 @@ public: } // Peek at the incoming data on the stream. - template + template std::size_t peek(impl_type& impl, Stream& next_layer, - const Mutable_Buffers& buffers, Error_Handler error_handler) + const Mutable_Buffers& buffers, boost::system::error_code& ec) { - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); return 0; } // Determine the amount of data that may be read without blocking. - template + template std::size_t in_avail(impl_type& impl, Stream& next_layer, - Error_Handler error_handler) + boost::system::error_code& ec) { - boost::asio::error e; - error_handler(e); + ec = boost::system::error_code(); return 0; } diff --git a/include/boost/asio/ssl/stream.hpp b/include/boost/asio/ssl/stream.hpp index 3ccb2fe3..e32ddeab 100644 --- a/include/boost/asio/ssl/stream.hpp +++ b/include/boost/asio/ssl/stream.hpp @@ -26,10 +26,10 @@ #include #include -#include #include #include #include +#include namespace boost { namespace asio { @@ -68,9 +68,6 @@ public: /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type; - /// The type used for reporting errors. - typedef typename next_layer_type::error_type error_type; - /// The type of the service that will be used to provide stream operations. typedef Service service_type; @@ -159,11 +156,13 @@ public: * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void handshake(handshake_type type) { - service_.handshake(impl_, next_layer_, type, throw_error()); + boost::system::error_code ec; + service_.handshake(impl_, next_layer_, type, ec); + boost::asio::detail::throw_error(ec); } /// Perform SSL handshaking. @@ -174,17 +173,12 @@ public: * @param type The type of handshaking to be performed, i.e. as a client or as * a server. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void handshake(handshake_type type, Error_Handler error_handler) + boost::system::error_code handshake(handshake_type type, + boost::system::error_code& ec) { - service_.handshake(impl_, next_layer_, type, error_handler); + return service_.handshake(impl_, next_layer_, type, ec); } /// Start an asynchronous SSL handshake. @@ -199,7 +193,7 @@ public: * completes. Copies will be made of the handler as required. The equivalent * function signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation + * const boost::system::error_code& error // Result of operation. * ); @endcode */ template @@ -213,11 +207,13 @@ public: * This function is used to shut down SSL on the stream. The function call * will block until SSL has been shut down or an error occurs. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ void shutdown() { - service_.shutdown(impl_, next_layer_, throw_error()); + boost::system::error_code ec; + service_.shutdown(impl_, next_layer_, ec); + boost::asio::detail::throw_error(ec); } /// Shut down SSL on the stream. @@ -225,17 +221,11 @@ public: * This function is used to shut down SSL on the stream. The function call * will block until SSL has been shut down or an error occurs. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. */ - template - void shutdown(Error_Handler error_handler) + boost::system::error_code shutdown(boost::system::error_code& ec) { - service_.shutdown(impl_, next_layer_, error_handler); + return service_.shutdown(impl_, next_layer_, ec); } /// Asynchronously shut down SSL on the stream. @@ -247,7 +237,7 @@ public: * completes. Copies will be made of the handler as required. The equivalent * function signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation + * const boost::system::error_code& error // Result of operation. * ); @endcode */ template @@ -266,7 +256,7 @@ public: * * @returns The number of bytes written. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that all @@ -275,7 +265,10 @@ public: template std::size_t write_some(const Const_Buffers& buffers) { - return service_.write_some(impl_, next_layer_, buffers, throw_error()); + boost::system::error_code ec; + std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Write some data to the stream. @@ -286,25 +279,19 @@ public: * * @param buffers The data to be written to the stream. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes written. Returns 0 if an error occurred and - * the error handler did not throw an exception. + * @returns The number of bytes written. Returns 0 if an error occurred. * * @note The write_some operation may not transmit all of the data to the * peer. Consider using the @ref write function if you need to ensure that all * data is written before the blocking operation completes. */ - template + template std::size_t write_some(const Const_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return service_.write_some(impl_, next_layer_, buffers, error_handler); + return service_.write_some(impl_, next_layer_, buffers, ec); } /// Start an asynchronous write. @@ -321,8 +308,8 @@ public: * Copies will be made of the handler as required. The equivalent function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * * @note The async_write_some operation may not transmit all of the data to @@ -345,7 +332,7 @@ public: * * @returns The number of bytes read. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the @@ -354,7 +341,10 @@ public: template std::size_t read_some(const Mutable_Buffers& buffers) { - return service_.read_some(impl_, next_layer_, buffers, throw_error()); + boost::system::error_code ec; + std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Read some data from the stream. @@ -365,25 +355,19 @@ public: * * @param buffers The buffers into which the data will be read. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes read. Returns 0 if an error occurred and the - * error handler did not throw an exception. + * @returns The number of bytes read. Returns 0 if an error occurred. * * @note The read_some operation may not read all of the requested number of * bytes. Consider using the @ref read function if you need to ensure that the * requested amount of data is read before the blocking operation completes. */ - template + template std::size_t read_some(const Mutable_Buffers& buffers, - Error_Handler error_handler) + boost::system::error_code& ec) { - return service_.read_some(impl_, next_layer_, buffers, error_handler); + return service_.read_some(impl_, next_layer_, buffers, ec); } /// Start an asynchronous read. @@ -400,8 +384,8 @@ public: * Copies will be made of the handler as required. The equivalent function * signature of the handler must be: * @code void handler( - * const boost::asio::error& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * * @note The async_read_some operation may not read all of the requested @@ -425,12 +409,15 @@ public: * * @returns The number of bytes read. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ template std::size_t peek(const Mutable_Buffers& buffers) { - return service_.peek(impl_, next_layer_, buffers, throw_error()); + boost::system::error_code ec; + std::size_t s = service_.peek(impl_, next_layer_, buffers, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Peek at the incoming data on the stream. @@ -441,20 +428,15 @@ public: * * @param buffers The buffers into which the data will be read. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes read. Returns 0 if an error occurred and the - * error handler did not throw an exception. + * @returns The number of bytes read. Returns 0 if an error occurred. */ - template - std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler) + template + std::size_t peek(const Mutable_Buffers& buffers, + boost::system::error_code& ec) { - return service_.peek(impl_, next_layer_, buffers, error_handler); + return service_.peek(impl_, next_layer_, buffers, ec); } /// Determine the amount of data that may be read without blocking. @@ -464,11 +446,14 @@ public: * * @returns The number of bytes of data that can be read without blocking. * - * @throws boost::asio::error Thrown on failure. + * @throws boost::system::system_error Thrown on failure. */ std::size_t in_avail() { - return service_.in_avail(impl_, next_layer_, throw_error()); + boost::system::error_code ec; + std::size_t s = service_.in_avail(impl_, next_layer_, ec); + boost::asio::detail::throw_error(ec); + return s; } /// Determine the amount of data that may be read without blocking. @@ -476,19 +461,13 @@ public: * This function is used to determine the amount of data, in bytes, that may * be read from the stream without blocking. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const boost::asio::error& error // Result of operation - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * * @returns The number of bytes of data that can be read without blocking. */ - template - std::size_t in_avail(Error_Handler error_handler) + std::size_t in_avail(boost::system::error_code& ec) { - return service_.in_avail(impl_, next_layer_, error_handler); + return service_.in_avail(impl_, next_layer_, ec); } private: diff --git a/include/boost/asio/ssl/stream_service.hpp b/include/boost/asio/ssl/stream_service.hpp index def8554d..f93064fc 100644 --- a/include/boost/asio/ssl/stream_service.hpp +++ b/include/boost/asio/ssl/stream_service.hpp @@ -83,11 +83,11 @@ public: } /// Perform SSL handshaking. - template - void handshake(impl_type& impl, Stream& next_layer, - stream_base::handshake_type type, Error_Handler error_handler) + template + boost::system::error_code handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, boost::system::error_code& ec) { - service_impl_.handshake(impl, next_layer, type, error_handler); + return service_impl_.handshake(impl, next_layer, type, ec); } /// Start an asynchronous SSL handshake. @@ -99,11 +99,11 @@ public: } /// Shut down SSL on the stream. - template - void shutdown(impl_type& impl, Stream& next_layer, - Error_Handler error_handler) + template + boost::system::error_code shutdown(impl_type& impl, Stream& next_layer, + boost::system::error_code& ec) { - service_impl_.shutdown(impl, next_layer, error_handler); + return service_impl_.shutdown(impl, next_layer, ec); } /// Asynchronously shut down SSL on the stream. @@ -114,11 +114,11 @@ public: } /// Write some data to the stream. - template + template std::size_t write_some(impl_type& impl, Stream& next_layer, - const Const_Buffers& buffers, Error_Handler error_handler) + const Const_Buffers& buffers, boost::system::error_code& ec) { - return service_impl_.write_some(impl, next_layer, buffers, error_handler); + return service_impl_.write_some(impl, next_layer, buffers, ec); } /// Start an asynchronous write. @@ -130,11 +130,11 @@ public: } /// Read some data from the stream. - template + template std::size_t read_some(impl_type& impl, Stream& next_layer, - const Mutable_Buffers& buffers, Error_Handler error_handler) + const Mutable_Buffers& buffers, boost::system::error_code& ec) { - return service_impl_.read_some(impl, next_layer, buffers, error_handler); + return service_impl_.read_some(impl, next_layer, buffers, ec); } /// Start an asynchronous read. @@ -146,19 +146,19 @@ public: } /// Peek at the incoming data on the stream. - template + template std::size_t peek(impl_type& impl, Stream& next_layer, - const Mutable_Buffers& buffers, Error_Handler error_handler) + const Mutable_Buffers& buffers, boost::system::error_code& ec) { - return service_impl_.peek(impl, next_layer, buffers, error_handler); + return service_impl_.peek(impl, next_layer, buffers, ec); } /// Determine the amount of data that may be read without blocking. - template + template std::size_t in_avail(impl_type& impl, Stream& next_layer, - Error_Handler error_handler) + boost::system::error_code& ec) { - return service_impl_.in_avail(impl, next_layer, error_handler); + return service_impl_.in_avail(impl, next_layer, ec); } private: diff --git a/include/boost/asio/stream_socket_service.hpp b/include/boost/asio/stream_socket_service.hpp index b61073d5..1c4598a4 100644 --- a/include/boost/asio/stream_socket_service.hpp +++ b/include/boost/asio/stream_socket_service.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -99,29 +100,29 @@ public: } /// Open a stream socket. - template - void open(implementation_type& impl, const protocol_type& protocol, - Error_Handler error_handler) + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) { if (protocol.type() == SOCK_STREAM) - service_impl_.open(impl, protocol, error_handler); + service_impl_.open(impl, protocol, ec); else - error_handler(boost::asio::error(boost::asio::error::invalid_argument)); + ec = boost::asio::error::invalid_argument; + return ec; } /// Assign an existing native socket to a stream socket. - template - void assign(implementation_type& impl, const protocol_type& protocol, - const native_type& native_socket, Error_Handler error_handler) + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + boost::system::error_code& ec) { - service_impl_.assign(impl, protocol, native_socket, error_handler); + return service_impl_.assign(impl, protocol, native_socket, ec); } /// Close a stream socket implementation. - template - void close(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) { - service_impl_.close(impl, error_handler); + return service_impl_.close(impl, ec); } /// Get the native socket implementation. @@ -131,26 +132,24 @@ public: } /// Cancel all asynchronous operations associated with the socket. - template - void cancel(implementation_type& impl, Error_Handler error_handler) + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) { - service_impl_.cancel(impl, error_handler); + return service_impl_.cancel(impl, ec); } /// Bind the stream socket to the specified local endpoint. - template - void bind(implementation_type& impl, const endpoint_type& endpoint, - Error_Handler error_handler) + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) { - service_impl_.bind(impl, endpoint, error_handler); + return service_impl_.bind(impl, endpoint, ec); } /// Connect the stream socket to the specified endpoint. - template - void connect(implementation_type& impl, const endpoint_type& peer_endpoint, - Error_Handler error_handler) + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) { - service_impl_.connect(impl, peer_endpoint, error_handler); + return service_impl_.connect(impl, peer_endpoint, ec); } /// Start an asynchronous connect. @@ -162,63 +161,56 @@ public: } /// Set a socket option. - template - void set_option(implementation_type& impl, const Option& option, - Error_Handler error_handler) + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) { - service_impl_.set_option(impl, option, error_handler); + return service_impl_.set_option(impl, option, ec); } /// Get a socket option. - template - void get_option(const implementation_type& impl, Option& option, - Error_Handler error_handler) const + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const { - service_impl_.get_option(impl, option, error_handler); + return service_impl_.get_option(impl, option, ec); } /// Perform an IO control command on the socket. - template - void io_control(implementation_type& impl, IO_Control_Command& command, - Error_Handler error_handler) + template + boost::system::error_code io_control(implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) { - service_impl_.io_control(impl, command, error_handler); + return service_impl_.io_control(impl, command, ec); } /// Get the local endpoint. - template endpoint_type local_endpoint(const implementation_type& impl, - Error_Handler error_handler) const + boost::system::error_code& ec) const { - endpoint_type endpoint; - service_impl_.get_local_endpoint(impl, endpoint, error_handler); - return endpoint; + return service_impl_.local_endpoint(impl, ec); } /// Get the remote endpoint. - template endpoint_type remote_endpoint(const implementation_type& impl, - Error_Handler error_handler) const + boost::system::error_code& ec) const { - endpoint_type endpoint; - service_impl_.get_remote_endpoint(impl, endpoint, error_handler); - return endpoint; + return service_impl_.remote_endpoint(impl, ec); } /// Disable sends or receives on the socket. - template - void shutdown(implementation_type& impl, socket_base::shutdown_type what, - Error_Handler error_handler) + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) { - service_impl_.shutdown(impl, what, error_handler); + return service_impl_.shutdown(impl, what, ec); } /// Send the given data to the peer. - template + template std::size_t send(implementation_type& impl, const Const_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return service_impl_.send(impl, buffers, flags, error_handler); + return service_impl_.send(impl, buffers, flags, ec); } /// Start an asynchronous send. @@ -230,11 +222,11 @@ public: } /// Receive some data from the peer. - template + template std::size_t receive(implementation_type& impl, const Mutable_Buffers& buffers, - socket_base::message_flags flags, Error_Handler error_handler) + socket_base::message_flags flags, boost::system::error_code& ec) { - return service_impl_.receive(impl, buffers, flags, error_handler); + return service_impl_.receive(impl, buffers, flags, ec); } /// Start an asynchronous receive. diff --git a/include/boost/asio/system_exception.hpp b/include/boost/asio/system_exception.hpp deleted file mode 100644 index e7e25879..00000000 --- a/include/boost/asio/system_exception.hpp +++ /dev/null @@ -1,200 +0,0 @@ -// -// error.hpp -// ~~~~~~~~~ -// -// Copyright (c) 2003-2006 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_SYSTEM_EXCEPTION_HPP -#define BOOST_ASIO_SYSTEM_EXCEPTION_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -# include -#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -#include - -#include - -namespace boost { -namespace asio { - -/// The system_exception class is used to represent system conditions that -/// prevent the library from operating correctly. -class system_exception - : public std::exception -{ -public: - /// Construct with a specific context and error code. - system_exception(const std::string& context, int code) - : context_(context), - code_(code) - { - } - - /// Copy constructor. - system_exception(const system_exception& e) - : std::exception(e), - context_(e.context_), - code_(e.code_) - { - } - - /// Destructor. - virtual ~system_exception() throw () - { - } - - /// Assignment operator. - system_exception& operator=(const system_exception& e) - { - context_ = e.context_; - code_ = e.code_; - what_.reset(); - return *this; - } - - /// Get a string representation of the exception. - virtual const char* what() const throw () - { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - try - { - if (!what_) - { - char* msg = 0; - DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER - | FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS, 0, code_, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); - detail::local_free_on_block_exit local_free_obj(msg); - if (length && msg[length - 1] == '\n') - msg[--length] = '\0'; - if (length && msg[length - 1] == '\r') - msg[--length] = '\0'; - if (length) - { - std::string tmp(context_); - tmp += ": "; - tmp += msg; - what_.reset(new std::string(tmp)); - } - else - { - return "asio system_exception"; - } - } - return what_->c_str(); - } - catch (std::exception&) - { - return "asio system_exception"; - } -#elif defined(__sun) || defined(__QNX__) - return strerror(code_); -#elif defined(__MACH__) && defined(__APPLE__) \ - || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - try - { - char buf[256] = ""; - strerror_r(code_, buf, sizeof(buf)); - std::string tmp(context_); - tmp += ": "; - tmp += buf; - what_.reset(new std::string(tmp)); - return what_->c_str(); - } - catch (std::exception&) - { - return "asio system_exception"; - } -#else - try - { - char buf[256] = ""; - std::string tmp(context_); - tmp += ": "; - tmp += strerror_r(code_, buf, sizeof(buf)); - what_.reset(new std::string(tmp)); - return what_->c_str(); - } - catch (std::exception&) - { - return "asio system_exception"; - } -#endif - } - - /// Get the implementation-defined context associated with the exception. - const std::string& context() const - { - return context_; - } - - /// Get the implementation-defined code associated with the exception. - int code() const - { - return code_; - } - -private: - // The context associated with the error. - std::string context_; - - // The code associated with the error. - int code_; - - // The string representation of the error. - mutable boost::scoped_ptr what_; -}; - -/// Output the string associated with a system exception. -/** - * Used to output a human-readable string that is associated with a system - * exception. - * - * @param os The output stream to which the string will be written. - * - * @param e The exception to be written. - * - * @return The output stream. - * - * @relates boost::asio::system_exception - */ -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -std::ostream& operator<<(std::ostream& os, const system_exception& e) -{ - os << e.what(); - return os; -} -#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -template -Ostream& operator<<(Ostream& os, const system_exception& e) -{ - os << e.what(); - return os; -} -#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_SYSTEM_EXCEPTION_HPP diff --git a/include/boost/asio/write.hpp b/include/boost/asio/write.hpp index 03777a12..ac2bc5fe 100644 --- a/include/boost/asio/write.hpp +++ b/include/boost/asio/write.hpp @@ -23,6 +23,7 @@ #include #include +#include namespace boost { namespace asio { @@ -54,7 +55,7 @@ namespace asio { * * @returns The number of bytes transferred. * - * @throws Sync_Write_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To write a single data buffer use the @ref buffer function as follows: @@ -66,8 +67,7 @@ namespace asio { * @note This overload is equivalent to calling: * @code boost::asio::write( * s, buffers, - * boost::asio::transfer_all(), - * boost::asio::throw_error()); @endcode + * boost::asio::transfer_all()); @endcode */ template std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers); @@ -96,11 +96,11 @@ std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers); * whether the write operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Write_Stream::error_type& error, // Result of latest write_some - * // operation. + * const boost::system::error_code& error, // Result of latest write_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the write operation is complete. False * indicates that further calls to the stream's write_some function are @@ -108,7 +108,7 @@ std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers); * * @returns The number of bytes transferred. * - * @throws Sync_Write_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @par Example: * To write a single data buffer use the @ref buffer function as follows: @@ -117,12 +117,6 @@ std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers); * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or * std::vector. - * - * @note This overload is equivalent to calling: - * @code boost::asio::write( - * s, buffers, - * completion_condition, - * boost::asio::throw_error()); @endcode */ template @@ -153,31 +147,25 @@ std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers, * whether the write operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Write_Stream::error_type& error, // Result of latest write_some - * // operation. + * const boost::system::error_code& error, // Result of latest write_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the write operation is complete. False * indicates that further calls to the stream's write_some function are * required. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const Sync_Write_Stream::error_type& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes written. If an error occurs, and the error - * handler does not throw an exception, returns the total number of bytes - * successfully transferred prior to the error. + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. */ template + typename Completion_Condition> std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers, - Completion_Condition completion_condition, Error_Handler error_handler); + Completion_Condition completion_condition, boost::system::error_code& ec); /// Write a certain amount of data to a stream before returning. /** @@ -198,13 +186,12 @@ std::size_t write(Sync_Write_Stream& s, const Const_Buffers& buffers, * * @returns The number of bytes transferred. * - * @throws Sync_Write_Stream::error_type Thrown on failure. + * @throws boost::system::system_error Thrown on failure. * * @note This overload is equivalent to calling: * @code boost::asio::write( * s, b, - * boost::asio::transfer_all(), - * boost::asio::throw_error()); @endcode + * boost::asio::transfer_all()); @endcode */ template std::size_t write(Sync_Write_Stream& s, basic_streambuf& b); @@ -230,11 +217,11 @@ std::size_t write(Sync_Write_Stream& s, basic_streambuf& b); * whether the write operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Write_Stream::error_type& error, // Result of latest write_some - * // operation. + * const boost::system::error_code& error, // Result of latest write_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the write operation is complete. False * indicates that further calls to the stream's write_some function are @@ -242,13 +229,7 @@ std::size_t write(Sync_Write_Stream& s, basic_streambuf& b); * * @returns The number of bytes transferred. * - * @throws Sync_Write_Stream::error_type Thrown on failure. - * - * @note This overload is equivalent to calling: - * @code boost::asio::write( - * s, b, - * completion_condition, - * boost::asio::throw_error()); @endcode + * @throws boost::system::system_error Thrown on failure. */ template @@ -276,31 +257,25 @@ std::size_t write(Sync_Write_Stream& s, basic_streambuf& b, * whether the write operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Sync_Write_Stream::error_type& error, // Result of latest write_some - * // operation. + * const boost::system::error_code& error, // Result of latest write_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the write operation is complete. False * indicates that further calls to the stream's write_some function are * required. * - * @param error_handler A handler to be called when the operation completes, - * to indicate whether or not an error has occurred. Copies will be made of - * the handler as required. The function signature of the handler must be: - * @code void error_handler( - * const Sync_Write_Stream::error_type& error // Result of operation. - * ); @endcode + * @param ec Set to indicate what error occurred, if any. * - * @returns The number of bytes written. If an error occurs, and the error - * handler does not throw an exception, returns the total number of bytes - * successfully transferred prior to the error. + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. */ template + typename Completion_Condition> std::size_t write(Sync_Write_Stream& s, basic_streambuf& b, - Completion_Condition completion_condition, Error_Handler error_handler); + Completion_Condition completion_condition, boost::system::error_code& ec); /*@}*/ /** @@ -336,13 +311,12 @@ std::size_t write(Sync_Write_Stream& s, basic_streambuf& b, * Copies will be made of the handler as required. The function signature of * the handler must be: * @code void handler( - * const Async_Write_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes written - * // from the buffers. If an - * // error occurred, this will - * // be less than the sum of the - * // buffer sizes. + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -390,11 +364,11 @@ void async_write(Async_Write_Stream& s, const Const_Buffers& buffers, * whether the write operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Async_Write_Stream::error_type& error, // Result of latest write_some - * // operation. + * const boost::system::error_code& error, // Result of latest write_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the write operation is complete. False * indicates that further calls to the stream's async_write_some function are @@ -404,13 +378,12 @@ void async_write(Async_Write_Stream& s, const Const_Buffers& buffers, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Write_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes written - * // from the buffers. If an - * // error occurred, this will - * // be less than the sum of the - * // buffer sizes. + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -458,13 +431,12 @@ void async_write(Async_Write_Stream& s, const Const_Buffers& buffers, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Write_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes written - * // from the buffers. If an - * // error occurred, this will - * // be less than the sum of the - * // buffer sizes. + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of @@ -501,11 +473,11 @@ void async_write(Async_Write_Stream& s, basic_streambuf& b, * whether the write operation is complete. The signature of the function object * must be: * @code bool completion_condition( - * const Async_Write_Stream::error_type& error, // Result of latest write_some - * // operation. + * const boost::system::error_code& error, // Result of latest write_some + * // operation. * - * std::size_t bytes_transferred // Number of bytes transferred - * // so far. + * std::size_t bytes_transferred // Number of bytes transferred + * // so far. * ); @endcode * A return value of true indicates that the write operation is complete. False * indicates that further calls to the stream's async_write_some function are @@ -515,13 +487,12 @@ void async_write(Async_Write_Stream& s, basic_streambuf& b, * Copies will be made of the handler as required. The function signature of the * handler must be: * @code void handler( - * const Async_Write_Stream::error_type& error, // Result of operation. + * const boost::system::error_code& error, // Result of operation. * - * std::size_t bytes_transferred // Number of bytes written - * // from the buffers. If an - * // error occurred, this will - * // be less than the sum of the - * // buffer sizes. + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or * not, the handler will not be invoked from within this function. Invocation of diff --git a/test/Jamfile b/test/Jamfile index 3870944c..8fd9697b 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -7,6 +7,8 @@ subproject libs/asio/test ; +project boost : $(BOOST_ROOT) ; + # bring in the rules for testing import testing ; @@ -22,7 +24,8 @@ if $(UNIX) } template asio_unit_test - : ../../../libs/thread/build/boost_thread + : @boost/libs/thread/build/boost_thread + @boost/libs/system/build/boost_system : ../../.. BOOST_ALL_NO_LIB=1 multi @@ -33,44 +36,43 @@ template asio_unit_test test-suite "asio" : - [ link basic_datagram_socket.cpp