Compare commits

..

1 Commits

Author SHA1 Message Date
d30ab7e683 tagging the 0.5 release 2007-03-18 16:39:07 +00:00
298 changed files with 13713 additions and 30721 deletions

View File

@ -1,7 +1,5 @@
include LICENSE
include README
include README.Packagers
include Makefile
include deluge.desktop
include deluge.xpm
include msgfmt.py

View File

@ -1,15 +0,0 @@
#
# Makefile for Deluge
#
PREFIX = /usr
all:
python setup.py build
install:
python setup.py install --prefix=$(PREFIX)
clean:
python setup.py clean; rm -rf ./build; rm msgfmt.pyc

12
README
View File

@ -3,7 +3,6 @@ Deluge BitTorrent Client
Authors:
Zach Tibbitts, aka zachtib
Alon Zakai, aka kripkenstein
Marcos Pinto, aka markybob
Homepage: http://deluge-torrent.org
@ -15,7 +14,6 @@ First, make sure you have the proper bulid
dependencies installed. On a normal Debian
or Ubuntu system, those dependencies are:
g++
python-all-dev
python-all
python-support
@ -23,7 +21,9 @@ libboost-dev
libboost-thread-dev
libboost-date-time-dev
libboost-filesystem-dev
libssl-dev
libboost-serialization-dev
libboost-program-options-dev
libboost-regex-dev
zlib1g-dev
But the names of the packages may vary
@ -55,9 +55,3 @@ Notes:
things. The solution is to either add symlinks
from the short names to those with "-mt", or to
alter setup.py to look for the "-mt" versions.
2) After upgrading your Deluge installation, it
may fail to start. If this happens to you, you
need to remove your ~/.config/deluge directory
to allow Deluge to rebuild it's configuration
file.

View File

@ -1,11 +0,0 @@
NOTE: Deluge 0.5.1 uses an unstable build of libtorrent. This
build differs from a clean libtorrent source checkout and has
been hacked in order to get it to work properly with Deluge.
As a result, Deluge will likely not build properly against a
vanilla libtorrent 0.12 installation or a nightly build of
libtorrent 0.13. It is recommended that you build against our
included libtorrent, as our build will not conflict with any
installed libtorrent.
- zachtib

View File

@ -8,7 +8,7 @@
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<property name="website"></property>
<property name="website">http://deluge-torrent.org</property>
<property name="authors"></property>
<property name="documenters"></property>
<property name="artists"></property>

File diff suppressed because it is too large Load Diff

731
glade/dgtkpref.glade Normal file
View File

@ -0,0 +1,731 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkDialog" id="pref_dialog">
<property name="width_request">480</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Preferences Dialog</property>
<property name="default_width">583</property>
<property name="default_height">431</property>
<property name="destroy_with_parent">True</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkNotebook" id="pref_notebook">
<property name="visible">True</property>
<child>
<widget class="GtkScrolledWindow" id="gen_options">
<property name="visible">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkViewport" id="viewport2">
<property name="visible">True</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="resize_mode">GTK_RESIZE_IMMEDIATE</property>
<child>
<widget class="GtkExpander" id="expander6">
<property name="visible">True</property>
<property name="expanded">True</property>
<child>
<widget class="GtkTable" id="table5">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkCheckButton" id="chk_use_tray">
<property name="visible">True</property>
<property name="label" translatable="yes">Enable system tray icon</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="tray_toggle"/>
</widget>
<packing>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_min_on_close">
<property name="visible">True</property>
<property name="label" translatable="yes">Minimize to tray on close</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_padding">12</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label29">
<property name="visible">True</property>
<property name="label" translatable="yes">Options</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="expanded">True</property>
<child>
<widget class="GtkTable" id="table3">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkFileChooserButton" id="download_path_button">
<property name="visible">True</property>
<property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radio_save_all_to">
<property name="visible">True</property>
<property name="label" translatable="yes">Save all downloads to:</property>
<property name="draw_indicator">True</property>
<property name="group">radio_ask_save</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radio_ask_save">
<property name="visible">True</property>
<property name="label" translatable="yes">Ask me where to save each download</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="right_attach">2</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label16">
<property name="visible">True</property>
<property name="label" translatable="yes">Save Location</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkExpander" id="expander2">
<property name="visible">True</property>
<property name="expanded">True</property>
<child>
<widget class="GtkTable" id="table4">
<property name="visible">True</property>
<property name="n_rows">1</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkSpinButton" id="ratio_spinner">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="width_chars">5</property>
<property name="xalign">0.5</property>
<property name="adjustment">1 0 10 0.10000000000000001 10 10</property>
<property name="climb_rate">0.05000000074505806</property>
<property name="digits">2</property>
<property name="snap_to_ticks">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_autoseed">
<property name="visible">True</property>
<property name="label" translatable="yes">Stop seeding torrents when
their share ratio reaches:</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label21">
<property name="visible">True</property>
<property name="label" translatable="yes">Seeding</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkExpander" id="expander3">
<property name="visible">True</property>
<property name="expanded">True</property>
<child>
<widget class="GtkCheckButton" id="chk_compact">
<property name="visible">True</property>
<property name="label" translatable="yes">Use compact storage allocation</property>
<property name="draw_indicator">True</property>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="label" translatable="yes">Storage</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label13">
<property name="visible">True</property>
<property name="label" translatable="yes">General</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="net_options">
<property name="visible">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkViewport" id="viewport3">
<property name="visible">True</property>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<child>
<widget class="GtkExpander" id="expander5">
<property name="visible">True</property>
<property name="expanded">True</property>
<child>
<widget class="GtkTable" id="table6">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">4</property>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkLabel" id="label25">
<property name="visible">True</property>
<property name="label" translatable="yes">Try from:</property>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label26">
<property name="visible">True</property>
<property name="label" translatable="yes">to:</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_port_min">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0.5</property>
<property name="adjustment">0 0 65535 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_port_max">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0.5</property>
<property name="adjustment">0 0 65535 1 10 10</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label27">
<property name="visible">True</property>
<property name="label" translatable="yes">Active port:</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="active_port_label">
<property name="visible">True</property>
<property name="label" translatable="yes">0000</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="btn_test_port">
<property name="label" translatable="yes">Test Port</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label24">
<property name="visible">True</property>
<property name="label" translatable="yes">TCP Port</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkExpander" id="expander4">
<property name="visible">True</property>
<property name="expanded">True</property>
<child>
<widget class="GtkTable" id="table7">
<property name="visible">True</property>
<property name="n_rows">5</property>
<property name="n_columns">3</property>
<child>
<widget class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;i&gt;(-1 is unlimited)&lt;/i&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="right_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="label" translatable="yes">KB/s</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_max_download">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="width_chars">10</property>
<property name="xalign">1</property>
<property name="adjustment">0 -1 2048 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_num_upload">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="width_chars">10</property>
<property name="xalign">1</property>
<property name="adjustment">0 -1 100 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Maximum Download Rate:</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Upload Slots</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Maximum Connections</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_num_download">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="width_chars">10</property>
<property name="xalign">1</property>
<property name="adjustment">0 -1 100 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Maximum Upload Rate:</property>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_max_upload">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="width_chars">10</property>
<property name="xalign">1</property>
<property name="adjustment">0 -1 1024 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">KB/s</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="label" translatable="yes">Bandwidth </property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label17">
<property name="visible">True</property>
<property name="label" translatable="yes">Network</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="position">1</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button5">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="use_stock">True</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button4">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="plugin_dialog">
<property name="width_request">480</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Plugin Manager</property>
<property name="default_width">583</property>
<property name="default_height">431</property>
<property name="destroy_with_parent">True</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkNotebook" id="pref_notebook1">
<property name="visible">True</property>
<property name="show_tabs">False</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<child>
<widget class="GtkTreeView" id="plugin_view">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<child>
<widget class="GtkTextView" id="plugin_text">
<property name="visible">True</property>
<property name="editable">False</property>
<property name="wrap_mode">GTK_WRAP_WORD</property>
<property name="cursor_visible">False</property>
</widget>
<packing>
<property name="padding">10</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
<child>
<widget class="GtkButton" id="plugin_conf">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">gtk-preferences</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="plugin_pref"/>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">10</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label34">
<property name="visible">True</property>
<property name="label" translatable="yes">Plugins</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button10">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-close</property>
<property name="use_stock">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -1,100 +0,0 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkMenu" id="file_tab_menu">
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="select_all">
<property name="visible">True</property>
<property name="label" translatable="yes">Select All</property>
<property name="use_underline">True</property>
<signal name="activate" handler="select_all" last_modification_time="Mon, 11 Jun 2007 12:54:52 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image22">
<property name="visible">True</property>
<property name="stock">gtk-select-all</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="unselect_all">
<property name="visible">True</property>
<property name="label" translatable="yes">Unselect All</property>
<property name="use_underline">True</property>
<signal name="activate" handler="unselect_all" last_modification_time="Mon, 11 Jun 2007 13:16:59 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image23">
<property name="visible">True</property>
<property name="stock">gtk-file</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="check_selected">
<property name="visible">True</property>
<property name="label" translatable="yes">Check Selected</property>
<property name="use_underline">True</property>
<signal name="activate" handler="check_selected" last_modification_time="Mon, 11 Jun 2007 12:54:52 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image24">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="uncheck_selected">
<property name="visible">True</property>
<property name="label" translatable="yes">Uncheck Selected</property>
<property name="use_underline">True</property>
<signal name="activate" handler="uncheck_selected" last_modification_time="Mon, 11 Jun 2007 12:54:52 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image25">
<property name="visible">True</property>
<property name="stock">gtk-remove</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -1,114 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkDialog" id="plugin_dialog">
<property name="width_request">480</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Plugin Manager</property>
<property name="default_width">583</property>
<property name="default_height">431</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkNotebook" id="pref_notebook1">
<property name="visible">True</property>
<property name="show_tabs">False</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<child>
<widget class="GtkTreeView" id="plugin_view">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<child>
<widget class="GtkTextView" id="plugin_text">
<property name="visible">True</property>
<property name="editable">False</property>
<property name="wrap_mode">GTK_WRAP_WORD</property>
<property name="cursor_visible">False</property>
</widget>
<packing>
<property name="padding">10</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
<child>
<widget class="GtkButton" id="plugin_conf">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">gtk-preferences</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="plugin_pref"/>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">10</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label34">
<property name="visible">True</property>
<property name="label" translatable="yes">Plugins</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button10">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-close</property>
<property name="use_stock">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

File diff suppressed because it is too large Load Diff

View File

@ -4,23 +4,6 @@
<glade-interface>
<widget class="GtkMenu" id="torrent_menu">
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="menu_pause">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">StartPause</property>
<property name="use_underline">True</property>
<signal name="activate" handler="start_pause"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image9">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem5">
<property name="visible">True</property>
@ -38,86 +21,48 @@
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem2">
<widget class="GtkImageMenuItem" id="menuitem6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Queue</property>
<property name="label" translatable="yes">Queue Up</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu1">
<signal name="activate" handler="queue_up"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkImageMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Top</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image10">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-goto-top</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem6">
<property name="visible">True</property>
<property name="label" translatable="yes">Up</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_up"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-go-up</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem7">
<property name="visible">True</property>
<property name="label" translatable="yes">Down</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_down"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image7">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem8">
<property name="visible">True</property>
<property name="label" translatable="yes">Bottom</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_bottom"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image8">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-goto-bottom</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<property name="stock">gtk-go-up</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem7">
<property name="visible">True</property>
<property name="label" translatable="yes">Queue Down</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_down"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image11">
<widget class="GtkImage" id="menu-item-image7">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-sort-ascending</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem8">
<property name="visible">True</property>
<property name="label" translatable="yes">Queue to Bottom</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_bottom"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image8">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-goto-bottom</property>
<property name="icon_size">1</property>
</widget>
</child>

60
libtorrent/include/libtorrent/alert.hpp Executable file → Normal file
View File

@ -49,17 +49,15 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"
#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif
#define TORRENT_MAX_ALERT_TYPES 10
namespace libtorrent {
@ -72,9 +70,9 @@ namespace libtorrent {
virtual ~alert();
// a timestamp is automatically created in the constructor
ptime timestamp() const;
boost::posix_time::ptime timestamp() const;
std::string const& msg() const;
const std::string& msg() const;
severity_t severity() const;
@ -83,7 +81,7 @@ namespace libtorrent {
private:
std::string m_msg;
severity_t m_severity;
ptime m_timestamp;
boost::posix_time::ptime m_timestamp;
};
class TORRENT_EXPORT alert_manager
@ -114,45 +112,57 @@ namespace libtorrent {
struct void_;
template<class Handler
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
template<
class Handler
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)
>
void handle_alert_dispatch(
const std::auto_ptr<alert>& alert_, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
const std::auto_ptr<alert>& alert_
, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
{
if (typeid_ == typeid(T0))
handler(*static_cast<T0*>(alert_.get()));
else
handle_alert_dispatch(alert_, handler, typeid_
, BOOST_PP_ENUM_SHIFTED_PARAMS(
TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
handle_alert_dispatch(
alert_
, handler
, typeid_
, BOOST_PP_ENUM_SHIFTED_PARAMS(TORRENT_MAX_ALERT_TYPES, p), (void_*)0
);
}
template<class Handler>
void handle_alert_dispatch(
const std::auto_ptr<alert>& alert_
, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
const std::auto_ptr<alert>& alert_
, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
{
throw unhandled_alert();
}
} // namespace detail
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
template<
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(TORRENT_MAX_ALERT_TYPES, class T, detail::void_)
>
struct TORRENT_EXPORT handle_alert
{
template<class Handler>
handle_alert(const std::auto_ptr<alert>& alert_
, const Handler& handler)
handle_alert(
const std::auto_ptr<alert>& alert_
, const Handler& handler)
{
#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0
detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));
detail::handle_alert_dispatch(
alert_
, handler
, typeid(*alert_)
, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _)
);
#undef ALERT_POINTER_TYPE
}

152
libtorrent/include/libtorrent/alert_types.hpp Executable file → Normal file
View File

@ -41,24 +41,14 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
struct TORRENT_EXPORT torrent_alert: alert
{
torrent_alert(torrent_handle const& h, alert::severity_t s
, std::string const& msg)
: alert(s, msg)
, handle(h)
{}
torrent_handle handle;
};
struct TORRENT_EXPORT tracker_alert: torrent_alert
struct TORRENT_EXPORT tracker_alert: alert
{
tracker_alert(torrent_handle const& h
, int times
, int status
, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
, times_in_row(times)
, status_code(status)
{}
@ -66,75 +56,85 @@ namespace libtorrent
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_alert(*this)); }
torrent_handle handle;
int times_in_row;
int status_code;
};
struct TORRENT_EXPORT tracker_warning_alert: torrent_alert
struct TORRENT_EXPORT tracker_warning_alert: alert
{
tracker_warning_alert(torrent_handle const& h
, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_warning_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT tracker_reply_alert: torrent_alert
struct TORRENT_EXPORT tracker_reply_alert: alert
{
tracker_reply_alert(torrent_handle const& h
, int np
, std::string const& msg)
: torrent_alert(h, alert::info, msg)
, num_peers(np)
: alert(alert::info, msg)
, handle(h)
{}
int num_peers;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_reply_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT tracker_announce_alert: torrent_alert
struct TORRENT_EXPORT tracker_announce_alert: alert
{
tracker_announce_alert(torrent_handle const& h, std::string const& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_announce_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT hash_failed_alert: torrent_alert
struct TORRENT_EXPORT hash_failed_alert: alert
{
hash_failed_alert(
torrent_handle const& h
, int index
, std::string const& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
, piece_index(index)
{ assert(index >= 0);}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new hash_failed_alert(*this)); }
torrent_handle handle;
int piece_index;
};
struct TORRENT_EXPORT peer_ban_alert: torrent_alert
struct TORRENT_EXPORT peer_ban_alert: alert
{
peer_ban_alert(tcp::endpoint const& pip, torrent_handle h, std::string const& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, ip(pip)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new peer_ban_alert(*this)); }
tcp::endpoint ip;
torrent_handle handle;
};
struct TORRENT_EXPORT peer_error_alert: alert
@ -152,7 +152,25 @@ namespace libtorrent
peer_id pid;
};
struct TORRENT_EXPORT invalid_request_alert: torrent_alert
struct TORRENT_EXPORT chat_message_alert: alert
{
chat_message_alert(
const torrent_handle& h
, const tcp::endpoint& sender
, const std::string& msg)
: alert(alert::critical, msg)
, handle(h)
, ip(sender)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new chat_message_alert(*this)); }
torrent_handle handle;
tcp::endpoint ip;
};
struct TORRENT_EXPORT invalid_request_alert: alert
{
invalid_request_alert(
peer_request const& r
@ -160,7 +178,8 @@ namespace libtorrent
, tcp::endpoint const& sender
, peer_id const& pid_
, std::string const& msg)
: torrent_alert(h, alert::debug, msg)
: alert(alert::debug, msg)
, handle(h)
, ip(sender)
, request(r)
, pid(pid_)
@ -169,30 +188,33 @@ namespace libtorrent
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new invalid_request_alert(*this)); }
torrent_handle handle;
tcp::endpoint ip;
peer_request request;
peer_id pid;
};
struct TORRENT_EXPORT torrent_finished_alert: torrent_alert
struct TORRENT_EXPORT torrent_finished_alert: alert
{
torrent_finished_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new torrent_finished_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT url_seed_alert: torrent_alert
struct TORRENT_EXPORT url_seed_alert: alert
{
url_seed_alert(
torrent_handle const& h
, const std::string& url_
const std::string& url_
, const std::string& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, url(url_)
{}
@ -202,40 +224,49 @@ namespace libtorrent
std::string url;
};
struct TORRENT_EXPORT file_error_alert: torrent_alert
struct TORRENT_EXPORT file_error_alert: alert
{
file_error_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::fatal, msg)
: alert(alert::fatal, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new file_error_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT metadata_failed_alert: torrent_alert
struct TORRENT_EXPORT metadata_failed_alert: alert
{
metadata_failed_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new metadata_failed_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT metadata_received_alert: torrent_alert
struct TORRENT_EXPORT metadata_received_alert: alert
{
metadata_received_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new metadata_received_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT listen_failed_alert: alert
@ -249,49 +280,18 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new listen_failed_alert(*this)); }
};
struct TORRENT_EXPORT portmap_error_alert: alert
{
portmap_error_alert(const std::string& msg)
: alert(alert::warning, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new portmap_error_alert(*this)); }
};
struct TORRENT_EXPORT portmap_alert: alert
{
portmap_alert(const std::string& msg)
: alert(alert::info, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new portmap_alert(*this)); }
};
struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert
struct TORRENT_EXPORT fastresume_rejected_alert: alert
{
fastresume_rejected_alert(torrent_handle const& h
, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new fastresume_rejected_alert(*this)); }
};
struct TORRENT_EXPORT peer_blocked_alert: alert
{
peer_blocked_alert(address const& ip_
, std::string const& msg)
: alert(alert::info, msg)
, ip(ip_)
{}
address ip;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new peer_blocked_alert(*this)); }
torrent_handle handle;
};
}

View File

@ -41,7 +41,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/resource_request.hpp"
#include "libtorrent/peer_id.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/session.hpp"
namespace libtorrent
{
@ -67,11 +66,6 @@ namespace libtorrent
, std::map<tcp::endpoint, peer_connection*>& connections
, resource_request peer_connection::* res);
// Used for global limits.
void allocate_resources(
int resources
, std::vector<session*>& _sessions
, resource_request session::* res);
}

View File

@ -2,7 +2,7 @@
// asio.hpp
// ~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -18,6 +18,7 @@
#include "asio/basic_datagram_socket.hpp"
#include "asio/basic_deadline_timer.hpp"
#include "asio/basic_io_object.hpp"
#include "asio/basic_resolver.hpp"
#include "asio/basic_socket_acceptor.hpp"
#include "asio/basic_socket_iostream.hpp"
#include "asio/basic_socket_streambuf.hpp"
@ -34,8 +35,8 @@
#include "asio/datagram_socket_service.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/deadline_timer.hpp"
#include "asio/error_handler.hpp"
#include "asio/error.hpp"
#include "asio/error_code.hpp"
#include "asio/handler_alloc_hook.hpp"
#include "asio/handler_invoke_hook.hpp"
#include "asio/io_service.hpp"
@ -43,29 +44,26 @@
#include "asio/ip/address_v4.hpp"
#include "asio/ip/address_v6.hpp"
#include "asio/ip/basic_endpoint.hpp"
#include "asio/ip/basic_resolver.hpp"
#include "asio/ip/basic_resolver_entry.hpp"
#include "asio/ip/basic_resolver_iterator.hpp"
#include "asio/ip/basic_resolver_query.hpp"
#include "asio/ip/host_name.hpp"
#include "asio/ip/multicast.hpp"
#include "asio/ip/resolver_query_base.hpp"
#include "asio/ip/resolver_service.hpp"
#include "asio/ip/tcp.hpp"
#include "asio/ip/udp.hpp"
#include "asio/ip/unicast.hpp"
#include "asio/ip/v6_only.hpp"
#include "asio/is_read_buffered.hpp"
#include "asio/is_write_buffered.hpp"
#include "asio/placeholders.hpp"
#include "asio/read.hpp"
#include "asio/read_until.hpp"
#include "asio/resolver_service.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_base.hpp"
#include "asio/strand.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/streambuf.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/thread.hpp"
#include "asio/time_traits.hpp"
#include "asio/write.hpp"

View File

@ -2,7 +2,7 @@
// basic_datagram_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -24,8 +24,7 @@
#include "asio/basic_socket.hpp"
#include "asio/datagram_socket_service.hpp"
#include "asio/error.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error_handler.hpp"
namespace asio {
@ -34,18 +33,21 @@ namespace asio {
* The basic_datagram_socket class template provides asynchronous and blocking
* datagram-oriented socket functionality.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* Async_Object, Error_Source.
*/
template <typename Protocol,
typename DatagramSocketService = datagram_socket_service<Protocol> >
typename Service = datagram_socket_service<Protocol> >
class basic_datagram_socket
: public basic_socket<Protocol, DatagramSocketService>
: public basic_socket<Protocol, Service>
{
public:
/// The native representation of a socket.
typedef typename DatagramSocketService::native_type native_type;
typedef typename Service::native_type native_type;
/// The protocol type.
typedef Protocol protocol_type;
@ -63,7 +65,7 @@ public:
* socket.
*/
explicit basic_datagram_socket(asio::io_service& io_service)
: basic_socket<Protocol, DatagramSocketService>(io_service)
: basic_socket<Protocol, Service>(io_service)
{
}
@ -77,11 +79,11 @@ public:
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_datagram_socket(asio::io_service& io_service,
const protocol_type& protocol)
: basic_socket<Protocol, DatagramSocketService>(io_service, protocol)
: basic_socket<Protocol, Service>(io_service, protocol)
{
}
@ -99,11 +101,11 @@ public:
* @param endpoint An endpoint on the local machine to which the datagram
* socket will be bound.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_datagram_socket(asio::io_service& io_service,
const endpoint_type& endpoint)
: basic_socket<Protocol, DatagramSocketService>(io_service, endpoint)
: basic_socket<Protocol, Service>(io_service, endpoint)
{
}
@ -120,12 +122,11 @@ public:
*
* @param native_socket The new underlying socket implementation.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_datagram_socket(asio::io_service& io_service,
const protocol_type& protocol, const native_type& native_socket)
: basic_socket<Protocol, DatagramSocketService>(
io_service, protocol, native_socket)
: basic_socket<Protocol, Service>(io_service, protocol, native_socket)
{
}
@ -139,25 +140,22 @@ public:
*
* @returns The number of bytes sent.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::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.
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code socket.send(asio::buffer(data, size)); @endcode
* See the @ref buffer documentation for information on sending multiple
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence>
std::size_t send(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t send(const Const_Buffers& buffers)
{
asio::error_code ec;
std::size_t s = this->service.send(this->implementation, buffers, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.send(this->implementation, buffers, 0, throw_error());
}
/// Send some data on a connected socket.
@ -172,20 +170,17 @@ public:
*
* @returns The number of bytes sent.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::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.
*/
template <typename ConstBufferSequence>
std::size_t send(const ConstBufferSequence& buffers,
template <typename Const_Buffers>
std::size_t send(const Const_Buffers& buffers,
socket_base::message_flags flags)
{
asio::error_code ec;
std::size_t s = this->service.send(
this->implementation, buffers, flags, ec);
asio::detail::throw_error(ec);
return s;
return this->service.send(this->implementation, buffers, flags,
throw_error());
}
/// Send some data on a connected socket.
@ -198,18 +193,24 @@ public:
*
* @param flags Flags specifying how the send call is to be made.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @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 <typename ConstBufferSequence>
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
template <typename Const_Buffers, typename Error_Handler>
std::size_t send(const Const_Buffers& buffers,
socket_base::message_flags flags, Error_Handler error_handler)
{
return this->service.send(this->implementation, buffers, flags, ec);
return this->service.send(this->implementation, buffers, flags,
error_handler);
}
/// Start an asynchronous send on a connected socket.
@ -227,8 +228,8 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* const asio::error& 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
@ -239,7 +240,7 @@ public:
* Use the async_send_to function to send data on an unconnected datagram
* socket.
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code
* socket.async_send(asio::buffer(data, size), handler);
@ -248,8 +249,8 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_send(const Const_Buffers& buffers, Handler handler)
{
this->service.async_send(this->implementation, buffers, 0, handler);
}
@ -271,8 +272,8 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* const asio::error& 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
@ -283,9 +284,9 @@ public:
* Use the async_send_to function to send data on an unconnected datagram
* socket.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_send(const Const_Buffers& buffers,
socket_base::message_flags flags, Handler handler)
{
this->service.async_send(this->implementation, buffers, flags, handler);
}
@ -302,9 +303,9 @@ public:
*
* @returns The number of bytes sent.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code
* asio::ip::udp::endpoint destination(
@ -315,15 +316,12 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence>
std::size_t send_to(const ConstBufferSequence& buffers,
template <typename Const_Buffers>
std::size_t send_to(const Const_Buffers& buffers,
const endpoint_type& destination)
{
asio::error_code ec;
std::size_t s = this->service.send_to(
this->implementation, buffers, destination, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.send_to(this->implementation, buffers, destination, 0,
throw_error());
}
/// Send a datagram to the specified endpoint.
@ -340,17 +338,14 @@ public:
*
* @returns The number of bytes sent.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
template <typename ConstBufferSequence>
std::size_t send_to(const ConstBufferSequence& buffers,
template <typename Const_Buffers>
std::size_t send_to(const Const_Buffers& buffers,
const endpoint_type& destination, socket_base::message_flags flags)
{
asio::error_code ec;
std::size_t s = this->service.send_to(
this->implementation, buffers, destination, flags, ec);
asio::detail::throw_error(ec);
return s;
return this->service.send_to(this->implementation, buffers, destination,
flags, throw_error());
}
/// Send a datagram to the specified endpoint.
@ -365,17 +360,22 @@ public:
*
* @param flags Flags specifying how the send call is to be made.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @returns The number of bytes sent.
*/
template <typename ConstBufferSequence>
std::size_t send_to(const ConstBufferSequence& buffers,
template <typename Const_Buffers, typename Error_Handler>
std::size_t send_to(const Const_Buffers& buffers,
const endpoint_type& destination, socket_base::message_flags flags,
asio::error_code& ec)
Error_Handler error_handler)
{
return this->service.send_to(this->implementation,
buffers, destination, flags, ec);
return this->service.send_to(this->implementation, buffers, destination,
flags, error_handler);
}
/// Start an asynchronous send.
@ -395,15 +395,15 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* const asio::error& 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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code
* asio::ip::udp::endpoint destination(
@ -415,9 +415,9 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_send_to(const Const_Buffers& buffers,
const endpoint_type& destination, Handler handler)
{
this->service.async_send_to(this->implementation, buffers, destination, 0,
handler);
@ -442,18 +442,18 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* const asio::error& 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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_send_to(const ConstBufferSequence& buffers,
template <typename Const_Buffers, typename Handler>
void async_send_to(const Const_Buffers& buffers,
const endpoint_type& destination, socket_base::message_flags flags,
WriteHandler handler)
Handler handler)
{
this->service.async_send_to(this->implementation, buffers, destination,
flags, handler);
@ -469,13 +469,13 @@ public:
*
* @returns The number of bytes received.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::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
* socket.
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code socket.receive(asio::buffer(data, size)); @endcode
@ -483,14 +483,11 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence>
std::size_t receive(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t receive(const Mutable_Buffers& buffers)
{
asio::error_code ec;
std::size_t s = this->service.receive(
this->implementation, buffers, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.receive(this->implementation, buffers, 0,
throw_error());
}
/// Receive some data on a connected socket.
@ -505,21 +502,18 @@ public:
*
* @returns The number of bytes received.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::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
* socket.
*/
template <typename MutableBufferSequence>
std::size_t receive(const MutableBufferSequence& buffers,
template <typename Mutable_Buffers>
std::size_t receive(const Mutable_Buffers& buffers,
socket_base::message_flags flags)
{
asio::error_code ec;
std::size_t s = this->service.receive(
this->implementation, buffers, flags, ec);
asio::detail::throw_error(ec);
return s;
return this->service.receive(this->implementation, buffers, flags,
throw_error());
}
/// Receive some data on a connected socket.
@ -532,7 +526,12 @@ public:
*
* @param flags Flags specifying how the receive call is to be made.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @returns The number of bytes received.
*
@ -540,11 +539,12 @@ public:
* the receive_from function to receive data on an unconnected datagram
* socket.
*/
template <typename MutableBufferSequence>
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t receive(const Mutable_Buffers& buffers,
socket_base::message_flags flags, Error_Handler error_handler)
{
return this->service.receive(this->implementation, buffers, flags, ec);
return this->service.receive(this->implementation, buffers, flags,
error_handler);
}
/// Start an asynchronous receive on a connected socket.
@ -561,8 +561,8 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* const asio::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
@ -573,7 +573,7 @@ public:
* Use the async_receive_from function to receive data on an unconnected
* datagram socket.
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code
@ -583,8 +583,8 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_receive(const Mutable_Buffers& buffers, Handler handler)
{
this->service.async_receive(this->implementation, buffers, 0, handler);
}
@ -605,8 +605,8 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* const asio::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
@ -617,9 +617,9 @@ public:
* Use the async_receive_from function to receive data on an unconnected
* datagram socket.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_receive(const Mutable_Buffers& buffers,
socket_base::message_flags flags, Handler handler)
{
this->service.async_receive(this->implementation, buffers, flags, handler);
}
@ -636,9 +636,9 @@ public:
*
* @returns The number of bytes received.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code
@ -650,15 +650,12 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence>
std::size_t receive_from(const MutableBufferSequence& buffers,
template <typename Mutable_Buffers>
std::size_t receive_from(const Mutable_Buffers& buffers,
endpoint_type& sender_endpoint)
{
asio::error_code ec;
std::size_t s = this->service.receive_from(
this->implementation, buffers, sender_endpoint, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.receive_from(this->implementation, buffers,
sender_endpoint, 0, throw_error());
}
/// Receive a datagram with the endpoint of the sender.
@ -675,17 +672,14 @@ public:
*
* @returns The number of bytes received.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
template <typename MutableBufferSequence>
std::size_t receive_from(const MutableBufferSequence& buffers,
template <typename Mutable_Buffers>
std::size_t receive_from(const Mutable_Buffers& buffers,
endpoint_type& sender_endpoint, socket_base::message_flags flags)
{
asio::error_code ec;
std::size_t s = this->service.receive_from(
this->implementation, buffers, sender_endpoint, flags, ec);
asio::detail::throw_error(ec);
return s;
return this->service.receive_from(this->implementation, buffers,
sender_endpoint, flags, throw_error());
}
/// Receive a datagram with the endpoint of the sender.
@ -700,17 +694,22 @@ public:
*
* @param flags Flags specifying how the receive call is to be made.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @returns The number of bytes received.
*/
template <typename MutableBufferSequence>
std::size_t receive_from(const MutableBufferSequence& buffers,
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t receive_from(const Mutable_Buffers& buffers,
endpoint_type& sender_endpoint, socket_base::message_flags flags,
asio::error_code& ec)
Error_Handler error_handler)
{
return this->service.receive_from(this->implementation, buffers,
sender_endpoint, flags, ec);
sender_endpoint, flags, error_handler);
}
/// Start an asynchronous receive.
@ -732,15 +731,15 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::system_error& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* const asio::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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code socket.async_receive_from(
@ -749,9 +748,9 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_receive_from(const Mutable_Buffers& buffers,
endpoint_type& sender_endpoint, Handler handler)
{
this->service.async_receive_from(this->implementation, buffers,
sender_endpoint, 0, handler);
@ -778,18 +777,18 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* const asio::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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive_from(const MutableBufferSequence& buffers,
template <typename Mutable_Buffers, typename Handler>
void async_receive_from(const Mutable_Buffers& buffers,
endpoint_type& sender_endpoint, socket_base::message_flags flags,
ReadHandler handler)
Handler handler)
{
this->service.async_receive_from(this->implementation, buffers,
sender_endpoint, flags, handler);

View File

@ -2,7 +2,7 @@
// basic_deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -25,7 +25,6 @@
#include "asio/basic_io_object.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/error.hpp"
#include "asio/detail/throw_error.hpp"
namespace asio {
@ -36,13 +35,16 @@ namespace asio {
*
* Most applications will use the asio::deadline_timer typedef.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* Async_Object, Error_Source.
*
* @sa @ref deadline_timer_reset
*
* @par Examples
* @par Examples:
* Performing a blocking wait:
* @code
* // Construct a timer without setting an expiry time.
@ -58,7 +60,7 @@ namespace asio {
* @par
* Performing an asynchronous wait:
* @code
* void handler(const asio::error_code& error)
* void handler(const asio::error& error)
* {
* if (!error)
* {
@ -76,15 +78,18 @@ namespace asio {
* timer.async_wait(handler);
* @endcode
*/
template <typename Time,
typename TimeTraits = asio::time_traits<Time>,
typename TimerService = deadline_timer_service<Time, TimeTraits> >
template <typename Time_Type,
typename Time_Traits = asio::time_traits<Time_Type>,
typename Service = deadline_timer_service<Time_Type, Time_Traits> >
class basic_deadline_timer
: public basic_io_object<TimerService>
: public basic_io_object<Service>
{
public:
/// The type used for reporting errors.
typedef asio::error error_type;
/// The time traits type.
typedef TimeTraits traits_type;
typedef Time_Traits traits_type;
/// The time type.
typedef typename traits_type::time_type time_type;
@ -102,7 +107,7 @@ public:
* handlers for any asynchronous operations performed on the timer.
*/
explicit basic_deadline_timer(asio::io_service& io_service)
: basic_io_object<TimerService>(io_service)
: basic_io_object<Service>(io_service)
{
}
@ -118,11 +123,9 @@ public:
*/
basic_deadline_timer(asio::io_service& io_service,
const time_type& expiry_time)
: basic_io_object<TimerService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.expires_at(this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
this->service.expires_at(this->implementation, expiry_time);
}
/// Constructor to set a particular expiry time relative to now.
@ -137,11 +140,9 @@ public:
*/
basic_deadline_timer(asio::io_service& io_service,
const duration_type& expiry_time)
: basic_io_object<TimerService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.expires_from_now(this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
this->service.expires_from_now(this->implementation, expiry_time);
}
/// Cancel any asynchronous operations that are waiting on the timer.
@ -153,32 +154,10 @@ public:
* Cancelling the timer does not change the expiry time.
*
* @return The number of asynchronous operations that were cancelled.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t cancel()
{
asio::error_code ec;
std::size_t s = this->service.cancel(this->implementation, ec);
asio::detail::throw_error(ec);
return s;
}
/// Cancel any asynchronous operations that are waiting on the timer.
/**
* This function forces the completion of any pending asynchronous wait
* operations against the timer. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* Cancelling the timer does not change the expiry time.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t cancel(asio::error_code& ec)
{
return this->service.cancel(this->implementation, ec);
return this->service.cancel(this->implementation);
}
/// Get the timer's expiry time as an absolute time.
@ -203,37 +182,10 @@ public:
* @param expiry_time The expiry time to be used for the timer.
*
* @return The number of asynchronous operations that were cancelled.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t expires_at(const time_type& expiry_time)
{
asio::error_code ec;
std::size_t s = this->service.expires_at(
this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
return s;
}
/// Set the timer's expiry time as an absolute time.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* See @ref deadline_timer_reset for more information on altering the expiry
* time of an active timer.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t expires_at(const time_type& expiry_time,
asio::error_code& ec)
{
return this->service.expires_at(this->implementation, expiry_time, ec);
return this->service.expires_at(this->implementation, expiry_time);
}
/// Get the timer's expiry time relative to now.
@ -258,38 +210,10 @@ public:
* @param expiry_time The expiry time to be used for the timer.
*
* @return The number of asynchronous operations that were cancelled.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t expires_from_now(const duration_type& expiry_time)
{
asio::error_code ec;
std::size_t s = this->service.expires_from_now(
this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
return s;
}
/// Set the timer's expiry time relative to now.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* See @ref deadline_timer_reset for more information on altering the expiry
* time of an active timer.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t expires_from_now(const duration_type& expiry_time,
asio::error_code& ec)
{
return this->service.expires_from_now(
this->implementation, expiry_time, ec);
return this->service.expires_from_now(this->implementation, expiry_time);
}
/// Perform a blocking wait on the timer.
@ -297,25 +221,11 @@ 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 asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void wait()
{
asio::error_code ec;
this->service.wait(this->implementation, ec);
asio::detail::throw_error(ec);
}
/// Perform a blocking wait on the timer.
/**
* This function is used to wait for the timer to expire. This function
* blocks and does not return until the timer has expired.
*
* @param ec Set to indicate what error occurred, if any.
*/
void wait(asio::error_code& ec)
{
this->service.wait(this->implementation, ec);
this->service.wait(this->implementation);
}
/// Start an asynchronous wait on the timer.
@ -335,15 +245,15 @@ public:
* will be made of the handler as required. The function signature of the
* handler must be:
* @code void handler(
* const asio::error_code& error // Result of operation.
* const asio::error& 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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*/
template <typename WaitHandler>
void async_wait(WaitHandler handler)
template <typename Handler>
void async_wait(Handler handler)
{
this->service.async_wait(this->implementation, handler);
}
@ -371,7 +281,7 @@ public:
* }
* }
*
* void on_timeout(const asio::error_code& e)
* void on_timeout(const asio::error& e)
* {
* if (e != asio::error::operation_aborted)
* {
@ -386,8 +296,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 asio::error_code passed to
* it contains the value asio::error::operation_aborted.
* @li If a wait handler is cancelled, the asio::error passed to it
* contains the value asio::error::operation_aborted.
*
* @sa asio::basic_deadline_timer
*/

View File

@ -2,7 +2,7 @@
// basic_io_object.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -23,13 +23,13 @@
namespace asio {
/// Base class for all I/O objects.
template <typename IoObjectService>
template <typename Service>
class basic_io_object
: private noncopyable
{
public:
/// The type of the service that will be used to provide I/O operations.
typedef IoObjectService service_type;
typedef Service service_type;
/// The underlying implementation type of I/O object.
typedef typename service_type::implementation_type implementation_type;
@ -50,7 +50,7 @@ public:
protected:
/// Construct a basic_io_object.
explicit basic_io_object(asio::io_service& io_service)
: service(asio::use_service<IoObjectService>(io_service))
: service(asio::use_service<Service>(io_service))
{
service.construct(implementation);
}

View File

@ -2,7 +2,7 @@
// basic_socket.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -19,8 +19,8 @@
#include "asio/basic_io_object.hpp"
#include "asio/error.hpp"
#include "asio/error_handler.hpp"
#include "asio/socket_base.hpp"
#include "asio/detail/throw_error.hpp"
namespace asio {
@ -29,18 +29,21 @@ namespace asio {
* The basic_socket class template provides functionality that is common to both
* stream-oriented and datagram-oriented sockets.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* Error_Source, IO_Object.
*/
template <typename Protocol, typename SocketService>
template <typename Protocol, typename Service>
class basic_socket
: public basic_io_object<SocketService>,
: public basic_io_object<Service>,
public socket_base
{
public:
/// The native representation of a socket.
typedef typename SocketService::native_type native_type;
typedef typename Service::native_type native_type;
/// The protocol type.
typedef Protocol protocol_type;
@ -48,8 +51,11 @@ public:
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
/// The type used for reporting errors.
typedef asio::error error_type;
/// A basic_socket is always the lowest layer.
typedef basic_socket<Protocol, SocketService> lowest_layer_type;
typedef basic_socket<Protocol, Service> lowest_layer_type;
/// Construct a basic_socket without opening it.
/**
@ -59,7 +65,7 @@ public:
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_socket(asio::io_service& io_service)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
}
@ -72,15 +78,13 @@ public:
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket(asio::io_service& io_service,
const protocol_type& protocol)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.open(this->implementation, protocol, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, protocol, throw_error());
}
/// Construct a basic_socket, opening it and binding it to the given local
@ -96,17 +100,15 @@ public:
* @param endpoint An endpoint on the local machine to which the socket will
* be bound.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket(asio::io_service& io_service,
const endpoint_type& endpoint)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.open(this->implementation, endpoint.protocol(), ec);
asio::detail::throw_error(ec);
this->service.bind(this->implementation, endpoint, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, endpoint.protocol(),
throw_error());
this->service.bind(this->implementation, endpoint, throw_error());
}
/// Construct a basic_socket on an existing native socket.
@ -120,15 +122,14 @@ public:
*
* @param native_socket A native socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket(asio::io_service& io_service,
const protocol_type& protocol, const native_type& native_socket)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.assign(this->implementation, protocol, native_socket, ec);
asio::detail::throw_error(ec);
this->service.assign(this->implementation, protocol, native_socket,
throw_error());
}
/// Get a reference to the lowest layer.
@ -151,9 +152,9 @@ public:
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* socket.open(asio::ip::tcp::v4());
@ -161,9 +162,7 @@ public:
*/
void open(const protocol_type& protocol = protocol_type())
{
asio::error_code ec;
this->service.open(this->implementation, protocol, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, protocol, throw_error());
}
/// Open the socket using the specified protocol.
@ -172,23 +171,28 @@ public:
*
* @param protocol An object specifying which protocol is to be used.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* asio::error_code ec;
* socket.open(asio::ip::tcp::v4(), ec);
* if (ec)
* asio::error error;
* socket.open(asio::ip::tcp::v4(), asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code open(const protocol_type& protocol,
asio::error_code& ec)
template <typename Error_Handler>
void open(const protocol_type& protocol, Error_Handler error_handler)
{
return this->service.open(this->implementation, protocol, ec);
this->service.open(this->implementation, protocol, error_handler);
}
/// Assign an existing native socket to the socket.
@ -199,13 +203,12 @@ public:
*
* @param native_socket A native socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void assign(const protocol_type& protocol, const native_type& native_socket)
{
asio::error_code ec;
this->service.assign(this->implementation, protocol, native_socket, ec);
asio::detail::throw_error(ec);
this->service.assign(this->implementation, protocol, native_socket,
throw_error());
}
/// Assign an existing native socket to the socket.
@ -216,19 +219,19 @@ public:
*
* @param native_socket A native socket.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*/
asio::error_code assign(const protocol_type& protocol,
const native_type& native_socket, asio::error_code& ec)
template <typename Error_Handler>
void assign(const protocol_type& protocol, const native_type& native_socket,
Error_Handler error_handler)
{
return this->service.assign(this->implementation,
protocol, native_socket, ec);
}
/// Determine whether the socket is open.
bool is_open() const
{
return this->service.is_open(this->implementation);
this->service.assign(this->implementation, protocol, native_socket,
error_handler);
}
/// Close the socket.
@ -237,13 +240,11 @@ public:
* or connect operations will be cancelled immediately, and will complete
* with the asio::error::operation_aborted error.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void close()
{
asio::error_code ec;
this->service.close(this->implementation, ec);
asio::detail::throw_error(ec);
this->service.close(this->implementation, throw_error());
}
/// Close the socket.
@ -252,23 +253,29 @@ public:
* or connect operations will be cancelled immediately, and will complete
* with the asio::error::operation_aborted error.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* socket.close(ec);
* if (ec)
* asio::error error;
* socket.close(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code close(asio::error_code& ec)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return this->service.close(this->implementation, ec);
this->service.close(this->implementation, error_handler);
}
/// Get the native socket representation.
@ -288,13 +295,11 @@ public:
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void cancel()
{
asio::error_code ec;
this->service.cancel(this->implementation, ec);
asio::detail::throw_error(ec);
this->service.cancel(this->implementation, throw_error());
}
/// Cancel all asynchronous operations associated with the socket.
@ -303,77 +308,17 @@ public:
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*/
asio::error_code cancel(asio::error_code& ec)
template <typename Error_Handler>
void cancel(Error_Handler error_handler)
{
return this->service.cancel(this->implementation, ec);
}
/// Determine whether the socket is at the out-of-band data mark.
/**
* This function is used to check whether the socket input is currently
* positioned at the out-of-band data mark.
*
* @return A bool indicating whether the socket is at the out-of-band data
* mark.
*
* @throws asio::system_error Thrown on failure.
*/
bool at_mark() const
{
asio::error_code ec;
bool b = this->service.at_mark(this->implementation, ec);
asio::detail::throw_error(ec);
return b;
}
/// Determine whether the socket is at the out-of-band data mark.
/**
* This function is used to check whether the socket input is currently
* positioned at the out-of-band data mark.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return A bool indicating whether the socket is at the out-of-band data
* mark.
*/
bool at_mark(asio::error_code& ec) const
{
return this->service.at_mark(this->implementation, ec);
}
/// Determine the number of bytes available for reading.
/**
* This function is used to determine the number of bytes that may be read
* without blocking.
*
* @return The number of bytes that may be read without blocking, or 0 if an
* error occurs.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t available() const
{
asio::error_code ec;
std::size_t s = this->service.available(this->implementation, ec);
asio::detail::throw_error(ec);
return s;
}
/// Determine the number of bytes available for reading.
/**
* This function is used to determine the number of bytes that may be read
* without blocking.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of bytes that may be read without blocking, or 0 if an
* error occurs.
*/
std::size_t available(asio::error_code& ec) const
{
return this->service.available(this->implementation, ec);
this->service.cancel(this->implementation, error_handler);
}
/// Bind the socket to the given local endpoint.
@ -384,9 +329,9 @@ public:
* @param endpoint An endpoint on the local machine to which the socket will
* be bound.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* socket.open(asio::ip::tcp::v4());
@ -396,9 +341,7 @@ public:
*/
void bind(const endpoint_type& endpoint)
{
asio::error_code ec;
this->service.bind(this->implementation, endpoint, ec);
asio::detail::throw_error(ec);
this->service.bind(this->implementation, endpoint, throw_error());
}
/// Bind the socket to the given local endpoint.
@ -409,25 +352,31 @@ public:
* @param endpoint An endpoint on the local machine to which the socket will
* be bound.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* socket.open(asio::ip::tcp::v4());
* asio::error_code ec;
* asio::error error;
* socket.bind(asio::ip::tcp::endpoint(
* asio::ip::tcp::v4(), 12345), ec);
* if (ec)
* asio::ip::tcp::v4(), 12345),
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code bind(const endpoint_type& endpoint,
asio::error_code& ec)
template <typename Error_Handler>
void bind(const endpoint_type& endpoint, Error_Handler error_handler)
{
return this->service.bind(this->implementation, endpoint, ec);
this->service.bind(this->implementation, endpoint, error_handler);
}
/// Connect the socket to the specified endpoint.
@ -443,9 +392,9 @@ public:
* @param peer_endpoint The remote endpoint to which the socket will be
* connected.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* asio::ip::tcp::endpoint endpoint(
@ -455,14 +404,7 @@ public:
*/
void connect(const endpoint_type& peer_endpoint)
{
asio::error_code ec;
if (!is_open())
{
this->service.open(this->implementation, peer_endpoint.protocol(), ec);
asio::detail::throw_error(ec);
}
this->service.connect(this->implementation, peer_endpoint, ec);
asio::detail::throw_error(ec);
this->service.connect(this->implementation, peer_endpoint, throw_error());
}
/// Connect the socket to the specified endpoint.
@ -478,34 +420,30 @@ public:
* @param peer_endpoint The remote endpoint to which the socket will be
* connected.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* asio::ip::tcp::endpoint endpoint(
* asio::ip::address::from_string("1.2.3.4"), 12345);
* asio::error_code ec;
* socket.connect(endpoint, ec);
* if (ec)
* asio::error error;
* socket.connect(endpoint, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code connect(const endpoint_type& peer_endpoint,
asio::error_code& ec)
template <typename Error_Handler>
void connect(const endpoint_type& peer_endpoint, Error_Handler error_handler)
{
if (!is_open())
{
if (this->service.open(this->implementation,
peer_endpoint.protocol(), ec))
{
return ec;
}
}
return this->service.connect(this->implementation, peer_endpoint, ec);
this->service.connect(this->implementation, peer_endpoint, error_handler);
}
/// Start an asynchronous connect.
@ -524,16 +462,16 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error // Result of operation
* const asio::error& 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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*
* @par Example
* @par Example:
* @code
* void connect_handler(const asio::error_code& error)
* void connect_handler(const asio::error& error)
* {
* if (!error)
* {
@ -549,20 +487,9 @@ public:
* socket.async_connect(endpoint, connect_handler);
* @endcode
*/
template <typename ConnectHandler>
void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler)
template <typename Handler>
void async_connect(const endpoint_type& peer_endpoint, Handler handler)
{
if (!is_open())
{
asio::error_code ec;
if (this->service.open(this->implementation,
peer_endpoint.protocol(), ec))
{
this->io_service().post(asio::detail::bind_handler(handler, ec));
return;
}
}
this->service.async_connect(this->implementation, peer_endpoint, handler);
}
@ -572,9 +499,9 @@ public:
*
* @param option The new option value to be set on the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa SettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -591,7 +518,7 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -600,12 +527,10 @@ public:
* socket.set_option(option);
* @endcode
*/
template <typename SettableSocketOption>
void set_option(const SettableSocketOption& option)
template <typename Socket_Option>
void set_option(const Socket_Option& option)
{
asio::error_code ec;
this->service.set_option(this->implementation, option, ec);
asio::detail::throw_error(ec);
this->service.set_option(this->implementation, option, throw_error());
}
/// Set an option on the socket.
@ -614,9 +539,14 @@ public:
*
* @param option The new option value to be set on the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @sa SettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -633,25 +563,24 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::ip::tcp::no_delay option(true);
* asio::error_code ec;
* socket.set_option(option, ec);
* if (ec)
* asio::error error;
* socket.set_option(option, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
template <typename SettableSocketOption>
asio::error_code set_option(const SettableSocketOption& option,
asio::error_code& ec)
template <typename Socket_Option, typename Error_Handler>
void set_option(const Socket_Option& option, Error_Handler error_handler)
{
return this->service.set_option(this->implementation, option, ec);
this->service.set_option(this->implementation, option, error_handler);
}
/// Get an option from the socket.
@ -660,9 +589,9 @@ public:
*
* @param option The option value to be obtained from the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa GettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -679,7 +608,7 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -689,12 +618,10 @@ public:
* bool is_set = option.get();
* @endcode
*/
template <typename GettableSocketOption>
void get_option(GettableSocketOption& option) const
template <typename Socket_Option>
void get_option(Socket_Option& option) const
{
asio::error_code ec;
this->service.get_option(this->implementation, option, ec);
asio::detail::throw_error(ec);
this->service.get_option(this->implementation, option, throw_error());
}
/// Get an option from the socket.
@ -703,9 +630,14 @@ public:
*
* @param option The option value to be obtained from the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @sa GettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -722,26 +654,25 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::ip::tcp::socket::keep_alive option;
* asio::error_code ec;
* socket.get_option(option, ec);
* if (ec)
* asio::error error;
* socket.get_option(option, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* bool is_set = option.get();
* @endcode
*/
template <typename GettableSocketOption>
asio::error_code get_option(GettableSocketOption& option,
asio::error_code& ec) const
template <typename Socket_Option, typename Error_Handler>
void get_option(Socket_Option& option, Error_Handler error_handler) const
{
return this->service.get_option(this->implementation, option, ec);
this->service.get_option(this->implementation, option, error_handler);
}
/// Perform an IO control command on the socket.
@ -750,13 +681,13 @@ public:
*
* @param command The IO control command to be performed on the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa IoControlCommand @n
* @sa IO_Control_Command @n
* asio::socket_base::bytes_readable @n
* asio::socket_base::non_blocking_io
*
* @par Example
* @par Example:
* Getting the number of bytes ready to read:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -766,12 +697,10 @@ public:
* std::size_t bytes_readable = command.get();
* @endcode
*/
template <typename IoControlCommand>
void io_control(IoControlCommand& command)
template <typename IO_Control_Command>
void io_control(IO_Control_Command& command)
{
asio::error_code ec;
this->service.io_control(this->implementation, command, ec);
asio::detail::throw_error(ec);
this->service.io_control(this->implementation, command, throw_error());
}
/// Perform an IO control command on the socket.
@ -780,32 +709,36 @@ public:
*
* @param command The IO control command to be performed on the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @sa IoControlCommand @n
* @sa IO_Control_Command @n
* asio::socket_base::bytes_readable @n
* asio::socket_base::non_blocking_io
*
* @par Example
* @par Example:
* Getting the number of bytes ready to read:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::ip::tcp::socket::bytes_readable command;
* asio::error_code ec;
* socket.io_control(command, ec);
* if (ec)
* asio::error error;
* socket.io_control(command, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* std::size_t bytes_readable = command.get();
* @endcode
*/
template <typename IoControlCommand>
asio::error_code io_control(IoControlCommand& command,
asio::error_code& ec)
template <typename IO_Control_Command, typename Error_Handler>
void io_control(IO_Control_Command& command, Error_Handler error_handler)
{
return this->service.io_control(this->implementation, command, ec);
this->service.io_control(this->implementation, command, error_handler);
}
/// Get the local endpoint of the socket.
@ -814,9 +747,9 @@ public:
*
* @returns An object that represents the local endpoint of the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
@ -825,36 +758,41 @@ public:
*/
endpoint_type local_endpoint() const
{
asio::error_code ec;
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
asio::detail::throw_error(ec);
return ep;
return this->service.local_endpoint(this->implementation, throw_error());
}
/// Get the local endpoint of the socket.
/**
* This function is used to obtain the locally bound endpoint of the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @returns An object that represents the local endpoint of the socket.
* Returns a default-constructed endpoint object if an error occurred.
* Returns a default-constructed endpoint object if an error occurred and the
* error handler did not throw an exception.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
* if (ec)
* asio::error error;
* asio::ip::tcp::endpoint endpoint
* = socket.local_endpoint(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
endpoint_type local_endpoint(asio::error_code& ec) const
template <typename Error_Handler>
endpoint_type local_endpoint(Error_Handler error_handler) const
{
return this->service.local_endpoint(this->implementation, ec);
return this->service.local_endpoint(this->implementation, error_handler);
}
/// Get the remote endpoint of the socket.
@ -863,9 +801,9 @@ public:
*
* @returns An object that represents the remote endpoint of the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
@ -874,36 +812,41 @@ public:
*/
endpoint_type remote_endpoint() const
{
asio::error_code ec;
endpoint_type ep = this->service.remote_endpoint(this->implementation, ec);
asio::detail::throw_error(ec);
return ep;
return this->service.remote_endpoint(this->implementation, throw_error());
}
/// Get the remote endpoint of the socket.
/**
* This function is used to obtain the remote endpoint of the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @returns An object that represents the remote endpoint of the socket.
* Returns a default-constructed endpoint object if an error occurred.
* Returns a default-constructed endpoint object if an error occurred and the
* error handler did not throw an exception.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
* if (ec)
* asio::error error;
* asio::ip::tcp::endpoint endpoint
* = socket.remote_endpoint(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
endpoint_type remote_endpoint(asio::error_code& ec) const
template <typename Error_Handler>
endpoint_type remote_endpoint(Error_Handler error_handler) const
{
return this->service.remote_endpoint(this->implementation, ec);
return this->service.remote_endpoint(this->implementation, error_handler);
}
/// Disable sends or receives on the socket.
@ -913,9 +856,9 @@ public:
*
* @param what Determines what types of operation will no longer be allowed.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* Shutting down the send side of the socket:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -925,9 +868,7 @@ public:
*/
void shutdown(shutdown_type what)
{
asio::error_code ec;
this->service.shutdown(this->implementation, what, ec);
asio::detail::throw_error(ec);
this->service.shutdown(this->implementation, what, throw_error());
}
/// Disable sends or receives on the socket.
@ -937,25 +878,31 @@ public:
*
* @param what Determines what types of operation will no longer be allowed.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* Shutting down the send side of the socket:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
* if (ec)
* asio::error error;
* socket.shutdown(asio::ip::tcp::socket::shutdown_send,
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code shutdown(shutdown_type what,
asio::error_code& ec)
template <typename Error_Handler>
void shutdown(shutdown_type what, Error_Handler error_handler)
{
return this->service.shutdown(this->implementation, what, ec);
this->service.shutdown(this->implementation, what, error_handler);
}
protected:

View File

@ -2,7 +2,7 @@
// basic_socket_acceptor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -20,9 +20,9 @@
#include "asio/basic_io_object.hpp"
#include "asio/basic_socket.hpp"
#include "asio/error.hpp"
#include "asio/error_handler.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_base.hpp"
#include "asio/detail/throw_error.hpp"
namespace asio {
@ -31,11 +31,14 @@ namespace asio {
* The basic_socket_acceptor class template is used for accepting new socket
* connections.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Example
* @par Concepts:
* Async_Object, Error_Source.
*
* @par Example:
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
@ -47,14 +50,14 @@ namespace asio {
* @endcode
*/
template <typename Protocol,
typename SocketAcceptorService = socket_acceptor_service<Protocol> >
typename Service = socket_acceptor_service<Protocol> >
class basic_socket_acceptor
: public basic_io_object<SocketAcceptorService>,
: public basic_io_object<Service>,
public socket_base
{
public:
/// The native representation of an acceptor.
typedef typename SocketAcceptorService::native_type native_type;
typedef typename Service::native_type native_type;
/// The protocol type.
typedef Protocol protocol_type;
@ -62,6 +65,9 @@ public:
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
/// The type used for reporting errors.
typedef asio::error error_type;
/// Construct an acceptor without opening it.
/**
* This constructor creates an acceptor without opening it to listen for new
@ -73,7 +79,7 @@ public:
* acceptor.
*/
explicit basic_socket_acceptor(asio::io_service& io_service)
: basic_io_object<SocketAcceptorService>(io_service)
: basic_io_object<Service>(io_service)
{
}
@ -87,15 +93,13 @@ public:
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket_acceptor(asio::io_service& io_service,
const protocol_type& protocol)
: basic_io_object<SocketAcceptorService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.open(this->implementation, protocol, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, protocol, throw_error());
}
/// Construct an acceptor opened on the given endpoint.
@ -113,7 +117,7 @@ public:
* @param reuse_addr Whether the constructor should set the socket option
* socket_base::reuse_address.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @note This constructor is equivalent to the following code:
* @code
@ -127,22 +131,18 @@ public:
*/
basic_socket_acceptor(asio::io_service& io_service,
const endpoint_type& endpoint, bool reuse_addr = true)
: basic_io_object<SocketAcceptorService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.open(this->implementation, endpoint.protocol(), ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, endpoint.protocol(),
throw_error());
if (reuse_addr)
{
this->service.set_option(this->implementation,
socket_base::reuse_address(true), ec);
asio::detail::throw_error(ec);
socket_base::reuse_address(true), throw_error());
}
this->service.bind(this->implementation, endpoint, ec);
asio::detail::throw_error(ec);
this->service.bind(this->implementation, endpoint, throw_error());
this->service.listen(this->implementation,
socket_base::max_connections, ec);
asio::detail::throw_error(ec);
socket_base::max_connections, throw_error());
}
/// Construct a basic_socket_acceptor on an existing native acceptor.
@ -158,15 +158,14 @@ public:
*
* @param native_acceptor A native acceptor.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket_acceptor(asio::io_service& io_service,
const protocol_type& protocol, const native_type& native_acceptor)
: basic_io_object<SocketAcceptorService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.assign(this->implementation, protocol, native_acceptor, ec);
asio::detail::throw_error(ec);
this->service.assign(this->implementation, protocol, native_acceptor,
throw_error());
}
/// Open the acceptor using the specified protocol.
@ -176,9 +175,7 @@ public:
*
* @param protocol An object specifying which protocol is to be used.
*
* @throws asio::system_error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* acceptor.open(asio::ip::tcp::v4());
@ -186,9 +183,7 @@ public:
*/
void open(const protocol_type& protocol = protocol_type())
{
asio::error_code ec;
this->service.open(this->implementation, protocol, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, protocol, throw_error());
}
/// Open the acceptor using the specified protocol.
@ -198,23 +193,29 @@ public:
*
* @param protocol An object specifying which protocol is to be used.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* asio::error_code ec;
* acceptor.open(asio::ip::tcp::v4(), ec);
* if (ec)
* asio::error error;
* acceptor.open(asio::ip::tcp::v4(),
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code open(const protocol_type& protocol,
asio::error_code& ec)
template <typename Error_Handler>
void open(const protocol_type& protocol, Error_Handler error_handler)
{
return this->service.open(this->implementation, protocol, ec);
this->service.open(this->implementation, protocol, error_handler);
}
/// Assigns an existing native acceptor to the acceptor.
@ -225,13 +226,12 @@ public:
*
* @param native_acceptor A native acceptor.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void assign(const protocol_type& protocol, const native_type& native_acceptor)
{
asio::error_code ec;
this->service.assign(this->implementation, protocol, native_acceptor, ec);
asio::detail::throw_error(ec);
this->service.assign(this->implementation, protocol, native_acceptor,
throw_error());
}
/// Assigns an existing native acceptor to the acceptor.
@ -242,19 +242,19 @@ public:
*
* @param native_acceptor A native acceptor.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*/
asio::error_code assign(const protocol_type& protocol,
const native_type& native_acceptor, asio::error_code& ec)
template <typename Error_Handler>
void assign(const protocol_type& protocol, const native_type& native_acceptor,
Error_Handler error_handler)
{
return this->service.assign(this->implementation,
protocol, native_acceptor, ec);
}
/// Determine whether the acceptor is open.
bool is_open() const
{
return this->service.is_open(this->implementation);
this->service.assign(this->implementation, protocol, native_acceptor,
error_handler);
}
/// Bind the acceptor to the given local endpoint.
@ -265,9 +265,9 @@ public:
* @param endpoint An endpoint on the local machine to which the socket
* acceptor will be bound.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* acceptor.open(asio::ip::tcp::v4());
@ -276,9 +276,7 @@ public:
*/
void bind(const endpoint_type& endpoint)
{
asio::error_code ec;
this->service.bind(this->implementation, endpoint, ec);
asio::detail::throw_error(ec);
this->service.bind(this->implementation, endpoint, throw_error());
}
/// Bind the acceptor to the given local endpoint.
@ -289,24 +287,30 @@ public:
* @param endpoint An endpoint on the local machine to which the socket
* acceptor will be bound.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* acceptor.open(asio::ip::tcp::v4());
* asio::error_code ec;
* acceptor.bind(asio::ip::tcp::endpoint(12345), ec);
* if (ec)
* asio::error error;
* acceptor.bind(asio::ip::tcp::endpoint(12345),
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code bind(const endpoint_type& endpoint,
asio::error_code& ec)
template <typename Error_Handler>
void bind(const endpoint_type& endpoint, Error_Handler error_handler)
{
return this->service.bind(this->implementation, endpoint, ec);
this->service.bind(this->implementation, endpoint, error_handler);
}
/// Place the acceptor into the state where it will listen for new
@ -316,14 +320,10 @@ public:
* new connections.
*
* @param backlog The maximum length of the queue of pending connections.
*
* @throws asio::system_error Thrown on failure.
*/
void listen(int backlog = socket_base::max_connections)
{
asio::error_code ec;
this->service.listen(this->implementation, backlog, ec);
asio::detail::throw_error(ec);
this->service.listen(this->implementation, backlog, throw_error());
}
/// Place the acceptor into the state where it will listen for new
@ -334,23 +334,30 @@ public:
*
* @param backlog The maximum length of the queue of pending connections.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::error_code ec;
* acceptor.listen(asio::socket_base::max_connections, ec);
* if (ec)
* asio::error error;
* acceptor.listen(asio::socket_base::max_connections,
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code listen(int backlog, asio::error_code& ec)
template <typename Error_Handler>
void listen(int backlog, Error_Handler error_handler)
{
return this->service.listen(this->implementation, backlog, ec);
this->service.listen(this->implementation, backlog, error_handler);
}
/// Close the acceptor.
@ -361,13 +368,11 @@ public:
* A subsequent call to open() is required before the acceptor can again be
* used to again perform socket accept operations.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void close()
{
asio::error_code ec;
this->service.close(this->implementation, ec);
asio::detail::throw_error(ec);
this->service.close(this->implementation, throw_error());
}
/// Close the acceptor.
@ -378,23 +383,29 @@ public:
* A subsequent call to open() is required before the acceptor can again be
* used to again perform socket accept operations.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::error_code ec;
* acceptor.close(ec);
* if (ec)
* asio::error error;
* acceptor.close(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code close(asio::error_code& ec)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return this->service.close(this->implementation, ec);
this->service.close(this->implementation, error_handler);
}
/// Get the native acceptor representation.
@ -414,13 +425,11 @@ public:
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void cancel()
{
asio::error_code ec;
this->service.cancel(this->implementation, ec);
asio::detail::throw_error(ec);
this->service.cancel(this->implementation, throw_error());
}
/// Cancel all asynchronous operations associated with the acceptor.
@ -429,11 +438,17 @@ public:
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*/
asio::error_code cancel(asio::error_code& ec)
template <typename Error_Handler>
void cancel(Error_Handler error_handler)
{
return this->service.cancel(this->implementation, ec);
this->service.cancel(this->implementation, error_handler);
}
/// Set an option on the acceptor.
@ -442,13 +457,13 @@ public:
*
* @param option The new option value to be set on the acceptor.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa SettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::reuse_address
* asio::socket_base::enable_connection_aborted
*
* @par Example
* @par Example:
* Setting the SOL_SOCKET/SO_REUSEADDR option:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
@ -457,12 +472,10 @@ public:
* acceptor.set_option(option);
* @endcode
*/
template <typename SettableSocketOption>
void set_option(const SettableSocketOption& option)
template <typename Option>
void set_option(const Option& option)
{
asio::error_code ec;
this->service.set_option(this->implementation, option, ec);
asio::detail::throw_error(ec);
this->service.set_option(this->implementation, option, throw_error());
}
/// Set an option on the acceptor.
@ -471,31 +484,35 @@ public:
*
* @param option The new option value to be set on the acceptor.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @sa SettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::reuse_address
* asio::socket_base::enable_connection_aborted
*
* @par Example
* @par Example:
* Setting the SOL_SOCKET/SO_REUSEADDR option:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::ip::tcp::acceptor::reuse_address option(true);
* asio::error_code ec;
* acceptor.set_option(option, ec);
* if (ec)
* asio::error error;
* acceptor.set_option(option, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
template <typename SettableSocketOption>
asio::error_code set_option(const SettableSocketOption& option,
asio::error_code& ec)
template <typename Option, typename Error_Handler>
void set_option(const Option& option, Error_Handler error_handler)
{
return this->service.set_option(this->implementation, option, ec);
this->service.set_option(this->implementation, option, error_handler);
}
/// Get an option from the acceptor.
@ -505,12 +522,12 @@ public:
*
* @param option The option value to be obtained from the acceptor.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa GettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::reuse_address
*
* @par Example
* @par Example:
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
@ -520,12 +537,10 @@ public:
* bool is_set = option.get();
* @endcode
*/
template <typename GettableSocketOption>
void get_option(GettableSocketOption& option)
template <typename Option>
void get_option(Option& option)
{
asio::error_code ec;
this->service.get_option(this->implementation, option, ec);
asio::detail::throw_error(ec);
this->service.get_option(this->implementation, option, throw_error());
}
/// Get an option from the acceptor.
@ -535,31 +550,35 @@ public:
*
* @param option The option value to be obtained from the acceptor.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @sa GettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::reuse_address
*
* @par Example
* @par Example:
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::ip::tcp::acceptor::reuse_address option;
* asio::error_code ec;
* acceptor.get_option(option, ec);
* if (ec)
* asio::error error;
* acceptor.get_option(option, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* bool is_set = option.get();
* @endcode
*/
template <typename GettableSocketOption>
asio::error_code get_option(GettableSocketOption& option,
asio::error_code& ec)
template <typename Option, typename Error_Handler>
void get_option(Option& option, Error_Handler error_handler)
{
return this->service.get_option(this->implementation, option, ec);
this->service.get_option(this->implementation, option, error_handler);
}
/// Get the local endpoint of the acceptor.
@ -568,9 +587,9 @@ public:
*
* @returns An object that represents the local endpoint of the acceptor.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
@ -579,37 +598,41 @@ public:
*/
endpoint_type local_endpoint() const
{
asio::error_code ec;
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
asio::detail::throw_error(ec);
return ep;
return this->service.local_endpoint(this->implementation, throw_error());
}
/// Get the local endpoint of the acceptor.
/**
* This function is used to obtain the locally bound endpoint of the acceptor.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @returns An object that represents the local endpoint of the acceptor.
* Returns a default-constructed endpoint object if an error occurred and the
* error handler did not throw an exception.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::error_code ec;
* asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
* if (ec)
* asio::error error;
* asio::ip::tcp::endpoint endpoint
* = acceptor.local_endpoint(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
endpoint_type local_endpoint(asio::error_code& ec) const
template <typename Error_Handler>
endpoint_type local_endpoint(Error_Handler error_handler) const
{
return this->service.local_endpoint(this->implementation, ec);
return this->service.local_endpoint(this->implementation, error_handler);
}
/// Accept a new connection.
@ -620,9 +643,9 @@ public:
*
* @param peer The socket into which the new connection will be accepted.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
@ -630,12 +653,10 @@ public:
* acceptor.accept(socket);
* @endcode
*/
template <typename SocketService>
void accept(basic_socket<protocol_type, SocketService>& peer)
template <typename Socket_Service>
void accept(basic_socket<protocol_type, Socket_Service>& peer)
{
asio::error_code ec;
this->service.accept(this->implementation, peer, 0, ec);
asio::detail::throw_error(ec);
this->service.accept(this->implementation, peer, throw_error());
}
/// Accept a new connection.
@ -646,27 +667,31 @@ public:
*
* @param peer The socket into which the new connection will be accepted.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::ip::tcp::soocket socket(io_service);
* asio::error_code ec;
* acceptor.accept(socket, ec);
* if (ec)
* asio::error error;
* acceptor.accept(socket, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
template <typename SocketService>
asio::error_code accept(
basic_socket<protocol_type, SocketService>& peer,
asio::error_code& ec)
template <typename Socket_Service, typename Error_Handler>
void accept(basic_socket<protocol_type, Socket_Service>& peer,
Error_Handler error_handler)
{
return this->service.accept(this->implementation, peer, 0, ec);
this->service.accept(this->implementation, peer, error_handler);
}
/// Start an asynchronous accept.
@ -682,16 +707,16 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error // Result of operation.
* const asio::error& 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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*
* @par Example
* @par Example:
* @code
* void accept_handler(const asio::error_code& error)
* void accept_handler(const asio::error& error)
* {
* if (!error)
* {
@ -707,11 +732,11 @@ public:
* acceptor.async_accept(socket, accept_handler);
* @endcode
*/
template <typename SocketService, typename AcceptHandler>
void async_accept(basic_socket<protocol_type, SocketService>& peer,
AcceptHandler handler)
template <typename Socket_Service, typename Handler>
void async_accept(basic_socket<protocol_type, Socket_Service>& peer,
Handler handler)
{
this->service.async_accept(this->implementation, peer, 0, handler);
this->service.async_accept(this->implementation, peer, handler);
}
/// Accept a new connection and obtain the endpoint of the peer
@ -726,24 +751,23 @@ public:
* @param peer_endpoint An endpoint object which will receive the endpoint of
* the remote peer.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::ip::tcp::socket socket(io_service);
* asio::ip::tcp::endpoint endpoint;
* acceptor.accept(socket, endpoint);
* acceptor.accept_endpoint(socket, endpoint);
* @endcode
*/
template <typename SocketService>
void accept(basic_socket<protocol_type, SocketService>& peer,
template <typename Socket_Service>
void accept_endpoint(basic_socket<protocol_type, Socket_Service>& peer,
endpoint_type& peer_endpoint)
{
asio::error_code ec;
this->service.accept(this->implementation, peer, &peer_endpoint, ec);
asio::detail::throw_error(ec);
this->service.accept_endpoint(this->implementation, peer, peer_endpoint,
throw_error());
}
/// Accept a new connection and obtain the endpoint of the peer
@ -758,28 +782,34 @@ public:
* @param peer_endpoint An endpoint object which will receive the endpoint of
* the remote peer.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::acceptor acceptor(io_service);
* ...
* asio::ip::tcp::socket socket(io_service);
* asio::ip::tcp::endpoint endpoint;
* asio::error_code ec;
* acceptor.accept(socket, endpoint, ec);
* if (ec)
* asio::error error;
* acceptor.accept_endpoint(socket, endpoint,
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
template <typename SocketService>
asio::error_code accept(
basic_socket<protocol_type, SocketService>& peer,
endpoint_type& peer_endpoint, asio::error_code& ec)
template <typename Socket_Service, typename Error_Handler>
void accept_endpoint(basic_socket<protocol_type, Socket_Service>& peer,
endpoint_type& peer_endpoint, Error_Handler error_handler)
{
return this->service.accept(this->implementation, peer, &peer_endpoint, ec);
this->service.accept_endpoint(this->implementation, peer, peer_endpoint,
error_handler);
}
/// Start an asynchronous accept.
@ -801,19 +831,19 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error // Result of operation.
* const asio::error& 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
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*/
template <typename SocketService, typename AcceptHandler>
void async_accept(basic_socket<protocol_type, SocketService>& peer,
endpoint_type& peer_endpoint, AcceptHandler handler)
template <typename Socket_Service, typename Handler>
void async_accept_endpoint(basic_socket<protocol_type, Socket_Service>& peer,
endpoint_type& peer_endpoint, Handler handler)
{
this->service.async_accept(this->implementation,
peer, &peer_endpoint, handler);
this->service.async_accept_endpoint(this->implementation, peer,
peer_endpoint, handler);
}
};

View File

@ -2,7 +2,7 @@
// basic_socket_iostream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -33,42 +33,74 @@
#endif // !defined(ASIO_SOCKET_IOSTREAM_MAX_ARITY)
// A macro that should expand to:
// template <typename T1, ..., typename Tn>
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
// template < typename T1, ..., typename Tn >
// explicit basic_socket_iostream( T1 x1, ..., Tn xn )
// : basic_iostream<char>(&this->boost::base_from_member<
// basic_socket_streambuf<Protocol, StreamSocketService> >::member)
// basic_socket_streambuf<Protocol, Service> >::member)
// {
// if (rdbuf()->connect(x1, ..., xn) == 0)
// try
// {
// rdbuf()->connect ( x1, ..., xn );
// }
// catch (asio::error&)
// {
// this->setstate(std::ios_base::failbit);
// if (this->exceptions() & std::ios_base::failbit)
// throw;
// }
// }
// This macro should only persist within this file.
#define ASIO_PRIVATE_CTR_DEF(z, n, data) \
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
explicit basic_socket_iostream(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
#define ASIO_PRIVATE_CTR_DEF( z, n, data ) \
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
explicit basic_socket_iostream( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
: std::basic_iostream<char>(&this->boost::base_from_member< \
basic_socket_streambuf<Protocol, StreamSocketService> >::member) \
basic_socket_streambuf<Protocol, Service> >::member) \
{ \
if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
try \
{ \
rdbuf()->connect( BOOST_PP_ENUM_PARAMS(n, x) ); \
} \
catch (asio::error&) \
{ \
this->setstate(std::ios_base::failbit); \
if (this->exceptions() & std::ios_base::failbit) \
throw; \
} \
} \
/**/
// A macro that should expand to:
// template <typename T1, ..., typename Tn>
// void connect(T1 x1, ..., Tn xn)
// template < typename T1, ..., typename Tn >
// void connect( T1 x1, ..., Tn xn )
// {
// if (rdbuf()->connect(x1, ..., xn) == 0)
// try
// {
// rdbuf()->connect ( x1, ..., xn );
// }
// catch (asio::error&)
// {
// this->setstate(std::ios_base::failbit);
// if (this->exceptions() & std::ios_base::failbit)
// throw;
// }
// }
// This macro should only persist within this file.
#define ASIO_PRIVATE_CONNECT_DEF(z, n, data) \
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
void connect(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
#define ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
void connect( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
{ \
if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
try \
{ \
rdbuf()->connect( BOOST_PP_ENUM_PARAMS(n, x) ); \
} \
catch (asio::error&) \
{ \
this->setstate(std::ios_base::failbit); \
if (this->exceptions() & std::ios_base::failbit) \
throw; \
} \
} \
/**/
@ -76,17 +108,16 @@ namespace asio {
/// Iostream interface for a socket.
template <typename Protocol,
typename StreamSocketService = stream_socket_service<Protocol> >
typename Service = stream_socket_service<Protocol> >
class basic_socket_iostream
: public boost::base_from_member<
basic_socket_streambuf<Protocol, StreamSocketService> >,
: public boost::base_from_member<basic_socket_streambuf<Protocol, Service> >,
public std::basic_iostream<char>
{
public:
/// Construct a basic_socket_iostream without establishing a connection.
basic_socket_iostream()
: std::basic_iostream<char>(&this->boost::base_from_member<
basic_socket_streambuf<Protocol, StreamSocketService> >::member)
basic_socket_streambuf<Protocol, Service> >::member)
{
}
@ -123,16 +154,15 @@ public:
/// Close the connection.
void close()
{
if (rdbuf()->close() == 0)
this->setstate(std::ios_base::failbit);
rdbuf()->close();
}
/// Return a pointer to the underlying streambuf.
basic_socket_streambuf<Protocol, StreamSocketService>* rdbuf() const
basic_socket_streambuf<Protocol, Service>* rdbuf() const
{
return const_cast<basic_socket_streambuf<Protocol, StreamSocketService>*>(
return const_cast<basic_socket_streambuf<Protocol, Service>*>(
&this->boost::base_from_member<
basic_socket_streambuf<Protocol, StreamSocketService> >::member);
basic_socket_streambuf<Protocol, Service> >::member);
}
};

View File

@ -2,7 +2,7 @@
// basic_socket_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -28,41 +28,61 @@
#include "asio/detail/pop_options.hpp"
#include "asio/basic_socket.hpp"
#include "asio/error_handler.hpp"
#include "asio/io_service.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/detail/throw_error.hpp"
#if !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
#define ASIO_SOCKET_STREAMBUF_MAX_ARITY 5
#endif // !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
// A macro that should expand to:
// template <typename T1, ..., typename Tn>
// basic_socket_streambuf<Protocol, StreamSocketService>* connect(
// T1 x1, ..., Tn xn)
// template < typename T1, ..., typename Tn >
// explicit basic_socket_streambuf( T1 x1, ..., Tn xn )
// : basic_socket<Protocol, Service>(
// boost::base_from_member<io_service>::member)
// {
// init_buffers();
// asio::error_code ec;
// this->basic_socket<Protocol, StreamSocketService>::close(ec);
// typedef typename Protocol::resolver_query resolver_query;
// resolver_query query(x1, ..., xn);
// resolve_and_connect(query, ec);
// return !ec ? this : 0;
// resolver_query query( x1, ..., xn );
// resolve_and_connect(query);
// }
// This macro should only persist within this file.
#define ASIO_PRIVATE_CTR_DEF( z, n, data ) \
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
explicit basic_socket_streambuf( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
: basic_socket<Protocol, Service>( \
boost::base_from_member<io_service>::member) \
{ \
init_buffers(); \
typedef typename Protocol::resolver_query resolver_query; \
resolver_query query( BOOST_PP_ENUM_PARAMS(n, x) ); \
resolve_and_connect(query); \
} \
/**/
// A macro that should expand to:
// template < typename T1, ..., typename Tn >
// void connect( T1 x1, ..., Tn xn )
// {
// this->basic_socket<Protocol, Service>::close();
// init_buffers();
// typedef typename Protocol::resolver_query resolver_query;
// resolver_query query( x1, ..., xn );
// resolve_and_connect(query);
// }
// This macro should only persist within this file.
#define ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
basic_socket_streambuf<Protocol, StreamSocketService>* connect( \
BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
void connect( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
{ \
this->basic_socket<Protocol, Service>::close(); \
init_buffers(); \
asio::error_code ec; \
this->basic_socket<Protocol, StreamSocketService>::close(ec); \
typedef typename Protocol::resolver_query resolver_query; \
resolver_query query(BOOST_PP_ENUM_PARAMS(n, x)); \
resolve_and_connect(query, ec); \
return !ec ? this : 0; \
resolver_query query( BOOST_PP_ENUM_PARAMS(n, x) ); \
resolve_and_connect(query); \
} \
/**/
@ -70,11 +90,11 @@ namespace asio {
/// Iostream streambuf for a socket.
template <typename Protocol,
typename StreamSocketService = stream_socket_service<Protocol> >
typename Service = stream_socket_service<Protocol> >
class basic_socket_streambuf
: public std::streambuf,
private boost::base_from_member<io_service>,
public basic_socket<Protocol, StreamSocketService>
public basic_socket<Protocol, Service>
{
public:
/// The endpoint type.
@ -82,50 +102,59 @@ public:
/// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf()
: basic_socket<Protocol, StreamSocketService>(
boost::base_from_member<asio::io_service>::member),
unbuffered_(false)
: basic_socket<Protocol, Service>(
boost::base_from_member<asio::io_service>::member)
{
init_buffers();
}
/// Destructor flushes buffered data.
virtual ~basic_socket_streambuf()
{
if (pptr() != pbase())
overflow(traits_type::eof());
}
/// Establish a connection.
/**
* This function establishes a connection to the specified endpoint.
*
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
basic_socket_streambuf<Protocol, StreamSocketService>* connect(
const endpoint_type& endpoint)
/// Establish a connection to the specified endpoint.
explicit basic_socket_streambuf(const endpoint_type& endpoint)
: basic_socket<Protocol, Service>(
boost::base_from_member<asio::io_service>::member)
{
init_buffers();
asio::error_code ec;
this->basic_socket<Protocol, StreamSocketService>::close(ec);
this->basic_socket<Protocol, StreamSocketService>::connect(endpoint, ec);
return !ec ? this : 0;
this->basic_socket<Protocol, Service>::connect(endpoint);
}
#if defined(GENERATING_DOCUMENTATION)
/// Establish a connection.
/// Establish a connection to an endpoint corresponding to a resolver query.
/**
* This constructor automatically establishes a connection based on the
* supplied resolver query parameters. The arguments are used to construct
* a resolver query object.
*/
template <typename T1, ..., typename TN>
explicit basic_socket_streambuf(T1 t1, ..., TN tn);
#else
BOOST_PP_REPEAT_FROM_TO(
1, BOOST_PP_INC(ASIO_SOCKET_STREAMBUF_MAX_ARITY),
ASIO_PRIVATE_CTR_DEF, _ )
#endif
/// Destructor flushes buffered data.
~basic_socket_streambuf()
{
sync();
}
/// Establish a connection to the specified endpoint.
void connect(const endpoint_type& endpoint)
{
this->basic_socket<Protocol, Service>::close();
init_buffers();
this->basic_socket<Protocol, Service>::connect(endpoint);
}
#if defined(GENERATING_DOCUMENTATION)
/// Establish a connection to an endpoint corresponding to a resolver query.
/**
* This function automatically establishes a connection based on the supplied
* resolver query parameters. The arguments are used to construct a resolver
* query object.
*
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
template <typename T1, ..., typename TN>
basic_socket_streambuf<Protocol, StreamSocketService>* connect(
T1 t1, ..., TN tn);
void connect(T1 t1, ..., TN tn);
#else
BOOST_PP_REPEAT_FROM_TO(
1, BOOST_PP_INC(ASIO_SOCKET_STREAMBUF_MAX_ARITY),
@ -133,18 +162,11 @@ public:
#endif
/// Close the connection.
/**
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
basic_socket_streambuf<Protocol, StreamSocketService>* close()
void close()
{
asio::error_code ec;
sync();
this->basic_socket<Protocol, StreamSocketService>::close(ec);
if (!ec)
init_buffers();
return !ec ? this : 0;
this->basic_socket<Protocol, Service>::close();
init_buffers();
}
protected:
@ -152,13 +174,17 @@ protected:
{
if (gptr() == egptr())
{
asio::error_code ec;
asio::error error;
std::size_t bytes_transferred = this->service.receive(
this->implementation,
asio::buffer(asio::buffer(get_buffer_) + putback_max),
0, ec);
if (ec)
0, asio::assign_error(error));
if (error)
{
if (error != asio::error::eof)
throw error;
return traits_type::eof();
}
setg(get_buffer_.begin(), get_buffer_.begin() + putback_max,
get_buffer_.begin() + putback_max + bytes_transferred);
return traits_type::to_int_type(*gptr());
@ -171,67 +197,42 @@ protected:
int_type overflow(int_type c)
{
if (unbuffered_)
if (!traits_type::eq_int_type(c, traits_type::eof()))
{
if (traits_type::eq_int_type(c, traits_type::eof()))
if (pptr() == epptr())
{
// Nothing to do.
return traits_type::not_eof(c);
asio::const_buffer buffer =
asio::buffer(pbase(), pptr() - pbase());
while (asio::buffer_size(buffer) > 0)
{
std::size_t bytes_transferred = this->service.send(
this->implementation, asio::buffer(buffer),
0, asio::throw_error());
buffer = buffer + bytes_transferred;
}
setp(put_buffer_.begin(), put_buffer_.end());
}
else
{
// Send the single character immediately.
asio::error_code ec;
char_type ch = traits_type::to_char_type(c);
this->service.send(this->implementation,
asio::buffer(&ch, sizeof(char_type)), 0, ec);
if (ec)
return traits_type::eof();
return c;
}
}
else
{
// Send all data in the output buffer.
asio::const_buffer buffer =
asio::buffer(pbase(), pptr() - pbase());
while (asio::buffer_size(buffer) > 0)
{
asio::error_code ec;
std::size_t bytes_transferred = this->service.send(
this->implementation, asio::buffer(buffer),
0, ec);
if (ec)
return traits_type::eof();
buffer = buffer + bytes_transferred;
}
setp(put_buffer_.begin(), put_buffer_.end());
// If the new character is eof then our work here is done.
if (traits_type::eq_int_type(c, traits_type::eof()))
return traits_type::not_eof(c);
// Add the new character to the output buffer.
*pptr() = traits_type::to_char_type(c);
pbump(1);
return c;
}
return traits_type::not_eof(c);
}
int sync()
{
return overflow(traits_type::eof());
}
std::streambuf* setbuf(char_type* s, std::streamsize n)
{
if (pptr() == pbase() && s == 0 && n == 0)
asio::const_buffer buffer =
asio::buffer(pbase(), pptr() - pbase());
while (asio::buffer_size(buffer) > 0)
{
unbuffered_ = true;
setp(0, 0);
return this;
std::size_t bytes_transferred = this->service.send(
this->implementation, asio::buffer(buffer),
0, asio::throw_error());
buffer = buffer + bytes_transferred;
}
setp(put_buffer_.begin(), put_buffer_.end());
return 0;
}
@ -241,42 +242,37 @@ private:
setg(get_buffer_.begin(),
get_buffer_.begin() + putback_max,
get_buffer_.begin() + putback_max);
if (unbuffered_)
setp(0, 0);
else
setp(put_buffer_.begin(), put_buffer_.end());
setp(put_buffer_.begin(), put_buffer_.end());
}
void resolve_and_connect(const typename Protocol::resolver_query& query,
asio::error_code& ec)
void resolve_and_connect(const typename Protocol::resolver_query& query)
{
typedef typename Protocol::resolver resolver_type;
typedef typename Protocol::resolver_iterator iterator_type;
resolver_type resolver(
boost::base_from_member<asio::io_service>::member);
iterator_type i = resolver.resolve(query, ec);
if (!ec)
iterator_type iterator = resolver.resolve(query);
asio::error error(asio::error::host_not_found);
while (error && iterator != iterator_type())
{
iterator_type end;
ec = asio::error::host_not_found;
while (ec && i != end)
{
this->basic_socket<Protocol, StreamSocketService>::close();
this->basic_socket<Protocol, StreamSocketService>::connect(*i, ec);
++i;
}
this->basic_socket<Protocol, Service>::close();
this->basic_socket<Protocol, Service>::connect(
*iterator, asio::assign_error(error));
++iterator;
}
if (error)
throw error;
}
enum { putback_max = 8 };
enum { buffer_size = 512 };
boost::array<char, buffer_size> get_buffer_;
boost::array<char, buffer_size> put_buffer_;
bool unbuffered_;
};
} // namespace asio
#undef ASIO_PRIVATE_CTR_DEF
#undef ASIO_PRIVATE_CONNECT_DEF
#include "asio/detail/pop_options.hpp"

View File

@ -2,7 +2,7 @@
// basic_stream_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -23,9 +23,8 @@
#include "asio/detail/pop_options.hpp"
#include "asio/basic_socket.hpp"
#include "asio/error.hpp"
#include "asio/error_handler.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/detail/throw_error.hpp"
namespace asio {
@ -34,21 +33,22 @@ namespace asio {
* The basic_stream_socket class template provides asynchronous and blocking
* stream-oriented socket functionality.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
* Async_Read_Stream, Async_Write_Stream, Error_Source, IO_Object, Stream,
* Sync_Read_Stream, Sync_Write_Stream.
*/
template <typename Protocol,
typename StreamSocketService = stream_socket_service<Protocol> >
typename Service = stream_socket_service<Protocol> >
class basic_stream_socket
: public basic_socket<Protocol, StreamSocketService>
: public basic_socket<Protocol, Service>
{
public:
/// The native representation of a socket.
typedef typename StreamSocketService::native_type native_type;
typedef typename Service::native_type native_type;
/// The protocol type.
typedef Protocol protocol_type;
@ -66,7 +66,7 @@ public:
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_stream_socket(asio::io_service& io_service)
: basic_socket<Protocol, StreamSocketService>(io_service)
: basic_socket<Protocol, Service>(io_service)
{
}
@ -80,11 +80,11 @@ public:
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_stream_socket(asio::io_service& io_service,
const protocol_type& protocol)
: basic_socket<Protocol, StreamSocketService>(io_service, protocol)
: basic_socket<Protocol, Service>(io_service, protocol)
{
}
@ -101,11 +101,11 @@ public:
* @param endpoint An endpoint on the local machine to which the stream
* socket will be bound.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_stream_socket(asio::io_service& io_service,
const endpoint_type& endpoint)
: basic_socket<Protocol, StreamSocketService>(io_service, endpoint)
: basic_socket<Protocol, Service>(io_service, endpoint)
{
}
@ -121,12 +121,11 @@ public:
*
* @param native_socket The new underlying socket implementation.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_stream_socket(asio::io_service& io_service,
const protocol_type& protocol, const native_type& native_socket)
: basic_socket<Protocol, StreamSocketService>(
io_service, protocol, native_socket)
: basic_socket<Protocol, Service>(io_service, protocol, native_socket)
{
}
@ -140,13 +139,13 @@ public:
*
* @returns The number of bytes sent.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::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
* is written before the blocking operation completes.
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code
* socket.send(asio::buffer(data, size));
@ -155,14 +154,10 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence>
std::size_t send(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t send(const Const_Buffers& buffers)
{
asio::error_code ec;
std::size_t s = this->service.send(
this->implementation, buffers, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.send(this->implementation, buffers, 0, throw_error());
}
/// Send some data on the socket.
@ -177,13 +172,13 @@ public:
*
* @returns The number of bytes sent.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::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
* is written before the blocking operation completes.
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code
* socket.send(asio::buffer(data, size), 0);
@ -192,15 +187,12 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence>
std::size_t send(const ConstBufferSequence& buffers,
template <typename Const_Buffers>
std::size_t send(const Const_Buffers& buffers,
socket_base::message_flags flags)
{
asio::error_code ec;
std::size_t s = this->service.send(
this->implementation, buffers, flags, ec);
asio::detail::throw_error(ec);
return s;
return this->service.send(this->implementation, buffers, flags,
throw_error());
}
/// Send some data on the socket.
@ -213,19 +205,27 @@ public:
*
* @param flags Flags specifying how the send call is to be made.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @returns The number of bytes sent. Returns 0 if an error occurred.
* @returns The number of bytes sent. Returns 0 if an error occurred and the
* error handler did not throw an exception.
*
* @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 <typename ConstBufferSequence>
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
template <typename Const_Buffers, typename Error_Handler>
std::size_t send(const Const_Buffers& buffers,
socket_base::message_flags flags,
Error_Handler error_handler)
{
return this->service.send(this->implementation, buffers, flags, ec);
return this->service.send(this->implementation, buffers, flags,
error_handler);
}
/// Start an asynchronous send.
@ -242,8 +242,8 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* const asio::error& 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
@ -254,7 +254,7 @@ public:
* Consider using the @ref async_write function if you need to ensure that all
* data is written before the asynchronous operation completes.
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code
* socket.async_send(asio::buffer(data, size), handler);
@ -263,8 +263,8 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_send(const Const_Buffers& buffers, Handler handler)
{
this->service.async_send(this->implementation, buffers, 0, handler);
}
@ -285,8 +285,8 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* const asio::error& 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
@ -297,7 +297,7 @@ public:
* Consider using the @ref async_write function if you need to ensure that all
* data is written before the asynchronous operation completes.
*
* @par Example
* @par Example:
* To send a single data buffer use the @ref buffer function as follows:
* @code
* socket.async_send(asio::buffer(data, size), 0, handler);
@ -306,9 +306,9 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_send(const Const_Buffers& buffers,
socket_base::message_flags flags, Handler handler)
{
this->service.async_send(this->implementation, buffers, flags, handler);
}
@ -323,7 +323,7 @@ public:
*
* @returns The number of bytes received.
*
* @throws asio::system_error Thrown on failure. An error code of
* @throws asio::error Thrown on failure. An error code of
* asio::error::eof indicates that the connection was closed by the
* peer.
*
@ -331,7 +331,7 @@ public:
* 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.
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code
@ -341,13 +341,11 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence>
std::size_t receive(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t receive(const Mutable_Buffers& buffers)
{
asio::error_code ec;
std::size_t s = this->service.receive(this->implementation, buffers, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.receive(this->implementation, buffers, 0,
throw_error());
}
/// Receive some data on the socket.
@ -362,7 +360,7 @@ public:
*
* @returns The number of bytes received.
*
* @throws asio::system_error Thrown on failure. An error code of
* @throws asio::error Thrown on failure. An error code of
* asio::error::eof indicates that the connection was closed by the
* peer.
*
@ -370,7 +368,7 @@ public:
* 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.
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code
@ -380,15 +378,12 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence>
std::size_t receive(const MutableBufferSequence& buffers,
template <typename Mutable_Buffers>
std::size_t receive(const Mutable_Buffers& buffers,
socket_base::message_flags flags)
{
asio::error_code ec;
std::size_t s = this->service.receive(
this->implementation, buffers, flags, ec);
asio::detail::throw_error(ec);
return s;
return this->service.receive(this->implementation, buffers, flags,
throw_error());
}
/// Receive some data on a connected socket.
@ -401,19 +396,26 @@ public:
*
* @param flags Flags specifying how the receive call is to be made.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation
* ); @endcode
*
* @returns The number of bytes received. Returns 0 if an error occurred.
* @returns The number of bytes received. Returns 0 if an error occurred and
* the error handler did not throw an exception.
*
* @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 <typename MutableBufferSequence>
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t receive(const Mutable_Buffers& buffers,
socket_base::message_flags flags, Error_Handler error_handler)
{
return this->service.receive(this->implementation, buffers, flags, ec);
return this->service.receive(this->implementation, buffers, flags,
error_handler);
}
/// Start an asynchronous receive.
@ -430,8 +432,8 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* const asio::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
@ -443,7 +445,7 @@ public:
* that the requested amount of data is received before the asynchronous
* operation completes.
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code
@ -453,8 +455,8 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_receive(const Mutable_Buffers& buffers, Handler handler)
{
this->service.async_receive(this->implementation, buffers, 0, handler);
}
@ -475,8 +477,8 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* const asio::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
@ -488,7 +490,7 @@ public:
* that the requested amount of data is received before the asynchronous
* operation completes.
*
* @par Example
* @par Example:
* To receive into a single data buffer use the @ref buffer function as
* follows:
* @code
@ -498,9 +500,9 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_receive(const Mutable_Buffers& buffers,
socket_base::message_flags flags, Handler handler)
{
this->service.async_receive(this->implementation, buffers, flags, handler);
}
@ -515,7 +517,7 @@ public:
*
* @returns The number of bytes written.
*
* @throws asio::system_error Thrown on failure. An error code of
* @throws asio::error Thrown on failure. An error code of
* asio::error::eof indicates that the connection was closed by the
* peer.
*
@ -523,7 +525,7 @@ public:
* peer. Consider using the @ref write function if you need to ensure that
* all data is written before the blocking operation completes.
*
* @par Example
* @par Example:
* To write a single data buffer use the @ref buffer function as follows:
* @code
* socket.write_some(asio::buffer(data, size));
@ -532,13 +534,10 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t write_some(const Const_Buffers& buffers)
{
asio::error_code ec;
std::size_t s = this->service.send(this->implementation, buffers, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.send(this->implementation, buffers, 0, throw_error());
}
/// Write some data to the socket.
@ -549,19 +548,25 @@ public:
*
* @param buffers One or more data buffers to be written to the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @returns The number of bytes written. Returns 0 if an error occurred.
* @returns The number of bytes written. Returns 0 if an error occurred and
* the error handler did not throw an exception.
*
* @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 <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
asio::error_code& ec)
template <typename Const_Buffers, typename Error_Handler>
std::size_t write_some(const Const_Buffers& buffers,
Error_Handler error_handler)
{
return this->service.send(this->implementation, buffers, 0, ec);
return this->service.send(this->implementation, buffers, 0, error_handler);
}
/// Start an asynchronous write.
@ -578,8 +583,8 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes written.
* const asio::error& 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
@ -590,7 +595,7 @@ public:
* Consider using the @ref async_write function if you need to ensure that all
* data is written before the asynchronous operation completes.
*
* @par Example
* @par Example:
* To write a single data buffer use the @ref buffer function as follows:
* @code
* socket.async_write_some(asio::buffer(data, size), handler);
@ -599,9 +604,8 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_write_some(const Const_Buffers& buffers, Handler handler)
{
this->service.async_send(this->implementation, buffers, 0, handler);
}
@ -616,7 +620,7 @@ public:
*
* @returns The number of bytes read.
*
* @throws asio::system_error Thrown on failure. An error code of
* @throws asio::error Thrown on failure. An error code of
* asio::error::eof indicates that the connection was closed by the
* peer.
*
@ -625,7 +629,7 @@ public:
* the requested amount of data is read before the blocking operation
* completes.
*
* @par Example
* @par Example:
* To read into a single data buffer use the @ref buffer function as follows:
* @code
* socket.read_some(asio::buffer(data, size));
@ -634,13 +638,11 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t read_some(const Mutable_Buffers& buffers)
{
asio::error_code ec;
std::size_t s = this->service.receive(this->implementation, buffers, 0, ec);
asio::detail::throw_error(ec);
return s;
return this->service.receive(this->implementation, buffers, 0,
throw_error());
}
/// Read some data from the socket.
@ -651,20 +653,27 @@ public:
*
* @param buffers One or more buffers into which the data will be read.
*
* @param ec Set to indicate what error occurred, if any.
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @returns The number of bytes read. Returns 0 if an error occurred.
* @returns The number of bytes read. Returns 0 if an error occurred and the
* error handler did not throw an exception.
*
* @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 <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
asio::error_code& ec)
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t read_some(const Mutable_Buffers& buffers,
Error_Handler error_handler)
{
return this->service.receive(this->implementation, buffers, 0, ec);
return this->service.receive(this->implementation, buffers, 0,
error_handler);
}
/// Start an asynchronous read.
@ -681,8 +690,8 @@ public:
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @code void handler(
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes read.
* const asio::error& 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
@ -694,7 +703,7 @@ public:
* requested amount of data is read before the asynchronous operation
* completes.
*
* @par Example
* @par Example:
* To read into a single data buffer use the @ref buffer function as follows:
* @code
* socket.async_read_some(asio::buffer(data, size), handler);
@ -703,12 +712,101 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
{
this->service.async_receive(this->implementation, buffers, 0, handler);
}
/// Peek at the incoming data on the stream socket.
/**
* This function is used to peek at the incoming data on the stream socket,
* without removing it from the input queue. The function call will block
* until data has been read successfully or an error occurs.
*
* @param buffers One or more buffers into which the data will be read.
*
* @returns The number of bytes read.
*
* @throws asio::error Thrown on failure.
*
* @par Example:
* To peek using a single data buffer use the @ref buffer function as
* follows:
* @code socket.peek(asio::buffer(data, size)); @endcode
* See the @ref buffer documentation for information on using multiple
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template <typename Mutable_Buffers>
std::size_t peek(const Mutable_Buffers& buffers)
{
return this->service.receive(this->implementation, buffers,
socket_base::message_peek, throw_error());
}
/// Peek at the incoming data on the stream socket.
/**
* This function is used to peek at the incoming data on the stream socket,
* without removing it from the input queue. The function call will block
* until data has been read successfully or an error occurs.
*
* @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 asio::error& error // Result of operation.
* ); @endcode
*
* @returns The number of bytes read. Returns 0 if an error occurred and the
* error handler did not throw an exception.
*/
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
{
return this->service.receive(this->implementation, buffers,
socket_base::message_peek, error_handler);
}
/// Determine the amount of data that may be read without blocking.
/**
* This function is used to determine the amount of data, in bytes, that may
* be read from the stream socket without blocking.
*
* @returns The number of bytes of data that can be read without blocking.
*
* @throws asio::error Thrown on failure.
*/
std::size_t in_avail()
{
socket_base::bytes_readable command;
this->service.io_control(this->implementation, command, throw_error());
return command.get();
}
/// Determine the amount of data that may be read without blocking.
/**
* 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 asio::error& error // Result of operation
* ); @endcode
*
* @returns The number of bytes of data that can be read without blocking.
*/
template <typename Error_Handler>
std::size_t in_avail(Error_Handler error_handler)
{
socket_base::bytes_readable command;
this->service.io_control(this->implementation, command, error_handler);
return command.get();
}
};
} // namespace asio

View File

@ -2,7 +2,7 @@
// basic_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -45,8 +45,8 @@ public:
/// The type used to represent the put area as a list of buffers.
typedef implementation_defined mutable_buffers_type;
#else
typedef asio::const_buffers_1 const_buffers_type;
typedef asio::mutable_buffers_1 mutable_buffers_type;
typedef asio::const_buffer_container_1 const_buffers_type;
typedef asio::mutable_buffer_container_1 mutable_buffers_type;
#endif
/// Construct a buffer with a specified maximum size.

View File

@ -2,7 +2,7 @@
// buffer.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -26,20 +26,6 @@
#include <vector>
#include "asio/detail/pop_options.hpp"
#if defined(BOOST_MSVC)
# if defined(_HAS_ITERATOR_DEBUGGING)
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
# define ASIO_ENABLE_BUFFER_DEBUGGING
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
# endif // defined(_HAS_ITERATOR_DEBUGGING)
#endif // defined(BOOST_MSVC)
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
# include "asio/detail/push_options.hpp"
# include <boost/function.hpp>
# include "asio/detail/pop_options.hpp"
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
namespace asio {
class mutable_buffer;
@ -75,21 +61,6 @@ public:
{
}
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
mutable_buffer(void* data, std::size_t size,
boost::function<void()> debug_check)
: data_(data),
size_(size),
debug_check_(debug_check)
{
}
const boost::function<void()>& get_debug_check() const
{
return debug_check_;
}
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
private:
friend void* asio::detail::buffer_cast_helper(
const mutable_buffer& b);
@ -98,20 +69,12 @@ private:
void* data_;
std::size_t size_;
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
boost::function<void()> debug_check_;
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
};
namespace detail {
inline void* buffer_cast_helper(const mutable_buffer& b)
{
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
if (b.debug_check_)
b.debug_check_();
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
return b.data_;
}
@ -126,10 +89,10 @@ inline std::size_t buffer_size_helper(const mutable_buffer& b)
/**
* @relates mutable_buffer
*/
template <typename PointerToPodType>
inline PointerToPodType buffer_cast(const mutable_buffer& b)
template <typename Pointer_To_Pod_Type>
inline Pointer_To_Pod_Type buffer_cast(const mutable_buffer& b)
{
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
return static_cast<Pointer_To_Pod_Type>(detail::buffer_cast_helper(b));
}
/// Get the number of bytes in a non-modifiable buffer.
@ -151,11 +114,7 @@ inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
return mutable_buffer();
char* new_data = buffer_cast<char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return mutable_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return mutable_buffer(new_data, new_size);
}
/// Create a new modifiable buffer that is offset from the start of another.
@ -168,16 +127,12 @@ inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
return mutable_buffer();
char* new_data = buffer_cast<char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return mutable_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return mutable_buffer(new_data, new_size);
}
/// Adapts a single modifiable buffer so that it meets the requirements of the
/// MutableBufferSequence concept.
class mutable_buffers_1
/// Mutable_Buffers concept.
class mutable_buffer_container_1
: public mutable_buffer
{
public:
@ -188,7 +143,7 @@ public:
typedef const mutable_buffer* const_iterator;
/// Construct to represent a single modifiable buffer.
explicit mutable_buffers_1(const mutable_buffer& b)
explicit mutable_buffer_container_1(const mutable_buffer& b)
: mutable_buffer(b)
{
}
@ -233,27 +188,9 @@ public:
const_buffer(const mutable_buffer& b)
: data_(asio::detail::buffer_cast_helper(b)),
size_(asio::detail::buffer_size_helper(b))
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, debug_check_(b.get_debug_check())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
{
}
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
const_buffer(const void* data, std::size_t size,
boost::function<void()> debug_check)
: data_(data),
size_(size),
debug_check_(debug_check)
{
}
const boost::function<void()>& get_debug_check() const
{
return debug_check_;
}
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
private:
friend const void* asio::detail::buffer_cast_helper(
const const_buffer& b);
@ -262,20 +199,12 @@ private:
const void* data_;
std::size_t size_;
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
boost::function<void()> debug_check_;
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
};
namespace detail {
inline const void* buffer_cast_helper(const const_buffer& b)
{
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
if (b.debug_check_)
b.debug_check_();
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
return b.data_;
}
@ -290,10 +219,10 @@ inline std::size_t buffer_size_helper(const const_buffer& b)
/**
* @relates const_buffer
*/
template <typename PointerToPodType>
inline PointerToPodType buffer_cast(const const_buffer& b)
template <typename Pointer_To_Pod_Type>
inline Pointer_To_Pod_Type buffer_cast(const const_buffer& b)
{
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
return static_cast<Pointer_To_Pod_Type>(detail::buffer_cast_helper(b));
}
/// Get the number of bytes in a non-modifiable buffer.
@ -315,11 +244,7 @@ inline const_buffer operator+(const const_buffer& b, std::size_t start)
return const_buffer();
const char* new_data = buffer_cast<const char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return const_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return const_buffer(new_data, new_size);
}
/// Create a new non-modifiable buffer that is offset from the start of another.
@ -332,16 +257,12 @@ inline const_buffer operator+(std::size_t start, const const_buffer& b)
return const_buffer();
const char* new_data = buffer_cast<const char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return const_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return const_buffer(new_data, new_size);
}
/// Adapts a single non-modifiable buffer so that it meets the requirements of
/// the ConstBufferSequence concept.
class const_buffers_1
/// the Const_Buffers concept.
class const_buffer_container_1
: public const_buffer
{
public:
@ -352,7 +273,7 @@ public:
typedef const const_buffer* const_iterator;
/// Construct to represent a single non-modifiable buffer.
explicit const_buffers_1(const const_buffer& b)
explicit const_buffer_container_1(const const_buffer& b)
: const_buffer(b)
{
}
@ -370,30 +291,6 @@ public:
}
};
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
namespace detail {
template <typename Iterator>
class buffer_debug_check
{
public:
buffer_debug_check(Iterator iter)
: iter_(iter)
{
}
void operator()()
{
*iter_;
}
private:
Iterator iter_;
};
} // namespace detail
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
/** @defgroup buffer asio::buffer
*
* @brief The asio::buffer function is used to create a buffer object to
@ -405,9 +302,9 @@ private:
* @code sock.write(asio::buffer(data, size)); @endcode
*
* In the above example, the return value of asio::buffer meets the
* requirements of the ConstBufferSequence concept so that it may be directly
* passed to the socket's write function. A buffer created for modifiable
* memory also meets the requirements of the MutableBufferSequence concept.
* requirements of the Const_Buffers concept so that it may be directly passed
* to the socket's write function. A buffer created for modifiable memory also
* meets the requirements of the Mutable_Buffers concept.
*
* An individual buffer may be created from a builtin array, std::vector or
* boost::array of POD elements. This helps prevent buffer overruns by
@ -424,7 +321,7 @@ private:
*
* To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
* buffer objects may be assigned into a container that supports the
* MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
* Mutable_Buffers (for read) or Const_Buffers (for write) concepts:
*
* @code
* char d1[128];
@ -446,107 +343,99 @@ private:
/*@{*/
/// Create a new modifiable buffer from an existing buffer.
inline mutable_buffers_1 buffer(const mutable_buffer& b)
inline mutable_buffer_container_1 buffer(const mutable_buffer& b)
{
return mutable_buffers_1(b);
return mutable_buffer_container_1(b);
}
/// Create a new modifiable buffer from an existing buffer.
inline mutable_buffers_1 buffer(const mutable_buffer& b,
inline mutable_buffer_container_1 buffer(const mutable_buffer& b,
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(buffer_cast<void*>(b),
buffer_size(b) < max_size_in_bytes
? buffer_size(b) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
? buffer_size(b) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer from an existing buffer.
inline const_buffers_1 buffer(const const_buffer& b)
inline const_buffer_container_1 buffer(const const_buffer& b)
{
return const_buffers_1(b);
return const_buffer_container_1(b);
}
/// Create a new non-modifiable buffer from an existing buffer.
inline const_buffers_1 buffer(const const_buffer& b,
inline const_buffer_container_1 buffer(const const_buffer& b,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(buffer_cast<const void*>(b),
buffer_size(b) < max_size_in_bytes
? buffer_size(b) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
? buffer_size(b) : max_size_in_bytes));
}
/// Create a new modifiable buffer that represents the given memory range.
inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
inline mutable_buffer_container_1 buffer(void* data, std::size_t size_in_bytes)
{
return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
return mutable_buffer_container_1(mutable_buffer(data, size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given memory range.
inline const_buffers_1 buffer(const void* data,
inline const_buffer_container_1 buffer(const void* data,
std::size_t size_in_bytes)
{
return const_buffers_1(const_buffer(data, size_in_bytes));
return const_buffer_container_1(const_buffer(data, size_in_bytes));
}
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(PodType (&data)[N])
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(Pod_Type (&data)[N])
{
return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
return mutable_buffer_container_1(mutable_buffer(data, N * sizeof(Pod_Type)));
}
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(PodType (&data)[N],
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(Pod_Type (&data)[N],
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(data,
N * sizeof(PodType) < max_size_in_bytes
? N * sizeof(PodType) : max_size_in_bytes));
N * sizeof(Pod_Type) < max_size_in_bytes
? N * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const PodType (&data)[N])
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const Pod_Type (&data)[N])
{
return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
return const_buffer_container_1(const_buffer(data, N * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const PodType (&data)[N],
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const Pod_Type (&data)[N],
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data,
N * sizeof(PodType) < max_size_in_bytes
? N * sizeof(PodType) : max_size_in_bytes));
N * sizeof(Pod_Type) < max_size_in_bytes
? N * sizeof(Pod_Type) : max_size_in_bytes));
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Borland C++ thinks the overloads:
//
// unspecified buffer(boost::array<PodType, N>& array ...);
// unspecified buffer(boost::array<Pod_Type, N>& array ...);
//
// and
//
// unspecified buffer(boost::array<const PodType, N>& array ...);
// unspecified buffer(boost::array<const Pod_Type, N>& array ...);
//
// are ambiguous. This will be worked around by using a buffer_types traits
// class that contains typedefs for the appropriate buffer and container
// classes, based on whether PodType is const or non-const.
// classes, based on whether Pod_Type is const or non-const.
namespace detail {
@ -557,109 +446,109 @@ template <>
struct buffer_types_base<false>
{
typedef mutable_buffer buffer_type;
typedef mutable_buffers_1 container_type;
typedef mutable_buffer_container_1 container_type;
};
template <>
struct buffer_types_base<true>
{
typedef const_buffer buffer_type;
typedef const_buffers_1 container_type;
typedef const_buffer_container_1 container_type;
};
template <typename PodType>
template <typename Pod_Type>
struct buffer_types
: public buffer_types_base<boost::is_const<PodType>::value>
: public buffer_types_base<boost::is_const<Pod_Type>::value>
{
};
} // namespace detail
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
buffer(boost::array<PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline typename detail::buffer_types<Pod_Type>::container_type
buffer(boost::array<Pod_Type, N>& data)
{
typedef typename asio::detail::buffer_types<PodType>::buffer_type
typedef typename asio::detail::buffer_types<Pod_Type>::buffer_type
buffer_type;
typedef typename asio::detail::buffer_types<PodType>::container_type
typedef typename asio::detail::buffer_types<Pod_Type>::container_type
container_type;
return container_type(
buffer_type(data.c_array(), data.size() * sizeof(PodType)));
buffer_type(data.c_array(), data.size() * sizeof(Pod_Type)));
}
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
template <typename Pod_Type, std::size_t N>
inline typename detail::buffer_types<Pod_Type>::container_type
buffer(boost::array<Pod_Type, N>& data, std::size_t max_size_in_bytes)
{
typedef typename asio::detail::buffer_types<PodType>::buffer_type
typedef typename asio::detail::buffer_types<Pod_Type>::buffer_type
buffer_type;
typedef typename asio::detail::buffer_types<PodType>::container_type
typedef typename asio::detail::buffer_types<Pod_Type>::container_type
container_type;
return container_type(
buffer_type(data.c_array(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(boost::array<Pod_Type, N>& data)
{
return mutable_buffers_1(
mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
return mutable_buffer_container_1(
mutable_buffer(data.c_array(), data.size() * sizeof(Pod_Type)));
}
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(boost::array<Pod_Type, N>& data,
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(data.c_array(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(boost::array<const Pod_Type, N>& data)
{
return const_buffers_1(
const_buffer(data.data(), data.size() * sizeof(PodType)));
return const_buffer_container_1(
const_buffer(data.data(), data.size() * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(boost::array<const Pod_Type, N>& data,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data.data(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const boost::array<Pod_Type, N>& data)
{
return const_buffers_1(
const_buffer(data.data(), data.size() * sizeof(PodType)));
return const_buffer_container_1(
const_buffer(data.data(), data.size() * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const boost::array<Pod_Type, N>& data,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data.data(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new modifiable buffer that represents the given POD vector.
@ -667,17 +556,11 @@ inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
template <typename Pod_Type, typename Allocator>
inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data)
{
return mutable_buffers_1(
mutable_buffer(&data[0], data.size() * sizeof(PodType)
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
return mutable_buffer_container_1(
mutable_buffer(&data[0], data.size() * sizeof(Pod_Type)));
}
/// Create a new modifiable buffer that represents the given POD vector.
@ -685,20 +568,14 @@ inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
template <typename Pod_Type, typename Allocator>
inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data,
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(&data[0],
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given POD vector.
@ -706,18 +583,12 @@ inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline const_buffers_1 buffer(
const std::vector<PodType, Allocator>& data)
template <typename Pod_Type, typename Allocator>
inline const_buffer_container_1 buffer(
const std::vector<Pod_Type, Allocator>& data)
{
return const_buffers_1(
const_buffer(&data[0], data.size() * sizeof(PodType)
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::const_iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
return const_buffer_container_1(
const_buffer(&data[0], data.size() * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD vector.
@ -725,20 +596,14 @@ inline const_buffers_1 buffer(
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline const_buffers_1 buffer(
const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
template <typename Pod_Type, typename Allocator>
inline const_buffer_container_1 buffer(
const std::vector<Pod_Type, Allocator>& data, std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(&data[0],
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::const_iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given string.
@ -746,13 +611,9 @@ inline const_buffers_1 buffer(
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
inline const_buffers_1 buffer(const std::string& data)
inline const_buffer_container_1 buffer(const std::string& data)
{
return const_buffers_1(const_buffer(data.data(), data.size()
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
return const_buffer_container_1(const_buffer(data.data(), data.size()));
}
/// Create a new non-modifiable buffer that represents the given string.
@ -760,17 +621,13 @@ inline const_buffers_1 buffer(const std::string& data)
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
inline const_buffers_1 buffer(const std::string& data,
inline const_buffer_container_1 buffer(const std::string& data,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data.data(),
data.size() < max_size_in_bytes
? data.size() : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
? data.size() : max_size_in_bytes));
}
/*@}*/

View File

@ -2,7 +2,7 @@
// buffered_read_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -40,12 +40,13 @@ namespace asio {
* The buffered_read_stream class template can be used to add buffering to the
* synchronous and asynchronous read operations of a stream.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, Sync_Read_Stream, SyncWriteStream.
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
* Sync_Read_Stream, Sync_Write_Stream.
*/
template <typename Stream>
class buffered_read_stream
@ -58,6 +59,9 @@ 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;
@ -106,33 +110,33 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return next_layer_.close(ec);
next_layer_.close(error_handler);
}
/// Write the given data to the stream. Returns the number of bytes written.
/// Throws an exception on failure.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t write_some(const Const_Buffers& buffers)
{
return next_layer_.write_some(buffers);
}
/// Write the given data to the stream. Returns the number of bytes written,
/// or 0 if an error occurred.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Const_Buffers, typename Error_Handler>
std::size_t write_some(const Const_Buffers& buffers,
Error_Handler error_handler)
{
return next_layer_.write_some(buffers, ec);
return next_layer_.write_some(buffers, error_handler);
}
/// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_write_some(const Const_Buffers& buffers, Handler handler)
{
next_layer_.async_write_some(buffers, handler);
}
@ -153,8 +157,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.
std::size_t fill(asio::error_code& ec)
/// buffer as a result of the operation, or 0 if an error occurred and the
/// error handler did not throw.
template <typename Error_Handler>
std::size_t fill(Error_Handler error_handler)
{
detail::buffer_resize_guard<detail::buffered_stream_storage>
resize_guard(storage_);
@ -163,18 +169,18 @@ public:
storage_.resize(previous_size + next_layer_.read_some(buffer(
storage_.data() + previous_size,
storage_.size() - previous_size),
ec));
error_handler));
resize_guard.commit();
return storage_.size() - previous_size;
}
template <typename ReadHandler>
template <typename Handler>
class fill_handler
{
public:
fill_handler(asio::io_service& io_service,
detail::buffered_stream_storage& storage,
std::size_t previous_size, ReadHandler handler)
std::size_t previous_size, Handler handler)
: io_service_(io_service),
storage_(storage),
previous_size_(previous_size),
@ -182,24 +188,24 @@ public:
{
}
void operator()(const asio::error_code& ec,
std::size_t bytes_transferred)
template <typename Error>
void operator()(const Error& e, std::size_t bytes_transferred)
{
storage_.resize(previous_size_ + bytes_transferred);
io_service_.dispatch(detail::bind_handler(
handler_, ec, bytes_transferred));
handler_, e, bytes_transferred));
}
private:
asio::io_service& io_service_;
detail::buffered_stream_storage& storage_;
std::size_t previous_size_;
ReadHandler handler_;
Handler handler_;
};
/// Start an asynchronous fill.
template <typename ReadHandler>
void async_fill(ReadHandler handler)
template <typename Handler>
void async_fill(Handler handler)
{
std::size_t previous_size = storage_.size();
storage_.resize(storage_.capacity());
@ -207,14 +213,13 @@ public:
buffer(
storage_.data() + previous_size,
storage_.size() - previous_size),
fill_handler<ReadHandler>(io_service(),
storage_, previous_size, handler));
fill_handler<Handler>(io_service(), storage_, previous_size, handler));
}
/// Read some data from the stream. Returns the number of bytes read. Throws
/// an exception on failure.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t read_some(const Mutable_Buffers& buffers)
{
if (storage_.empty())
fill();
@ -222,24 +227,23 @@ public:
}
/// Read some data from the stream. Returns the number of bytes read or 0 if
/// an error occurred.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// an error occurred and the error handler did not throw an exception.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t read_some(const Mutable_Buffers& buffers,
Error_Handler error_handler)
{
ec = asio::error_code();
if (storage_.empty() && !fill(ec))
if (storage_.empty() && !fill(error_handler))
return 0;
return copy(buffers);
}
template <typename MutableBufferSequence, typename ReadHandler>
template <typename Mutable_Buffers, typename Handler>
class read_some_handler
{
public:
read_some_handler(asio::io_service& io_service,
detail::buffered_stream_storage& storage,
const MutableBufferSequence& buffers, ReadHandler handler)
const Mutable_Buffers& buffers, Handler handler)
: io_service_(io_service),
storage_(storage),
buffers_(buffers),
@ -247,12 +251,12 @@ public:
{
}
void operator()(const asio::error_code& ec, std::size_t)
void operator()(const error_type& e, std::size_t)
{
if (ec || storage_.empty())
if (e || storage_.empty())
{
std::size_t length = 0;
io_service_.dispatch(detail::bind_handler(handler_, ec, length));
io_service_.dispatch(detail::bind_handler(handler_, e, length));
}
else
{
@ -261,8 +265,8 @@ public:
std::size_t bytes_avail = storage_.size();
std::size_t bytes_copied = 0;
typename MutableBufferSequence::const_iterator iter = buffers_.begin();
typename MutableBufferSequence::const_iterator end = buffers_.end();
typename Mutable_Buffers::const_iterator iter = buffers_.begin();
typename Mutable_Buffers::const_iterator end = buffers_.end();
for (; iter != end && bytes_avail > 0; ++iter)
{
std::size_t max_length = buffer_size(*iter);
@ -275,40 +279,38 @@ public:
}
storage_.consume(bytes_copied);
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
io_service_.dispatch(detail::bind_handler(handler_, e, bytes_copied));
}
}
private:
asio::io_service& io_service_;
detail::buffered_stream_storage& storage_;
MutableBufferSequence buffers_;
ReadHandler handler_;
Mutable_Buffers buffers_;
Handler handler_;
};
/// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
{
if (storage_.empty())
{
async_fill(read_some_handler<MutableBufferSequence, ReadHandler>(
async_fill(read_some_handler<Mutable_Buffers, Handler>(
io_service(), storage_, buffers, handler));
}
else
{
std::size_t length = copy(buffers);
io_service().post(detail::bind_handler(
handler, asio::error_code(), length));
io_service().post(detail::bind_handler(handler, 0, length));
}
}
/// Peek at the incoming data on the stream. Returns the number of bytes read.
/// Throws an exception on failure.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t peek(const Mutable_Buffers& buffers)
{
if (storage_.empty())
fill();
@ -316,13 +318,11 @@ public:
}
/// Peek at the incoming data on the stream. Returns the number of bytes read,
/// or 0 if an error occurred.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
{
ec = asio::error_code();
if (storage_.empty() && !fill(ec))
if (storage_.empty() && !fill(error_handler))
return 0;
return peek_copy(buffers);
}
@ -334,25 +334,25 @@ public:
}
/// Determine the amount of data that may be read without blocking.
std::size_t in_avail(asio::error_code& ec)
template <typename Error_Handler>
std::size_t in_avail(Error_Handler error_handler)
{
ec = asio::error_code();
return storage_.size();
}
private:
/// Copy data out of the internal buffer to the specified target buffer.
/// Returns the number of bytes copied.
template <typename MutableBufferSequence>
std::size_t copy(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t copy(const Mutable_Buffers& buffers)
{
using namespace std; // For memcpy.
std::size_t bytes_avail = storage_.size();
std::size_t bytes_copied = 0;
typename MutableBufferSequence::const_iterator iter = buffers.begin();
typename MutableBufferSequence::const_iterator end = buffers.end();
typename Mutable_Buffers::const_iterator iter = buffers.begin();
typename Mutable_Buffers::const_iterator end = buffers.end();
for (; iter != end && bytes_avail > 0; ++iter)
{
std::size_t max_length = buffer_size(*iter);
@ -370,16 +370,16 @@ private:
/// Copy data from the internal buffer to the specified target buffer, without
/// removing the data from the internal buffer. Returns the number of bytes
/// copied.
template <typename MutableBufferSequence>
std::size_t peek_copy(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t peek_copy(const Mutable_Buffers& buffers)
{
using namespace std; // For memcpy.
std::size_t bytes_avail = storage_.size();
std::size_t bytes_copied = 0;
typename MutableBufferSequence::const_iterator iter = buffers.begin();
typename MutableBufferSequence::const_iterator end = buffers.end();
typename Mutable_Buffers::const_iterator iter = buffers.begin();
typename Mutable_Buffers::const_iterator end = buffers.end();
for (; iter != end && bytes_avail > 0; ++iter)
{
std::size_t max_length = buffer_size(*iter);

View File

@ -2,7 +2,7 @@
// buffered_read_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// buffered_stream.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -36,12 +36,13 @@ namespace asio {
* The buffered_stream class template can be used to add buffering to the
* synchronous and asynchronous read and write operations of a stream.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
* Sync_Read_Stream, Sync_Write_Stream.
*/
template <typename Stream>
class buffered_stream
@ -54,6 +55,9 @@ 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 <typename Arg>
explicit buffered_stream(Arg& a)
@ -96,9 +100,10 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return stream_impl_.close(ec);
stream_impl_.close(error_handler);
}
/// Flush all data from the buffer to the next layer. Returns the number of
@ -111,41 +116,41 @@ 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.
std::size_t flush(asio::error_code& ec)
/// error occurred and the error handler did not throw.
template <typename Error_Handler>
std::size_t flush(Error_Handler error_handler)
{
return stream_impl_.next_layer().flush(ec);
return stream_impl_.next_layer().flush(error_handler);
}
/// Start an asynchronous flush.
template <typename WriteHandler>
void async_flush(WriteHandler handler)
template <typename Handler>
void async_flush(Handler handler)
{
return stream_impl_.next_layer().async_flush(handler);
}
/// Write the given data to the stream. Returns the number of bytes written.
/// Throws an exception on failure.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t write_some(const Const_Buffers& buffers)
{
return stream_impl_.write_some(buffers);
}
/// Write the given data to the stream. Returns the number of bytes written,
/// or 0 if an error occurred.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Const_Buffers, typename Error_Handler>
std::size_t write_some(const Const_Buffers& buffers,
Error_Handler error_handler)
{
return stream_impl_.write_some(buffers, ec);
return stream_impl_.write_some(buffers, error_handler);
}
/// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_write_some(const Const_Buffers& buffers, Handler handler)
{
stream_impl_.async_write_some(buffers, handler);
}
@ -158,60 +163,60 @@ 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.
std::size_t fill(asio::error_code& ec)
/// buffer as a result of the operation, or 0 if an error occurred and the
/// error handler did not throw.
template <typename Error_Handler>
std::size_t fill(Error_Handler error_handler)
{
return stream_impl_.fill(ec);
return stream_impl_.fill(error_handler);
}
/// Start an asynchronous fill.
template <typename ReadHandler>
void async_fill(ReadHandler handler)
template <typename Handler>
void async_fill(Handler handler)
{
stream_impl_.async_fill(handler);
}
/// Read some data from the stream. Returns the number of bytes read. Throws
/// an exception on failure.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t read_some(const Mutable_Buffers& buffers)
{
return stream_impl_.read_some(buffers);
}
/// Read some data from the stream. Returns the number of bytes read or 0 if
/// an error occurred.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// an error occurred and the error handler did not throw an exception.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t read_some(const Mutable_Buffers& buffers,
Error_Handler error_handler)
{
return stream_impl_.read_some(buffers, ec);
return stream_impl_.read_some(buffers, error_handler);
}
/// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
{
stream_impl_.async_read_some(buffers, handler);
}
/// Peek at the incoming data on the stream. Returns the number of bytes read.
/// Throws an exception on failure.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t peek(const Mutable_Buffers& buffers)
{
return stream_impl_.peek(buffers);
}
/// Peek at the incoming data on the stream. Returns the number of bytes read,
/// or 0 if an error occurred.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
{
return stream_impl_.peek(buffers, ec);
return stream_impl_.peek(buffers, error_handler);
}
/// Determine the amount of data that may be read without blocking.
@ -221,9 +226,10 @@ public:
}
/// Determine the amount of data that may be read without blocking.
std::size_t in_avail(asio::error_code& ec)
template <typename Error_Handler>
std::size_t in_avail(Error_Handler error_handler)
{
return stream_impl_.in_avail(ec);
return stream_impl_.in_avail(error_handler);
}
private:

View File

@ -2,7 +2,7 @@
// buffered_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// buffered_write_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -41,12 +41,13 @@ namespace asio {
* The buffered_write_stream class template can be used to add buffering to the
* synchronous and asynchronous write operations of a stream.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
* Sync_Read_Stream, Sync_Write_Stream.
*/
template <typename Stream>
class buffered_write_stream
@ -59,6 +60,9 @@ 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;
@ -107,9 +111,10 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return next_layer_.close(ec);
next_layer_.close(error_handler);
}
/// Flush all data from the buffer to the next layer. Returns the number of
@ -125,53 +130,53 @@ 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.
std::size_t flush(asio::error_code& ec)
/// error occurred and the error handler did not throw.
template <typename Error_Handler>
std::size_t flush(Error_Handler error_handler)
{
std::size_t bytes_written = write(next_layer_,
buffer(storage_.data(), storage_.size()),
transfer_all(), ec);
transfer_all(), error_handler);
storage_.consume(bytes_written);
return bytes_written;
}
template <typename WriteHandler>
template <typename Handler>
class flush_handler
{
public:
flush_handler(asio::io_service& io_service,
detail::buffered_stream_storage& storage, WriteHandler handler)
detail::buffered_stream_storage& storage, Handler handler)
: io_service_(io_service),
storage_(storage),
handler_(handler)
{
}
void operator()(const asio::error_code& ec,
std::size_t bytes_written)
void operator()(const error_type& e, std::size_t bytes_written)
{
storage_.consume(bytes_written);
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_written));
io_service_.dispatch(detail::bind_handler(handler_, e, bytes_written));
}
private:
asio::io_service& io_service_;
detail::buffered_stream_storage& storage_;
WriteHandler handler_;
Handler handler_;
};
/// Start an asynchronous flush.
template <typename WriteHandler>
void async_flush(WriteHandler handler)
template <typename Handler>
void async_flush(Handler handler)
{
async_write(next_layer_, buffer(storage_.data(), storage_.size()),
flush_handler<WriteHandler>(io_service(), storage_, handler));
flush_handler<Handler>(io_service(), storage_, handler));
}
/// Write the given data to the stream. Returns the number of bytes written.
/// Throws an exception on failure.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t write_some(const Const_Buffers& buffers)
{
if (storage_.size() == storage_.capacity())
flush();
@ -180,23 +185,22 @@ 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 <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
asio::error_code& ec)
template <typename Const_Buffers, typename Error_Handler>
std::size_t write_some(const Const_Buffers& buffers,
Error_Handler error_handler)
{
ec = asio::error_code();
if (storage_.size() == storage_.capacity() && !flush(ec))
if (storage_.size() == storage_.capacity() && !flush(error_handler))
return 0;
return copy(buffers);
}
template <typename ConstBufferSequence, typename WriteHandler>
template <typename Const_Buffers, typename Handler>
class write_some_handler
{
public:
write_some_handler(asio::io_service& io_service,
detail::buffered_stream_storage& storage,
const ConstBufferSequence& buffers, WriteHandler handler)
const Const_Buffers& buffers, Handler handler)
: io_service_(io_service),
storage_(storage),
buffers_(buffers),
@ -204,12 +208,12 @@ public:
{
}
void operator()(const asio::error_code& ec, std::size_t)
void operator()(const error_type& e, std::size_t)
{
if (ec)
if (e)
{
std::size_t length = 0;
io_service_.dispatch(detail::bind_handler(handler_, ec, length));
io_service_.dispatch(detail::bind_handler(handler_, e, length));
}
else
{
@ -219,8 +223,8 @@ public:
std::size_t space_avail = storage_.capacity() - orig_size;
std::size_t bytes_copied = 0;
typename ConstBufferSequence::const_iterator iter = buffers_.begin();
typename ConstBufferSequence::const_iterator end = buffers_.end();
typename Const_Buffers::const_iterator iter = buffers_.begin();
typename Const_Buffers::const_iterator end = buffers_.end();
for (; iter != end && space_avail > 0; ++iter)
{
std::size_t bytes_avail = buffer_size(*iter);
@ -233,77 +237,73 @@ public:
space_avail -= length;
}
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
io_service_.dispatch(detail::bind_handler(handler_, e, bytes_copied));
}
}
private:
asio::io_service& io_service_;
detail::buffered_stream_storage& storage_;
ConstBufferSequence buffers_;
WriteHandler handler_;
Const_Buffers buffers_;
Handler handler_;
};
/// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_write_some(const Const_Buffers& buffers, Handler handler)
{
if (storage_.size() == storage_.capacity())
{
async_flush(write_some_handler<ConstBufferSequence, WriteHandler>(
async_flush(write_some_handler<Const_Buffers, Handler>(
io_service(), storage_, buffers, handler));
}
else
{
std::size_t bytes_copied = copy(buffers);
io_service().post(detail::bind_handler(
handler, asio::error_code(), bytes_copied));
io_service().post(detail::bind_handler(handler, 0, bytes_copied));
}
}
/// Read some data from the stream. Returns the number of bytes read. Throws
/// an exception on failure.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t read_some(const Mutable_Buffers& buffers)
{
return next_layer_.read_some(buffers);
}
/// Read some data from the stream. Returns the number of bytes read or 0 if
/// an error occurred.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// an error occurred and the error handler did not throw an exception.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t read_some(const Mutable_Buffers& buffers,
Error_Handler error_handler)
{
return next_layer_.read_some(buffers, ec);
return next_layer_.read_some(buffers, error_handler);
}
/// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
{
next_layer_.async_read_some(buffers, handler);
}
/// Peek at the incoming data on the stream. Returns the number of bytes read.
/// Throws an exception on failure.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t peek(const Mutable_Buffers& buffers)
{
return next_layer_.peek(buffers);
}
/// Peek at the incoming data on the stream. Returns the number of bytes read,
/// or 0 if an error occurred.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
{
return next_layer_.peek(buffers, ec);
return next_layer_.peek(buffers, error_handler);
}
/// Determine the amount of data that may be read without blocking.
@ -313,16 +313,17 @@ public:
}
/// Determine the amount of data that may be read without blocking.
std::size_t in_avail(asio::error_code& ec)
template <typename Error_Handler>
std::size_t in_avail(Error_Handler error_handler)
{
return next_layer_.in_avail(ec);
return next_layer_.in_avail(error_handler);
}
private:
/// Copy data into the internal buffer from the specified source buffer.
/// Returns the number of bytes copied.
template <typename ConstBufferSequence>
std::size_t copy(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t copy(const Const_Buffers& buffers)
{
using namespace std; // For memcpy.
@ -330,8 +331,8 @@ private:
std::size_t space_avail = storage_.capacity() - orig_size;
std::size_t bytes_copied = 0;
typename ConstBufferSequence::const_iterator iter = buffers.begin();
typename ConstBufferSequence::const_iterator end = buffers.end();
typename Const_Buffers::const_iterator iter = buffers.begin();
typename Const_Buffers::const_iterator end = buffers.end();
for (; iter != end && space_avail > 0; ++iter)
{
std::size_t bytes_avail = buffer_size(*iter);

View File

@ -2,7 +2,7 @@
// buffered_write_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// completion_condition.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// datagram_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -22,12 +22,10 @@
#include <boost/config.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/io_service.hpp"
#include "asio/detail/epoll_reactor.hpp"
#include "asio/detail/kqueue_reactor.hpp"
#include "asio/detail/select_reactor.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/reactive_socket_service.hpp"
#include "asio/detail/win_iocp_socket_service.hpp"
@ -36,18 +34,9 @@ namespace asio {
/// Default service implementation for a datagram socket.
template <typename Protocol>
class datagram_socket_service
#if defined(GENERATING_DOCUMENTATION)
: public asio::io_service::service
#else
: public asio::detail::service_base<datagram_socket_service<Protocol> >
#endif
{
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static asio::io_service::id id;
#endif
/// The protocol type.
typedef Protocol protocol_type;
@ -86,8 +75,7 @@ public:
/// Construct a new datagram socket service for the specified io_service.
explicit datagram_socket_service(asio::io_service& io_service)
: asio::detail::service_base<
datagram_socket_service<Protocol> >(io_service),
: asio::io_service::service(io_service),
service_impl_(asio::use_service<service_impl_type>(io_service))
{
}
@ -110,35 +98,29 @@ public:
}
// Open a new datagram socket implementation.
asio::error_code open(implementation_type& impl,
const protocol_type& protocol, asio::error_code& ec)
template <typename Error_Handler>
void open(implementation_type& impl, const protocol_type& protocol,
Error_Handler error_handler)
{
if (protocol.type() == SOCK_DGRAM)
service_impl_.open(impl, protocol, ec);
service_impl_.open(impl, protocol, error_handler);
else
ec = asio::error::invalid_argument;
return ec;
error_handler(asio::error(asio::error::invalid_argument));
}
/// Assign an existing native socket to a datagram socket.
asio::error_code assign(implementation_type& impl,
const protocol_type& protocol, const native_type& native_socket,
asio::error_code& ec)
template <typename Error_Handler>
void assign(implementation_type& impl, const protocol_type& protocol,
const native_type& native_socket, Error_Handler error_handler)
{
return service_impl_.assign(impl, protocol, native_socket, ec);
}
/// Determine whether the socket is open.
bool is_open(const implementation_type& impl) const
{
return service_impl_.is_open(impl);
service_impl_.assign(impl, protocol, native_socket, error_handler);
}
/// Close a datagram socket implementation.
asio::error_code close(implementation_type& impl,
asio::error_code& ec)
template <typename Error_Handler>
void close(implementation_type& impl, Error_Handler error_handler)
{
return service_impl_.close(impl, ec);
service_impl_.close(impl, error_handler);
}
/// Get the native socket implementation.
@ -148,161 +130,154 @@ public:
}
/// Cancel all asynchronous operations associated with the socket.
asio::error_code cancel(implementation_type& impl,
asio::error_code& ec)
template <typename Error_Handler>
void cancel(implementation_type& impl, Error_Handler error_handler)
{
return service_impl_.cancel(impl, ec);
}
/// Determine whether the socket is at the out-of-band data mark.
bool at_mark(const implementation_type& impl,
asio::error_code& ec) const
{
return service_impl_.at_mark(impl, ec);
}
/// Determine the number of bytes available for reading.
std::size_t available(const implementation_type& impl,
asio::error_code& ec) const
{
return service_impl_.available(impl, ec);
service_impl_.cancel(impl, error_handler);
}
// Bind the datagram socket to the specified local endpoint.
asio::error_code bind(implementation_type& impl,
const endpoint_type& endpoint, asio::error_code& ec)
template <typename Error_Handler>
void bind(implementation_type& impl, const endpoint_type& endpoint,
Error_Handler error_handler)
{
return service_impl_.bind(impl, endpoint, ec);
service_impl_.bind(impl, endpoint, error_handler);
}
/// Connect the datagram socket to the specified endpoint.
asio::error_code connect(implementation_type& impl,
const endpoint_type& peer_endpoint, asio::error_code& ec)
template <typename Error_Handler>
void connect(implementation_type& impl, const endpoint_type& peer_endpoint,
Error_Handler error_handler)
{
return service_impl_.connect(impl, peer_endpoint, ec);
service_impl_.connect(impl, peer_endpoint, error_handler);
}
/// Start an asynchronous connect.
template <typename ConnectHandler>
template <typename Handler>
void async_connect(implementation_type& impl,
const endpoint_type& peer_endpoint, ConnectHandler handler)
const endpoint_type& peer_endpoint, Handler handler)
{
service_impl_.async_connect(impl, peer_endpoint, handler);
}
/// Set a socket option.
template <typename SettableSocketOption>
asio::error_code set_option(implementation_type& impl,
const SettableSocketOption& option, asio::error_code& ec)
template <typename Option, typename Error_Handler>
void set_option(implementation_type& impl, const Option& option,
Error_Handler error_handler)
{
return service_impl_.set_option(impl, option, ec);
service_impl_.set_option(impl, option, error_handler);
}
/// Get a socket option.
template <typename GettableSocketOption>
asio::error_code get_option(const implementation_type& impl,
GettableSocketOption& option, asio::error_code& ec) const
template <typename Option, typename Error_Handler>
void get_option(const implementation_type& impl, Option& option,
Error_Handler error_handler) const
{
return service_impl_.get_option(impl, option, ec);
service_impl_.get_option(impl, option, error_handler);
}
/// Perform an IO control command on the socket.
template <typename IoControlCommand>
asio::error_code io_control(implementation_type& impl,
IoControlCommand& command, asio::error_code& ec)
template <typename IO_Control_Command, typename Error_Handler>
void io_control(implementation_type& impl, IO_Control_Command& command,
Error_Handler error_handler)
{
return service_impl_.io_control(impl, command, ec);
service_impl_.io_control(impl, command, error_handler);
}
/// Get the local endpoint.
template <typename Error_Handler>
endpoint_type local_endpoint(const implementation_type& impl,
asio::error_code& ec) const
Error_Handler error_handler) const
{
return service_impl_.local_endpoint(impl, ec);
endpoint_type endpoint;
service_impl_.get_local_endpoint(impl, endpoint, error_handler);
return endpoint;
}
/// Get the remote endpoint.
template <typename Error_Handler>
endpoint_type remote_endpoint(const implementation_type& impl,
asio::error_code& ec) const
Error_Handler error_handler) const
{
return service_impl_.remote_endpoint(impl, ec);
endpoint_type endpoint;
service_impl_.get_remote_endpoint(impl, endpoint, error_handler);
return endpoint;
}
/// Disable sends or receives on the socket.
asio::error_code shutdown(implementation_type& impl,
socket_base::shutdown_type what, asio::error_code& ec)
template <typename Error_Handler>
void shutdown(implementation_type& impl, socket_base::shutdown_type what,
Error_Handler error_handler)
{
return service_impl_.shutdown(impl, what, ec);
service_impl_.shutdown(impl, what, error_handler);
}
/// Send the given data to the peer.
template <typename ConstBufferSequence>
std::size_t send(implementation_type& impl,
const ConstBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
template <typename Const_Buffers, typename Error_Handler>
std::size_t send(implementation_type& impl, const Const_Buffers& buffers,
socket_base::message_flags flags, Error_Handler error_handler)
{
return service_impl_.send(impl, buffers, flags, ec);
return service_impl_.send(impl, buffers, flags, error_handler);
}
/// Start an asynchronous send.
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(implementation_type& impl, const ConstBufferSequence& buffers,
socket_base::message_flags flags, WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_send(implementation_type& impl, const Const_Buffers& buffers,
socket_base::message_flags flags, Handler handler)
{
service_impl_.async_send(impl, buffers, flags, handler);
}
/// Send a datagram to the specified endpoint.
template <typename ConstBufferSequence>
std::size_t send_to(implementation_type& impl,
const ConstBufferSequence& buffers, const endpoint_type& destination,
socket_base::message_flags flags, asio::error_code& ec)
template <typename Const_Buffers, typename Error_Handler>
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)
{
return service_impl_.send_to(impl, buffers, destination, flags, ec);
return service_impl_.send_to(impl, buffers, destination, flags,
error_handler);
}
/// Start an asynchronous send.
template <typename ConstBufferSequence, typename WriteHandler>
void async_send_to(implementation_type& impl,
const ConstBufferSequence& buffers, const endpoint_type& destination,
socket_base::message_flags flags, WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_send_to(implementation_type& impl, const Const_Buffers& buffers,
const endpoint_type& destination, socket_base::message_flags flags,
Handler handler)
{
service_impl_.async_send_to(impl, buffers, destination, flags, handler);
}
/// Receive some data from the peer.
template <typename MutableBufferSequence>
std::size_t receive(implementation_type& impl,
const MutableBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t receive(implementation_type& impl, const Mutable_Buffers& buffers,
socket_base::message_flags flags, Error_Handler error_handler)
{
return service_impl_.receive(impl, buffers, flags, ec);
return service_impl_.receive(impl, buffers, flags, error_handler);
}
/// Start an asynchronous receive.
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(implementation_type& impl,
const MutableBufferSequence& buffers,
socket_base::message_flags flags, ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_receive(implementation_type& impl, const Mutable_Buffers& buffers,
socket_base::message_flags flags, Handler handler)
{
service_impl_.async_receive(impl, buffers, flags, handler);
}
/// Receive a datagram with the endpoint of the sender.
template <typename MutableBufferSequence>
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags, asio::error_code& ec)
const Mutable_Buffers& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags, Error_Handler error_handler)
{
return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
ec);
error_handler);
}
/// Start an asynchronous receive that will get the endpoint of the sender.
template <typename MutableBufferSequence, typename ReadHandler>
template <typename Mutable_Buffers, typename Handler>
void async_receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags, ReadHandler handler)
const Mutable_Buffers& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags, Handler handler)
{
service_impl_.async_receive_from(impl, buffers, sender_endpoint, flags,
handler);

View File

@ -2,7 +2,7 @@
// deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -28,29 +28,18 @@
#include "asio/detail/epoll_reactor.hpp"
#include "asio/detail/kqueue_reactor.hpp"
#include "asio/detail/select_reactor.hpp"
#include "asio/detail/service_base.hpp"
namespace asio {
/// Default service implementation for a timer.
template <typename TimeType,
typename TimeTraits = asio::time_traits<TimeType> >
template <typename Time_Type,
typename Time_Traits = asio::time_traits<Time_Type> >
class deadline_timer_service
#if defined(GENERATING_DOCUMENTATION)
: public asio::io_service::service
#else
: public asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >
#endif
{
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static asio::io_service::id id;
#endif
/// The time traits type.
typedef TimeTraits traits_type;
typedef Time_Traits traits_type;
/// The time type.
typedef typename traits_type::time_type time_type;
@ -84,8 +73,7 @@ public:
/// Construct a new timer service for the specified io_service.
explicit deadline_timer_service(asio::io_service& io_service)
: asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >(io_service),
: asio::io_service::service(io_service),
service_impl_(asio::use_service<service_impl_type>(io_service))
{
}
@ -108,9 +96,9 @@ public:
}
/// Cancel any asynchronous wait operations associated with the timer.
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
std::size_t cancel(implementation_type& impl)
{
return service_impl_.cancel(impl, ec);
return service_impl_.cancel(impl);
}
/// Get the expiry time for the timer as an absolute time.
@ -121,9 +109,9 @@ public:
/// Set the expiry time for the timer as an absolute time.
std::size_t expires_at(implementation_type& impl,
const time_type& expiry_time, asio::error_code& ec)
const time_type& expiry_time)
{
return service_impl_.expires_at(impl, expiry_time, ec);
return service_impl_.expires_at(impl, expiry_time);
}
/// Get the expiry time for the timer relative to now.
@ -134,20 +122,20 @@ public:
/// Set the expiry time for the timer relative to now.
std::size_t expires_from_now(implementation_type& impl,
const duration_type& expiry_time, asio::error_code& ec)
const duration_type& expiry_time)
{
return service_impl_.expires_from_now(impl, expiry_time, ec);
return service_impl_.expires_from_now(impl, expiry_time);
}
// Perform a blocking wait on the timer.
void wait(implementation_type& impl, asio::error_code& ec)
void wait(implementation_type& impl)
{
service_impl_.wait(impl, ec);
service_impl_.wait(impl);
}
// Start an asynchronous wait on the timer.
template <typename WaitHandler>
void async_wait(implementation_type& impl, WaitHandler handler)
template <typename Handler>
void async_wait(implementation_type& impl, Handler handler)
{
service_impl_.async_wait(impl, handler);
}

View File

@ -2,7 +2,7 @@
// bind_handler.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// buffer_resize_guard.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// buffered_stream_storage.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// call_stack.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// const_buffers_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -29,9 +29,9 @@ namespace asio {
namespace detail {
// A proxy iterator for a sub-range in a list of buffers.
template <typename ConstBufferSequence>
template <typename Const_Buffers>
class const_buffers_iterator
: public boost::iterator_facade<const_buffers_iterator<ConstBufferSequence>,
: public boost::iterator_facade<const_buffers_iterator<Const_Buffers>,
const char, boost::bidirectional_traversal_tag>
{
public:
@ -41,8 +41,7 @@ public:
}
// Create an iterator for the specified position.
const_buffers_iterator(const ConstBufferSequence& buffers,
std::size_t position)
const_buffers_iterator(const Const_Buffers& buffers, std::size_t position)
: begin_(buffers.begin()),
current_(buffers.begin()),
end_(buffers.end()),
@ -108,7 +107,7 @@ private:
return;
}
typename ConstBufferSequence::const_iterator iter = current_;
typename Const_Buffers::const_iterator iter = current_;
while (iter != begin_)
{
--iter;
@ -137,9 +136,9 @@ private:
asio::const_buffer current_buffer_;
std::size_t current_buffer_position_;
typename ConstBufferSequence::const_iterator begin_;
typename ConstBufferSequence::const_iterator current_;
typename ConstBufferSequence::const_iterator end_;
typename Const_Buffers::const_iterator begin_;
typename Const_Buffers::const_iterator current_;
typename Const_Buffers::const_iterator end_;
std::size_t position_;
};

View File

@ -2,7 +2,7 @@
// consuming_buffers.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -32,7 +32,8 @@ template <typename Buffer, typename Buffer_Iterator>
class consuming_buffers_iterator
: public boost::iterator_facade<
consuming_buffers_iterator<Buffer, Buffer_Iterator>,
const Buffer, boost::forward_traversal_tag>
const Buffer,
boost::forward_traversal_tag>
{
public:
// Default constructor creates an end iterator.
@ -46,32 +47,23 @@ public:
consuming_buffers_iterator(bool at_end, const Buffer& first,
Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder)
: at_end_(at_end),
first_(buffer(first, max_size)),
first_(first),
begin_remainder_(begin_remainder),
end_remainder_(end_remainder),
offset_(0)
end_remainder_(end_remainder)
{
}
private:
friend class boost::iterator_core_access;
enum { max_size = 65536 };
void increment()
{
if (!at_end_)
{
if (begin_remainder_ == end_remainder_
|| offset_ + buffer_size(first_) >= max_size)
{
if (begin_remainder_ == end_remainder_)
at_end_ = true;
}
else
{
offset_ += buffer_size(first_);
first_ = buffer(*begin_remainder_++, max_size - offset_);
}
first_ = *begin_remainder_++;
}
}
@ -96,7 +88,6 @@ private:
Buffer first_;
Buffer_Iterator begin_remainder_;
Buffer_Iterator end_remainder_;
std::size_t offset_;
};
// A proxy for a sub-range in a list of buffers.

View File

@ -2,7 +2,7 @@
// deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -27,7 +27,6 @@
#include "asio/io_service.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/socket_ops.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/timer_queue.hpp"
@ -37,8 +36,7 @@ namespace detail {
template <typename Time_Traits, typename Timer_Scheduler>
class deadline_timer_service
: public asio::detail::service_base<
deadline_timer_service<Time_Traits, Timer_Scheduler> >
: public asio::io_service::service
{
public:
// The time type.
@ -58,19 +56,12 @@ public:
// Constructor.
deadline_timer_service(asio::io_service& io_service)
: asio::detail::service_base<
deadline_timer_service<Time_Traits, Timer_Scheduler> >(io_service),
: asio::io_service::service(io_service),
scheduler_(asio::use_service<Timer_Scheduler>(io_service))
{
scheduler_.add_timer_queue(timer_queue_);
}
// Destructor.
~deadline_timer_service()
{
scheduler_.remove_timer_queue(timer_queue_);
}
// Destroy all user-defined handler objects owned by the service.
void shutdown_service()
{
@ -86,21 +77,16 @@ public:
// Destroy a timer implementation.
void destroy(implementation_type& impl)
{
asio::error_code ec;
cancel(impl, ec);
cancel(impl);
}
// Cancel any asynchronous wait operations associated with the timer.
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
std::size_t cancel(implementation_type& impl)
{
if (!impl.might_have_pending_waits)
{
ec = asio::error_code();
return 0;
}
std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl);
impl.might_have_pending_waits = false;
ec = asio::error_code();
return count;
}
@ -112,11 +98,10 @@ public:
// Set the expiry time for the timer as an absolute time.
std::size_t expires_at(implementation_type& impl,
const time_type& expiry_time, asio::error_code& ec)
const time_type& expiry_time)
{
std::size_t count = cancel(impl, ec);
std::size_t count = cancel(impl);
impl.expiry = expiry_time;
ec = asio::error_code();
return count;
}
@ -128,14 +113,13 @@ public:
// Set the expiry time for the timer relative to now.
std::size_t expires_from_now(implementation_type& impl,
const duration_type& expiry_time, asio::error_code& ec)
const duration_type& expiry_time)
{
return expires_at(impl,
Time_Traits::add(Time_Traits::now(), expiry_time), ec);
return expires_at(impl, Time_Traits::add(Time_Traits::now(), expiry_time));
}
// Perform a blocking wait on the timer.
void wait(implementation_type& impl, asio::error_code& ec)
void wait(implementation_type& impl)
{
time_type now = Time_Traits::now();
while (Time_Traits::less_than(now, impl.expiry))
@ -145,11 +129,9 @@ public:
::timeval tv;
tv.tv_sec = timeout.total_seconds();
tv.tv_usec = timeout.total_microseconds() % 1000000;
asio::error_code ec;
socket_ops::select(0, 0, 0, 0, &tv, ec);
socket_ops::select(0, 0, 0, 0, &tv);
now = Time_Traits::now();
}
ec = asio::error_code();
}
template <typename Handler>
@ -163,9 +145,10 @@ public:
{
}
void operator()(const asio::error_code& result)
void operator()(int result)
{
io_service_.post(detail::bind_handler(handler_, result));
asio::error e(result);
io_service_.post(detail::bind_handler(handler_, e));
}
private:
@ -180,7 +163,7 @@ public:
{
impl.might_have_pending_waits = true;
scheduler_.schedule_timer(timer_queue_, impl.expiry,
wait_handler<Handler>(this->io_service(), handler), &impl);
wait_handler<Handler>(io_service(), handler), &impl);
}
private:

View File

@ -2,7 +2,7 @@
// epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -30,9 +30,8 @@
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/io_service.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/hash_map.hpp"
#include "asio/detail/mutex.hpp"
@ -40,7 +39,6 @@
#include "asio/detail/thread.hpp"
#include "asio/detail/reactor_op_queue.hpp"
#include "asio/detail/select_interrupter.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/signal_blocker.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/timer_queue.hpp"
@ -50,12 +48,12 @@ namespace detail {
template <bool Own_Thread>
class epoll_reactor
: public asio::detail::service_base<epoll_reactor<Own_Thread> >
: public asio::io_service::service
{
public:
// Constructor.
epoll_reactor(asio::io_service& io_service)
: asio::detail::service_base<epoll_reactor<Own_Thread> >(io_service),
: asio::io_service::service(io_service),
mutex_(),
epoll_fd_(do_epoll_create()),
wait_in_progress_(false),
@ -141,7 +139,7 @@ public:
return;
if (!read_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (read_op_queue_.enqueue_operation(descriptor, handler))
@ -157,8 +155,8 @@ public:
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno, asio::native_ecat);
read_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
read_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -174,7 +172,7 @@ public:
return;
if (!write_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (write_op_queue_.enqueue_operation(descriptor, handler))
@ -190,8 +188,8 @@ public:
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -219,8 +217,8 @@ public:
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -250,9 +248,9 @@ public:
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
except_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
except_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -298,21 +296,6 @@ public:
timer_queues_.push_back(&timer_queue);
}
// Remove a timer queue from the reactor.
template <typename Time_Traits>
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(mutex_);
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
if (timer_queues_[i] == &timer_queue)
{
timer_queues_.erase(timer_queues_.begin() + i);
return;
}
}
}
// Schedule a timer in the given timer queue to expire at the specified
// absolute time. The handler object will be invoked when the timer expires.
template <typename Time_Traits, typename Handler>
@ -400,10 +383,9 @@ private:
{
if (events[i].events & (EPOLLERR | EPOLLHUP))
{
asio::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);
except_op_queue_.dispatch_all_operations(descriptor, 0);
read_op_queue_.dispatch_all_operations(descriptor, 0);
write_op_queue_.dispatch_all_operations(descriptor, 0);
epoll_event ev = { 0, { 0 } };
ev.events = 0;
@ -415,22 +397,21 @@ private:
bool more_reads = false;
bool more_writes = false;
bool more_except = false;
asio::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, ec);
more_except = except_op_queue_.dispatch_operation(descriptor, 0);
else
more_except = except_op_queue_.has_operation(descriptor);
if (events[i].events & EPOLLIN)
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
else
more_reads = read_op_queue_.has_operation(descriptor);
if (events[i].events & EPOLLOUT)
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
more_writes = write_op_queue_.dispatch_operation(descriptor, 0);
else
more_writes = write_op_queue_.has_operation(descriptor);
@ -446,10 +427,10 @@ private:
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0)
{
ec = asio::error_code(errno, asio::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);
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);
}
}
}
@ -507,9 +488,8 @@ private:
int fd = epoll_create(epoll_size);
if (fd == -1)
{
boost::throw_exception(asio::system_error(
asio::error_code(errno, asio::native_ecat),
"epoll"));
system_exception e("epoll", errno);
boost::throw_exception(e);
}
return fd;
}

View File

@ -2,7 +2,7 @@
// epoll_reactor_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -24,6 +24,8 @@
#include <linux/version.h>
#include "asio/detail/pop_options.hpp"
#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) // Only kernels >= 2.5.45.
// Define this to indicate that epoll is supported on the target platform.
#define ASIO_HAS_EPOLL 1
@ -36,6 +38,7 @@ class epoll_reactor;
} // namespace detail
} // namespace asio
#endif // LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45)
#endif // defined(__linux__)
#endif // !defined(ASIO_DISABLE_EPOLL)

View File

@ -2,7 +2,7 @@
// event.hpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// handler_alloc_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// handler_invoke_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// hash_map.hpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -25,23 +25,11 @@
#include "asio/detail/pop_options.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
namespace asio {
namespace detail {
template <typename T>
inline std::size_t calculate_hash_value(const T& t)
{
return boost::hash_value(t);
}
#if defined(_WIN64)
inline std::size_t calculate_hash_value(SOCKET s)
{
return static_cast<std::size_t>(s);
}
#endif // defined(_WIN64)
using boost::hash_value;
template <typename K, typename V>
class hash_map
@ -49,7 +37,7 @@ class hash_map
{
public:
// The type of a value in the map.
typedef std::pair<K, V> value_type;
typedef std::pair<const K, V> value_type;
// The type of a non-const iterator over the hash map.
typedef typename std::list<value_type>::iterator iterator;
@ -98,7 +86,7 @@ public:
// Find an entry in the map.
iterator find(const K& k)
{
size_t bucket = calculate_hash_value(k) % num_buckets;
size_t bucket = hash_value(k) % num_buckets;
iterator it = buckets_[bucket].first;
if (it == values_.end())
return values_.end();
@ -116,7 +104,7 @@ public:
// Find an entry in the map.
const_iterator find(const K& k) const
{
size_t bucket = calculate_hash_value(k) % num_buckets;
size_t bucket = hash_value(k) % num_buckets;
const_iterator it = buckets_[bucket].first;
if (it == values_.end())
return it;
@ -134,7 +122,7 @@ public:
// Insert a new entry into the map.
std::pair<iterator, bool> insert(const value_type& v)
{
size_t bucket = calculate_hash_value(v.first) % num_buckets;
size_t bucket = hash_value(v.first) % num_buckets;
iterator it = buckets_[bucket].first;
if (it == values_.end())
{
@ -159,7 +147,7 @@ public:
{
assert(it != values_.end());
size_t bucket = calculate_hash_value(it->first) % num_buckets;
size_t bucket = hash_value(it->first) % num_buckets;
bool is_first = (it == buckets_[bucket].first);
bool is_last = (it == buckets_[bucket].last);
if (is_first && is_last)

View File

@ -2,7 +2,7 @@
// io_control.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -90,7 +90,7 @@ public:
// Construct with a specific command value.
bytes_readable(std::size_t value)
: value_(static_cast<detail::ioctl_arg_type>(value))
: value_(value)
{
}

View File

@ -2,7 +2,7 @@
// kqueue_reactor.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -33,16 +33,14 @@
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/io_service.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/task_io_service.hpp"
#include "asio/detail/thread.hpp"
#include "asio/detail/reactor_op_queue.hpp"
#include "asio/detail/select_interrupter.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/signal_blocker.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/timer_queue.hpp"
@ -57,13 +55,12 @@ namespace detail {
template <bool Own_Thread>
class kqueue_reactor
: public asio::detail::service_base<kqueue_reactor<Own_Thread> >
: public asio::io_service::service
{
public:
// Constructor.
kqueue_reactor(asio::io_service& io_service)
: asio::detail::service_base<
kqueue_reactor<Own_Thread> >(io_service),
: asio::io_service::service(io_service),
mutex_(),
kqueue_fd_(do_kqueue_create()),
wait_in_progress_(false),
@ -141,7 +138,7 @@ public:
return;
if (!read_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (read_op_queue_.enqueue_operation(descriptor, handler))
@ -150,8 +147,8 @@ public:
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno, asio::native_ecat);
read_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
read_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -167,7 +164,7 @@ public:
return;
if (!write_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (write_op_queue_.enqueue_operation(descriptor, handler))
@ -176,8 +173,8 @@ public:
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -201,8 +198,8 @@ public:
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -224,8 +221,8 @@ public:
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
@ -238,9 +235,9 @@ public:
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, ec);
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -288,21 +285,6 @@ public:
timer_queues_.push_back(&timer_queue);
}
// Remove a timer queue from the reactor.
template <typename Time_Traits>
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(mutex_);
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
if (timer_queues_[i] == &timer_queue)
{
timer_queues_.erase(timer_queues_.begin() + i);
return;
}
}
}
// Schedule a timer in the given timer queue to expire at the specified
// absolute time. The handler object will be invoked when the timer expires.
template <typename Time_Traits, typename Handler>
@ -396,24 +378,21 @@ private:
bool more_except = false;
if (events[i].flags & EV_ERROR)
{
asio::error_code error(
events[i].data, asio::native_ecat);
int error = events[i].data;
except_op_queue_.dispatch_all_operations(descriptor, error);
read_op_queue_.dispatch_all_operations(descriptor, error);
}
else if (events[i].flags & EV_OOBAND)
{
asio::error_code error;
more_except = except_op_queue_.dispatch_operation(descriptor, error);
more_except = except_op_queue_.dispatch_operation(descriptor, 0);
if (events[i].data > 0)
more_reads = read_op_queue_.dispatch_operation(descriptor, error);
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
else
more_reads = read_op_queue_.has_operation(descriptor);
}
else
{
asio::error_code error;
more_reads = read_op_queue_.dispatch_operation(descriptor, error);
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
more_except = except_op_queue_.has_operation(descriptor);
}
@ -427,7 +406,7 @@ private:
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code error(errno, asio::native_ecat);
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
read_op_queue_.dispatch_all_operations(descriptor, error);
}
@ -438,14 +417,12 @@ private:
bool more_writes = false;
if (events[i].flags & EV_ERROR)
{
asio::error_code error(
events[i].data, asio::native_ecat);
int error = events[i].data;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
else
{
asio::error_code error;
more_writes = write_op_queue_.dispatch_operation(descriptor, error);
more_writes = write_op_queue_.dispatch_operation(descriptor, 0);
}
// Update the descriptor in the kqueue.
@ -456,7 +433,7 @@ private:
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code error(errno, asio::native_ecat);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
@ -512,9 +489,8 @@ private:
int fd = kqueue();
if (fd == -1)
{
boost::throw_exception(asio::system_error(
asio::error_code(errno, asio::native_ecat),
"kqueue"));
system_exception e("kqueue", errno);
boost::throw_exception(e);
}
return fd;
}
@ -563,7 +539,7 @@ private:
// Cancel all operations associated with the given descriptor. The do_cancel
// function of the handler objects will be invoked. This function does not
// acquire the kqueue_reactor's mutex.
// acquire the epoll_reactor's mutex.
void cancel_ops_unlocked(socket_type descriptor)
{
bool interrupt = read_op_queue_.cancel_operations(descriptor);
@ -576,13 +552,13 @@ private:
// Mutex to protect access to internal data.
asio::detail::mutex mutex_;
// The kqueue file descriptor.
// The epoll file descriptor.
int kqueue_fd_;
// Whether the kqueue wait call is currently in progress
bool wait_in_progress_;
// The interrupter is used to break a blocking kevent call.
// The interrupter is used to break a blocking epoll_wait call.
select_interrupter interrupter_;
// The queue of read operations.

View File

@ -2,7 +2,7 @@
// kqueue_reactor_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -1,59 +0,0 @@
//
// local_free_on_block_exit.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP
#define ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/config.hpp>
#include "asio/detail/pop_options.hpp"
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
namespace asio {
namespace detail {
class local_free_on_block_exit
: private noncopyable
{
public:
// Constructor blocks all signals for the calling thread.
explicit local_free_on_block_exit(void* p)
: p_(p)
{
}
// Destructor restores the previous signal mask.
~local_free_on_block_exit()
{
::LocalFree(p_);
}
private:
void* p_;
};
} // namespace detail
} // namespace asio
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP

View File

@ -2,7 +2,7 @@
// mutex.hpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// noncopyable.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// null_event.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// null_mutex.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// null_signal_blocker.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// null_thread.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -28,7 +28,7 @@
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
@ -42,8 +42,7 @@ public:
template <typename Function>
null_thread(Function f)
{
asio::system_error e(
asio::error::operation_not_supported, "thread");
system_exception e("thread", asio::error::not_supported);
boost::throw_exception(e);
}

View File

@ -2,7 +2,7 @@
// null_tss_ptr.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// old_win_sdk_compat.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -24,9 +24,9 @@
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
// Guess whether we are building against on old Platform SDK.
#if !defined(IN6ADDR_ANY_INIT)
#if !defined(IPPROTO_IPV6)
#define ASIO_HAS_OLD_WIN_SDK 1
#endif // !defined(IN6ADDR_ANY_INIT)
#endif // !defined(IPPROTO_IPV6)
#if defined(ASIO_HAS_OLD_WIN_SDK)
@ -305,11 +305,6 @@ inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a)
#endif // defined(ASIO_HAS_OLD_WIN_SDK)
// Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY.
#if !defined(IPV6_V6ONLY)
# define IPV6_V6ONLY 27
#endif
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#include "asio/detail/pop_options.hpp"

View File

@ -2,7 +2,7 @@
// pipe_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// pop_options.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// posix_event.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -28,7 +28,7 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
@ -45,9 +45,7 @@ public:
int error = ::pthread_mutex_init(&mutex_, 0);
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"event");
system_exception e("event", error);
boost::throw_exception(e);
}
@ -55,9 +53,7 @@ public:
if (error != 0)
{
::pthread_mutex_destroy(&mutex_);
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"event");
system_exception e("event", error);
boost::throw_exception(e);
}
}

View File

@ -2,7 +2,7 @@
// posix_fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -31,7 +31,6 @@ public:
posix_fd_set_adapter()
: max_descriptor_(invalid_socket)
{
using namespace std; // Needed for memset on Solaris.
FD_ZERO(&fd_set_);
}

View File

@ -2,7 +2,7 @@
// posix_mutex.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -28,7 +28,7 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/scoped_lock.hpp"
@ -47,9 +47,7 @@ public:
int error = ::pthread_mutex_init(&mutex_, 0);
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"mutex");
system_exception e("mutex", error);
boost::throw_exception(e);
}
}
@ -66,9 +64,7 @@ public:
int error = ::pthread_mutex_lock(&mutex_);
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"mutex");
system_exception e("mutex", error);
boost::throw_exception(e);
}
}
@ -79,9 +75,7 @@ public:
int error = ::pthread_mutex_unlock(&mutex_);
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"mutex");
system_exception e("mutex", error);
boost::throw_exception(e);
}
}

View File

@ -2,7 +2,7 @@
// posix_signal_blocker.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -26,7 +26,6 @@
#include "asio/detail/push_options.hpp"
#include <csignal>
#include <pthread.h>
#include <signal.h>
#include "asio/detail/pop_options.hpp"
#include "asio/detail/noncopyable.hpp"

View File

@ -2,7 +2,7 @@
// posix_thread.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -29,7 +29,7 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
@ -51,9 +51,7 @@ public:
asio_detail_posix_thread_function, arg.get());
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"thread");
system_exception e("thread", error);
boost::throw_exception(e);
}
arg.release();

View File

@ -2,7 +2,7 @@
// posix_tss_ptr.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -28,7 +28,7 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
@ -45,9 +45,7 @@ public:
int error = ::pthread_key_create(&tss_key_, 0);
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"tss");
system_exception e("tss", error);
boost::throw_exception(e);
}
}

View File

@ -2,7 +2,7 @@
// push_options.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// reactor_op_queue.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -100,8 +100,7 @@ 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,
const asio::error_code& result)
bool dispatch_operation(Descriptor descriptor, int result)
{
typename operation_map::iterator i = operations_.find(descriptor);
if (i != operations_.end())
@ -138,8 +137,7 @@ public:
}
// Dispatch all operations corresponding to the descriptor.
void dispatch_all_operations(Descriptor descriptor,
const asio::error_code& result)
void dispatch_all_operations(Descriptor descriptor, int result)
{
typename operation_map::iterator i = operations_.find(descriptor);
if (i != operations_.end())
@ -160,8 +158,8 @@ public:
i->second = this_op;
return;
}
operations_.erase(i);
}
operations_.erase(i);
}
}
@ -181,8 +179,7 @@ public:
// Dispatch the operations corresponding to the ready file descriptors
// contained in the given descriptor set.
template <typename Descriptor_Set>
void dispatch_descriptors(const Descriptor_Set& descriptors,
const asio::error_code& result)
void dispatch_descriptors(const Descriptor_Set& descriptors, int result)
{
typename operation_map::iterator i = operations_.begin();
while (i != operations_.end())
@ -285,7 +282,7 @@ private:
}
// Perform the operation.
bool invoke(const asio::error_code& result)
bool invoke(int result)
{
return invoke_func_(this, result);
}
@ -297,8 +294,7 @@ private:
}
protected:
typedef bool (*invoke_func_type)(op_base*,
const asio::error_code&);
typedef bool (*invoke_func_type)(op_base*, int);
typedef void (*destroy_func_type)(op_base*);
// Construct an operation for the given descriptor.
@ -347,8 +343,7 @@ private:
}
// Invoke the handler.
static bool invoke_handler(op_base* base,
const asio::error_code& result)
static bool invoke_handler(op_base* base, int result)
{
return static_cast<op<Handler>*>(base)->handler_(result);
}

View File

@ -2,7 +2,7 @@
// resolver_service.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -29,7 +29,6 @@
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/socket_ops.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/thread.hpp"
@ -39,7 +38,7 @@ namespace detail {
template <typename Protocol>
class resolver_service
: public asio::detail::service_base<resolver_service<Protocol> >
: public asio::io_service::service
{
private:
// Helper class to perform exception-safe cleanup of addrinfo objects.
@ -85,8 +84,7 @@ public:
// Constructor.
resolver_service(asio::io_service& io_service)
: asio::detail::service_base<
resolver_service<Protocol> >(io_service),
: asio::io_service::service(io_service),
mutex_(),
work_io_service_(new asio::io_service),
work_(new asio::io_service::work(*work_io_service_)),
@ -106,7 +104,7 @@ public:
work_.reset();
if (work_io_service_)
{
work_io_service_->stop();
work_io_service_->interrupt();
if (work_thread_)
{
work_thread_->join();
@ -134,21 +132,23 @@ public:
}
// Resolve a query to a list of entries.
template <typename Error_Handler>
iterator_type resolve(implementation_type&, const query_type& query,
asio::error_code& ec)
Error_Handler error_handler)
{
asio::detail::addrinfo_type* address_info = 0;
std::string host_name = query.host_name();
std::string service_name = query.service_name();
asio::detail::addrinfo_type hints = query.hints();
socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0,
service_name.c_str(), &hints, &address_info, ec);
int result = socket_ops::getaddrinfo(
host_name.length() ? host_name.c_str() : 0,
service_name.c_str(), &hints, &address_info);
auto_addrinfo auto_address_info(address_info);
if (ec)
error_handler(asio::error(result));
if (result != 0)
return iterator_type();
return iterator_type::create(address_info, host_name, service_name);
}
@ -173,7 +173,8 @@ public:
{
iterator_type iterator;
io_service_.post(asio::detail::bind_handler(handler_,
asio::error::operation_aborted, iterator));
asio::error(asio::error::operation_aborted),
iterator));
return;
}
@ -182,17 +183,18 @@ public:
std::string host_name = query_.host_name();
std::string service_name = query_.service_name();
asio::detail::addrinfo_type hints = query_.hints();
asio::error_code ec;
socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0,
service_name.c_str(), &hints, &address_info, ec);
int result = socket_ops::getaddrinfo(
host_name.length() ? host_name.c_str() : 0,
service_name.c_str(), &hints, &address_info);
auto_addrinfo auto_address_info(address_info);
// Invoke the handler and pass the result.
asio::error e(result);
iterator_type iterator;
if (!ec)
if (result == 0)
iterator = iterator_type::create(address_info, host_name, service_name);
io_service_.post(asio::detail::bind_handler(
handler_, ec, iterator));
handler_, e, iterator));
}
private:
@ -213,31 +215,32 @@ public:
start_work_thread();
work_io_service_->post(
resolve_query_handler<Handler>(
impl, query, this->io_service(), handler));
impl, query, io_service(), handler));
}
}
// Resolve an endpoint to a list of entries.
template <typename Error_Handler>
iterator_type resolve(implementation_type&,
const endpoint_type& endpoint, asio::error_code& ec)
const endpoint_type& endpoint, Error_Handler error_handler)
{
// 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;
socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
if (ec)
int result = socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
if (result)
{
flags |= NI_NUMERICSERV;
socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
result = socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
}
if (ec)
error_handler(asio::error(result));
if (result != 0)
return iterator_type();
return iterator_type::create(endpoint, host_name, service_name);
}
@ -263,7 +266,8 @@ public:
{
iterator_type iterator;
io_service_.post(asio::detail::bind_handler(handler_,
asio::error::operation_aborted, iterator));
asio::error(asio::error::operation_aborted),
iterator));
return;
}
@ -273,22 +277,22 @@ public:
char host_name[NI_MAXHOST];
char service_name[NI_MAXSERV];
int flags = endpoint_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
asio::error_code ec;
socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
if (ec)
int result = socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
if (result)
{
flags |= NI_NUMERICSERV;
socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
result = socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags);
}
// Invoke the handler and pass the result.
asio::error e(result);
iterator_type iterator;
if (!ec)
if (result == 0)
iterator = iterator_type::create(endpoint_, host_name, service_name);
io_service_.post(asio::detail::bind_handler(
handler_, ec, iterator));
handler_, e, iterator));
}
private:
@ -309,7 +313,7 @@ public:
start_work_thread();
work_io_service_->post(
resolve_endpoint_handler<Handler>(
impl, endpoint, this->io_service(), handler));
impl, endpoint, io_service(), handler));
}
}

View File

@ -2,7 +2,7 @@
// scoped_lock.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// select_reactor.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -31,15 +31,14 @@
#include "asio/detail/fd_set_adapter.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/task_io_service.hpp"
#include "asio/detail/thread.hpp"
#include "asio/detail/reactor_op_queue.hpp"
#include "asio/detail/select_interrupter.hpp"
#include "asio/detail/select_reactor_fwd.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/signal_blocker.hpp"
#include "asio/detail/socket_ops.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/task_io_service.hpp"
#include "asio/detail/thread.hpp"
#include "asio/detail/timer_queue.hpp"
namespace asio {
@ -47,13 +46,12 @@ namespace detail {
template <bool Own_Thread>
class select_reactor
: public asio::detail::service_base<select_reactor<Own_Thread> >
: public asio::io_service::service
{
public:
// Constructor.
select_reactor(asio::io_service& io_service)
: asio::detail::service_base<
select_reactor<Own_Thread> >(io_service),
: asio::io_service::service(io_service),
mutex_(),
select_in_progress_(false),
interrupter_(),
@ -196,21 +194,6 @@ public:
timer_queues_.push_back(&timer_queue);
}
// Remove a timer queue from the reactor.
template <typename Time_Traits>
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(mutex_);
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
if (timer_queues_[i] == &timer_queue)
{
timer_queues_.erase(timer_queues_.begin() + i);
return;
}
}
}
// Schedule a timer in the given timer queue to expire at the specified
// absolute time. The handler object will be invoked when the timer expires.
template <typename Time_Traits, typename Handler>
@ -292,9 +275,8 @@ private:
timeval* tv = block ? get_timeout(tv_buf) : &tv_buf;
select_in_progress_ = true;
lock.unlock();
asio::error_code ec;
int retval = socket_ops::select(static_cast<int>(max_fd + 1),
read_fds, write_fds, except_fds, tv, ec);
read_fds, write_fds, except_fds, tv);
lock.lock();
select_in_progress_ = false;
@ -310,12 +292,9 @@ 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,
asio::error_code());
read_op_queue_.dispatch_descriptors(read_fds,
asio::error_code());
write_op_queue_.dispatch_descriptors(write_fds,
asio::error_code());
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_cancellations();
read_op_queue_.dispatch_cancellations();
write_op_queue_.dispatch_cancellations();

View File

@ -2,7 +2,7 @@
// select_reactor_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -1,49 +0,0 @@
//
// service_base.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_SERVICE_BASE_HPP
#define ASIO_DETAIL_SERVICE_BASE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
#include "asio/io_service.hpp"
#include "asio/detail/service_id.hpp"
namespace asio {
namespace detail {
// Special service base class to keep classes header-file only.
template <typename Type>
class service_base
: public asio::io_service::service
{
public:
static asio::detail::service_id<Type> id;
// Constructor.
service_base(asio::io_service& io_service)
: asio::io_service::service(io_service)
{
}
};
template <typename Type>
asio::detail::service_id<Type> service_base<Type>::id;
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_SERVICE_BASE_HPP

View File

@ -1,37 +0,0 @@
//
// service_id.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_SERVICE_ID_HPP
#define ASIO_DETAIL_SERVICE_ID_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
#include "asio/io_service.hpp"
namespace asio {
namespace detail {
// Special derived service id type to keep classes header-file only.
template <typename Type>
class service_id
: public asio::io_service::id
{
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_SERVICE_ID_HPP

View File

@ -2,7 +2,7 @@
// service_registry.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -22,20 +22,19 @@
#include <typeinfo>
#include "asio/detail/pop_options.hpp"
#include "asio/io_service.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/service_id.hpp"
namespace asio {
namespace detail {
template <typename Owner>
class service_registry
: private noncopyable
{
public:
// Constructor.
service_registry(asio::io_service& o)
service_registry(Owner& o)
: owner_(o),
first_service_(0)
{
@ -47,7 +46,7 @@ public:
// Shutdown all services. This must be done in a separate loop before the
// services are destroyed since the destructors of user-defined handler
// objects may try to access other service objects.
asio::io_service::service* service = first_service_;
typename Owner::service* service = first_service_;
while (service)
{
service->shutdown_service();
@ -57,7 +56,7 @@ public:
// Destroy all services.
while (first_service_)
{
asio::io_service::service* next_service = first_service_->next_;
typename Owner::service* next_service = first_service_->next_;
delete first_service_;
first_service_ = next_service;
}
@ -72,10 +71,10 @@ public:
asio::detail::mutex::scoped_lock lock(mutex_);
// First see if there is an existing service object for the given type.
asio::io_service::service* service = first_service_;
typename Owner::service* service = first_service_;
while (service)
{
if (service_id_matches(*service, Service::id))
if (*service->type_info_ == typeid(Service))
return *static_cast<Service*>(service);
service = service->next_;
}
@ -85,7 +84,7 @@ public:
// service's constructor.
lock.unlock();
std::auto_ptr<Service> new_service(new Service(owner_));
init_service_id(*new_service, Service::id);
new_service->type_info_ = &typeid(Service);
Service& new_service_ref = *new_service;
lock.lock();
@ -94,7 +93,7 @@ public:
service = first_service_;
while (service)
{
if (service_id_matches(*service, Service::id))
if (*service->type_info_ == typeid(Service))
return *static_cast<Service*>(service);
service = service->next_;
}
@ -114,20 +113,18 @@ public:
asio::detail::mutex::scoped_lock lock(mutex_);
// Check if there is an existing service object for the given type.
asio::io_service::service* service = first_service_;
typename Owner::service* service = first_service_;
while (service)
{
if (service_id_matches(*service, Service::id))
if (*service->type_info_ == typeid(Service))
return false;
service = service->next_;
}
// Take ownership of the service object.
init_service_id(*new_service, Service::id);
new_service->type_info_ = &typeid(Service);
new_service->next_ = first_service_;
first_service_ = new_service;
return true;
}
// Check whether a service object of the specified type already exists.
@ -136,10 +133,10 @@ public:
{
asio::detail::mutex::scoped_lock lock(mutex_);
asio::io_service::service* service = first_service_;
typename Owner::service* service = first_service_;
while (service)
{
if (service_id_matches(*service, Service::id))
if (*service->type_info_ == typeid(Service))
return true;
service = service->next_;
}
@ -148,46 +145,14 @@ public:
}
private:
// Set a service's id.
void init_service_id(asio::io_service::service& service,
const asio::io_service::id& id)
{
service.type_info_ = 0;
service.id_ = &id;
}
// Set a service's id.
template <typename Service>
void init_service_id(asio::io_service::service& service,
const asio::detail::service_id<Service>& /*id*/)
{
service.type_info_ = &typeid(Service);
service.id_ = 0;
}
// Check if a service matches the given id.
bool service_id_matches(const asio::io_service::service& service,
const asio::io_service::id& id)
{
return service.id_ == &id;
}
// Check if a service matches the given id.
template <typename Service>
bool service_id_matches(const asio::io_service::service& service,
const asio::detail::service_id<Service>& /*id*/)
{
return service.type_info_ != 0 && *service.type_info_ == typeid(Service);
}
// Mutex to protect access to internal data.
mutable asio::detail::mutex mutex_;
// The owner of this service registry and the services it contains.
asio::io_service& owner_;
Owner& owner_;
// The first service in the list of contained services.
asio::io_service::service* first_service_;
typename Owner::service* first_service_;
};
} // namespace detail

View File

@ -1,30 +0,0 @@
//
// service_registry_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP
#define ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
class service_registry;
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP

View File

@ -2,7 +2,7 @@
// signal_blocker.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// signal_init.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// socket_holder.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -44,10 +44,7 @@ public:
~socket_holder()
{
if (socket_ != invalid_socket)
{
asio::error_code ec;
socket_ops::close(socket_, ec);
}
socket_ops::close(socket_);
}
// Get the underlying socket.
@ -61,8 +58,7 @@ public:
{
if (socket_ != invalid_socket)
{
asio::error_code ec;
socket_ops::close(socket_, ec);
socket_ops::close(socket_);
socket_ = invalid_socket;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
// socket_option.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -19,7 +19,6 @@
#include "asio/detail/push_options.hpp"
#include <cstddef>
#include <stdexcept>
#include <boost/config.hpp>
#include "asio/detail/pop_options.hpp"
@ -41,34 +40,21 @@ public:
}
// Construct with a specific option value.
explicit boolean(bool v)
: value_(v ? 1 : 0)
boolean(bool value)
: value_(value ? 1 : 0)
{
}
// Set the current value of the boolean.
boolean& operator=(bool v)
// Set the value of the boolean.
void set(bool value)
{
value_ = v ? 1 : 0;
return *this;
value_ = value ? 1 : 0;
}
// Get the current value of the boolean.
bool value() const
bool get() const
{
return !!value_;
}
// Convert to bool.
operator bool() const
{
return !!value_;
}
// Test for false.
bool operator!() const
{
return !value_;
return value_;
}
// Get the level of the socket option.
@ -106,14 +92,6 @@ public:
return sizeof(value_);
}
// Set the size of the boolean data.
template <typename Protocol>
void resize(const Protocol&, std::size_t s)
{
if (s != sizeof(value_))
throw std::length_error("boolean socket option resize");
}
private:
int value_;
};
@ -130,20 +108,19 @@ public:
}
// Construct with a specific option value.
explicit integer(int v)
: value_(v)
integer(int value)
: value_(value)
{
}
// Set the value of the int option.
integer& operator=(int v)
void set(int value)
{
value_ = v;
return *this;
value_ = value;
}
// Get the current value of the int option.
int value() const
int get() const
{
return value_;
}
@ -183,16 +160,76 @@ public:
return sizeof(value_);
}
// Set the size of the int data.
template <typename Protocol>
void resize(const Protocol&, std::size_t s)
private:
int value_;
};
// Helper template for implementing unsigned integer options.
template <int Level, int Name>
class unsigned_integer
{
public:
// Default constructor.
unsigned_integer()
: value_(0)
{
if (s != sizeof(value_))
throw std::length_error("integer socket option resize");
}
// Construct with a specific option value.
unsigned_integer(unsigned int value)
: value_(value)
{
}
// Set the value of the int option.
void set(unsigned int value)
{
value_ = value;
}
// Get the current value of the int option.
unsigned int get() const
{
return value_;
}
// Get the level of the socket option.
template <typename Protocol>
int level(const Protocol&) const
{
return Level;
}
// Get the name of the socket option.
template <typename Protocol>
int name(const Protocol&) const
{
return Name;
}
// Get the address of the int data.
template <typename Protocol>
unsigned int* data(const Protocol&)
{
return &value_;
}
// Get the address of the int data.
template <typename Protocol>
const unsigned int* data(const Protocol&) const
{
return &value_;
}
// Get the size of the int data.
template <typename Protocol>
std::size_t size(const Protocol&) const
{
return sizeof(value_);
}
private:
int value_;
unsigned int value_;
};
// Helper template for implementing linger options.
@ -208,10 +245,10 @@ public:
}
// Construct with specific option values.
linger(bool e, int t)
linger(bool value, unsigned short timeout)
{
enabled(e);
timeout(t);
value_.l_onoff = value ? 1 : 0;
value_.l_linger = timeout;
}
// Set the value for whether linger is enabled.
@ -227,19 +264,15 @@ public:
}
// Set the value for the linger timeout.
void timeout(int value)
void timeout(unsigned short value)
{
#if defined(WIN32)
value_.l_linger = static_cast<u_short>(value);
#else
value_.l_linger = value;
#endif
}
// Get the value for the linger timeout.
int timeout() const
unsigned short timeout() const
{
return static_cast<int>(value_.l_linger);
return value_.l_linger;
}
// Get the level of the socket option.
@ -277,14 +310,6 @@ public:
return sizeof(value_);
}
// Set the size of the int data.
template <typename Protocol>
void resize(const Protocol&, std::size_t s)
{
if (s != sizeof(value_))
throw std::length_error("linger socket option resize");
}
private:
::linger value_;
};

View File

@ -2,7 +2,7 @@
// socket_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -22,7 +22,6 @@
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/socket_holder.hpp"
#include "asio/detail/socket_ops.hpp"
#include "asio/detail/socket_types.hpp"
@ -36,18 +35,17 @@ public:
// Constructor.
socket_select_interrupter()
{
asio::error_code ec;
socket_holder acceptor(socket_ops::socket(
AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
socket_holder acceptor(socket_ops::socket(AF_INET, SOCK_STREAM,
IPPROTO_TCP));
if (acceptor.get() == invalid_socket)
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
int opt = 1;
socket_ops::setsockopt(acceptor.get(),
SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec);
SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sockaddr_in4_type addr;
socket_addr_len_type addr_len = sizeof(addr);
@ -55,69 +53,67 @@ 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, ec) == socket_error_retval)
addr_len) == socket_error_retval)
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr,
&addr_len, ec) == socket_error_retval)
if (getsockname(acceptor.get(), (socket_addr_type*)&addr, &addr_len)
== socket_error_retval)
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
if (socket_ops::listen(acceptor.get(),
SOMAXCONN, ec) == socket_error_retval)
if (socket_ops::listen(acceptor.get(), SOMAXCONN) == socket_error_retval)
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
socket_holder client(socket_ops::socket(
AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
socket_holder client(socket_ops::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
if (client.get() == invalid_socket)
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr,
addr_len, ec) == socket_error_retval)
addr_len) == socket_error_retval)
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec));
socket_holder server(socket_ops::accept(acceptor.get(), 0, 0));
if (server.get() == invalid_socket)
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
ioctl_arg_type non_blocking = 1;
if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking, ec))
if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking))
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
opt = 1;
socket_ops::setsockopt(client.get(),
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
non_blocking = 1;
if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking, ec))
if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking))
{
asio::system_error e(ec, "socket_select_interrupter");
asio::error e(socket_ops::get_error());
boost::throw_exception(e);
}
opt = 1;
socket_ops::setsockopt(server.get(),
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
read_descriptor_ = server.release();
write_descriptor_ = client.release();
@ -126,11 +122,10 @@ public:
// Destructor.
~socket_select_interrupter()
{
asio::error_code ec;
if (read_descriptor_ != invalid_socket)
socket_ops::close(read_descriptor_, ec);
socket_ops::close(read_descriptor_);
if (write_descriptor_ != invalid_socket)
socket_ops::close(write_descriptor_, ec);
socket_ops::close(write_descriptor_);
}
// Interrupt the select call.
@ -139,8 +134,7 @@ public:
char byte = 0;
socket_ops::buf b;
socket_ops::init_buf(b, &byte, 1);
asio::error_code ec;
socket_ops::send(write_descriptor_, &b, 1, 0, ec);
socket_ops::send(write_descriptor_, &b, 1, 0);
}
// Reset the select interrupt. Returns true if the call was interrupted.
@ -149,11 +143,10 @@ public:
char data[1024];
socket_ops::buf b;
socket_ops::init_buf(b, data, sizeof(data));
asio::error_code ec;
int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0);
bool was_interrupted = (bytes_read > 0);
while (bytes_read == sizeof(data))
bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0);
return was_interrupted;
}

View File

@ -2,7 +2,7 @@
// socket_types.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -100,7 +100,6 @@
# include <net/if.h>
# if defined(__sun)
# include <sys/filio.h>
# include <sys/sockio.h>
# endif
#endif
#include "asio/detail/pop_options.hpp"
@ -170,6 +169,13 @@ const int message_do_not_route = MSG_DONTROUTE;
const int custom_socket_option_level = 0xA5100000;
const int enable_connection_aborted_option = 1;
#if defined(_WIN64)
std::size_t hash_value(SOCKET s)
{
return static_cast<std::size_t>(s);
}
#endif // defined(_WIN64)
} // namespace detail
} // namespace asio

View File

@ -2,7 +2,7 @@
// strand_service.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -30,14 +30,13 @@
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/service_base.hpp"
namespace asio {
namespace detail {
// Default service implementation for a strand.
class strand_service
: public asio::detail::service_base<strand_service>
: public asio::io_service::service
{
public:
class handler_base;
@ -242,9 +241,12 @@ public:
return impl_->handler_storage_.address();
}
// The asio_handler_invoke hook is not defined here since the default one
// provides the correct behaviour, and including it here breaks MSVC 7.1
// in some situations.
template <typename Function>
friend void asio_handler_invoke(Function function,
invoke_current_handler*)
{
function();
}
private:
strand_service& service_impl_;
@ -352,7 +354,7 @@ public:
// Construct a new strand service for the specified io_service.
explicit strand_service(asio::io_service& io_service)
: asio::detail::service_base<strand_service>(io_service),
: asio::io_service::service(io_service),
mutex_(),
impl_list_(0)
{
@ -428,7 +430,7 @@ public:
// This handler now has the lock, so can be dispatched immediately.
impl->current_handler_ = ptr.get();
lock.unlock();
this->io_service().dispatch(invoke_current_handler(*this, impl));
io_service().dispatch(invoke_current_handler(*this, impl));
ptr.release();
}
else
@ -468,7 +470,7 @@ public:
// This handler now has the lock, so can be dispatched immediately.
impl->current_handler_ = ptr.get();
lock.unlock();
this->io_service().post(invoke_current_handler(*this, impl));
io_service().post(invoke_current_handler(*this, impl));
ptr.release();
}
else

View File

@ -2,7 +2,7 @@
// task_io_service.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -17,14 +17,12 @@
#include "asio/detail/push_options.hpp"
#include "asio/error_code.hpp"
#include "asio/io_service.hpp"
#include "asio/detail/call_stack.hpp"
#include "asio/detail/event.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/task_io_service_fwd.hpp"
namespace asio {
@ -32,27 +30,23 @@ namespace detail {
template <typename Task>
class task_io_service
: public asio::detail::service_base<task_io_service<Task> >
: public asio::io_service::service
{
public:
// Constructor.
task_io_service(asio::io_service& io_service)
: asio::detail::service_base<task_io_service<Task> >(io_service),
: asio::io_service::service(io_service),
mutex_(),
task_(use_service<Task>(io_service)),
outstanding_work_(0),
handler_queue_(&task_handler_),
handler_queue_end_(&task_handler_),
stopped_(false),
interrupted_(false),
shutdown_(false),
first_idle_thread_(0)
{
}
void init(size_t /*concurrency_hint*/)
{
}
// Destroy all user-defined handler objects owned by the service.
void shutdown_service()
{
@ -75,7 +69,7 @@ public:
}
// Run the event loop until interrupted or no more work.
size_t run(asio::error_code& ec)
size_t run()
{
typename call_stack<task_io_service>::context ctx(this);
@ -86,14 +80,14 @@ public:
asio::detail::mutex::scoped_lock lock(mutex_);
size_t n = 0;
while (do_one(lock, &this_idle_thread, ec))
while (do_one(lock, &this_idle_thread))
if (n != (std::numeric_limits<size_t>::max)())
++n;
return n;
}
// Run until interrupted or one operation is performed.
size_t run_one(asio::error_code& ec)
size_t run_one()
{
typename call_stack<task_io_service>::context ctx(this);
@ -103,45 +97,45 @@ public:
asio::detail::mutex::scoped_lock lock(mutex_);
return do_one(lock, &this_idle_thread, ec);
return do_one(lock, &this_idle_thread);
}
// Poll for operations without blocking.
size_t poll(asio::error_code& ec)
size_t poll()
{
typename call_stack<task_io_service>::context ctx(this);
asio::detail::mutex::scoped_lock lock(mutex_);
size_t n = 0;
while (do_one(lock, 0, ec))
while (do_one(lock, 0))
if (n != (std::numeric_limits<size_t>::max)())
++n;
return n;
}
// Poll for one operation without blocking.
size_t poll_one(asio::error_code& ec)
size_t poll_one()
{
typename call_stack<task_io_service>::context ctx(this);
asio::detail::mutex::scoped_lock lock(mutex_);
return do_one(lock, 0, ec);
return do_one(lock, 0);
}
// Interrupt the event processing loop.
void stop()
void interrupt()
{
asio::detail::mutex::scoped_lock lock(mutex_);
stop_all_threads();
interrupt_all_threads();
}
// Reset in preparation for a subsequent run invocation.
void reset()
{
asio::detail::mutex::scoped_lock lock(mutex_);
stopped_ = false;
interrupted_ = false;
}
// Notify that some work has started.
@ -156,7 +150,7 @@ public:
{
asio::detail::mutex::scoped_lock lock(mutex_);
if (--outstanding_work_ == 0)
stop_all_threads();
interrupt_all_threads();
}
// Request invocation of the given handler.
@ -210,18 +204,17 @@ private:
struct idle_thread_info;
size_t do_one(asio::detail::mutex::scoped_lock& lock,
idle_thread_info* this_idle_thread, asio::error_code& ec)
idle_thread_info* this_idle_thread)
{
if (outstanding_work_ == 0 && !stopped_)
if (outstanding_work_ == 0 && !interrupted_)
{
stop_all_threads();
ec = asio::error_code();
interrupt_all_threads();
return 0;
}
bool polling = !this_idle_thread;
bool task_has_run = false;
while (!stopped_)
while (!interrupted_)
{
if (handler_queue_)
{
@ -237,10 +230,7 @@ private:
{
// If the task has already run and we're polling then we're done.
if (task_has_run && polling)
{
ec = asio::error_code();
return 0;
}
task_has_run = true;
task_cleanup c(lock, *this);
@ -257,7 +247,6 @@ private:
// Invoke the handler. May throw an exception.
h->call(); // call() deletes the handler object
ec = asio::error_code();
return 1;
}
}
@ -292,19 +281,17 @@ private:
}
else
{
ec = asio::error_code();
return 0;
}
}
ec = asio::error_code();
return 0;
}
// Stop the task and all idle threads.
void stop_all_threads()
// Interrupt the task and all idle threads.
void interrupt_all_threads()
{
stopped_ = true;
interrupted_ = true;
interrupt_all_idle_threads();
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
task_.interrupt();
@ -339,7 +326,6 @@ private:
}
class task_cleanup;
friend class task_cleanup;
// The base class for all handler wrappers. A function pointer is used
// instead of virtual functions to avoid the associated overhead.
@ -426,6 +412,8 @@ private:
};
// Helper class to perform task-related operations on block exit.
class task_cleanup;
friend class task_cleanup;
class task_cleanup
{
public:
@ -478,7 +466,7 @@ private:
{
lock_.lock();
if (--task_io_service_.outstanding_work_ == 0)
task_io_service_.stop_all_threads();
task_io_service_.interrupt_all_threads();
}
private:
@ -512,8 +500,8 @@ private:
// The end of a linked list of handlers that are ready to be delivered.
handler_base* handler_queue_end_;
// Flag to indicate that the dispatcher has been stopped.
bool stopped_;
// Flag to indicate that the dispatcher has been interrupted.
bool interrupted_;
// Flag to indicate that the dispatcher has been shut down.
bool shutdown_;

View File

@ -2,7 +2,7 @@
// task_io_service_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// thread.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -1,44 +0,0 @@
//
// throw_error.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_THROW_ERROR_HPP
#define ASIO_DETAIL_THROW_ERROR_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/error_code.hpp"
#include "asio/system_error.hpp"
namespace asio {
namespace detail {
inline void throw_error(const asio::error_code& err)
{
if (err)
{
asio::system_error e(err);
boost::throw_exception(e);
}
}
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_THROW_ERROR_HPP

View File

@ -2,7 +2,7 @@
// timer_queue.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -111,7 +111,7 @@ public:
{
timer_base* t = heap_[0];
remove_timer(t);
t->invoke(asio::error_code());
t->invoke(0);
}
}
@ -160,7 +160,7 @@ private:
{
public:
// Perform the timer operation and then destroy.
void invoke(const asio::error_code& result)
void invoke(int result)
{
invoke_func_(this, result);
}
@ -172,8 +172,7 @@ private:
}
protected:
typedef void (*invoke_func_type)(timer_base*,
const asio::error_code&);
typedef void (*invoke_func_type)(timer_base*, int);
typedef void (*destroy_func_type)(timer_base*);
// Constructor.
@ -235,8 +234,7 @@ private:
}
// Invoke the handler and then destroy it.
static void invoke_handler(timer_base* base,
const asio::error_code& result)
static void invoke_handler(timer_base* base, int result)
{
std::auto_ptr<timer<Handler> > t(static_cast<timer<Handler>*>(base));
t->handler_(result);

View File

@ -2,7 +2,7 @@
// timer_queue_base.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// tss_ptr.hpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

View File

@ -2,7 +2,7 @@
// win_event.hpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -23,7 +23,7 @@
#if defined(BOOST_WINDOWS)
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
@ -45,9 +45,7 @@ public:
if (!event_)
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
"event");
system_exception e("event", last_error);
boost::throw_exception(e);
}
}

View File

@ -2,7 +2,7 @@
// win_fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -28,8 +28,6 @@ namespace detail {
class win_fd_set_adapter
{
public:
enum { win_fd_set_size = 1024 };
win_fd_set_adapter()
: max_descriptor_(invalid_socket)
{
@ -64,6 +62,7 @@ public:
private:
// This structure is defined to be compatible with the Windows API fd_set
// structure, but without being dependent on the value of FD_SETSIZE.
enum { win_fd_set_size = 1024 };
struct win_fd_set
{
u_int fd_count;

View File

@ -2,7 +2,7 @@
// win_iocp_io_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)
@ -27,11 +27,10 @@
#include "asio/detail/pop_options.hpp"
#include "asio/io_service.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/call_stack.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/win_iocp_operation.hpp"
@ -39,7 +38,7 @@ namespace asio {
namespace detail {
class win_iocp_io_service
: public asio::detail::service_base<win_iocp_io_service>
: public asio::io_service::service
{
public:
// Base class for all operations.
@ -47,24 +46,16 @@ public:
// Constructor.
win_iocp_io_service(asio::io_service& io_service)
: asio::detail::service_base<win_iocp_io_service>(io_service),
iocp_(),
: asio::io_service::service(io_service),
iocp_(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0)),
outstanding_work_(0),
stopped_(0),
interrupted_(0),
shutdown_(0)
{
}
void init(size_t concurrency_hint)
{
iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,
static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0))));
if (!iocp_.handle)
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
"iocp");
system_exception e("iocp", last_error);
boost::throw_exception(e);
}
}
@ -83,98 +74,84 @@ public:
DWORD_PTR completion_key = 0;
#endif
LPOVERLAPPED overlapped = 0;
::SetLastError(0);
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle,
::GetQueuedCompletionStatus(iocp_.handle,
&bytes_transferred, &completion_key, &overlapped, 0);
DWORD last_error = ::GetLastError();
if (!ok && overlapped == 0 && last_error == WAIT_TIMEOUT)
if (last_error == WAIT_TIMEOUT)
break;
if (overlapped)
static_cast<operation*>(overlapped)->destroy();
}
}
// Register a handle with the IO completion port.
void register_handle(HANDLE handle)
// Register a socket with the IO completion port.
void register_socket(socket_type sock)
{
::CreateIoCompletionPort(handle, iocp_.handle, 0, 0);
HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
::CreateIoCompletionPort(sock_as_handle, iocp_.handle, 0, 0);
}
// Run the event loop until stopped or no more work.
size_t run(asio::error_code& ec)
// Run the event loop until interrupted or no more work.
size_t run()
{
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
{
ec = asio::error_code();
return 0;
}
call_stack<win_iocp_io_service>::context ctx(this);
size_t n = 0;
while (do_one(true, ec))
while (do_one(true))
if (n != (std::numeric_limits<size_t>::max)())
++n;
return n;
}
// Run until stopped or one operation is performed.
size_t run_one(asio::error_code& ec)
// Run until interrupted or one operation is performed.
size_t run_one()
{
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
{
ec = asio::error_code();
return 0;
}
call_stack<win_iocp_io_service>::context ctx(this);
return do_one(true, ec);
return do_one(true);
}
// Poll for operations without blocking.
size_t poll(asio::error_code& ec)
size_t poll()
{
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
{
ec = asio::error_code();
return 0;
}
call_stack<win_iocp_io_service>::context ctx(this);
size_t n = 0;
while (do_one(false, ec))
while (do_one(false))
if (n != (std::numeric_limits<size_t>::max)())
++n;
return n;
}
// Poll for one operation without blocking.
size_t poll_one(asio::error_code& ec)
size_t poll_one()
{
if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
{
ec = asio::error_code();
return 0;
}
call_stack<win_iocp_io_service>::context ctx(this);
return do_one(false, ec);
return do_one(false);
}
// Stop the event processing loop.
void stop()
// Interrupt the event processing loop.
void interrupt()
{
if (::InterlockedExchange(&stopped_, 1) == 0)
if (::InterlockedExchange(&interrupted_, 1) == 0)
{
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
"pqcs");
system_exception e("pqcs", last_error);
boost::throw_exception(e);
}
}
@ -183,7 +160,7 @@ public:
// Reset in preparation for a subsequent run invocation.
void reset()
{
::InterlockedExchange(&stopped_, 0);
::InterlockedExchange(&interrupted_, 0);
}
// Notify that some work has started.
@ -196,7 +173,7 @@ public:
void work_finished()
{
if (::InterlockedDecrement(&outstanding_work_) == 0)
stop();
interrupt();
}
// Request invocation of the given handler.
@ -227,9 +204,7 @@ public:
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, ptr.get()))
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
"pqcs");
system_exception e("pqcs", last_error);
boost::throw_exception(e);
}
@ -246,9 +221,7 @@ public:
bytes_transferred, op_last_error, op))
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
"pqcs");
system_exception e("pqcs", last_error);
boost::throw_exception(e);
}
}
@ -257,7 +230,7 @@ private:
// Dequeues at most one operation from the I/O completion port, and then
// executes it. Returns the number of operations that were dequeued (i.e.
// either 0 or 1).
size_t do_one(bool block, asio::error_code& ec)
size_t do_one(bool block)
{
for (;;)
{
@ -271,16 +244,11 @@ private:
LPOVERLAPPED overlapped = 0;
::SetLastError(0);
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
&completion_key, &overlapped, block ? 1000 : 0);
&completion_key, &overlapped, block ? INFINITE : 0);
DWORD last_error = ::GetLastError();
if (!ok && overlapped == 0)
{
if (block && last_error == WAIT_TIMEOUT)
continue;
ec = asio::error_code();
return 0;
}
if (overlapped)
{
@ -298,25 +266,22 @@ private:
operation* op = static_cast<operation*>(overlapped);
op->do_completion(last_error, bytes_transferred);
ec = asio::error_code();
return 1;
}
else
{
// The stopped_ flag is always checked to ensure that any leftover
// The interrupted_ flag is always checked to ensure that any leftover
// interrupts from a previous run invocation are ignored.
if (::InterlockedExchangeAdd(&stopped_, 0) != 0)
if (::InterlockedExchangeAdd(&interrupted_, 0) != 0)
{
// Wake up next thread that is blocked on GetQueuedCompletionStatus.
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
{
DWORD last_error = ::GetLastError();
ec = asio::error_code(last_error,
asio::native_ecat);
return 0;
system_exception e("pqcs", last_error);
boost::throw_exception(e);
}
ec = asio::error_code();
return 0;
}
}
@ -400,15 +365,15 @@ private:
struct iocp_holder
{
HANDLE handle;
iocp_holder() : handle(0) {}
~iocp_holder() { if (handle) ::CloseHandle(handle); }
iocp_holder(HANDLE h) : handle(h) {}
~iocp_holder() { ::CloseHandle(handle); }
} iocp_;
// The count of unfinished work.
long outstanding_work_;
// Flag to indicate whether the event loop has been stopped.
long stopped_;
// Flag to indicate whether the event loop has been interrupted.
long interrupted_;
// Flag to indicate whether the service has been shut down.
long shutdown_;

View File

@ -2,7 +2,7 @@
// win_iocp_io_service_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// 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)

Some files were not shown because too many files have changed in this diff Show More