Compare commits

..

1 Commits

Author SHA1 Message Date
Marcos Pinto
315dbbfa4d tag 0.5.4.1 release 2007-08-10 22:31:46 +00:00
383 changed files with 47780 additions and 91934 deletions

View File

@@ -1,56 +1,3 @@
Deluge 0.5.6.2 (31 October 2007)
* Set default piece size to 256-KiB in TorrentCreator plugin and add 2048KiB
as a size option.
* Fix a bug in Debian package that caused the UI to completely freeze when a
torrent finished
* Find and fix another shutdown bug that mostly Gutsy users were incountering
* Fix a couple of WebUI bugs, including the "index" page erroring out
Deluge 0.5.6.1 (28 October 2007)
* Fix invalid handle error
* Fix shutdown hang
Deluge 0.5.6 (24 October 2007)
* Web Interface Plugin
* Hopefully fix "losing data" and having to re-download parts (for real this time :p)
* Use new full allocation method which does not create files until one of its
pieces is downloaded
* Tray lock password is no longer stored in plain text
* Update the Scheduler plugin and fix a bunch of bugs on it
* Double-clicking on a torrent opens up its containing folder
* Fix SpeedLimiter plugin when setting upload limits
* Fix MoveTorrent plugin when moving actively downloading torrents
* Pause torrents while importing blocklist and resume them when finished
* Remove TorrentPieces and disable its use
* A whole bunch of stuff for Win32
* Add private flag to TorrentCreator plugin
* Use SVG for internal logo usage (except on Win32)
* Use theme for tray icon instead of hard-coded
* Properly release port on shutdown
* TorrentFiles plugin now has progress bars
* Removing torrent files no longer deletes files that werent part of the torrent
* New max half-open connections setting to deal with cheap/broken routers
* Inherit UPnP fixes from libtorrent
* Use threading for everything, instead of spawnning
Deluge 0.5.5 (09 September 2007)
* Editing a torrent's tracker list is now persistent between sessions
* Persistence between sessions for Speed Limiter, Web Seed and Desired Ratio
plugins
* New wizard to aid first-time users with configuration
* Reorderable tabs and remember order (with exception of details tab)
* Fix losing data and having to re-download parts
* Fix password lock showing when main window is not hidden
* Get rid of the plugin manager and integrate it into preferences
* New Move torrent plugin - takes over for "move completed downloads" feature
and provides a "Move Torrent" option when right-clicking on a torrent
* Save column widths
* Queue order after restart fixes.
* Use payload instead of including protocol overhead to ease user confusion
of seeding torrents "downloading"
* New Web Seed plugin for adding URLs to torrents for http seeding
* Add FAST-extension (http://www.bittorrent.org/fast_extensions.html)
Deluge 0.5.4.1 (10 August 2007)
* Add "Open containing folder" and "Open File" to the torrent and file
menu, respectively

View File

@@ -8,7 +8,7 @@ things, in which case I *might* edit it. Don't bet on it, though.
Here are the highlights:
Indents are FOUR (4) spaces. Not 8, not 5 or 2 and definitely NOT tab.
Limit all lines to a maximum of 80 characters.
Limit all lines to a maximum of 79 characters.
Use UTF-8 encoding
Every single import should be on its own line
Avoid extraneous whitespace in the following situations:

View File

@@ -7,6 +7,6 @@ include deluge.png
include msgfmt.py
recursive-include libtorrent/ *
recursive-include glade/ *.glade
recursive-include pixmaps/ *.png *.svg
recursive-include pixmaps/ *.png
recursive-include plugins/ *
recursive-include po/ *

2
README
View File

@@ -34,8 +34,6 @@ python-all-dev
python-all version >= 2.4
python-dbus
python-gtk2 version >= 2.9
python-notify
librsvg2-common
python-xdg
python-support
libboost-dev >= 1.33.1

6
TODO
View File

@@ -1,6 +0,0 @@
for 0.5.7
1. manual recheck
2. preference for .torrent location
3. have blocklist detect 7zip files and popup a warning instead of crashing
4. add auto-pickup folder
5. remap filenames

View File

@@ -1,5 +0,0 @@
#!/bin/bash
for size in 16 22 24 32 36 48 64 72 96 128 192 256; do mkdir -p icons/hicolor/\
${size}x${size}/apps; rsvg-convert -w ${size} -h ${size} \
-o icons/hicolor/${size}x${size}/apps/deluge.png pixmaps/deluge.svg; mkdir -p \
icons/scalable/apps/; cp pixmaps/deluge.svg icons/scalable/apps/deluge.svg; done

View File

@@ -456,11 +456,45 @@
<child>
<widget class="GtkTable" id="table3">
<property name="visible">True</property>
<property name="n_rows">7</property>
<property name="n_rows">6</property>
<property name="n_columns">2</property>
<property name="row_spacing">2</property>
<child>
<widget class="GtkLabel" id="summary_torrent_path">
<widget class="GtkAlignment" id="alignment23">
<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="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label20">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;# of files:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_num_files">
<property name="visible">True</property>
<property name="xalign">0</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="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_total_size">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
@@ -473,37 +507,15 @@
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment24">
<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="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label18">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;Path:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_total_size">
<widget class="GtkLabel" id="summary_name">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</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="y_options"></property>
</packing>
</child>
@@ -523,149 +535,13 @@
</child>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_num_files">
<property name="visible">True</property>
<property name="xalign">0</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="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_tracker">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</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="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_tracker_status">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment19">
<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="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label21">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;Tracker Status:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_next_announce">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment20">
<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="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;Next Announce:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_name">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment15">
<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="right_padding">5</property>
<child>
<widget class="GtkAlignment" id="alignment23">
<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="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label20">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;# of files:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment17">
<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="right_padding">5</property>
@@ -686,12 +562,61 @@
</widget>
</child>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment17">
<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="right_padding">5</property>
<child>
<widget class="GtkAlignment" id="alignment19">
<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="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label21">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;Tracker Status:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment20">
<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="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;Next Announce:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment13">
<property name="visible">True</property>
@@ -712,6 +637,47 @@
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_tracker">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</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="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_tracker_status">
<property name="visible">True</property>
<property name="xalign">0</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="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_next_announce">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
@@ -741,7 +707,6 @@
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="reorderable">True</property>
</packing>
</child>
<child>
@@ -871,22 +836,6 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem7">
<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">Plu_gins</property>
<property name="use_underline">True</property>
<signal name="activate" handler="plugin_clicked"/>
<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-disconnect</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem9">
<property name="visible">True</property>
@@ -896,6 +845,21 @@
<signal name="activate" handler="pref_clicked"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="plugins1">
<property name="visible">True</property>
<property name="label" translatable="yes">Pl_ugins</property>
<property name="use_underline">True</property>
<signal name="activate" handler="plugins_clicked"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image3">
<property name="visible">True</property>
<property name="stock">gtk-disconnect</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
@@ -1061,30 +1025,6 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem8">
<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="tooltip" translatable="yes">Runs the first-time configuration wizard</property>
<property name="label" translatable="yes">_Run Configuration Wizard</property>
<property name="use_underline">True</property>
<signal name="activate" handler="run_wizard"/>
<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-preferences</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem4">
<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>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem4">
<property name="visible">True</property>
@@ -1166,7 +1106,7 @@
<child>
<widget class="GtkToolButton" id="toolbutton_clear">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Clear Seeding Torrents</property>
<property name="tooltip" translatable="yes">Clear Finished Torrents</property>
<property name="label" translatable="yes">Clear</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-clear</property>
@@ -1189,7 +1129,7 @@
<widget class="GtkToolButton" id="toolbutton_resume">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="tooltip" translatable="yes">Start or Resume Torrent</property>
<property name="tooltip" translatable="yes">Start or Pause torrent</property>
<property name="label" translatable="yes">Resume</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-media-play</property>
@@ -1203,7 +1143,6 @@
<widget class="GtkToolButton" id="toolbutton_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="tooltip" translatable="yes">Pause Torrent</property>
<property name="label" translatable="yes">Pause</property>
<property name="stock_id">gtk-media-pause</property>
<signal name="clicked" handler="tor_pause"/>
@@ -1265,10 +1204,11 @@
<child>
<widget class="GtkToolButton" id="toolbutton2">
<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="tooltip" translatable="yes">Open the plugins dialog</property>
<property name="label" translatable="yes">Plugins</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-disconnect</property>
<signal name="clicked" handler="plugin_clicked"/>
<signal name="clicked" handler="plugins_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
@@ -1285,5 +1225,3 @@
</child>
</widget>
</glade-interface>

142
glade/plugin_dialog.glade Normal file
View File

@@ -0,0 +1,142 @@
<?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_NORMAL</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="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">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="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkViewport" id="viewport1">
<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="resize_mode">GTK_RESIZE_QUEUE</property>
<child>
<widget class="GtkTreeView" id="plugin_view">
<property name="visible">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">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="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</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>
</child>
</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">gtk-preferences</property>
<property name="use_stock">True</property>
<property name="response_id">0</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">gtk-close</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_close_clicked"/>
</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

@@ -81,8 +81,14 @@
<widget class="GtkImageMenuItem" id="download_limit">
<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">_Download Speed Limit</property>
<property name="label" translatable="yes">Global _Down Speed Limit</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu1">
<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>
</widget>
</child>
<child internal-child="image">
<widget class="GtkImage" id="download-limit-image">
<property name="visible">True</property>
@@ -97,7 +103,7 @@
<widget class="GtkImageMenuItem" id="upload_limit">
<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">_Upload Speed Limit</property>
<property name="label" translatable="yes">Global _Up Speed Limit</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="upload-limit-image">
@@ -115,6 +121,39 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="preferences">
<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">gtk-preferences</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="preferences"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="plugins">
<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">Plu_gins</property>
<property name="use_underline">True</property>
<signal name="activate" handler="plugins"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image3">
<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-disconnect</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem2">
<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>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="quit">
<property name="visible">True</property>

View File

@@ -1,520 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.2.2 on Tue Oct 9 20:54:45 2007 by markybob@peg-->
<glade-interface>
<widget class="GtkAssistant" id="wizard">
<property name="width_request">500</property>
<property name="height_request">335</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">2</property>
<property name="title" translatable="yes">First Launch Configuration</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<signal name="close" handler="close"/>
<signal name="cancel" handler="cancel"/>
<signal name="apply" handler="apply_prefs"/>
<child>
<widget class="GtkLabel" id="label1">
<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">This wizard will help you set up Deluge to your liking. If you are new to Deluge, please note that most of Deluge's functionality and features come in the form of plugins, which can be accessed by clicking on Plugins in the Edit menu or the toolbar.</property>
<property name="wrap">True</property>
</widget>
<packing>
<property name="page_type">GTK_ASSISTANT_PAGE_INTRO</property>
<property name="title">Deluge Configuration</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="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</property>
<child>
<widget class="GtkLabel" id="label2">
<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">Deluge needs a range of ports that it will try to listen to for incoming connections. The default ports for bittorrent are 6881-6889, however, most ISPs block those ports, so you're encouraged to pick others, between 49152 and 65535. Alternatively, you can have Deluge automatically pick random ports for you.</property>
<property name="wrap">True</property>
</widget>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<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="GtkLabel" id="label4">
<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">From:</property>
</widget>
</child>
<child>
<widget class="GtkSpinButton" id="spin_port_min">
<property name="visible">True</property>
<property name="can_focus">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="adjustment">0 0 65535 1 10 10</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label5">
<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">To:</property>
</widget>
<packing>
<property name="position">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="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="adjustment">0 0 65535 1 10 10</property>
</widget>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_random_ports">
<property name="visible">True</property>
<property name="can_focus">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">Use _Random Ports</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="toggle"/>
</widget>
<packing>
<property name="position">4</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="title">Deluge Configuration</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="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</property>
<child>
<widget class="GtkLabel" id="label3">
<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">Would you like Deluge to automatically download to a predefined location, or would you like to specify the download location every time?</property>
<property name="wrap">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator1">
<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>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">28</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radio_ask_save">
<property name="visible">True</property>
<property name="can_focus">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">Ask where to save each file</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox3">
<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="GtkAlignment" id="alignment2">
<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="GtkRadioButton" id="radio_save_all_to">
<property name="visible">True</property>
<property name="can_focus">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">Store all downloads in: </property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">radio_ask_save</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment1">
<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="GtkFileChooserButton" id="download_path_button">
<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="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
<property name="title" translatable="yes">Select A Folder</property>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
</widget>
<packing>
<property name="title">Deluge Configuration</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<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="GtkLabel" id="label10">
<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">Please select the upload speed of your connection, which we will then use to automatically make suggestions for the settings below</property>
<property name="wrap">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table1">
<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="n_rows">6</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkAlignment" id="alignment7">
<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="GtkLabel" id="label7">
<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="tooltip" translatable="yes">The number of active torrents that Deluge will run. Set to -1 for unlimited.</property>
<property name="label" translatable="yes">Maximum Active Torrents:</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment4">
<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="GtkLabel" id="label9">
<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="tooltip" translatable="yes">The maximum upload slots for all torrents. Set -1 for unlimited.</property>
<property name="label" translatable="yes">Maximum Upload Slots:</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment5">
<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="GtkLabel" id="label8">
<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="tooltip" translatable="yes">The maximum upload speed for all torrents. Set -1 for unlimited.</property>
<property name="label" translatable="yes">Maximum Upload Speed (KiB/s):</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment9">
<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="GtkLabel" id="label6">
<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="tooltip" translatable="yes">The maximum number of connections allowed. Set -1 for unlimited.</property>
<property name="label" translatable="yes">Maximum Connections:</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment3">
<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="GtkSpinButton" id="spin_max_upload_slots_global">
<property name="visible">True</property>
<property name="can_focus">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="tooltip" translatable="yes">The maximum upload slots for all torrents. Set -1 for unlimited.</property>
<property name="adjustment">0 -1 9000 1 10 10</property>
</widget>
</child>
</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">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment6">
<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="GtkSpinButton" id="spin_max_upload">
<property name="visible">True</property>
<property name="can_focus">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="tooltip" translatable="yes">The maximum upload speed for all torrents. Set -1 for unlimited.</property>
<property name="adjustment">0 -1 9000 1 10 10</property>
</widget>
</child>
</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">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment10">
<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="GtkSpinButton" id="spin_max_connections_global">
<property name="visible">True</property>
<property name="can_focus">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="tooltip" translatable="yes">The maximum number of connections allowed. Set -1 for unlimited.</property>
<property name="adjustment">0 -1 9000 1 10 10</property>
</widget>
</child>
</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">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment12">
<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="GtkComboBox" id="combo_upload_line">
<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="items" translatable="yes">28.8k
56k
64k
96k
128k
192k
256k
384k
512k
640k
768k
1Mbit
2Mbit
10Mbit
20Mbit
40Mbit
50Mbit
100Mbit</property>
<signal name="changed" handler="toggle"/>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label11">
<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">Your Upload Line Speed:</property>
</widget>
<packing>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment13">
<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="GtkLabel" id="label13">
<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="tooltip" translatable="yes">The maximum half-open connections. A high value may crash some cheap routers. Set -1 for unlimited.</property>
<property name="label" translatable="yes">Maximum Half-Open Connections:</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment15">
<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="GtkSpinButton" id="spin_max_half_open">
<property name="visible">True</property>
<property name="can_focus">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="tooltip" translatable="yes">The maximum half-open connections. A high value may crash some cheap routers. Set -1 for unlimited.</property>
<property name="adjustment">8 -1 9000 1 10 10</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment16">
<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="GtkSpinButton" id="spin_torrents">
<property name="visible">True</property>
<property name="can_focus">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="tooltip" translatable="yes">The number of active torrents that Deluge will run. Set to -1 for unlimited.</property>
<property name="adjustment">0 -1 9000 1 10 10</property>
</widget>
</child>
</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">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="title">Deluge Configuration</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_send_info">
<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">_Help us improve Deluge by sending us your Python and PyGTK
versions, OS and processor types. Absolutely no other
information is sent.</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="page_type">GTK_ASSISTANT_PAGE_CONFIRM</property>
<property name="title">Deluge Configuration</property>
</packing>
</child>
</widget>
</glade-interface>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,402 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48px"
height="48px"
id="svg3440"
sodipodi:version="0.32"
inkscape:version="0.45"
sodipodi:docbase="/home/zach/deluge/trunk"
sodipodi:docname="deluge.svg"
inkscape:export-filename="/home/zach/deluge.png"
inkscape:export-xdpi="480"
inkscape:export-ydpi="480"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="TRUE">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient2973">
<stop
style="stop-color:#eeeeec;stop-opacity:1;"
offset="0"
id="stop2975" />
<stop
style="stop-color:#eeeeec;stop-opacity:0;"
offset="1"
id="stop2977" />
</linearGradient>
<linearGradient
id="linearGradient4126">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop4128" />
<stop
style="stop-color:#ffffff;stop-opacity:0.16494845;"
offset="1.0000000"
id="stop4130" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4114">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop4116" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4118" />
</linearGradient>
<linearGradient
id="linearGradient3962">
<stop
style="stop-color:#d3e9ff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop3964" />
<stop
style="stop-color:#d3e9ff;stop-opacity:1.0000000;"
offset="0.15517241"
id="stop4134" />
<stop
style="stop-color:#4074ae;stop-opacity:1.0000000;"
offset="0.75000000"
id="stop4346" />
<stop
style="stop-color:#36486c;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop3966" />
</linearGradient>
<radialGradient
r="13.994944"
fy="33.506763"
fx="-10.089286"
cy="33.506763"
cx="-10.089286"
gradientTransform="matrix(1,0,0,0.791446,-14.01786,-11.28667)"
gradientUnits="userSpaceOnUse"
id="radialGradient4019"
xlink:href="#linearGradient3993"
inkscape:collect="always" />
<radialGradient
r="14.057444"
fy="31.329016"
fx="-10.323107"
cy="31.329016"
cx="-10.323107"
gradientTransform="matrix(1,0,0,0.792374,-19.58761,2.818569)"
gradientUnits="userSpaceOnUse"
id="radialGradient4004"
xlink:href="#linearGradient3993"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.792374,0,6.785475)"
r="14.057444"
fy="31.329016"
fx="-10.323107"
cy="31.329016"
cx="-10.323107"
id="radialGradient3999"
xlink:href="#linearGradient3993"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.341185,-0.153831,1.08001,2.395374,-15.42222,-25.62103)"
r="13.994946"
fy="24.241488"
fx="61.662098"
cy="24.241488"
cx="61.662098"
id="radialGradient3943"
xlink:href="#linearGradient1312"
inkscape:collect="always" />
<linearGradient
id="linearGradient1312">
<stop
id="stop1314"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop1316"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient3993">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3995" />
<stop
style="stop-color:#000000;stop-opacity:0"
offset="1"
id="stop3997" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2973"
id="radialGradient3866"
cx="-22.375"
cy="18.499998"
fx="-22.375"
fy="18.499998"
r="14.33462"
gradientTransform="matrix(1,0,0,1.140022,40.17678,1.347091)"
gradientUnits="userSpaceOnUse" />
<radialGradient
gradientUnits="userSpaceOnUse"
r="12.289036"
fy="63.965388"
fx="15.115514"
cy="63.965388"
cx="15.115514"
gradientTransform="scale(1.643990,0.608276)"
id="radialGradient5000"
xlink:href="#linearGradient4114"
inkscape:collect="always" />
<linearGradient
id="linearGradient4989">
<stop
id="stop4991"
offset="0.0000000"
style="stop-color:#d3e9ff;stop-opacity:1.0000000;" />
<stop
id="stop4993"
offset="0.15517241"
style="stop-color:#d3e9ff;stop-opacity:1.0000000;" />
<stop
id="stop4995"
offset="0.75000000"
style="stop-color:#4074ae;stop-opacity:1.0000000;" />
<stop
id="stop4997"
offset="1.0000000"
style="stop-color:#36486c;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient4977">
<stop
id="stop4979"
offset="0.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
<stop
id="stop4981"
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:0.16494845;" />
</linearGradient>
<linearGradient
id="linearGradient4825"
inkscape:collect="always">
<stop
id="stop4827"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop4829"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4114"
id="radialGradient6090"
gradientUnits="userSpaceOnUse"
gradientTransform="scale(1.64399,0.608276)"
cx="15.115514"
cy="63.965388"
fx="15.115514"
fy="63.965388"
r="12.289036" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4825"
id="radialGradient6098"
gradientUnits="userSpaceOnUse"
cx="12.071323"
cy="12.493138"
fx="12.071323"
fy="12.493138"
r="6.7175145" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2973"
id="radialGradient6103"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.25463,-0.898371,0.979785,0.277703,-18.00903,32.03312)"
cx="17.903898"
cy="40.159222"
fx="17.903898"
fy="40.159222"
r="14.33681" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2973"
id="radialGradient6106"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.583269,-0.431533,0.577146,0.78008,-5.80022,4.004109)"
cx="12.525543"
cy="38.09042"
fx="12.525543"
fy="38.09042"
r="14.33681" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1312"
id="radialGradient6109"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.768231,1.13675,-0.820972,0.554824,-3.72248,-85.07126)"
cx="65.800331"
cy="27.16758"
fx="65.800331"
fy="27.16758"
r="12.972491" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4989"
id="radialGradient6115"
cx="16.651781"
cy="32.187485"
fx="16.651781"
fy="32.187485"
r="17.089519"
gradientTransform="matrix(1.486175,-1.536108,0.932321,0.902016,-38.10476,31.42646)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.17254902"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="36.250498"
inkscape:cy="38.275489"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1266"
inkscape:window-height="944"
inkscape:window-x="124"
inkscape:window-y="52"
inkscape:showpageshadow="false" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Internet Category</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:contributor>
<cc:Agent>
<dc:title>Tuomas Kuosmanen</dc:title>
</cc:Agent>
</dc:contributor>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:source>http://jimmac.musichall.cz</dc:source>
<dc:subject>
<rdf:Bag>
<rdf:li>internet</rdf:li>
<rdf:li>tools</rdf:li>
<rdf:li>applications</rdf:li>
<rdf:li>category</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Attribution" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="fill:url(#radialGradient6090);fill-opacity:1;stroke:none;stroke-opacity:1"
id="path4112"
sodipodi:cx="24.849752"
sodipodi:cy="38.908627"
sodipodi:rx="20.203051"
sodipodi:ry="7.4751287"
d="M 45.052803 38.908627 A 20.203051 7.4751287 0 1 1 4.6467018,38.908627 A 20.203051 7.4751287 0 1 1 45.052803 38.908627 z"
transform="matrix(0.947409,0,0,1.17786,1.244375,-6.853427)"
inkscape:export-xdpi="480"
inkscape:export-ydpi="480" />
<path
style="fill:url(#radialGradient6115);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.07523891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 23.942923,0.9561338 L 37.330543,18.266721 C 46.998995,29.84687 41.49692,43.923891 26.7742,45.000491 C 6.0597413,45.582655 6.5086231,27.37483 11.255313,18.609381 L 23.942923,0.9561338 z "
id="path2069"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#1b4075;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.07523891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 35.111358,26.143133 C 28.972772,13.030586 17.560684,17.697957 17.274449,26.949974 C 16.894738,39.223415 34.748874,37.615429 36.715244,41.468778 C 28.821643,47.675479 14.973233,45.226508 10.962289,39.715204 C 6.9574776,34.212326 7.2383598,25.630263 10.784249,19.587632 C 24.158625,0.978654 39.749127,24.383766 35.111358,26.143133 z "
id="path2969"
sodipodi:nodetypes="cscscc" />
<path
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:white;stroke-width:1.1000706;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.36612022"
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z "
id="path2071"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:0.46;fill:url(#radialGradient6109);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.07523891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 23.940758,0.96491709 L 34.727367,14.909752 C 42.647208,24.392311 40.447304,20.283975 28.362481,21.278846 C 25.083165,11.203805 18.13871,11.859899 13.523802,15.675236 L 23.940758,0.96491709 z "
id="path3945"
sodipodi:nodetypes="ccccc" />
<path
style="fill:url(#radialGradient6106);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.07523891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 35.159701,26.173667 C 29.021115,13.06112 18.734027,17.978491 18.447792,27.230508 C 18.068081,39.503949 34.797217,37.645963 36.763587,41.499312 C 28.869986,47.706013 15.021576,45.257042 11.010632,39.745738 C 7.0058197,34.24286 7.2867027,25.660797 10.832592,19.618166 C 24.206968,1.0091879 39.79747,24.4143 35.159701,26.173667 z "
id="path3868"
sodipodi:nodetypes="cscscc" />
<path
style="fill:url(#radialGradient6103);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.07523891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 35.120795,26.14195 C 28.553327,12.814962 15.685968,17.224233 15.399733,26.47625 C 15.020022,38.749691 32.874158,37.141705 34.840528,40.995054 C 26.946927,47.201755 13.098517,44.752784 9.0875727,39.24148 C 5.0827617,33.738602 5.3636437,25.156539 8.9095327,19.113908 C 22.315509,0.47615954 40.03233,23.660113 35.120795,26.14195 z "
id="path4874"
sodipodi:nodetypes="cscscc" />
<path
transform="matrix(-0.829136,1.052307,1.239307,7.58326e-2,26.32898,25.58605)"
inkscape:r_cy="true"
inkscape:r_cx="true"
d="M 18.788838 12.493138 A 6.7175145 6.7175145 0 1 1 5.3538089,12.493138 A 6.7175145 6.7175145 0 1 1 18.788838 12.493138 z"
sodipodi:ry="6.7175145"
sodipodi:rx="6.7175145"
sodipodi:cy="12.493138"
sodipodi:cx="12.071323"
id="path4941"
style="opacity:0.21999996;color:black;fill:url(#radialGradient6098);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,25 +0,0 @@
Written by Arvid Norberg. Copyright (c) 2003-2007
Lots of testing, suggestions and contributions by:
Massaroddel
Tianhao Qiu.
Contributions by:
Shyam
Magnus Jonsson
Daniel Wallin
Cory Nelson
Stas Khirman
Ryan Norton
Building and maintainance of the autotools scripts:
Michael Wojciechowski
Peter Koeleman
Thanks to Reimond Retz for bugfixes, suggestions and testing
Thanks to University of Ume<6D> for providing development and test hardware.
Project is hosted by sourceforge.

View File

@@ -1,28 +0,0 @@
Copyright (c) 2003 - 2007, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of Rasterbar Software nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <memory>
#include <queue>
#include <string>
#include <cassert>
#include <typeinfo>
#ifdef _MSC_VER
@@ -55,7 +56,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15

View File

@@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket.hpp"
#include "libtorrent/peer_connection.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
namespace libtorrent
{
@@ -115,7 +114,7 @@ namespace libtorrent
, std::string const& msg)
: torrent_alert(h, alert::info, msg)
, piece_index(index)
{ TORRENT_ASSERT(index >= 0);}
{ assert(index >= 0);}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new hash_failed_alert(*this)); }
@@ -191,9 +190,9 @@ namespace libtorrent
const torrent_handle& h
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::debug, msg)
: torrent_alert(h, alert::warning, msg)
, piece_index(piece_num)
{ TORRENT_ASSERT(piece_index >= 0);}
{ assert(piece_index >= 0);}
int piece_index;
@@ -208,10 +207,10 @@ namespace libtorrent
, int block_num
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::debug, msg)
: torrent_alert(h, alert::warning, msg)
, block_index(block_num)
, piece_index(piece_num)
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);}
{ assert(block_index >= 0 && piece_index >= 0);}
int block_index;
int piece_index;
@@ -224,15 +223,15 @@ namespace libtorrent
{
block_downloading_alert(
const torrent_handle& h
, char const* speedmsg
, std::string& speedmsg
, int block_num
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::debug, msg)
: torrent_alert(h, alert::warning, msg)
, peer_speedmsg(speedmsg)
, block_index(block_num)
, piece_index(piece_num)
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);}
{ assert(block_index >= 0 && piece_index >= 0);}
std::string peer_speedmsg;
int block_index;
@@ -252,16 +251,6 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new storage_moved_alert(*this)); }
};
struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert
{
torrent_deleted_alert(torrent_handle const& h, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new torrent_deleted_alert(*this)); }
};
struct TORRENT_EXPORT torrent_paused_alert: torrent_alert
{
torrent_paused_alert(torrent_handle const& h, std::string const& msg)
@@ -272,17 +261,6 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new torrent_paused_alert(*this)); }
};
struct TORRENT_EXPORT torrent_checked_alert: torrent_alert
{
torrent_checked_alert(torrent_handle const& h, std::string const& msg)
: torrent_alert(h, alert::info, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new torrent_checked_alert(*this)); }
};
struct TORRENT_EXPORT url_seed_alert: torrent_alert
{
url_seed_alert(
@@ -338,33 +316,14 @@ namespace libtorrent
struct TORRENT_EXPORT listen_failed_alert: alert
{
listen_failed_alert(
tcp::endpoint const& ep
, std::string const& msg)
const std::string& msg)
: alert(alert::fatal, msg)
, endpoint(ep)
{}
tcp::endpoint endpoint;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new listen_failed_alert(*this)); }
};
struct TORRENT_EXPORT listen_succeeded_alert: alert
{
listen_succeeded_alert(
tcp::endpoint const& ep
, std::string const& msg)
: alert(alert::fatal, msg)
, endpoint(ep)
{}
tcp::endpoint endpoint;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new listen_succeeded_alert(*this)); }
};
struct TORRENT_EXPORT portmap_error_alert: alert
{
portmap_error_alert(const std::string& msg)

View File

@@ -0,0 +1,74 @@
//
// asio.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_HPP
#define ASIO_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/basic_datagram_socket.hpp"
#include "asio/basic_deadline_timer.hpp"
#include "asio/basic_io_object.hpp"
#include "asio/basic_socket_acceptor.hpp"
#include "asio/basic_socket_iostream.hpp"
#include "asio/basic_socket_streambuf.hpp"
#include "asio/basic_stream_socket.hpp"
#include "asio/basic_streambuf.hpp"
#include "asio/buffer.hpp"
#include "asio/buffered_read_stream_fwd.hpp"
#include "asio/buffered_read_stream.hpp"
#include "asio/buffered_stream_fwd.hpp"
#include "asio/buffered_stream.hpp"
#include "asio/buffered_write_stream_fwd.hpp"
#include "asio/buffered_write_stream.hpp"
#include "asio/completion_condition.hpp"
#include "asio/datagram_socket_service.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/deadline_timer.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"
#include "asio/ip/address.hpp"
#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/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/thread.hpp"
#include "asio/time_traits.hpp"
#include "asio/version.hpp"
#include "asio/write.hpp"
#endif // ASIO_HPP

View File

@@ -1,4 +0,0 @@
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)

View File

@@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -732,8 +732,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::system_error& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation

View File

@@ -34,8 +34,7 @@ public:
/// The underlying implementation type of I/O object.
typedef typename service_type::implementation_type implementation_type;
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the I/O
* object uses to dispatch handlers for asynchronous operations.
@@ -45,20 +44,7 @@ public:
*/
asio::io_service& io_service()
{
return service.get_io_service();
}
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_service& get_io_service()
{
return service.get_io_service();
return service.io_service();
}
protected:

View File

@@ -238,9 +238,6 @@ public:
* with the asio::error::operation_aborted error.
*
* @throws asio::system_error Thrown on failure.
*
* @note For portable behaviour with respect to graceful closure of a
* connected socket, call shutdown() before closing the socket.
*/
void close()
{
@@ -268,9 +265,6 @@ public:
* // An error occurred.
* }
* @endcode
*
* @note For portable behaviour with respect to graceful closure of a
* connected socket, call shutdown() before closing the socket.
*/
asio::error_code close(asio::error_code& ec)
{
@@ -564,8 +558,7 @@ public:
if (this->service.open(this->implementation,
peer_endpoint.protocol(), ec))
{
this->get_io_service().post(
asio::detail::bind_handler(handler, ec));
this->io_service().post(asio::detail::bind_handler(handler, ec));
return;
}
}

View File

@@ -542,10 +542,9 @@ inline const_buffers_1 buffer(const PodType (&data)[N],
? N * sizeof(PodType) : max_size_in_bytes));
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// Borland C++ and Sun Studio think the overloads:
// Borland C++ thinks the overloads:
//
// unspecified buffer(boost::array<PodType, N>& array ...);
//
@@ -611,7 +610,6 @@ buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
}
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
@@ -652,7 +650,6 @@ inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
}
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>

View File

@@ -93,17 +93,10 @@ public:
return next_layer_.lowest_layer();
}
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
/// Get the io_service associated with the object.
asio::io_service& io_service()
{
return next_layer_.get_io_service();
}
/// Get the io_service associated with the object.
asio::io_service& get_io_service()
{
return next_layer_.get_io_service();
return next_layer_.io_service();
}
/// Close the stream.
@@ -214,7 +207,7 @@ public:
buffer(
storage_.data() + previous_size,
storage_.size() - previous_size),
fill_handler<ReadHandler>(get_io_service(),
fill_handler<ReadHandler>(io_service(),
storage_, previous_size, handler));
}
@@ -302,12 +295,12 @@ public:
if (storage_.empty())
{
async_fill(read_some_handler<MutableBufferSequence, ReadHandler>(
get_io_service(), storage_, buffers, handler));
io_service(), storage_, buffers, handler));
}
else
{
std::size_t length = copy(buffers);
get_io_service().post(detail::bind_handler(
io_service().post(detail::bind_handler(
handler, asio::error_code(), length));
}
}

View File

@@ -83,17 +83,10 @@ public:
return stream_impl_.lowest_layer();
}
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
/// Get the io_service associated with the object.
asio::io_service& io_service()
{
return stream_impl_.get_io_service();
}
/// Get the io_service associated with the object.
asio::io_service& get_io_service()
{
return stream_impl_.get_io_service();
return stream_impl_.io_service();
}
/// Close the stream.

View File

@@ -94,17 +94,10 @@ public:
return next_layer_.lowest_layer();
}
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
/// Get the io_service associated with the object.
asio::io_service& io_service()
{
return next_layer_.get_io_service();
}
/// Get the io_service associated with the object.
asio::io_service& get_io_service()
{
return next_layer_.get_io_service();
return next_layer_.io_service();
}
/// Close the stream.
@@ -172,7 +165,7 @@ public:
void async_flush(WriteHandler handler)
{
async_write(next_layer_, buffer(storage_.data(), storage_.size()),
flush_handler<WriteHandler>(get_io_service(), storage_, handler));
flush_handler<WriteHandler>(io_service(), storage_, handler));
}
/// Write the given data to the stream. Returns the number of bytes written.
@@ -260,12 +253,12 @@ public:
if (storage_.size() == storage_.capacity())
{
async_flush(write_some_handler<ConstBufferSequence, WriteHandler>(
get_io_service(), storage_, buffers, handler));
io_service(), storage_, buffers, handler));
}
else
{
std::size_t bytes_copied = copy(buffers);
get_io_service().post(detail::bind_handler(
io_service().post(detail::bind_handler(
handler, asio::error_code(), bytes_copied));
}
}

View File

@@ -64,9 +64,6 @@ private:
#elif defined(ASIO_HAS_KQUEUE)
typedef detail::reactive_socket_service<
Protocol, detail::kqueue_reactor<false> > service_impl_type;
#elif defined(ASIO_HAS_DEV_POLL)
typedef detail::reactive_socket_service<
Protocol, detail::dev_poll_reactor<false> > service_impl_type;
#else
typedef detail::reactive_socket_service<
Protocol, detail::select_reactor<false> > service_impl_type;

View File

@@ -69,9 +69,6 @@ private:
#elif defined(ASIO_HAS_KQUEUE)
typedef detail::deadline_timer_service<
traits_type, detail::kqueue_reactor<false> > service_impl_type;
#elif defined(ASIO_HAS_DEV_POLL)
typedef detail::deadline_timer_service<
traits_type, detail::dev_poll_reactor<false> > service_impl_type;
#else
typedef detail::deadline_timer_service<
traits_type, detail::select_reactor<false> > service_impl_type;

View File

@@ -180,7 +180,7 @@ public:
{
impl.might_have_pending_waits = true;
scheduler_.schedule_timer(timer_queue_, impl.expiry,
wait_handler<Handler>(this->get_io_service(), handler), &impl);
wait_handler<Handler>(this->io_service(), handler), &impl);
}
private:

View File

@@ -1,639 +0,0 @@
//
// dev_poll_reactor.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_DEV_POLL_REACTOR_HPP
#define ASIO_DETAIL_DEV_POLL_REACTOR_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/dev_poll_reactor_fwd.hpp"
#if defined(ASIO_HAS_DEV_POLL)
#include "asio/detail/push_options.hpp"
#include <cstddef>
#include <vector>
#include <boost/config.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/throw_exception.hpp>
#include <sys/devpoll.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/io_service.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/hash_map.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"
namespace asio {
namespace detail {
template <bool Own_Thread>
class dev_poll_reactor
: public asio::detail::service_base<dev_poll_reactor<Own_Thread> >
{
public:
// Constructor.
dev_poll_reactor(asio::io_service& io_service)
: asio::detail::service_base<
dev_poll_reactor<Own_Thread> >(io_service),
mutex_(),
dev_poll_fd_(do_dev_poll_create()),
wait_in_progress_(false),
interrupter_(),
read_op_queue_(),
write_op_queue_(),
except_op_queue_(),
pending_cancellations_(),
stop_thread_(false),
thread_(0),
shutdown_(false)
{
// Start the reactor's internal thread only if needed.
if (Own_Thread)
{
asio::detail::signal_blocker sb;
thread_ = new asio::detail::thread(
bind_handler(&dev_poll_reactor::call_run_thread, this));
}
// Add the interrupter's descriptor to /dev/poll.
::pollfd ev = { 0 };
ev.fd = interrupter_.read_descriptor();
ev.events = POLLIN | POLLERR;
ev.revents = 0;
::write(dev_poll_fd_, &ev, sizeof(ev));
}
// Destructor.
~dev_poll_reactor()
{
shutdown_service();
::close(dev_poll_fd_);
}
// Destroy all user-defined handler objects owned by the service.
void shutdown_service()
{
asio::detail::mutex::scoped_lock lock(mutex_);
shutdown_ = true;
stop_thread_ = true;
lock.unlock();
if (thread_)
{
interrupter_.interrupt();
thread_->join();
delete thread_;
thread_ = 0;
}
read_op_queue_.destroy_operations();
write_op_queue_.destroy_operations();
except_op_queue_.destroy_operations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
timer_queues_[i]->destroy_timers();
timer_queues_.clear();
}
// Register a socket with the reactor. Returns 0 on success, system error
// code on failure.
int register_descriptor(socket_type descriptor)
{
return 0;
}
// Start a new read operation. The handler object will be invoked when the
// given descriptor is ready to be read, or an error has occurred.
template <typename Handler>
void start_read_op(socket_type descriptor, Handler handler)
{
asio::detail::mutex::scoped_lock lock(mutex_);
if (shutdown_)
return;
if (!read_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
return;
if (read_op_queue_.enqueue_operation(descriptor, handler))
{
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLIN | POLLERR | POLLHUP;
if (write_op_queue_.has_operation(descriptor))
ev.events |= POLLOUT;
if (except_op_queue_.has_operation(descriptor))
ev.events |= POLLPRI;
ev.revents = 0;
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
if (result != sizeof(ev))
{
asio::error_code ec(errno,
asio::error::system_category);
read_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
}
// Start a new write operation. The handler object will be invoked when the
// given descriptor is ready to be written, or an error has occurred.
template <typename Handler>
void start_write_op(socket_type descriptor, Handler handler)
{
asio::detail::mutex::scoped_lock lock(mutex_);
if (shutdown_)
return;
if (!write_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
return;
if (write_op_queue_.enqueue_operation(descriptor, handler))
{
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLOUT | POLLERR | POLLHUP;
if (read_op_queue_.has_operation(descriptor))
ev.events |= POLLIN;
if (except_op_queue_.has_operation(descriptor))
ev.events |= POLLPRI;
ev.revents = 0;
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
if (result != sizeof(ev))
{
asio::error_code ec(errno,
asio::error::system_category);
write_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
}
// Start a new exception operation. The handler object will be invoked when
// the given descriptor has exception information, or an error has occurred.
template <typename Handler>
void start_except_op(socket_type descriptor, Handler handler)
{
asio::detail::mutex::scoped_lock lock(mutex_);
if (shutdown_)
return;
if (except_op_queue_.enqueue_operation(descriptor, handler))
{
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLPRI | POLLERR | POLLHUP;
if (read_op_queue_.has_operation(descriptor))
ev.events |= POLLIN;
if (write_op_queue_.has_operation(descriptor))
ev.events |= POLLOUT;
ev.revents = 0;
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
if (result != sizeof(ev))
{
asio::error_code ec(errno,
asio::error::system_category);
except_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
}
// Start new write and exception operations. The handler object will be
// invoked when the given descriptor is ready for writing or has exception
// information available, or an error has occurred.
template <typename Handler>
void start_write_and_except_ops(socket_type descriptor, Handler handler)
{
asio::detail::mutex::scoped_lock lock(mutex_);
if (shutdown_)
return;
bool need_mod = write_op_queue_.enqueue_operation(descriptor, handler);
need_mod = except_op_queue_.enqueue_operation(descriptor, handler)
&& need_mod;
if (need_mod)
{
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLOUT | POLLPRI | POLLERR | POLLHUP;
if (read_op_queue_.has_operation(descriptor))
ev.events |= POLLIN;
ev.revents = 0;
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
if (result != sizeof(ev))
{
asio::error_code ec(errno,
asio::error::system_category);
write_op_queue_.dispatch_all_operations(descriptor, ec);
except_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
}
// Cancel all operations associated with the given descriptor. The
// handlers associated with the descriptor will be invoked with the
// operation_aborted error.
void cancel_ops(socket_type descriptor)
{
asio::detail::mutex::scoped_lock lock(mutex_);
cancel_ops_unlocked(descriptor);
}
// Enqueue cancellation of all operations associated with the given
// descriptor. The handlers associated with the descriptor will be invoked
// with the operation_aborted error. This function does not acquire the
// dev_poll_reactor's mutex, and so should only be used from within a reactor
// handler.
void enqueue_cancel_ops_unlocked(socket_type descriptor)
{
pending_cancellations_.push_back(descriptor);
}
// Cancel any operations that are running against the descriptor and remove
// its registration from the reactor.
void close_descriptor(socket_type descriptor)
{
asio::detail::mutex::scoped_lock lock(mutex_);
// Remove the descriptor from /dev/poll.
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLREMOVE;
ev.revents = 0;
::write(dev_poll_fd_, &ev, sizeof(ev));
// Cancel any outstanding operations associated with the descriptor.
cancel_ops_unlocked(descriptor);
}
// Add a new timer queue to the reactor.
template <typename Time_Traits>
void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(mutex_);
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>
void schedule_timer(timer_queue<Time_Traits>& timer_queue,
const typename Time_Traits::time_type& time, Handler handler, void* token)
{
asio::detail::mutex::scoped_lock lock(mutex_);
if (!shutdown_)
if (timer_queue.enqueue_timer(time, handler, token))
interrupter_.interrupt();
}
// Cancel the timer associated with the given token. Returns the number of
// handlers that have been posted or dispatched.
template <typename Time_Traits>
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
{
asio::detail::mutex::scoped_lock lock(mutex_);
std::size_t n = timer_queue.cancel_timer(token);
if (n > 0)
interrupter_.interrupt();
return n;
}
private:
friend class task_io_service<dev_poll_reactor<Own_Thread> >;
// Run /dev/poll once until interrupted or events are ready to be dispatched.
void run(bool block)
{
asio::detail::mutex::scoped_lock lock(mutex_);
// Dispatch any operation cancellations that were made while the select
// loop was not running.
read_op_queue_.dispatch_cancellations();
write_op_queue_.dispatch_cancellations();
except_op_queue_.dispatch_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
timer_queues_[i]->dispatch_cancellations();
// Check if the thread is supposed to stop.
if (stop_thread_)
{
cleanup_operations_and_timers(lock);
return;
}
// We can return immediately if there's no work to do and the reactor is
// not supposed to block.
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
&& except_op_queue_.empty() && all_timer_queues_are_empty())
{
cleanup_operations_and_timers(lock);
return;
}
int timeout = block ? get_timeout() : 0;
wait_in_progress_ = true;
lock.unlock();
// Block on the /dev/poll descriptor.
::pollfd events[128] = { { 0 } };
::dvpoll dp = { 0 };
dp.dp_fds = events;
dp.dp_nfds = 128;
dp.dp_timeout = timeout;
int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp);
lock.lock();
wait_in_progress_ = false;
// Block signals while dispatching operations.
asio::detail::signal_blocker sb;
// Dispatch the waiting events.
for (int i = 0; i < num_events; ++i)
{
int descriptor = events[i].fd;
if (descriptor == interrupter_.read_descriptor())
{
interrupter_.reset();
}
else
{
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 & (POLLPRI | POLLERR | POLLHUP))
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
else
more_except = except_op_queue_.has_operation(descriptor);
if (events[i].events & (POLLIN | POLLERR | POLLHUP))
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
else
more_reads = read_op_queue_.has_operation(descriptor);
if (events[i].events & (POLLOUT | POLLERR | POLLHUP))
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
else
more_writes = write_op_queue_.has_operation(descriptor);
if ((events[i].events == POLLHUP)
&& !more_except && !more_reads && !more_writes)
{
// If we have only an POLLHUP event and no operations associated
// with the descriptor then we need to delete the descriptor from
// /dev/poll. The poll operation might produce POLLHUP events even
// if they are not specifically requested, so if we do not remove the
// descriptor we can end up in a tight polling loop.
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLREMOVE;
ev.revents = 0;
::write(dev_poll_fd_, &ev, sizeof(ev));
}
else
{
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLERR | POLLHUP;
if (more_reads)
ev.events |= POLLIN;
if (more_writes)
ev.events |= POLLOUT;
if (more_except)
ev.events |= POLLPRI;
ev.revents = 0;
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
if (result != sizeof(ev))
{
ec = asio::error_code(errno,
asio::error::system_category);
read_op_queue_.dispatch_all_operations(descriptor, ec);
write_op_queue_.dispatch_all_operations(descriptor, ec);
except_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
}
}
read_op_queue_.dispatch_cancellations();
write_op_queue_.dispatch_cancellations();
except_op_queue_.dispatch_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
timer_queues_[i]->dispatch_timers();
timer_queues_[i]->dispatch_cancellations();
}
// Issue any pending cancellations.
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
cancel_ops_unlocked(pending_cancellations_[i]);
pending_cancellations_.clear();
cleanup_operations_and_timers(lock);
}
// Run the select loop in the thread.
void run_thread()
{
asio::detail::mutex::scoped_lock lock(mutex_);
while (!stop_thread_)
{
lock.unlock();
run(true);
lock.lock();
}
}
// Entry point for the select loop thread.
static void call_run_thread(dev_poll_reactor* reactor)
{
reactor->run_thread();
}
// Interrupt the select loop.
void interrupt()
{
interrupter_.interrupt();
}
// Create the /dev/poll file descriptor. Throws an exception if the descriptor
// cannot be created.
static int do_dev_poll_create()
{
int fd = ::open("/dev/poll", O_RDWR);
if (fd == -1)
{
boost::throw_exception(
asio::system_error(
asio::error_code(errno,
asio::error::system_category),
"/dev/poll"));
}
return fd;
}
// Check if all timer queues are empty.
bool all_timer_queues_are_empty() const
{
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
if (!timer_queues_[i]->empty())
return false;
return true;
}
// Get the timeout value for the /dev/poll DP_POLL operation. The timeout
// value is returned as a number of milliseconds. A return value of -1
// indicates that the poll should block indefinitely.
int get_timeout()
{
if (all_timer_queues_are_empty())
return -1;
// By default we will wait no longer than 5 minutes. This will ensure that
// any changes to the system clock are detected after no longer than this.
boost::posix_time::time_duration minimum_wait_duration
= boost::posix_time::minutes(5);
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
boost::posix_time::time_duration wait_duration
= timer_queues_[i]->wait_duration();
if (wait_duration < minimum_wait_duration)
minimum_wait_duration = wait_duration;
}
if (minimum_wait_duration > boost::posix_time::time_duration())
{
int milliseconds = minimum_wait_duration.total_milliseconds();
return milliseconds > 0 ? milliseconds : 1;
}
else
{
return 0;
}
}
// 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 dev_poll_reactor's mutex.
void cancel_ops_unlocked(socket_type descriptor)
{
bool interrupt = read_op_queue_.cancel_operations(descriptor);
interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt;
interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt;
if (interrupt)
interrupter_.interrupt();
}
// Clean up operations and timers. We must not hold the lock since the
// destructors may make calls back into this reactor. We make a copy of the
// vector of timer queues since the original may be modified while the lock
// is not held.
void cleanup_operations_and_timers(
asio::detail::mutex::scoped_lock& lock)
{
timer_queues_for_cleanup_ = timer_queues_;
lock.unlock();
read_op_queue_.cleanup_operations();
write_op_queue_.cleanup_operations();
except_op_queue_.cleanup_operations();
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
timer_queues_for_cleanup_[i]->cleanup_timers();
}
// Mutex to protect access to internal data.
asio::detail::mutex mutex_;
// The /dev/poll file descriptor.
int dev_poll_fd_;
// Whether the DP_POLL operation is currently in progress
bool wait_in_progress_;
// The interrupter is used to break a blocking DP_POLL operation.
select_interrupter interrupter_;
// The queue of read operations.
reactor_op_queue<socket_type> read_op_queue_;
// The queue of write operations.
reactor_op_queue<socket_type> write_op_queue_;
// The queue of except operations.
reactor_op_queue<socket_type> except_op_queue_;
// The timer queues.
std::vector<timer_queue_base*> timer_queues_;
// A copy of the timer queues, used when cleaning up timers. The copy is
// stored as a class data member to avoid unnecessary memory allocation.
std::vector<timer_queue_base*> timer_queues_for_cleanup_;
// The descriptors that are pending cancellation.
std::vector<socket_type> pending_cancellations_;
// Does the reactor loop thread need to stop.
bool stop_thread_;
// The thread that is running the reactor loop.
asio::detail::thread* thread_;
// Whether the service has been shut down.
bool shutdown_;
};
} // namespace detail
} // namespace asio
#endif // defined(ASIO_HAS_DEV_POLL)
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_DEV_POLL_REACTOR_HPP

View File

@@ -1,40 +0,0 @@
//
// dev_poll_reactor_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_DEV_POLL_REACTOR_FWD_HPP
#define ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
#if !defined(ASIO_DISABLE_DEV_POLL)
#if defined(__sun) // This service is only supported on Solaris.
// Define this to indicate that /dev/poll is supported on the target platform.
#define ASIO_HAS_DEV_POLL 1
namespace asio {
namespace detail {
template <bool Own_Thread>
class dev_poll_reactor;
} // namespace detail
} // namespace asio
#endif // defined(__sun)
#endif // !defined(ASIO_DISABLE_DEV_POLL)
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP

View File

@@ -155,12 +155,9 @@ public:
ev.data.fd = descriptor;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0 && errno == ENOENT)
result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno,
asio::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
read_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
@@ -191,12 +188,9 @@ public:
ev.data.fd = descriptor;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0 && errno == ENOENT)
result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno,
asio::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
@@ -223,12 +217,9 @@ public:
ev.data.fd = descriptor;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0 && errno == ENOENT)
result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno,
asio::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
@@ -257,12 +248,9 @@ public:
ev.data.fd = descriptor;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0 && errno == ENOENT)
result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
{
asio::error_code ec(errno,
asio::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
except_op_queue_.dispatch_all_operations(descriptor, ec);
}
@@ -427,40 +415,22 @@ private:
else
more_writes = write_op_queue_.has_operation(descriptor);
if ((events[i].events == EPOLLHUP)
&& !more_except && !more_reads && !more_writes)
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLERR | EPOLLHUP;
if (more_reads)
ev.events |= EPOLLIN;
if (more_writes)
ev.events |= EPOLLOUT;
if (more_except)
ev.events |= EPOLLPRI;
ev.data.fd = descriptor;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0)
{
// If we have only an EPOLLHUP event and no operations associated
// with the descriptor then we need to delete the descriptor from
// epoll. The epoll_wait system call will produce EPOLLHUP events
// even if they are not specifically requested, so if we do not
// remove the descriptor we can end up in a tight loop of repeated
// calls to epoll_wait.
epoll_event ev = { 0, { 0 } };
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
}
else
{
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLERR | EPOLLHUP;
if (more_reads)
ev.events |= EPOLLIN;
if (more_writes)
ev.events |= EPOLLOUT;
if (more_except)
ev.events |= EPOLLPRI;
ev.data.fd = descriptor;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
if (result != 0 && errno == ENOENT)
result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
{
ec = asio::error_code(errno,
asio::error::system_category);
read_op_queue_.dispatch_all_operations(descriptor, ec);
write_op_queue_.dispatch_all_operations(descriptor, ec);
except_op_queue_.dispatch_all_operations(descriptor, ec);
}
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);
}
}
}
@@ -515,10 +485,8 @@ private:
int fd = epoll_create(epoll_size);
if (fd == -1)
{
boost::throw_exception(
asio::system_error(
asio::error_code(errno,
asio::error::system_category),
boost::throw_exception(asio::system_error(
asio::error_code(errno, asio::native_ecat),
"epoll"));
}
return fd;
@@ -556,8 +524,7 @@ private:
if (minimum_wait_duration > boost::posix_time::time_duration())
{
int milliseconds = minimum_wait_duration.total_milliseconds();
return milliseconds > 0 ? milliseconds : 1;
return minimum_wait_duration.total_milliseconds();
}
else
{

View File

@@ -1,219 +0,0 @@
//
// handler_queue.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_HANDLER_QUEUE_HPP
#define ASIO_DETAIL_HANDLER_QUEUE_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/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
namespace detail {
class handler_queue
: private noncopyable
{
public:
// Base class for handlers in the queue.
class handler
: private noncopyable
{
public:
void invoke()
{
invoke_func_(this);
}
void destroy()
{
destroy_func_(this);
}
protected:
typedef void (*invoke_func_type)(handler*);
typedef void (*destroy_func_type)(handler*);
handler(invoke_func_type invoke_func,
destroy_func_type destroy_func)
: next_(0),
invoke_func_(invoke_func),
destroy_func_(destroy_func)
{
}
~handler()
{
}
private:
friend class handler_queue;
handler* next_;
invoke_func_type invoke_func_;
destroy_func_type destroy_func_;
};
// Smart point to manager handler lifetimes.
class scoped_ptr
: private noncopyable
{
public:
explicit scoped_ptr(handler* h)
: handler_(h)
{
}
~scoped_ptr()
{
if (handler_)
handler_->destroy();
}
handler* get() const
{
return handler_;
}
handler* release()
{
handler* tmp = handler_;
handler_ = 0;
return tmp;
}
private:
handler* handler_;
};
// Constructor.
handler_queue()
: front_(0),
back_(0)
{
}
// Wrap a handler to be pushed into the queue.
template <typename Handler>
static handler* wrap(Handler h)
{
// Allocate and construct an object to wrap the handler.
typedef handler_wrapper<Handler> value_type;
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(h);
handler_ptr<alloc_traits> ptr(raw_ptr, h);
return ptr.release();
}
// Get the handler at the front of the queue.
handler* front()
{
return front_;
}
// Pop a handler from the front of the queue.
void pop()
{
if (front_)
{
handler* tmp = front_;
front_ = front_->next_;
if (front_ == 0)
back_ = 0;
tmp->next_= 0;
}
}
// Push a handler on to the back of the queue.
void push(handler* h)
{
h->next_ = 0;
if (back_)
{
back_->next_ = h;
back_ = h;
}
else
{
front_ = back_ = h;
}
}
// Whether the queue is empty.
bool empty() const
{
return front_ == 0;
}
private:
// Template wrapper for handlers.
template <typename Handler>
class handler_wrapper
: public handler
{
public:
handler_wrapper(Handler h)
: handler(
&handler_wrapper<Handler>::do_call,
&handler_wrapper<Handler>::do_destroy),
handler_(h)
{
}
static void do_call(handler* base)
{
// Take ownership of the handler object.
typedef handler_wrapper<Handler> this_type;
this_type* h(static_cast<this_type*>(base));
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
handler_ptr<alloc_traits> ptr(h->handler_, h);
// Make a copy of the handler so that the memory can be deallocated before
// the upcall is made.
Handler handler(h->handler_);
// Free the memory associated with the handler.
ptr.reset();
// Make the upcall.
asio_handler_invoke_helpers::invoke(handler, &handler);
}
static void do_destroy(handler* base)
{
// Take ownership of the handler object.
typedef handler_wrapper<Handler> this_type;
this_type* h(static_cast<this_type*>(base));
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
handler_ptr<alloc_traits> ptr(h->handler_, h);
}
private:
Handler handler_;
};
// The front of the queue.
handler* front_;
// The back of the queue.
handler* back_;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_HANDLER_QUEUE_HPP

View File

@@ -150,8 +150,7 @@ 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::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
read_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
@@ -177,8 +176,7 @@ 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::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
@@ -203,8 +201,7 @@ 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::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
@@ -227,8 +224,7 @@ 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::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, ec);
}
}
@@ -242,8 +238,7 @@ 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::error::system_category);
asio::error_code ec(errno, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, ec);
write_op_queue_.dispatch_all_operations(descriptor, ec);
}
@@ -397,7 +392,7 @@ private:
if (events[i].flags & EV_ERROR)
{
asio::error_code error(
events[i].data, asio::error::system_category);
events[i].data, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, error);
read_op_queue_.dispatch_all_operations(descriptor, error);
}
@@ -427,8 +422,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::error::system_category);
asio::error_code error(errno, asio::native_ecat);
except_op_queue_.dispatch_all_operations(descriptor, error);
read_op_queue_.dispatch_all_operations(descriptor, error);
}
@@ -440,7 +434,7 @@ private:
if (events[i].flags & EV_ERROR)
{
asio::error_code error(
events[i].data, asio::error::system_category);
events[i].data, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, error);
}
else
@@ -457,8 +451,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::error::system_category);
asio::error_code error(errno, asio::native_ecat);
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
@@ -512,10 +505,8 @@ private:
int fd = kqueue();
if (fd == -1)
{
boost::throw_exception(
asio::system_error(
asio::error_code(errno,
asio::error::system_category),
boost::throw_exception(asio::system_error(
asio::error_code(errno, asio::native_ecat),
"kqueue"));
}
return fd;

View File

@@ -43,20 +43,17 @@ public:
}
// Signal the event.
template <typename Lock>
void signal(Lock&)
void signal()
{
}
// Reset the event.
template <typename Lock>
void clear(Lock&)
void clear()
{
}
// Wait for the event to become signalled.
template <typename Lock>
void wait(Lock&)
void wait()
{
}
};

View File

@@ -19,7 +19,6 @@
#include "asio/detail/push_options.hpp"
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
@@ -28,8 +27,6 @@
#include <fcntl.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/socket_types.hpp"
namespace asio {
@@ -49,12 +46,6 @@ public:
write_descriptor_ = pipe_fds[1];
::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
}
else
{
asio::error_code ec(errno, asio::error::system_category);
asio::system_error e(ec, "pipe_select_interrupter");
boost::throw_exception(e);
}
}
// Destructor.

View File

@@ -24,12 +24,10 @@
#if defined(BOOST_HAS_PTHREADS)
#include "asio/detail/push_options.hpp"
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
@@ -44,11 +42,21 @@ public:
posix_event()
: signalled_(false)
{
int error = ::pthread_cond_init(&cond_, 0);
int error = ::pthread_mutex_init(&mutex_, 0);
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"event");
boost::throw_exception(e);
}
error = ::pthread_cond_init(&cond_, 0);
if (error != 0)
{
::pthread_mutex_destroy(&mutex_);
asio::system_error e(
asio::error_code(error, asio::native_ecat),
"event");
boost::throw_exception(e);
}
@@ -58,37 +66,37 @@ public:
~posix_event()
{
::pthread_cond_destroy(&cond_);
::pthread_mutex_destroy(&mutex_);
}
// Signal the event.
template <typename Lock>
void signal(Lock& lock)
void signal()
{
BOOST_ASSERT(lock.locked());
(void)lock;
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
signalled_ = true;
::pthread_cond_signal(&cond_); // Ignore EINVAL.
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
}
// Reset the event.
template <typename Lock>
void clear(Lock& lock)
void clear()
{
BOOST_ASSERT(lock.locked());
(void)lock;
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
signalled_ = false;
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
}
// Wait for the event to become signalled.
template <typename Lock>
void wait(Lock& lock)
void wait()
{
BOOST_ASSERT(lock.locked());
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
while (!signalled_)
::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL.
::pthread_cond_wait(&cond_, &mutex_); // Ignore EINVAL.
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
}
private:
::pthread_mutex_t mutex_;
::pthread_cond_t cond_;
bool signalled_;
};

View File

@@ -58,7 +58,7 @@ public:
}
private:
mutable fd_set fd_set_;
fd_set fd_set_;
socket_type max_descriptor_;
};

View File

@@ -28,7 +28,6 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/scoped_lock.hpp"
@@ -36,8 +35,6 @@
namespace asio {
namespace detail {
class posix_event;
class posix_mutex
: private noncopyable
{
@@ -51,7 +48,7 @@ public:
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"mutex");
boost::throw_exception(e);
}
@@ -70,7 +67,7 @@ public:
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"mutex");
boost::throw_exception(e);
}
@@ -83,14 +80,13 @@ public:
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"mutex");
boost::throw_exception(e);
}
}
private:
friend class posix_event;
::pthread_mutex_t mutex_;
};

View File

@@ -29,7 +29,6 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
@@ -53,7 +52,7 @@ public:
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"thread");
boost::throw_exception(e);
}

View File

@@ -28,7 +28,6 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
@@ -47,7 +46,7 @@ public:
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"tss");
boost::throw_exception(e);
}

View File

@@ -86,7 +86,7 @@ public:
};
// The maximum number of buffers to support in a single operation.
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
enum { max_buffers = 16 };
// Constructor.
reactive_socket_service(asio::io_service& io_service)
@@ -157,7 +157,7 @@ public:
if (int err = reactor_.register_descriptor(sock.get()))
{
ec = asio::error_code(err, asio::error::system_category);
ec = asio::error_code(err, asio::native_ecat);
return ec;
}
@@ -181,7 +181,7 @@ public:
if (int err = reactor_.register_descriptor(native_socket))
{
ec = asio::error_code(err, asio::error::system_category);
ec = asio::error_code(err, asio::native_ecat);
return ec;
}
@@ -450,7 +450,7 @@ public:
}
endpoint_type endpoint;
std::size_t addr_len = endpoint.capacity();
socket_addr_len_type addr_len = endpoint.capacity();
if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
return endpoint_type();
endpoint.resize(addr_len);
@@ -468,7 +468,7 @@ public:
}
endpoint_type endpoint;
std::size_t addr_len = endpoint.capacity();
socket_addr_len_type addr_len = endpoint.capacity();
if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
return endpoint_type();
endpoint.resize(addr_len);
@@ -624,7 +624,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@@ -645,7 +645,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (total_buffer_size == 0)
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error_code(), 0));
return;
}
@@ -658,7 +658,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->get_io_service().post(bind_handler(handler, ec, 0));
this->io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@@ -666,7 +666,7 @@ public:
reactor_.start_write_op(impl.socket_,
send_handler<ConstBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers, flags, handler));
impl.socket_, this->io_service(), buffers, flags, handler));
}
}
@@ -804,7 +804,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@@ -816,7 +816,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->get_io_service().post(bind_handler(handler, ec, 0));
this->io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@@ -824,7 +824,7 @@ public:
reactor_.start_write_op(impl.socket_,
send_to_handler<ConstBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers,
impl.socket_, this->io_service(), buffers,
destination, flags, handler));
}
}
@@ -975,7 +975,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@@ -996,7 +996,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (total_buffer_size == 0)
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error_code(), 0));
return;
}
@@ -1009,7 +1009,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->get_io_service().post(bind_handler(handler, ec, 0));
this->io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@@ -1019,13 +1019,13 @@ public:
{
reactor_.start_except_op(impl.socket_,
receive_handler<MutableBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers, flags, handler));
impl.socket_, this->io_service(), buffers, flags, handler));
}
else
{
reactor_.start_read_op(impl.socket_,
receive_handler<MutableBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers, flags, handler));
impl.socket_, this->io_service(), buffers, flags, handler));
}
}
}
@@ -1073,7 +1073,7 @@ public:
for (;;)
{
// Try to complete the operation without blocking.
std::size_t addr_len = sender_endpoint.capacity();
socket_addr_len_type addr_len = sender_endpoint.capacity();
int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs, i, flags,
sender_endpoint.data(), &addr_len, ec);
@@ -1124,7 +1124,7 @@ public:
bool operator()(const asio::error_code& result)
{
// Check whether the operation was successful.
if (result)
if (result != 0)
{
io_service_.post(bind_handler(handler_, result, 0));
return true;
@@ -1144,7 +1144,7 @@ public:
}
// Receive some data.
std::size_t addr_len = sender_endpoint_.capacity();
socket_addr_len_type addr_len = sender_endpoint_.capacity();
asio::error_code ec;
int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_,
sender_endpoint_.data(), &addr_len, ec);
@@ -1181,7 +1181,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@@ -1193,7 +1193,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->get_io_service().post(bind_handler(handler, ec, 0));
this->io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@@ -1201,7 +1201,7 @@ public:
reactor_.start_read_op(impl.socket_,
receive_from_handler<MutableBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers,
impl.socket_, this->io_service(), buffers,
sender_endpoint, flags, handler));
}
}
@@ -1242,7 +1242,7 @@ public:
// Try to complete the operation without blocking.
asio::error_code ec;
socket_holder new_socket;
std::size_t addr_len = 0;
socket_addr_len_type addr_len = 0;
if (peer_endpoint)
{
addr_len = peer_endpoint->capacity();
@@ -1327,7 +1327,7 @@ public:
// Accept the waiting connection.
asio::error_code ec;
socket_holder new_socket;
std::size_t addr_len = 0;
socket_addr_len_type addr_len = 0;
if (peer_endpoint_)
{
addr_len = peer_endpoint_->capacity();
@@ -1384,12 +1384,12 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
}
else if (peer.is_open())
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::already_open));
}
else
@@ -1401,7 +1401,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->get_io_service().post(bind_handler(handler, ec));
this->io_service().post(bind_handler(handler, ec));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@@ -1409,7 +1409,7 @@ public:
reactor_.start_read_op(impl.socket_,
accept_handler<Socket, Handler>(
impl.socket_, this->get_io_service(),
impl.socket_, this->io_service(),
peer, impl.protocol_, peer_endpoint,
(impl.flags_ & implementation_type::enable_connection_aborted) != 0,
handler));
@@ -1489,7 +1489,7 @@ public:
if (connect_error)
{
ec = asio::error_code(connect_error,
asio::error::system_category);
asio::native_ecat);
io_service_.post(bind_handler(handler_, ec));
return true;
}
@@ -1515,7 +1515,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
return;
}
@@ -1527,7 +1527,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->get_io_service().post(bind_handler(handler, ec));
this->io_service().post(bind_handler(handler, ec));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@@ -1541,7 +1541,7 @@ public:
{
// The connect operation has finished successfully so we need to post the
// handler immediately.
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error_code()));
}
else if (ec == asio::error::in_progress
@@ -1551,13 +1551,13 @@ public:
// until the socket becomes writeable.
boost::shared_ptr<bool> completed(new bool(false));
reactor_.start_write_and_except_ops(impl.socket_,
connect_handler<Handler>(impl.socket_, completed,
this->get_io_service(), reactor_, handler));
connect_handler<Handler>(
impl.socket_, completed, this->io_service(), reactor_, handler));
}
else
{
// The connect operation has failed, so post the handler immediately.
this->get_io_service().post(bind_handler(handler, ec));
this->io_service().post(bind_handler(handler, ec));
}
}

View File

@@ -213,7 +213,7 @@ public:
start_work_thread();
work_io_service_->post(
resolve_query_handler<Handler>(
impl, query, this->get_io_service(), handler));
impl, query, this->io_service(), handler));
}
}
@@ -309,7 +309,7 @@ public:
start_work_thread();
work_io_service_->post(
resolve_endpoint_handler<Handler>(
impl, endpoint, this->get_io_service(), handler));
impl, endpoint, this->io_service(), handler));
}
}

View File

@@ -63,18 +63,6 @@ public:
}
}
// Test whether the lock is held.
bool locked() const
{
return locked_;
}
// Get the underlying mutex.
Mutex& mutex()
{
return mutex_;
}
private:
// The underlying mutex.
Mutex& mutex_;

View File

@@ -166,8 +166,7 @@ private:
}
// Check if a service matches the given id.
static bool service_id_matches(
const asio::io_service::service& service,
bool service_id_matches(const asio::io_service::service& service,
const asio::io_service::id& id)
{
return service.id_ == &id;
@@ -175,8 +174,7 @@ private:
// Check if a service matches the given id.
template <typename Service>
static bool service_id_matches(
const asio::io_service::service& 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);

View File

@@ -26,6 +26,9 @@
#include <cerrno>
#include <boost/detail/workaround.hpp>
#include <new>
#if defined(__MACH__) && defined(__APPLE__)
# include <AvailabilityMacros.h>
#endif // defined(__MACH__) && defined(__APPLE__)
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
@@ -35,17 +38,6 @@ namespace asio {
namespace detail {
namespace socket_ops {
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
struct msghdr { int msg_namelen; };
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#if defined(__hpux)
// HP-UX doesn't declare these functions extern "C", so they are declared again
// here to avoid linker errors about undefined symbols.
extern "C" char* if_indextoname(unsigned int, char*);
extern "C" unsigned int if_nametoindex(const char*);
#endif // defined(__hpux)
inline void clear_error(asio::error_code& ec)
{
errno = 0;
@@ -60,36 +52,22 @@ inline ReturnType error_wrapper(ReturnType return_value,
asio::error_code& ec)
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
ec = asio::error_code(WSAGetLastError(),
asio::error::system_category);
ec = asio::error_code(WSAGetLastError(), asio::native_ecat);
#else
ec = asio::error_code(errno, asio::error::system_category);
ec = asio::error_code(errno, asio::native_ecat);
#endif
return return_value;
}
template <typename SockLenType>
inline socket_type call_accept(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
if (addrlen)
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
inline socket_type accept(socket_type s, socket_addr_type* addr,
std::size_t* addrlen, asio::error_code& ec)
socket_addr_len_type* addrlen, asio::error_code& ec)
{
clear_error(ec);
socket_type new_s = error_wrapper(call_accept(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
socket_type new_s = error_wrapper(::accept(s, addr, addrlen), ec);
if (new_s == invalid_socket)
return new_s;
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
int optval = 1;
int result = error_wrapper(::setsockopt(new_s,
SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
@@ -98,23 +76,18 @@ inline socket_type accept(socket_type s, socket_addr_type* addr,
::close(new_s);
return invalid_socket;
}
#endif
return new_s;
}
template <typename SockLenType>
inline int call_bind(SockLenType msghdr::*,
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
{
return ::bind(s, addr, (SockLenType)addrlen);
#else
return error_wrapper(::accept(s, addr, addrlen), ec);
#endif
}
inline int bind(socket_type s, const socket_addr_type* addr,
std::size_t addrlen, asio::error_code& ec)
socket_addr_len_type addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_bind(&msghdr::msg_namelen, s, addr, addrlen), ec);
return error_wrapper(::bind(s, addr, addrlen), ec);
}
inline int close(socket_type s, asio::error_code& ec)
@@ -133,19 +106,11 @@ inline int shutdown(socket_type s, int what, asio::error_code& ec)
return error_wrapper(::shutdown(s, what), ec);
}
template <typename SockLenType>
inline int call_connect(SockLenType msghdr::*,
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
{
return ::connect(s, addr, (SockLenType)addrlen);
}
inline int connect(socket_type s, const socket_addr_type* addr,
std::size_t addrlen, asio::error_code& ec)
socket_addr_len_type addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_connect(
&msghdr::msg_namelen, s, addr, addrlen), ec);
return error_wrapper(::connect(s, addr, addrlen), ec);
}
inline int listen(socket_type s, int backlog, asio::error_code& ec)
@@ -182,28 +147,6 @@ inline void init_buf(buf& b, const void* data, size_t size)
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
{
name = addr;
}
inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
{
name = const_cast<socket_addr_type*>(addr);
}
template <typename T>
inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
{
name = reinterpret_cast<T>(addr);
}
template <typename T>
inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
{
name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
}
inline int recv(socket_type s, buf* bufs, size_t count, int flags,
asio::error_code& ec)
{
@@ -219,15 +162,20 @@ inline int recv(socket_type s, buf* bufs, size_t count, int flags,
return -1;
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
msghdr msg;
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = bufs;
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
return error_wrapper(::recvmsg(s, &msg, flags), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
socket_addr_type* addr, std::size_t* addrlen,
socket_addr_type* addr, socket_addr_len_type* addrlen,
asio::error_code& ec)
{
clear_error(ec);
@@ -236,19 +184,25 @@ inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
DWORD recv_buf_count = static_cast<DWORD>(count);
DWORD bytes_transferred = 0;
DWORD recv_flags = flags;
int tmp_addrlen = (int)*addrlen;
int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
&bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);
*addrlen = (std::size_t)tmp_addrlen;
&bytes_transferred, &recv_flags, addr, addrlen, 0, 0), ec);
if (result != 0)
return -1;
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
init_msghdr_msg_name(msg.msg_name, addr);
msghdr msg;
#if defined(__MACH__) && defined(__APPLE__) \
&& (MAC_OS_X_VERSION_MAX_ALLOWED < 1040)
msg.msg_name = reinterpret_cast<char*>(addr);
#else
msg.msg_name = addr;
#endif
msg.msg_namelen = *addrlen;
msg.msg_iov = bufs;
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
*addrlen = msg.msg_namelen;
return result;
@@ -270,9 +224,14 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
return -1;
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
msghdr msg;
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = const_cast<buf*>(bufs);
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
#if defined(__linux__)
flags |= MSG_NOSIGNAL;
#endif // defined(__linux__)
@@ -281,7 +240,7 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
}
inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
const socket_addr_type* addr, std::size_t addrlen,
const socket_addr_type* addr, socket_addr_len_type addrlen,
asio::error_code& ec)
{
clear_error(ec);
@@ -295,11 +254,19 @@ inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
return -1;
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
init_msghdr_msg_name(msg.msg_name, addr);
msghdr msg;
#if defined(__MACH__) && defined(__APPLE__) \
&& (MAC_OS_X_VERSION_MAX_ALLOWED < 1040)
msg.msg_name = reinterpret_cast<char*>(const_cast<socket_addr_type*>(addr));
#else
msg.msg_name = const_cast<socket_addr_type*>(addr);
#endif
msg.msg_namelen = addrlen;
msg.msg_iov = const_cast<buf*>(bufs);
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
#if defined(__linux__)
flags |= MSG_NOSIGNAL;
#endif // defined(__linux__)
@@ -348,17 +315,8 @@ inline socket_type socket(int af, int type, int protocol,
#endif
}
template <typename SockLenType>
inline int call_setsockopt(SockLenType msghdr::*,
socket_type s, int level, int optname,
const void* optval, std::size_t optlen)
{
return ::setsockopt(s, level, optname,
(const char*)optval, (SockLenType)optlen);
}
inline int setsockopt(socket_type s, int level, int optname,
const void* optval, std::size_t optlen, asio::error_code& ec)
const void* optval, size_t optlen, asio::error_code& ec)
{
if (level == custom_socket_option_level && optname == always_fail_option)
{
@@ -383,22 +341,15 @@ inline int setsockopt(socket_type s, int level, int optname,
}
ec = asio::error::fault;
return -1;
#else // defined(__BORLANDC__)
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
return error_wrapper(call_setsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen), ec);
#endif // defined(__BORLANDC__)
}
template <typename SockLenType>
inline int call_getsockopt(SockLenType msghdr::*,
socket_type s, int level, int optname,
void* optval, std::size_t* optlen)
{
SockLenType tmp_optlen = (SockLenType)*optlen;
int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
*optlen = (std::size_t)tmp_optlen;
return result;
return error_wrapper(::setsockopt(s, level, optname,
reinterpret_cast<const char*>(optval), static_cast<int>(optlen)), ec);
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
return error_wrapper(::setsockopt(s, level, optname, optval,
static_cast<socklen_t>(optlen)), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
inline int getsockopt(socket_type s, int level, int optname, void* optval,
@@ -442,8 +393,10 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
return -1;
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen), ec);
int tmp_optlen = static_cast<int>(*optlen);
int result = error_wrapper(::getsockopt(s, level, optname,
reinterpret_cast<char*>(optval), &tmp_optlen), ec);
*optlen = static_cast<size_t>(tmp_optlen);
if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
&& ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
{
@@ -458,8 +411,10 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen), ec);
socklen_t tmp_optlen = static_cast<socklen_t>(*optlen);
int result = error_wrapper(::getsockopt(s, level, optname,
optval, &tmp_optlen), ec);
*optlen = static_cast<size_t>(tmp_optlen);
#if defined(__linux__)
if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
&& (optname == SO_SNDBUF || optname == SO_RCVBUF))
@@ -476,40 +431,18 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
template <typename SockLenType>
inline int call_getpeername(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = (SockLenType)*addrlen;
int result = ::getpeername(s, addr, &tmp_addrlen);
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
inline int getpeername(socket_type s, socket_addr_type* addr,
std::size_t* addrlen, asio::error_code& ec)
socket_addr_len_type* addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_getpeername(
&msghdr::msg_namelen, s, addr, addrlen), ec);
}
template <typename SockLenType>
inline int call_getsockname(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = (SockLenType)*addrlen;
int result = ::getsockname(s, addr, &tmp_addrlen);
*addrlen = (std::size_t)tmp_addrlen;
return result;
return error_wrapper(::getpeername(s, addr, addrlen), ec);
}
inline int getsockname(socket_type s, socket_addr_type* addr,
std::size_t* addrlen, asio::error_code& ec)
socket_addr_len_type* addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(call_getsockname(
&msghdr::msg_namelen, s, addr, addrlen), ec);
return error_wrapper(::getsockname(s, addr, addrlen), ec);
}
inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
@@ -548,17 +481,8 @@ inline int select(int nfds, fd_set* readfds, fd_set* writefds,
&& timeout->tv_usec > 0 && timeout->tv_usec < 1000)
timeout->tv_usec = 1000;
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#if defined(__hpux) && defined(__HP_aCC)
timespec ts;
ts.tv_sec = timeout ? timeout->tv_sec : 0;
ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
return error_wrapper(::pselect(nfds, readfds,
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
#else
return error_wrapper(::select(nfds, readfds,
writefds, exceptfds, timeout), ec);
#endif
}
inline int poll_read(socket_type s, asio::error_code& ec)
@@ -999,13 +923,6 @@ inline void gai_free(void* p)
::operator delete(p);
}
inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
{
using namespace std;
*target = 0;
strncat(target, source, max_size);
}
enum { gai_clone_flag = 1 << 30 };
inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
@@ -1375,15 +1292,14 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
&& (hints.ai_flags & AI_CANONNAME) && canon == 0)
{
std::size_t canon_len = strlen(hptr->h_name) + 1;
canon = gai_alloc<char>(canon_len);
canon = gai_alloc<char>(strlen(hptr->h_name) + 1);
if (canon == 0)
{
freeaddrinfo_emulation(aihead);
socket_ops::freehostent(hptr);
return EAI_MEMORY;
}
gai_strcpy(canon, hptr->h_name, canon_len);
strcpy(canon, hptr->h_name);
}
// Create an addrinfo structure for each returned address.
@@ -1419,14 +1335,13 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
}
else
{
std::size_t canonname_len = strlen(search[0].host) + 1;
aihead->ai_canonname = gai_alloc<char>(canonname_len);
aihead->ai_canonname = gai_alloc<char>(strlen(search[0].host) + 1);
if (aihead->ai_canonname == 0)
{
freeaddrinfo_emulation(aihead);
return EAI_MEMORY;
}
gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
strcpy(aihead->ai_canonname, search[0].host);
}
}
gai_free(canon);
@@ -1448,7 +1363,7 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
}
inline asio::error_code getnameinfo_emulation(
const socket_addr_type* sa, std::size_t salen, char* host,
const socket_addr_type* sa, socket_addr_len_type salen, char* host,
std::size_t hostlen, char* serv, std::size_t servlen, int flags,
asio::error_code& ec)
{
@@ -1509,7 +1424,8 @@ inline asio::error_code getnameinfo_emulation(
*dot = 0;
}
}
gai_strcpy(host, hptr->h_name, hostlen);
*host = '\0';
strncat(host, hptr->h_name, hostlen);
socket_ops::freehostent(hptr);
}
else
@@ -1547,7 +1463,8 @@ inline asio::error_code getnameinfo_emulation(
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
{
gai_strcpy(serv, sptr->s_name, servlen);
*serv = '\0';
strncat(serv, sptr->s_name, servlen);
}
else
{
@@ -1601,10 +1518,10 @@ inline asio::error_code translate_addrinfo_error(int error)
default: // Possibly the non-portable EAI_SYSTEM.
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return asio::error_code(
WSAGetLastError(), asio::error::system_category);
WSAGetLastError(), asio::native_ecat);
#else
return asio::error_code(
errno, asio::error::system_category);
errno, asio::native_ecat);
#endif
}
}
@@ -1670,7 +1587,7 @@ inline void freeaddrinfo(addrinfo_type* ai)
}
inline asio::error_code getnameinfo(const socket_addr_type* addr,
std::size_t addrlen, char* host, std::size_t hostlen,
socket_addr_len_type addrlen, char* host, std::size_t hostlen,
char* serv, std::size_t servlen, int flags, asio::error_code& ec)
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -1683,7 +1600,7 @@ inline asio::error_code getnameinfo(const socket_addr_type* addr,
# else
// Building for Windows 2000 or earlier.
typedef int (WSAAPI *gni_t)(const socket_addr_type*,
int, char*, std::size_t, char*, std::size_t, int);
socket_addr_len_type, char*, std::size_t, char*, std::size_t, int);
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
{
if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
@@ -1737,8 +1654,6 @@ inline u_short_type host_to_network_short(u_short_type value)
} // namespace detail
} // namespace asio
#undef ASIO_SOCKET_CALL
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_SOCKET_OPS_HPP

View File

@@ -110,19 +110,8 @@ public:
template <typename Protocol>
void resize(const Protocol&, std::size_t s)
{
// On some platforms (e.g. Windows Vista), the getsockopt function will
// return the size of a boolean socket option as one byte, even though a
// four byte integer was passed in.
switch (s)
{
case sizeof(char):
value_ = *reinterpret_cast<char*>(&value_) ? 1 : 0;
break;
case sizeof(value_):
break;
default:
if (s != sizeof(value_))
throw std::length_error("boolean socket option resize");
}
}
private:

View File

@@ -52,7 +52,7 @@ public:
using namespace std; // For memset.
sockaddr_in4_type addr;
std::size_t addr_len = sizeof(addr);
socket_addr_len_type addr_len = sizeof(addr);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");

View File

@@ -29,12 +29,12 @@
# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER) || defined(__BORLANDC__)
# pragma message("Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately")
# pragma message("Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target)")
# pragma message("Assuming _WIN32_WINNT=0x0500 (i.e. Windows 2000 target)")
# else // defined(_MSC_VER) || defined(__BORLANDC__)
# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately
# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target)
# warning Assuming _WIN32_WINNT=0x0500 (i.e. Windows 2000 target)
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
# define _WIN32_WINNT 0x0501
# define _WIN32_WINNT 0x0500
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER)
# if defined(_WIN32) && !defined(WIN32)
@@ -98,7 +98,6 @@
# include <arpa/inet.h>
# include <netdb.h>
# include <net/if.h>
# include <limits.h>
# if defined(__sun)
# include <sys/filio.h>
# include <sys/sockio.h>
@@ -116,6 +115,7 @@ const int socket_error_retval = SOCKET_ERROR;
const int max_addr_v4_str_len = 256;
const int max_addr_v6_str_len = 256;
typedef sockaddr socket_addr_type;
typedef int socket_addr_len_type;
typedef in_addr in4_addr_type;
typedef ip_mreq in4_mreq_type;
typedef sockaddr_in sockaddr_in4_type;
@@ -141,11 +141,6 @@ const int shutdown_both = SD_BOTH;
const int message_peek = MSG_PEEK;
const int message_out_of_band = MSG_OOB;
const int message_do_not_route = MSG_DONTROUTE;
# if defined (_WIN32_WINNT)
const int max_iov_len = 64;
# else
const int max_iov_len = 16;
# endif
#else
typedef int socket_type;
const int invalid_socket = -1;
@@ -153,6 +148,7 @@ const int socket_error_retval = -1;
const int max_addr_v4_str_len = INET_ADDRSTRLEN;
const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
typedef sockaddr socket_addr_type;
typedef socklen_t socket_addr_len_type;
typedef in_addr in4_addr_type;
typedef ip_mreq in4_mreq_type;
typedef sockaddr_in sockaddr_in4_type;
@@ -170,7 +166,6 @@ const int shutdown_both = SHUT_RDWR;
const int message_peek = MSG_PEEK;
const int message_out_of_band = MSG_OOB;
const int message_do_not_route = MSG_DONTROUTE;
const int max_iov_len = IOV_MAX;
#endif
const int custom_socket_option_level = 0xA5100000;
const int enable_connection_aborted_option = 1;

View File

@@ -135,9 +135,9 @@ public:
handler_base* last_waiter_;
// Storage for posted handlers.
typedef boost::aligned_storage<128> handler_storage_type;
typedef boost::aligned_storage<64> handler_storage_type;
#if defined(__BORLANDC__)
boost::aligned_storage<128> handler_storage_;
boost::aligned_storage<64> handler_storage_;
#else
handler_storage_type handler_storage_;
#endif
@@ -235,11 +235,10 @@ public:
void* do_handler_allocate(std::size_t size)
{
#if defined(__BORLANDC__)
BOOST_ASSERT(size <= boost::aligned_storage<128>::size);
BOOST_ASSERT(size <= boost::aligned_storage<64>::size);
#else
BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
#endif
(void)size;
return impl_->handler_storage_.address();
}
@@ -276,7 +275,7 @@ public:
if (impl_->first_waiter_ == 0)
impl_->last_waiter_ = 0;
lock.unlock();
service_impl_.get_io_service().post(
service_impl_.io_service().post(
invoke_current_handler(service_impl_, impl_));
}
}
@@ -416,20 +415,20 @@ public:
}
else
{
asio::detail::mutex::scoped_lock lock(impl->mutex_);
// Allocate and construct an object to wrap the handler.
typedef handler_wrapper<Handler> value_type;
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
asio::detail::mutex::scoped_lock lock(impl->mutex_);
if (impl->current_handler_ == 0)
{
// This handler now has the lock, so can be dispatched immediately.
impl->current_handler_ = ptr.get();
lock.unlock();
this->get_io_service().dispatch(invoke_current_handler(*this, impl));
this->io_service().dispatch(invoke_current_handler(*this, impl));
ptr.release();
}
else
@@ -456,20 +455,20 @@ public:
template <typename Handler>
void post(implementation_type& impl, Handler handler)
{
asio::detail::mutex::scoped_lock lock(impl->mutex_);
// Allocate and construct an object to wrap the handler.
typedef handler_wrapper<Handler> value_type;
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
asio::detail::mutex::scoped_lock lock(impl->mutex_);
if (impl->current_handler_ == 0)
{
// This handler now has the lock, so can be dispatched immediately.
impl->current_handler_ = ptr.get();
lock.unlock();
this->get_io_service().post(invoke_current_handler(*this, impl));
this->io_service().post(invoke_current_handler(*this, impl));
ptr.release();
}
else

View File

@@ -23,7 +23,6 @@
#include "asio/detail/event.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_queue.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/task_io_service_fwd.hpp"
@@ -41,13 +40,13 @@ public:
: asio::detail::service_base<task_io_service<Task> >(io_service),
mutex_(),
task_(use_service<Task>(io_service)),
task_interrupted_(true),
outstanding_work_(0),
handler_queue_(&task_handler_),
handler_queue_end_(&task_handler_),
stopped_(false),
shutdown_(false),
first_idle_thread_(0)
{
handler_queue_.push(&task_handler_);
}
void init(size_t /*concurrency_hint*/)
@@ -62,16 +61,17 @@ public:
lock.unlock();
// Destroy handler objects.
while (!handler_queue_.empty())
while (handler_queue_)
{
handler_queue::handler* h = handler_queue_.front();
handler_queue_.pop();
handler_base* h = handler_queue_;
handler_queue_ = h->next_;
if (h != &task_handler_)
h->destroy();
}
// Reset handler queue to initial state.
handler_queue_.push(&task_handler_);
handler_queue_ = &task_handler_;
handler_queue_end_ = &task_handler_;
}
// Run the event loop until interrupted or no more work.
@@ -80,7 +80,8 @@ public:
typename call_stack<task_io_service>::context ctx(this);
idle_thread_info this_idle_thread;
this_idle_thread.next = 0;
this_idle_thread.prev = &this_idle_thread;
this_idle_thread.next = &this_idle_thread;
asio::detail::mutex::scoped_lock lock(mutex_);
@@ -97,7 +98,8 @@ public:
typename call_stack<task_io_service>::context ctx(this);
idle_thread_info this_idle_thread;
this_idle_thread.next = 0;
this_idle_thread.prev = &this_idle_thread;
this_idle_thread.next = &this_idle_thread;
asio::detail::mutex::scoped_lock lock(mutex_);
@@ -132,7 +134,7 @@ public:
void stop()
{
asio::detail::mutex::scoped_lock lock(mutex_);
stop_all_threads(lock);
stop_all_threads();
}
// Reset in preparation for a subsequent run invocation.
@@ -154,7 +156,7 @@ public:
{
asio::detail::mutex::scoped_lock lock(mutex_);
if (--outstanding_work_ == 0)
stop_all_threads(lock);
stop_all_threads();
}
// Request invocation of the given handler.
@@ -172,7 +174,10 @@ public:
void post(Handler handler)
{
// Allocate and construct an operation to wrap the handler.
handler_queue::scoped_ptr ptr(handler_queue::wrap(handler));
typedef handler_wrapper<Handler> value_type;
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
asio::detail::mutex::scoped_lock lock(mutex_);
@@ -181,21 +186,24 @@ public:
return;
// Add the handler to the end of the queue.
handler_queue_.push(ptr.get());
if (handler_queue_end_)
{
handler_queue_end_->next_ = ptr.get();
handler_queue_end_ = ptr.get();
}
else
{
handler_queue_ = handler_queue_end_ = ptr.get();
}
ptr.release();
// An undelivered handler is treated as unfinished work.
++outstanding_work_;
// Wake up a thread to execute the handler.
if (!interrupt_one_idle_thread(lock))
{
if (!task_interrupted_)
{
task_interrupted_ = true;
if (!interrupt_one_idle_thread())
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
task_.interrupt();
}
}
}
private:
@@ -206,7 +214,7 @@ private:
{
if (outstanding_work_ == 0 && !stopped_)
{
stop_all_threads(lock);
stop_all_threads();
ec = asio::error_code();
return 0;
}
@@ -215,28 +223,26 @@ private:
bool task_has_run = false;
while (!stopped_)
{
if (!handler_queue_.empty())
if (handler_queue_)
{
// Prepare to execute first handler from queue.
handler_queue::handler* h = handler_queue_.front();
handler_queue_.pop();
handler_base* h = handler_queue_;
handler_queue_ = h->next_;
if (handler_queue_ == 0)
handler_queue_end_ = 0;
bool more_handlers = (handler_queue_ != 0);
lock.unlock();
if (h == &task_handler_)
{
bool more_handlers = (!handler_queue_.empty());
task_interrupted_ = more_handlers || polling;
// If the task has already run and we're polling then we're done.
if (task_has_run && polling)
{
task_interrupted_ = true;
handler_queue_.push(&task_handler_);
ec = asio::error_code();
return 0;
}
task_has_run = true;
lock.unlock();
task_cleanup c(lock, *this);
// Run the task. May throw an exception. Only block if the handler
@@ -246,11 +252,10 @@ private:
}
else
{
lock.unlock();
handler_cleanup c(lock, *this);
// Invoke the handler. May throw an exception.
h->invoke(); // invoke() deletes the handler object
h->call(); // call() deletes the handler object
ec = asio::error_code();
return 1;
@@ -259,10 +264,31 @@ private:
else if (this_idle_thread)
{
// Nothing to run right now, so just wait for work to do.
this_idle_thread->next = first_idle_thread_;
if (first_idle_thread_)
{
this_idle_thread->next = first_idle_thread_;
this_idle_thread->prev = first_idle_thread_->prev;
first_idle_thread_->prev->next = this_idle_thread;
first_idle_thread_->prev = this_idle_thread;
}
first_idle_thread_ = this_idle_thread;
this_idle_thread->wakeup_event.clear(lock);
this_idle_thread->wakeup_event.wait(lock);
this_idle_thread->wakeup_event.clear();
lock.unlock();
this_idle_thread->wakeup_event.wait();
lock.lock();
if (this_idle_thread->next == this_idle_thread)
{
first_idle_thread_ = 0;
}
else
{
if (first_idle_thread_ == this_idle_thread)
first_idle_thread_ = this_idle_thread->next;
this_idle_thread->next->prev = this_idle_thread->prev;
this_idle_thread->prev->next = this_idle_thread->next;
this_idle_thread->next = this_idle_thread;
this_idle_thread->prev = this_idle_thread;
}
}
else
{
@@ -276,50 +302,130 @@ private:
}
// Stop the task and all idle threads.
void stop_all_threads(
asio::detail::mutex::scoped_lock& lock)
void stop_all_threads()
{
stopped_ = true;
interrupt_all_idle_threads(lock);
if (!task_interrupted_)
{
task_interrupted_ = true;
interrupt_all_idle_threads();
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
task_.interrupt();
}
}
// Interrupt a single idle thread. Returns true if a thread was interrupted,
// false if no running thread could be found to interrupt.
bool interrupt_one_idle_thread(
asio::detail::mutex::scoped_lock& lock)
bool interrupt_one_idle_thread()
{
if (first_idle_thread_)
{
idle_thread_info* idle_thread = first_idle_thread_;
first_idle_thread_ = idle_thread->next;
idle_thread->next = 0;
idle_thread->wakeup_event.signal(lock);
first_idle_thread_->wakeup_event.signal();
first_idle_thread_ = first_idle_thread_->next;
return true;
}
return false;
}
// Interrupt all idle threads.
void interrupt_all_idle_threads(
asio::detail::mutex::scoped_lock& lock)
void interrupt_all_idle_threads()
{
while (first_idle_thread_)
if (first_idle_thread_)
{
idle_thread_info* idle_thread = first_idle_thread_;
first_idle_thread_ = idle_thread->next;
idle_thread->next = 0;
idle_thread->wakeup_event.signal(lock);
first_idle_thread_->wakeup_event.signal();
idle_thread_info* current_idle_thread = first_idle_thread_->next;
while (current_idle_thread != first_idle_thread_)
{
current_idle_thread->wakeup_event.signal();
current_idle_thread = current_idle_thread->next;
}
}
}
// Helper class to perform task-related operations on block exit.
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.
class handler_base
{
public:
typedef void (*call_func_type)(handler_base*);
typedef void (*destroy_func_type)(handler_base*);
handler_base(call_func_type call_func, destroy_func_type destroy_func)
: next_(0),
call_func_(call_func),
destroy_func_(destroy_func)
{
}
void call()
{
call_func_(this);
}
void destroy()
{
destroy_func_(this);
}
protected:
// Prevent deletion through this type.
~handler_base()
{
}
private:
friend class task_io_service<Task>;
friend class task_cleanup;
handler_base* next_;
call_func_type call_func_;
destroy_func_type destroy_func_;
};
// Template wrapper for handlers.
template <typename Handler>
class handler_wrapper
: public handler_base
{
public:
handler_wrapper(Handler handler)
: handler_base(&handler_wrapper<Handler>::do_call,
&handler_wrapper<Handler>::do_destroy),
handler_(handler)
{
}
static void do_call(handler_base* base)
{
// Take ownership of the handler object.
typedef handler_wrapper<Handler> this_type;
this_type* h(static_cast<this_type*>(base));
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
handler_ptr<alloc_traits> ptr(h->handler_, h);
// Make a copy of the handler so that the memory can be deallocated before
// the upcall is made.
Handler handler(h->handler_);
// Free the memory associated with the handler.
ptr.reset();
// Make the upcall.
asio_handler_invoke_helpers::invoke(handler, &handler);
}
static void do_destroy(handler_base* base)
{
// Take ownership of the handler object.
typedef handler_wrapper<Handler> this_type;
this_type* h(static_cast<this_type*>(base));
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
handler_ptr<alloc_traits> ptr(h->handler_, h);
}
private:
Handler handler_;
};
// Helper class to perform task-related operations on block exit.
class task_cleanup
{
public:
@@ -334,8 +440,20 @@ private:
{
// Reinsert the task at the end of the handler queue.
lock_.lock();
task_io_service_.task_interrupted_ = true;
task_io_service_.handler_queue_.push(&task_io_service_.task_handler_);
task_io_service_.task_handler_.next_ = 0;
if (task_io_service_.handler_queue_end_)
{
task_io_service_.handler_queue_end_->next_
= &task_io_service_.task_handler_;
task_io_service_.handler_queue_end_
= &task_io_service_.task_handler_;
}
else
{
task_io_service_.handler_queue_
= task_io_service_.handler_queue_end_
= &task_io_service_.task_handler_;
}
}
private:
@@ -360,7 +478,7 @@ private:
{
lock_.lock();
if (--task_io_service_.outstanding_work_ == 0)
task_io_service_.stop_all_threads(lock_);
task_io_service_.stop_all_threads();
}
private:
@@ -376,23 +494,23 @@ private:
// Handler object to represent the position of the task in the queue.
class task_handler
: public handler_queue::handler
: public handler_base
{
public:
task_handler()
: handler_queue::handler(0, 0)
: handler_base(0, 0)
{
}
} task_handler_;
// Whether the task has been interrupted.
bool task_interrupted_;
// The count of unfinished work.
int outstanding_work_;
// The queue of handlers that are ready to be delivered.
handler_queue handler_queue_;
// The start of a linked list of handlers that are ready to be delivered.
handler_base* handler_queue_;
// 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_;
@@ -404,6 +522,7 @@ private:
struct idle_thread_info
{
event wakeup_event;
idle_thread_info* prev;
idle_thread_info* next;
};

View File

@@ -23,13 +23,11 @@
#if defined(BOOST_WINDOWS)
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
@@ -48,8 +46,7 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::system_category),
asio::error_code(last_error, asio::native_ecat),
"event");
boost::throw_exception(e);
}
@@ -62,31 +59,21 @@ public:
}
// Signal the event.
template <typename Lock>
void signal(Lock& lock)
void signal()
{
BOOST_ASSERT(lock.locked());
(void)lock;
::SetEvent(event_);
}
// Reset the event.
template <typename Lock>
void clear(Lock& lock)
void clear()
{
BOOST_ASSERT(lock.locked());
(void)lock;
::ResetEvent(event_);
}
// Wait for the event to become signalled.
template <typename Lock>
void wait(Lock& lock)
void wait()
{
BOOST_ASSERT(lock.locked());
lock.unlock();
::WaitForSingleObject(event_, INFINITE);
lock.lock();
}
private:

View File

@@ -63,8 +63,7 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::system_category),
asio::error_code(last_error, asio::native_ecat),
"iocp");
boost::throw_exception(e);
}
@@ -174,8 +173,7 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::system_category),
asio::error_code(last_error, asio::native_ecat),
"pqcs");
boost::throw_exception(e);
}
@@ -230,8 +228,7 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::system_category),
asio::error_code(last_error, asio::native_ecat),
"pqcs");
boost::throw_exception(e);
}
@@ -250,8 +247,7 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::system_category),
asio::error_code(last_error, asio::native_ecat),
"pqcs");
boost::throw_exception(e);
}
@@ -316,7 +312,7 @@ private:
{
DWORD last_error = ::GetLastError();
ec = asio::error_code(last_error,
asio::error::system_category);
asio::native_ecat);
return 0;
}

View File

@@ -137,7 +137,7 @@ public:
enum
{
enable_connection_aborted = 1, // User wants connection_aborted errors.
close_might_block = 2, // User set linger option for blocking close.
user_set_linger = 2, // The user set the linger option.
user_set_non_blocking = 4 // The user wants a non-blocking socket.
};
@@ -170,7 +170,7 @@ public:
typedef detail::select_reactor<true> reactor_type;
// The maximum number of buffers to support in a single operation.
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
enum { max_buffers = 16 };
// Constructor.
win_iocp_socket_service(asio::io_service& io_service)
@@ -192,7 +192,7 @@ public:
while (impl)
{
asio::error_code ignored_ec;
close_for_destruction(*impl);
close(*impl, ignored_ec);
impl = impl->next_;
}
}
@@ -217,7 +217,34 @@ public:
// Destroy a socket implementation.
void destroy(implementation_type& impl)
{
close_for_destruction(impl);
if (impl.socket_ != invalid_socket)
{
// Check if the reactor was created, in which case we need to close the
// socket on the reactor as well to cancel any operations that might be
// running there.
reactor_type* reactor = static_cast<reactor_type*>(
interlocked_compare_exchange_pointer(
reinterpret_cast<void**>(&reactor_), 0, 0));
if (reactor)
reactor->close_descriptor(impl.socket_);
if (impl.flags_ & implementation_type::user_set_linger)
{
::linger opt;
opt.l_onoff = 0;
opt.l_linger = 0;
asio::error_code ignored_ec;
socket_ops::setsockopt(impl.socket_,
SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
}
asio::error_code ignored_ec;
socket_ops::close(impl.socket_, ignored_ec);
impl.socket_ = invalid_socket;
impl.flags_ = 0;
impl.cancel_token_.reset();
impl.safe_cancellation_thread_id_ = 0;
}
// Remove implementation from linked list of all implementations.
asio::detail::mutex::scoped_lock lock(mutex_);
@@ -326,25 +353,6 @@ public:
{
ec = asio::error::bad_descriptor;
}
else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
::GetModuleHandleA("KERNEL32"), "CancelIoEx"))
{
// The version of Windows supports cancellation from any thread.
typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;
socket_type sock = impl.socket_;
HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
if (!cancel_io_ex(sock_as_handle, 0))
{
DWORD last_error = ::GetLastError();
ec = asio::error_code(last_error,
asio::error::system_category);
}
else
{
ec = asio::error_code();
}
}
else if (impl.safe_cancellation_thread_id_ == 0)
{
// No operations have been started, so there's nothing to cancel.
@@ -359,8 +367,7 @@ public:
if (!::CancelIo(sock_as_handle))
{
DWORD last_error = ::GetLastError();
ec = asio::error_code(last_error,
asio::error::system_category);
ec = asio::error_code(last_error, asio::native_ecat);
}
else
{
@@ -468,12 +475,7 @@ public:
if (option.level(impl.protocol_) == SOL_SOCKET
&& option.name(impl.protocol_) == SO_LINGER)
{
const ::linger* linger_option =
reinterpret_cast<const ::linger*>(option.data(impl.protocol_));
if (linger_option->l_onoff != 0 && linger_option->l_linger != 0)
impl.flags_ |= implementation_type::close_might_block;
else
impl.flags_ &= ~implementation_type::close_might_block;
impl.flags_ |= implementation_type::user_set_linger;
}
socket_ops::setsockopt(impl.socket_,
@@ -561,7 +563,7 @@ public:
}
endpoint_type endpoint;
std::size_t addr_len = endpoint.capacity();
socket_addr_len_type addr_len = endpoint.capacity();
if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
return endpoint_type();
endpoint.resize(addr_len);
@@ -600,7 +602,7 @@ public:
else
{
endpoint_type endpoint;
std::size_t addr_len = endpoint.capacity();
socket_addr_len_type addr_len = endpoint.capacity();
if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
return endpoint_type();
endpoint.resize(addr_len);
@@ -666,8 +668,7 @@ public:
last_error = WSAECONNRESET;
else if (last_error == ERROR_PORT_UNREACHABLE)
last_error = WSAECONNREFUSED;
ec = asio::error_code(last_error,
asio::error::system_category);
ec = asio::error_code(last_error, asio::native_ecat);
return 0;
}
@@ -718,8 +719,7 @@ public:
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
// Map non-portable errors to their portable counterparts.
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
if (ec.value() == ERROR_NETNAME_DELETED)
{
if (handler_op->cancel_token_.expired())
@@ -767,7 +767,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@@ -783,7 +783,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->get_io_service(), impl.cancel_token_, buffers, handler);
this->io_service(), impl.cancel_token_, buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@@ -803,7 +803,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
{
asio::io_service::work work(this->get_io_service());
asio::io_service::work work(this->io_service());
ptr.reset();
asio::error_code error;
iocp_service_.post(bind_handler(handler, error, 0));
@@ -819,10 +819,9 @@ public:
// Check if the operation completed immediately.
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->get_io_service());
asio::io_service::work work(this->io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
}
else
@@ -866,8 +865,7 @@ public:
DWORD last_error = ::WSAGetLastError();
if (last_error == ERROR_PORT_UNREACHABLE)
last_error = WSAECONNREFUSED;
ec = asio::error_code(last_error,
asio::error::system_category);
ec = asio::error_code(last_error, asio::native_ecat);
return 0;
}
@@ -916,8 +914,7 @@ public:
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
// Map non-portable errors to their portable counterparts.
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
if (ec.value() == ERROR_PORT_UNREACHABLE)
{
ec = asio::error::connection_refused;
@@ -958,7 +955,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@@ -974,7 +971,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->get_io_service(), buffers, handler);
this->io_service(), buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@@ -998,10 +995,9 @@ public:
// Check if the operation completed immediately.
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->get_io_service());
asio::io_service::work work(this->io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
}
else
@@ -1055,8 +1051,7 @@ public:
last_error = WSAECONNRESET;
else if (last_error == ERROR_PORT_UNREACHABLE)
last_error = WSAECONNREFUSED;
ec = asio::error_code(last_error,
asio::error::system_category);
ec = asio::error_code(last_error, asio::native_ecat);
return 0;
}
if (bytes_transferred == 0)
@@ -1114,8 +1109,7 @@ public:
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
// Map non-portable errors to their portable counterparts.
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
if (ec.value() == ERROR_NETNAME_DELETED)
{
if (handler_op->cancel_token_.expired())
@@ -1170,7 +1164,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@@ -1186,7 +1180,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->get_io_service(), impl.cancel_token_, buffers, handler);
this->io_service(), impl.cancel_token_, buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@@ -1205,7 +1199,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
{
asio::io_service::work work(this->get_io_service());
asio::io_service::work work(this->io_service());
ptr.reset();
asio::error_code error;
iocp_service_.post(bind_handler(handler, error, 0));
@@ -1220,10 +1214,9 @@ public:
DWORD last_error = ::WSAGetLastError();
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->get_io_service());
asio::io_service::work work(this->io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
}
else
@@ -1261,7 +1254,7 @@ public:
// Receive some data.
DWORD bytes_transferred = 0;
DWORD recv_flags = flags;
int endpoint_size = static_cast<int>(sender_endpoint.capacity());
int endpoint_size = sender_endpoint.capacity();
int result = ::WSARecvFrom(impl.socket_, bufs, i, &bytes_transferred,
&recv_flags, sender_endpoint.data(), &endpoint_size, 0, 0);
if (result != 0)
@@ -1269,8 +1262,7 @@ public:
DWORD last_error = ::WSAGetLastError();
if (last_error == ERROR_PORT_UNREACHABLE)
last_error = WSAECONNREFUSED;
ec = asio::error_code(last_error,
asio::error::system_category);
ec = asio::error_code(last_error, asio::native_ecat);
return 0;
}
if (bytes_transferred == 0)
@@ -1279,7 +1271,7 @@ public:
return 0;
}
sender_endpoint.resize(static_cast<std::size_t>(endpoint_size));
sender_endpoint.resize(endpoint_size);
ec = asio::error_code();
return bytes_transferred;
@@ -1299,7 +1291,7 @@ public:
&receive_from_operation<
MutableBufferSequence, Handler>::destroy_impl),
endpoint_(endpoint),
endpoint_size_(static_cast<int>(endpoint.capacity())),
endpoint_size_(endpoint.capacity()),
work_(io_service),
buffers_(buffers),
handler_(handler)
@@ -1336,8 +1328,7 @@ public:
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
// Map non-portable errors to their portable counterparts.
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
if (ec.value() == ERROR_PORT_UNREACHABLE)
{
ec = asio::error::connection_refused;
@@ -1390,7 +1381,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@@ -1406,7 +1397,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->get_io_service(), sender_endp, buffers, handler);
this->io_service(), sender_endp, buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@@ -1429,10 +1420,9 @@ public:
DWORD last_error = ::WSAGetLastError();
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->get_io_service());
asio::io_service::work work(this->io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
}
else
@@ -1463,7 +1453,7 @@ public:
{
asio::error_code ec;
socket_holder new_socket;
std::size_t addr_len = 0;
socket_addr_len_type addr_len = 0;
if (peer_endpoint)
{
addr_len = peer_endpoint->capacity();
@@ -1517,7 +1507,7 @@ public:
peer_(peer),
protocol_(protocol),
peer_endpoint_(peer_endpoint),
work_(io_service.get_io_service()),
work_(io_service.io_service()),
enable_connection_aborted_(enable_connection_aborted),
handler_(handler)
{
@@ -1618,8 +1608,7 @@ public:
GetAcceptExSockaddrs(handler_op->output_buffer(), 0,
handler_op->address_length(), handler_op->address_length(),
&local_addr, &local_addr_length, &remote_addr, &remote_addr_length);
if (static_cast<std::size_t>(remote_addr_length)
> peer_endpoint.capacity())
if (remote_addr_length > peer_endpoint.capacity())
{
last_error = WSAEINVAL;
}
@@ -1627,7 +1616,7 @@ public:
{
using namespace std; // For memcpy.
memcpy(peer_endpoint.data(), remote_addr, remote_addr_length);
peer_endpoint.resize(static_cast<std::size_t>(remote_addr_length));
peer_endpoint.resize(remote_addr_length);
}
}
@@ -1670,8 +1659,7 @@ public:
ptr.reset();
// Call the handler.
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
asio_handler_invoke_helpers::invoke(
detail::bind_handler(handler, ec), &handler);
}
@@ -1706,7 +1694,7 @@ public:
// Check whether acceptor has been initialised.
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
return;
}
@@ -1714,7 +1702,7 @@ public:
// Check that peer socket has not already been opened.
if (peer.is_open())
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::already_open));
return;
}
@@ -1731,7 +1719,7 @@ public:
impl.protocol_.type(), impl.protocol_.protocol(), ec));
if (sock.get() == invalid_socket)
{
this->get_io_service().post(bind_handler(handler, ec));
this->io_service().post(bind_handler(handler, ec));
return;
}
@@ -1769,10 +1757,9 @@ public:
}
else
{
asio::io_service::work work(this->get_io_service());
asio::io_service::work work(this->io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
asio::error_code ec(last_error, asio::native_ecat);
iocp_service_.post(bind_handler(handler, ec));
}
}
@@ -1848,8 +1835,8 @@ public:
// If connection failed then post the handler with the error code.
if (connect_error)
{
ec = asio::error_code(connect_error,
asio::error::system_category);
ec = asio::error_code(
connect_error, asio::native_ecat);
io_service_.post(bind_handler(handler_, ec));
return true;
}
@@ -1888,7 +1875,7 @@ public:
{
if (!is_open(impl))
{
this->get_io_service().post(bind_handler(handler,
this->io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
return;
}
@@ -1905,8 +1892,7 @@ public:
reinterpret_cast<void**>(&reactor_), 0, 0));
if (!reactor)
{
reactor = &(asio::use_service<reactor_type>(
this->get_io_service()));
reactor = &(asio::use_service<reactor_type>(this->io_service()));
interlocked_exchange_pointer(
reinterpret_cast<void**>(&reactor_), reactor);
}
@@ -1917,7 +1903,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->get_io_service().post(bind_handler(handler, ec));
this->io_service().post(bind_handler(handler, ec));
return;
}
@@ -1934,7 +1920,7 @@ public:
// The connect operation has finished successfully so we need to post the
// handler immediately.
this->get_io_service().post(bind_handler(handler, ec));
this->io_service().post(bind_handler(handler, ec));
}
else if (ec == asio::error::in_progress
|| ec == asio::error::would_block)
@@ -1946,7 +1932,7 @@ public:
connect_handler<Handler>(
impl.socket_,
(impl.flags_ & implementation_type::user_set_non_blocking) != 0,
completed, this->get_io_service(), *reactor, handler));
completed, this->io_service(), *reactor, handler));
}
else
{
@@ -1959,48 +1945,11 @@ public:
}
// The connect operation has failed, so post the handler immediately.
this->get_io_service().post(bind_handler(handler, ec));
this->io_service().post(bind_handler(handler, ec));
}
}
private:
// Helper function to close a socket when the associated object is being
// destroyed.
void close_for_destruction(implementation_type& impl)
{
if (is_open(impl))
{
// Check if the reactor was created, in which case we need to close the
// socket on the reactor as well to cancel any operations that might be
// running there.
reactor_type* reactor = static_cast<reactor_type*>(
interlocked_compare_exchange_pointer(
reinterpret_cast<void**>(&reactor_), 0, 0));
if (reactor)
reactor->close_descriptor(impl.socket_);
// The socket destructor must not block. If the user has changed the
// linger option to block in the foreground, we will change it back to the
// default so that the closure is performed in the background.
if (impl.flags_ & implementation_type::close_might_block)
{
::linger opt;
opt.l_onoff = 0;
opt.l_linger = 0;
asio::error_code ignored_ec;
socket_ops::setsockopt(impl.socket_,
SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
}
asio::error_code ignored_ec;
socket_ops::close(impl.socket_, ignored_ec);
impl.socket_ = invalid_socket;
impl.flags_ = 0;
impl.cancel_token_.reset();
impl.safe_cancellation_thread_id_ = 0;
}
}
// Helper function to emulate InterlockedCompareExchangePointer functionality
// for:
// - very old Platform SDKs; and

View File

@@ -23,7 +23,6 @@
#if defined(BOOST_WINDOWS)
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
@@ -49,7 +48,7 @@ public:
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"mutex");
boost::throw_exception(e);
}
@@ -68,7 +67,7 @@ public:
if (error != 0)
{
asio::system_error e(
asio::error_code(error, asio::error::system_category),
asio::error_code(error, asio::native_ecat),
"mutex");
boost::throw_exception(e);
}

View File

@@ -23,7 +23,6 @@
#if defined(BOOST_WINDOWS)
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
@@ -55,8 +54,7 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::system_category),
asio::error_code(last_error, asio::native_ecat),
"thread");
boost::throw_exception(e);
}

View File

@@ -23,7 +23,6 @@
#if defined(BOOST_WINDOWS)
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
@@ -48,8 +47,7 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::system_category),
asio::error_code(last_error, asio::native_ecat),
"tss");
boost::throw_exception(e);
}

View File

@@ -28,7 +28,6 @@
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
@@ -86,8 +85,7 @@ public:
if (this != &instance_ && ref_->result() != 0)
{
asio::system_error e(
asio::error_code(ref_->result(),
asio::error::system_category),
asio::error_code(ref_->result(), asio::native_ecat),
"winsock");
boost::throw_exception(e);
}

View File

@@ -17,10 +17,6 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/type_traits.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
@@ -34,9 +30,7 @@ class wrapped_handler
public:
typedef void result_type;
wrapped_handler(
typename boost::add_reference<Dispatcher>::type dispatcher,
Handler handler)
wrapped_handler(Dispatcher& dispatcher, Handler handler)
: dispatcher_(dispatcher),
handler_(handler)
{
@@ -123,7 +117,7 @@ public:
}
//private:
Dispatcher dispatcher_;
Dispatcher& dispatcher_;
Handler handler_;
};
@@ -177,9 +171,9 @@ inline void asio_handler_invoke(const Function& function,
function, this_handler->handler_));
}
template <typename Function, typename Handler, typename Context>
template <typename Function, typename Dispatcher, typename Handler>
inline void asio_handler_invoke(const Function& function,
rewrapped_handler<Handler, Context>* this_handler)
rewrapped_handler<Dispatcher, Handler>* this_handler)
{
asio_handler_invoke_helpers::invoke(
function, &this_handler->context_);

View File

@@ -37,204 +37,327 @@
/// INTERNAL ONLY.
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# define ASIO_NATIVE_ERROR(e) e
# define ASIO_SOCKET_ERROR(e) WSA ## e
# define ASIO_NETDB_ERROR(e) WSA ## e
# define ASIO_GETADDRINFO_ERROR(e) WSA ## e
# define ASIO_NATIVE_ERROR(e) \
asio::error_code(e, \
asio::native_ecat)
# define ASIO_SOCKET_ERROR(e) \
asio::error_code(WSA ## e, \
asio::native_ecat)
# define ASIO_NETDB_ERROR(e) \
asio::error_code(WSA ## e, \
asio::native_ecat)
# define ASIO_GETADDRINFO_ERROR(e) \
asio::error_code(WSA ## e, \
asio::native_ecat)
# define ASIO_MISC_ERROR(e) \
asio::error_code(e, \
asio::misc_ecat)
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win
#else
# define ASIO_NATIVE_ERROR(e) e
# define ASIO_SOCKET_ERROR(e) e
# define ASIO_NETDB_ERROR(e) e
# define ASIO_GETADDRINFO_ERROR(e) e
# define ASIO_NATIVE_ERROR(e) \
asio::error_code(e, \
asio::native_ecat)
# define ASIO_SOCKET_ERROR(e) \
asio::error_code(e, \
asio::native_ecat)
# define ASIO_NETDB_ERROR(e) \
asio::error_code(e, \
asio::netdb_ecat)
# define ASIO_GETADDRINFO_ERROR(e) \
asio::error_code(e, \
asio::addrinfo_ecat)
# define ASIO_MISC_ERROR(e) \
asio::error_code(e, \
asio::misc_ecat)
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix
#endif
namespace asio {
namespace error {
enum basic_errors
namespace detail {
/// Hack to keep asio library header-file-only.
template <typename T>
class error_base
{
public:
// boostify: error category declarations go here.
/// Permission denied.
access_denied = ASIO_SOCKET_ERROR(EACCES),
static const asio::error_code access_denied;
/// Address family not supported by protocol.
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
static const asio::error_code address_family_not_supported;
/// Port already in use.
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
/// Address already in use.
static const asio::error_code address_in_use;
/// Transport endpoint is already connected.
already_connected = ASIO_SOCKET_ERROR(EISCONN),
static const asio::error_code already_connected;
/// Already open.
static const asio::error_code already_open;
/// Operation already in progress.
already_started = ASIO_SOCKET_ERROR(EALREADY),
static const asio::error_code already_started;
/// A connection has been aborted.
connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED),
static const asio::error_code connection_aborted;
/// Connection refused.
connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED),
static const asio::error_code connection_refused;
/// Connection reset by peer.
connection_reset = ASIO_SOCKET_ERROR(ECONNRESET),
static const asio::error_code connection_reset;
/// Bad file descriptor.
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
/// Bad port.
fault = ASIO_SOCKET_ERROR(EFAULT),
/// No route to host.
host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH),
/// Operation now in progress.
in_progress = ASIO_SOCKET_ERROR(EINPROGRESS),
/// Interrupted system call.
interrupted = ASIO_SOCKET_ERROR(EINTR),
/// Invalid argument.
invalid_argument = ASIO_SOCKET_ERROR(EINVAL),
/// Message too long.
message_size = ASIO_SOCKET_ERROR(EMSGSIZE),
/// Network is down.
network_down = ASIO_SOCKET_ERROR(ENETDOWN),
/// Network dropped connection on reset.
network_reset = ASIO_SOCKET_ERROR(ENETRESET),
/// Network is unreachable.
network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH),
/// Too many open files.
no_descriptors = ASIO_SOCKET_ERROR(EMFILE),
/// No buffer space available.
no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS),
/// Cannot allocate memory.
no_memory = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY),
ASIO_NATIVE_ERROR(ENOMEM)),
/// Operation not permitted.
no_permission = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED),
ASIO_NATIVE_ERROR(EPERM)),
/// Protocol not available.
no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT),
/// Transport endpoint is not connected.
not_connected = ASIO_SOCKET_ERROR(ENOTCONN),
/// Socket operation on non-socket.
not_socket = ASIO_SOCKET_ERROR(ENOTSOCK),
/// Operation cancelled.
operation_aborted = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED),
ASIO_NATIVE_ERROR(ECANCELED)),
/// Operation not supported.
operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP),
/// Cannot send after transport endpoint shutdown.
shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN),
/// Connection timed out.
timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT),
/// Resource temporarily unavailable.
try_again = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_RETRY),
ASIO_NATIVE_ERROR(EAGAIN)),
/// The socket is marked non-blocking and the requested operation would block.
would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK)
};
enum netdb_errors
{
/// Host not found (authoritative).
host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND),
/// Host not found (non-authoritative).
host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN),
/// The query is valid but does not have associated address data.
no_data = ASIO_NETDB_ERROR(NO_DATA),
/// A non-recoverable error occurred.
no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY)
};
enum addrinfo_errors
{
/// The service is not supported for the given socket type.
service_not_found = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND),
ASIO_GETADDRINFO_ERROR(EAI_SERVICE)),
/// The socket type is not supported.
socket_type_not_supported = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT),
ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE))
};
enum misc_errors
{
/// Already open.
already_open = 1,
static const asio::error_code bad_descriptor;
/// End of file or stream.
eof,
static const asio::error_code eof;
/// Bad address.
static const asio::error_code fault;
/// Host not found (authoritative).
static const asio::error_code host_not_found;
/// Host not found (non-authoritative).
static const asio::error_code host_not_found_try_again;
/// No route to host.
static const asio::error_code host_unreachable;
/// Operation now in progress.
static const asio::error_code in_progress;
/// Interrupted system call.
static const asio::error_code interrupted;
/// Invalid argument.
static const asio::error_code invalid_argument;
/// Message too long.
static const asio::error_code message_size;
/// Network is down.
static const asio::error_code network_down;
/// Network dropped connection on reset.
static const asio::error_code network_reset;
/// Network is unreachable.
static const asio::error_code network_unreachable;
/// Too many open files.
static const asio::error_code no_descriptors;
/// No buffer space available.
static const asio::error_code no_buffer_space;
/// The query is valid but does not have associated address data.
static const asio::error_code no_data;
/// Cannot allocate memory.
static const asio::error_code no_memory;
/// Operation not permitted.
static const asio::error_code no_permission;
/// Protocol not available.
static const asio::error_code no_protocol_option;
/// A non-recoverable error occurred.
static const asio::error_code no_recovery;
/// Transport endpoint is not connected.
static const asio::error_code not_connected;
/// Element not found.
not_found
};
static const asio::error_code not_found;
enum ssl_errors
{
/// Socket operation on non-socket.
static const asio::error_code not_socket;
/// Operation cancelled.
static const asio::error_code operation_aborted;
/// Operation not supported.
static const asio::error_code operation_not_supported;
/// The service is not supported for the given socket type.
static const asio::error_code service_not_found;
/// The socket type is not supported.
static const asio::error_code socket_type_not_supported;
/// Cannot send after transport endpoint shutdown.
static const asio::error_code shut_down;
/// Connection timed out.
static const asio::error_code timed_out;
/// Resource temporarily unavailable.
static const asio::error_code try_again;
/// The socket is marked non-blocking and the requested operation would block.
static const asio::error_code would_block;
private:
error_base();
};
// boostify: error category definitions go here.
inline asio::error_code make_error_code(basic_errors e)
{
return asio::error_code(static_cast<int>(e), system_category);
}
template <typename T> const asio::error_code
error_base<T>::access_denied = ASIO_SOCKET_ERROR(EACCES);
inline asio::error_code make_error_code(netdb_errors e)
{
return asio::error_code(static_cast<int>(e), netdb_category);
}
template <typename T> const asio::error_code
error_base<T>::address_family_not_supported = ASIO_SOCKET_ERROR(
EAFNOSUPPORT);
inline asio::error_code make_error_code(addrinfo_errors e)
{
return asio::error_code(static_cast<int>(e), addrinfo_category);
}
template <typename T> const asio::error_code
error_base<T>::address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE);
inline asio::error_code make_error_code(misc_errors e)
{
return asio::error_code(static_cast<int>(e), misc_category);
}
template <typename T> const asio::error_code
error_base<T>::already_connected = ASIO_SOCKET_ERROR(EISCONN);
inline asio::error_code make_error_code(ssl_errors e)
{
return asio::error_code(static_cast<int>(e), ssl_category);
}
template <typename T> const asio::error_code
error_base<T>::already_open = ASIO_MISC_ERROR(1);
template <typename T> const asio::error_code
error_base<T>::already_started = ASIO_SOCKET_ERROR(EALREADY);
template <typename T> const asio::error_code
error_base<T>::connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED);
template <typename T> const asio::error_code
error_base<T>::connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED);
template <typename T> const asio::error_code
error_base<T>::connection_reset = ASIO_SOCKET_ERROR(ECONNRESET);
template <typename T> const asio::error_code
error_base<T>::bad_descriptor = ASIO_SOCKET_ERROR(EBADF);
template <typename T> const asio::error_code
error_base<T>::eof = ASIO_MISC_ERROR(2);
template <typename T> const asio::error_code
error_base<T>::fault = ASIO_SOCKET_ERROR(EFAULT);
template <typename T> const asio::error_code
error_base<T>::host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND);
template <typename T> const asio::error_code
error_base<T>::host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN);
template <typename T> const asio::error_code
error_base<T>::host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH);
template <typename T> const asio::error_code
error_base<T>::in_progress = ASIO_SOCKET_ERROR(EINPROGRESS);
template <typename T> const asio::error_code
error_base<T>::interrupted = ASIO_SOCKET_ERROR(EINTR);
template <typename T> const asio::error_code
error_base<T>::invalid_argument = ASIO_SOCKET_ERROR(EINVAL);
template <typename T> const asio::error_code
error_base<T>::message_size = ASIO_SOCKET_ERROR(EMSGSIZE);
template <typename T> const asio::error_code
error_base<T>::network_down = ASIO_SOCKET_ERROR(ENETDOWN);
template <typename T> const asio::error_code
error_base<T>::network_reset = ASIO_SOCKET_ERROR(ENETRESET);
template <typename T> const asio::error_code
error_base<T>::network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH);
template <typename T> const asio::error_code
error_base<T>::no_descriptors = ASIO_SOCKET_ERROR(EMFILE);
template <typename T> const asio::error_code
error_base<T>::no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS);
template <typename T> const asio::error_code
error_base<T>::no_data = ASIO_NETDB_ERROR(NO_DATA);
template <typename T> const asio::error_code
error_base<T>::no_memory = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY),
ASIO_NATIVE_ERROR(ENOMEM));
template <typename T> const asio::error_code
error_base<T>::no_permission = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED),
ASIO_NATIVE_ERROR(EPERM));
template <typename T> const asio::error_code
error_base<T>::no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT);
template <typename T> const asio::error_code
error_base<T>::no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY);
template <typename T> const asio::error_code
error_base<T>::not_connected = ASIO_SOCKET_ERROR(ENOTCONN);
template <typename T> const asio::error_code
error_base<T>::not_found = ASIO_MISC_ERROR(3);
template <typename T> const asio::error_code
error_base<T>::not_socket = ASIO_SOCKET_ERROR(ENOTSOCK);
template <typename T> const asio::error_code
error_base<T>::operation_aborted = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED),
ASIO_NATIVE_ERROR(ECANCELED));
template <typename T> const asio::error_code
error_base<T>::operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP);
template <typename T> const asio::error_code
error_base<T>::service_not_found = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND),
ASIO_GETADDRINFO_ERROR(EAI_SERVICE));
template <typename T> const asio::error_code
error_base<T>::socket_type_not_supported = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT),
ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE));
template <typename T> const asio::error_code
error_base<T>::shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN);
template <typename T> const asio::error_code
error_base<T>::timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT);
template <typename T> const asio::error_code
error_base<T>::try_again = ASIO_WIN_OR_POSIX(
ASIO_NATIVE_ERROR(ERROR_RETRY),
ASIO_NATIVE_ERROR(EAGAIN));
template <typename T> const asio::error_code
error_base<T>::would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK);
} // namespace detail
/// Contains error constants.
class error : public asio::detail::error_base<error>
{
private:
error();
};
} // namespace error
} // namespace asio
#undef ASIO_NATIVE_ERROR
#undef ASIO_SOCKET_ERROR
#undef ASIO_NETDB_ERROR
#undef ASIO_GETADDRINFO_ERROR
#undef ASIO_MISC_ERROR
#undef ASIO_WIN_OR_POSIX
#include "asio/impl/error_code.ipp"

View File

@@ -32,30 +32,24 @@
namespace asio {
namespace error
/// Available error code categories.
enum error_category
{
/// Available error code categories.
enum error_category
{
/// System error codes.
system_category = ASIO_WIN_OR_POSIX(0, 0),
/// Native error codes.
native_ecat = ASIO_WIN_OR_POSIX(0, 0),
/// Error codes from NetDB functions.
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1),
/// Error codes from NetDB functions.
netdb_ecat = ASIO_WIN_OR_POSIX(native_ecat, 1),
/// Error codes from getaddrinfo.
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2),
/// Error codes from getaddrinfo.
addrinfo_ecat = ASIO_WIN_OR_POSIX(native_ecat, 2),
/// Miscellaneous error codes.
misc_category = ASIO_WIN_OR_POSIX(3, 3),
/// Miscellaneous error codes.
misc_ecat = ASIO_WIN_OR_POSIX(3, 3),
/// SSL error codes.
ssl_category = ASIO_WIN_OR_POSIX(4, 4)
};
} // namespace error
/// Bring error category type into the asio namespace.
typedef asio::error::error_category error_category;
/// SSL error codes.
ssl_ecat = ASIO_WIN_OR_POSIX(4, 4)
};
/// Class to represent an error code value.
class error_code
@@ -67,7 +61,7 @@ public:
/// Default constructor.
error_code()
: value_(0),
category_(error::system_category)
category_(native_ecat)
{
}
@@ -78,13 +72,6 @@ public:
{
}
/// Construct from an error code enum.
template <typename ErrorEnum>
error_code(ErrorEnum e)
{
*this = make_error_code(e);
}
/// Get the error value.
value_type value() const
{

View File

@@ -35,12 +35,10 @@ inline std::string error_code::message() const
return "Already open.";
if (*this == error::not_found)
return "Not found.";
if (category_ == error::ssl_category)
if (category_ == ssl_ecat)
return "SSL error.";
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
value_type value = value_;
if (category() != error::system_category && *this != error::eof)
return "asio error";
if (*this == error::eof)
value = ERROR_HANDLE_EOF;
char* msg = 0;
@@ -78,13 +76,11 @@ inline std::string error_code::message() const
return "Service not found.";
if (*this == error::socket_type_not_supported)
return "Socket type not supported.";
if (category() != error::system_category)
return "asio error";
#if defined(__sun) || defined(__QNX__)
return strerror(value_);
#elif defined(__MACH__) && defined(__APPLE__) \
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
|| defined(_AIX) || defined(__hpux) || defined(__osf__)
|| defined(_AIX)
char buf[256] = "";
strerror_r(value_, buf, sizeof(buf));
return buf;

View File

@@ -21,7 +21,6 @@
#include <limits>
#include "asio/detail/pop_options.hpp"
#include "asio/detail/dev_poll_reactor.hpp"
#include "asio/detail/epoll_reactor.hpp"
#include "asio/detail/kqueue_reactor.hpp"
#include "asio/detail/select_reactor.hpp"
@@ -129,11 +128,11 @@ template <typename Handler>
#if defined(GENERATING_DOCUMENTATION)
unspecified
#else
inline detail::wrapped_handler<io_service&, Handler>
inline detail::wrapped_handler<io_service, Handler>
#endif
io_service::wrap(Handler handler)
{
return detail::wrapped_handler<io_service&, Handler>(*this, handler);
return detail::wrapped_handler<io_service, Handler>(*this, handler);
}
inline io_service::work::work(asio::io_service& io_service)
@@ -158,11 +157,6 @@ inline asio::io_service& io_service::work::io_service()
return io_service_;
}
inline asio::io_service& io_service::work::get_io_service()
{
return io_service_;
}
inline io_service::service::service(asio::io_service& owner)
: owner_(owner),
type_info_(0),
@@ -179,11 +173,6 @@ inline asio::io_service& io_service::service::io_service()
return owner_;
}
inline asio::io_service& io_service::service::get_io_service()
{
return owner_;
}
template <typename Service>
inline Service& use_service(io_service& ios)
{

View File

@@ -19,7 +19,6 @@
#include "asio/detail/push_options.hpp"
#include <algorithm>
#include <boost/optional.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/buffer.hpp"
@@ -139,25 +138,23 @@ namespace detail
std::size_t bytes_transferred)
{
total_transferred_ += bytes_transferred;
buffers_->consume(bytes_transferred);
if ((*completion_condition_)(ec, total_transferred_)
|| buffers_->begin() == buffers_->end())
buffers_.consume(bytes_transferred);
if (completion_condition_(ec, total_transferred_)
|| buffers_.begin() == buffers_.end())
{
buffers_.reset();
completion_condition_.reset();
handler_(ec, total_transferred_);
}
else
{
stream_.async_read_some(*buffers_, *this);
stream_.async_read_some(buffers_, *this);
}
}
//private:
AsyncReadStream& stream_;
boost::optional<buffers_type> buffers_;
buffers_type buffers_;
std::size_t total_transferred_;
boost::optional<CompletionCondition> completion_condition_;
CompletionCondition completion_condition_;
ReadHandler handler_;
};
@@ -238,9 +235,8 @@ namespace detail
total_transferred_ += bytes_transferred;
streambuf_.commit(bytes_transferred);
if (streambuf_.size() == streambuf_.max_size()
|| (*completion_condition_)(ec, total_transferred_))
|| completion_condition_(ec, total_transferred_))
{
completion_condition_.reset();
handler_(ec, total_transferred_);
}
else
@@ -255,7 +251,7 @@ namespace detail
AsyncReadStream& stream_;
asio::basic_streambuf<Allocator>& streambuf_;
std::size_t total_transferred_;
boost::optional<CompletionCondition> completion_condition_;
CompletionCondition completion_condition_;
ReadHandler handler_;
};

View File

@@ -311,8 +311,7 @@ namespace detail
if (streambuf_.size() == streambuf_.max_size())
{
std::size_t bytes = 0;
asio::error_code ec(error::not_found);
handler_(ec, bytes);
handler_(error::not_found, bytes);
return;
}
@@ -389,8 +388,7 @@ void async_read_until(AsyncReadStream& s,
// No match. Check if buffer is full.
if (b.size() == b.max_size())
{
asio::error_code ec(error::not_found);
s.io_service().post(detail::bind_handler(handler, ec, 0));
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
return;
}
@@ -471,8 +469,7 @@ namespace detail
if (streambuf_.size() == streambuf_.max_size())
{
std::size_t bytes = 0;
asio::error_code ec(error::not_found);
handler_(ec, bytes);
handler_(error::not_found, bytes);
return;
}
@@ -562,8 +559,7 @@ void async_read_until(AsyncReadStream& s,
// Check if buffer is full.
if (b.size() == b.max_size())
{
asio::error_code ec(error::not_found);
s.io_service().post(detail::bind_handler(handler, ec, 0));
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
return;
}
@@ -645,8 +641,7 @@ namespace detail
if (streambuf_.size() == streambuf_.max_size())
{
std::size_t bytes = 0;
asio::error_code ec(error::not_found);
handler_(ec, bytes);
handler_(error::not_found, bytes);
return;
}
@@ -736,8 +731,7 @@ void async_read_until(AsyncReadStream& s,
// Check if buffer is full.
if (b.size() == b.max_size())
{
asio::error_code ec(error::not_found);
s.io_service().post(detail::bind_handler(handler, ec, 0));
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
return;
}

View File

@@ -17,10 +17,6 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/optional.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/buffer.hpp"
#include "asio/completion_condition.hpp"
#include "asio/detail/bind_handler.hpp"
@@ -128,25 +124,23 @@ namespace detail
std::size_t bytes_transferred)
{
total_transferred_ += bytes_transferred;
buffers_->consume(bytes_transferred);
if ((*completion_condition_)(ec, total_transferred_)
|| buffers_->begin() == buffers_->end())
buffers_.consume(bytes_transferred);
if (completion_condition_(ec, total_transferred_)
|| buffers_.begin() == buffers_.end())
{
buffers_.reset();
completion_condition_.reset();
handler_(ec, total_transferred_);
}
else
{
stream_.async_write_some(*buffers_, *this);
stream_.async_write_some(buffers_, *this);
}
}
//private:
AsyncWriteStream& stream_;
boost::optional<buffers_type> buffers_;
buffers_type buffers_;
std::size_t total_transferred_;
boost::optional<CompletionCondition> completion_condition_;
CompletionCondition completion_condition_;
WriteHandler handler_;
};

View File

@@ -26,7 +26,6 @@
#include "asio/detail/pop_options.hpp"
#include "asio/error_code.hpp"
#include "asio/detail/dev_poll_reactor_fwd.hpp"
#include "asio/detail/epoll_reactor_fwd.hpp"
#include "asio/detail/kqueue_reactor_fwd.hpp"
#include "asio/detail/noncopyable.hpp"
@@ -40,11 +39,6 @@
namespace asio {
class io_service;
template <typename Service> Service& use_service(io_service& ios);
template <typename Service> void add_service(io_service& ios, Service* svc);
template <typename Service> bool has_service(io_service& ios);
/// Provides core I/O functionality.
/**
* The io_service class provides the core I/O functionality for users of the
@@ -112,8 +106,6 @@ private:
typedef detail::task_io_service<detail::epoll_reactor<false> > impl_type;
#elif defined(ASIO_HAS_KQUEUE)
typedef detail::task_io_service<detail::kqueue_reactor<false> > impl_type;
#elif defined(ASIO_HAS_DEV_POLL)
typedef detail::task_io_service<detail::dev_poll_reactor<false> > impl_type;
#else
typedef detail::task_io_service<detail::select_reactor<false> > impl_type;
#endif
@@ -328,7 +320,7 @@ public:
#if defined(GENERATING_DOCUMENTATION)
unspecified
#else
detail::wrapped_handler<io_service&, Handler>
detail::wrapped_handler<io_service, Handler>
#endif
wrap(Handler handler);
@@ -381,8 +373,7 @@ public:
private:
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
detail::winsock_init<> init_;
#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \
|| defined(__osf__)
#elif defined(__sun) || defined(__QNX__)
detail::signal_init<> init_;
#endif
@@ -430,12 +421,8 @@ public:
*/
~work();
/// (Deprecated: use get_io_service().) Get the io_service associated with the
/// work.
asio::io_service& io_service();
/// Get the io_service associated with the work.
asio::io_service& get_io_service();
asio::io_service& io_service();
private:
// Prevent assignment.
@@ -459,12 +446,8 @@ class io_service::service
: private noncopyable
{
public:
/// (Deprecated: use get_io_service().) Get the io_service object that owns
/// the service.
asio::io_service& io_service();
/// Get the io_service object that owns the service.
asio::io_service& get_io_service();
asio::io_service& io_service();
protected:
/// Constructor.

View File

@@ -268,12 +268,7 @@ std::basic_ostream<Elem, Traits>& operator<<(
asio::error_code ec;
std::string s = addr.to_string(ec);
if (ec)
{
if (os.exceptions() & std::ios::failbit)
asio::detail::throw_error(ec);
else
os.setstate(std::ios_base::failbit);
}
os.setstate(std::ios_base::failbit);
else
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
os << os.widen(*i);

View File

@@ -300,7 +300,7 @@ public:
{
using namespace std; // For memcmp.
int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
sizeof(asio::detail::in6_addr_type));
sizeof(asio::detail::in6_addr_type)) < 0;
if (memcmp_result < 0)
return true;
if (memcmp_result > 0)
@@ -386,12 +386,7 @@ std::basic_ostream<Elem, Traits>& operator<<(
asio::error_code ec;
std::string s = addr.to_string(ec);
if (ec)
{
if (os.exceptions() & std::ios::failbit)
asio::detail::throw_error(ec);
else
os.setstate(std::ios_base::failbit);
}
os.setstate(std::ios_base::failbit);
else
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
os << os.widen(*i);

View File

@@ -61,6 +61,14 @@ public:
typedef asio::detail::socket_addr_type data_type;
#endif
/// The type for the size of the endpoint structure. This type is dependent on
/// the underlying implementation of the socket layer.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined size_type;
#else
typedef asio::detail::socket_addr_len_type size_type;
#endif
/// Default constructor.
basic_endpoint()
: data_()
@@ -164,7 +172,7 @@ public:
/// The protocol associated with the endpoint.
protocol_type protocol() const
{
if (is_v4(data_))
if (is_v4())
return InternetProtocol::v4();
return InternetProtocol::v6();
}
@@ -182,18 +190,18 @@ public:
}
/// Get the underlying size of the endpoint in the native type.
std::size_t size() const
size_type size() const
{
if (is_v4(data_))
if (is_v4())
return sizeof(asio::detail::sockaddr_in4_type);
else
return sizeof(asio::detail::sockaddr_in6_type);
}
/// Set the underlying size of the endpoint in the native type.
void resize(std::size_t size)
void resize(size_type size)
{
if (size > sizeof(data_))
if (size > size_type(sizeof(data_)))
{
asio::system_error e(asio::error::invalid_argument);
boost::throw_exception(e);
@@ -201,7 +209,7 @@ public:
}
/// Get the capacity of the endpoint in the native type.
std::size_t capacity() const
size_type capacity() const
{
return sizeof(data_);
}
@@ -210,7 +218,7 @@ public:
/// the host's byte order.
unsigned short port() const
{
if (is_v4(data_))
if (is_v4())
{
return asio::detail::socket_ops::network_to_host_short(
reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
@@ -228,7 +236,7 @@ public:
/// the host's byte order.
void port(unsigned short port_num)
{
if (is_v4(data_))
if (is_v4())
{
reinterpret_cast<asio::detail::sockaddr_in4_type&>(data_).sin_port
= asio::detail::socket_ops::host_to_network_short(port_num);
@@ -244,7 +252,7 @@ public:
asio::ip::address address() const
{
using namespace std; // For memcpy.
if (is_v4(data_))
if (is_v4())
{
const asio::detail::sockaddr_in4_type& data
= reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
@@ -298,26 +306,14 @@ public:
private:
// Helper function to determine whether the endpoint is IPv4.
bool is_v4() const
{
#if defined(_AIX)
template <typename T, unsigned char (T::*)> struct is_v4_helper {};
template <typename T>
static bool is_v4(const T& ss, is_v4_helper<T, &T::ss_family>* = 0)
{
return ss.ss_family == AF_INET;
}
template <typename T>
static bool is_v4(const T& ss, is_v4_helper<T, &T::__ss_family>* = 0)
{
return ss.__ss_family == AF_INET;
}
return data_.__ss_family == AF_INET;
#else
static bool is_v4(const asio::detail::sockaddr_storage_type& ss)
{
return ss.ss_family == AF_INET;
}
return data_.ss_family == AF_INET;
#endif
}
// The underlying IP socket address.
asio::detail::sockaddr_storage_type data_;
@@ -341,23 +337,11 @@ std::ostream& operator<<(std::ostream& os,
const basic_endpoint<InternetProtocol>& endpoint)
{
const address& addr = endpoint.address();
asio::error_code ec;
std::string a = addr.to_string(ec);
if (ec)
{
if (os.exceptions() & std::ios::failbit)
asio::detail::throw_error(ec);
else
os.setstate(std::ios_base::failbit);
}
if (addr.is_v4())
os << addr.to_string();
else
{
if (addr.is_v4())
os << a;
else
os << '[' << a << ']';
os << ':' << endpoint.port();
}
os << '[' << addr.to_string() << ']';
os << ':' << endpoint.port();
return os;
}
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
@@ -367,23 +351,11 @@ std::basic_ostream<Elem, Traits>& operator<<(
const basic_endpoint<InternetProtocol>& endpoint)
{
const address& addr = endpoint.address();
asio::error_code ec;
std::string a = addr.to_string(ec);
if (ec)
{
if (os.exceptions() & std::ios::failbit)
asio::detail::throw_error(ec);
else
os.setstate(std::ios_base::failbit);
}
if (addr.is_v4())
os << addr.to_string();
else
{
if (addr.is_v4())
os << a;
else
os << '[' << a << ']';
os << ':' << endpoint.port();
}
os << '[' << addr.to_string() << ']';
os << ':' << endpoint.port();
return os;
}
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))

View File

@@ -80,7 +80,9 @@ public:
{
using namespace std; // For memcpy.
typename InternetProtocol::endpoint endpoint;
endpoint.resize(static_cast<std::size_t>(address_info->ai_addrlen));
endpoint.resize(
static_cast<asio::detail::socket_addr_len_type>(
address_info->ai_addrlen));
memcpy(endpoint.data(), address_info->ai_addr,
address_info->ai_addrlen);
iter.values_->push_back(

View File

@@ -32,60 +32,52 @@ namespace ip {
namespace detail {
namespace socket_option {
// Helper template for implementing multicast enable loopback options.
// Helper template for implementing boolean-based options.
template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name>
class multicast_enable_loopback
class boolean
{
public:
#if defined(__sun) || defined(__osf__)
typedef unsigned char ipv4_value_type;
typedef unsigned char ipv6_value_type;
#elif defined(_AIX) || defined(__hpux)
typedef unsigned char ipv4_value_type;
typedef unsigned int ipv6_value_type;
#if defined(__sun)
typedef unsigned char value_type;
#else
typedef int ipv4_value_type;
typedef int ipv6_value_type;
typedef int value_type;
#endif
// Default constructor.
multicast_enable_loopback()
: ipv4_value_(0),
ipv6_value_(0)
boolean()
: value_(0)
{
}
// Construct with a specific option value.
explicit multicast_enable_loopback(bool v)
: ipv4_value_(v ? 1 : 0),
ipv6_value_(v ? 1 : 0)
explicit boolean(bool v)
: value_(v ? 1 : 0)
{
}
// Set the value of the boolean.
multicast_enable_loopback& operator=(bool v)
boolean& operator=(bool v)
{
ipv4_value_ = v ? 1 : 0;
ipv6_value_ = v ? 1 : 0;
value_ = v ? 1 : 0;
return *this;
}
// Get the current value of the boolean.
bool value() const
{
return !!ipv4_value_;
return !!value_;
}
// Convert to bool.
operator bool() const
{
return !!ipv4_value_;
return !!value_;
}
// Test for false.
bool operator!() const
{
return !ipv4_value_;
return !value_;
}
// Get the level of the socket option.
@@ -108,58 +100,35 @@ public:
// Get the address of the boolean data.
template <typename Protocol>
void* data(const Protocol& protocol)
value_type* data(const Protocol&)
{
if (protocol.family() == PF_INET6)
return &ipv6_value_;
return &ipv4_value_;
return &value_;
}
// Get the address of the boolean data.
template <typename Protocol>
const void* data(const Protocol& protocol) const
const value_type* data(const Protocol&) const
{
if (protocol.family() == PF_INET6)
return &ipv6_value_;
return &ipv4_value_;
return &value_;
}
// Get the size of the boolean data.
template <typename Protocol>
std::size_t size(const Protocol& protocol) const
std::size_t size(const Protocol&) const
{
if (protocol.family() == PF_INET6)
return sizeof(ipv6_value_);
return sizeof(ipv4_value_);
return sizeof(value_);
}
// Set the size of the boolean data.
template <typename Protocol>
void resize(const Protocol& protocol, std::size_t s)
void resize(const Protocol&, std::size_t s)
{
if (protocol.family() == PF_INET6)
{
if (s != sizeof(ipv6_value_))
{
throw std::length_error(
"multicast_enable_loopback socket option resize");
}
ipv4_value_ = ipv6_value_ ? 1 : 0;
}
else
{
if (s != sizeof(ipv4_value_))
{
throw std::length_error(
"multicast_enable_loopback socket option resize");
}
ipv6_value_ = ipv4_value_ ? 1 : 0;
}
if (s != sizeof(value_))
throw std::length_error("boolean socket option resize");
}
private:
ipv4_value_type ipv4_value_;
ipv6_value_type ipv6_value_;
value_type value_;
};
// Helper template for implementing unicast hops options.
@@ -237,10 +206,6 @@ public:
{
if (s != sizeof(value_))
throw std::length_error("unicast hops socket option resize");
#if defined(__hpux)
if (value_ < 0)
value_ = value_ & 0xFF;
#endif
}
private:
@@ -512,7 +477,7 @@ public:
}
// Construct with IPv6 interface.
explicit network_interface(unsigned int ipv6_interface)
explicit network_interface(unsigned long ipv6_interface)
{
ipv4_value_.s_addr =
asio::detail::socket_ops::host_to_network_long(
@@ -558,7 +523,7 @@ public:
private:
asio::detail::in4_addr_type ipv4_value_;
unsigned int ipv6_value_;
unsigned long ipv6_value_;
};
} // namespace socket_option

View File

@@ -167,7 +167,7 @@ typedef asio::ip::detail::socket_option::multicast_hops<
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined enable_loopback;
#else
typedef asio::ip::detail::socket_option::multicast_enable_loopback<
typedef asio::ip::detail::socket_option::boolean<
IPPROTO_IP, IP_MULTICAST_LOOP, IPPROTO_IPV6, IPV6_MULTICAST_LOOP>
enable_loopback;
#endif

View File

@@ -27,17 +27,17 @@ namespace placeholders {
#if defined(GENERATING_DOCUMENTATION)
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// An argument placeholder, for use with @ref boost_bind, that corresponds to
/// the error argument of a handler for any of the asynchronous functions.
unspecified error;
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// An argument placeholder, for use with @ref boost_bind, that corresponds to
/// the bytes_transferred argument of a handler for asynchronous functions such
/// as asio::basic_stream_socket::async_write_some or
/// asio::async_write.
unspecified bytes_transferred;
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// An argument placeholder, for use with @ref boost_bind, that corresponds to
/// the iterator argument of a handler for asynchronous functions such as
/// asio::basic_resolver::resolve.
unspecified iterator;

View File

@@ -60,9 +60,6 @@ private:
#elif defined(ASIO_HAS_KQUEUE)
typedef detail::reactive_socket_service<
Protocol, detail::kqueue_reactor<false> > service_impl_type;
#elif defined(ASIO_HAS_DEV_POLL)
typedef detail::reactive_socket_service<
Protocol, detail::dev_poll_reactor<false> > service_impl_type;
#else
typedef detail::reactive_socket_service<
Protocol, detail::select_reactor<false> > service_impl_type;

View File

@@ -174,12 +174,12 @@ public:
if (error_code == SSL_ERROR_SYSCALL)
{
return handler_(asio::error_code(
sys_error_code, asio::error::system_category), rc);
sys_error_code, asio::native_ecat), rc);
}
else
{
return handler_(asio::error_code(
error_code, asio::error::ssl_category), rc);
error_code, asio::ssl_ecat), rc);
}
}

View File

@@ -238,7 +238,7 @@ public:
typedef handshake_handler<Stream, Handler> connect_handler;
connect_handler* local_handler =
new connect_handler(handler, get_io_service());
new connect_handler(handler, io_service());
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
@@ -259,7 +259,7 @@ public:
);
local_handler->set_operation(op);
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Shut down SSL on the stream.
@@ -294,7 +294,7 @@ public:
typedef shutdown_handler<Stream, Handler> disconnect_handler;
disconnect_handler* local_handler =
new disconnect_handler(handler, get_io_service());
new disconnect_handler(handler, io_service());
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
@@ -313,7 +313,7 @@ public:
);
local_handler->set_operation(op);
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Write some data to the stream.
@@ -354,7 +354,7 @@ public:
{
typedef io_handler<Stream, Handler> send_handler;
send_handler* local_handler = new send_handler(handler, get_io_service());
send_handler* local_handler = new send_handler(handler, io_service());
boost::function<int (SSL*)> send_func =
boost::bind(&::SSL_write, boost::arg<1>(),
@@ -378,7 +378,7 @@ public:
);
local_handler->set_operation(op);
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Read some data from the stream.
@@ -419,7 +419,7 @@ public:
{
typedef io_handler<Stream, Handler> recv_handler;
recv_handler* local_handler = new recv_handler(handler, get_io_service());
recv_handler* local_handler = new recv_handler(handler, io_service());
boost::function<int (SSL*)> recv_func =
boost::bind(&::SSL_read, boost::arg<1>(),
@@ -443,7 +443,7 @@ public:
);
local_handler->set_operation(op);
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Peek at the incoming data on the stream.

View File

@@ -85,7 +85,7 @@ public:
template <typename Arg, typename Context_Service>
explicit stream(Arg& arg, basic_context<Context_Service>& context)
: next_layer_(arg),
service_(asio::use_service<Service>(next_layer_.get_io_service())),
service_(asio::use_service<Service>(next_layer_.io_service())),
impl_(service_.null())
{
service_.create(impl_, next_layer_, context);
@@ -97,8 +97,7 @@ public:
service_.destroy(impl_, next_layer_);
}
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the stream
* uses to dispatch handlers for asynchronous operations.
@@ -108,20 +107,7 @@ public:
*/
asio::io_service& io_service()
{
return next_layer_.get_io_service();
}
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the stream
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that stream will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_service& get_io_service()
{
return next_layer_.get_io_service();
return next_layer_.io_service();
}
/// Get a reference to the next layer.

View File

@@ -65,8 +65,7 @@ public:
service_.destroy(impl_);
}
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the strand.
/// Get the io_service associated with the strand.
/**
* This function may be used to obtain the io_service object that the strand
* uses to dispatch handlers for asynchronous operations.
@@ -76,20 +75,7 @@ public:
*/
asio::io_service& io_service()
{
return service_.get_io_service();
}
/// Get the io_service associated with the strand.
/**
* This function may be used to obtain the io_service object that the strand
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that the strand will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_service& get_io_service()
{
return service_.get_io_service();
return service_.io_service();
}
/// Request the strand to invoke the given handler.

View File

@@ -64,9 +64,6 @@ private:
#elif defined(ASIO_HAS_KQUEUE)
typedef detail::reactive_socket_service<
Protocol, detail::kqueue_reactor<false> > service_impl_type;
#elif defined(ASIO_HAS_DEV_POLL)
typedef detail::reactive_socket_service<
Protocol, detail::dev_poll_reactor<false> > service_impl_type;
#else
typedef detail::reactive_socket_service<
Protocol, detail::select_reactor<false> > service_impl_type;

View File

@@ -1,48 +0,0 @@
/*
Copyright (c) 2007, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_ASSERT
#include "libtorrent/config.hpp"
#include <cassert>
#if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !defined(NDEBUG)
TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* file, char const* function);
#define TORRENT_ASSERT(x) if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__)
#else
#define TORRENT_ASSERT(x) assert(x)
#endif
#endif

View File

@@ -83,7 +83,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket_type.hpp"
#include "libtorrent/connection_queue.hpp"
#include "libtorrent/disk_io_thread.hpp"
#include "libtorrent/assert.hpp"
namespace libtorrent
{
@@ -115,7 +114,6 @@ namespace libtorrent
std::vector<piece_picker::downloading_piece> unfinished_pieces;
std::vector<piece_picker::block_info> block_info;
std::vector<tcp::endpoint> peers;
std::vector<tcp::endpoint> banned_peers;
entry resume_data;
// this is true if this torrent is being processed (checked)
@@ -140,7 +138,7 @@ namespace libtorrent
checker_impl(session_impl& s): m_ses(s), m_abort(false) {}
void operator()();
piece_checker_data* find_torrent(const sha1_hash& info_hash);
void remove_torrent(sha1_hash const& info_hash, int options);
void remove_torrent(sha1_hash const& info_hash);
#ifndef NDEBUG
void check_invariant() const;
@@ -169,10 +167,6 @@ namespace libtorrent
// thread started to run the main downloader loop
struct session_impl: boost::noncopyable
{
// the size of each allocation that is chained in the send buffer
enum { send_buffer_size = 200 };
#ifndef NDEBUG
friend class ::libtorrent::peer_connection;
#endif
@@ -190,20 +184,15 @@ namespace libtorrent
~session_impl();
#ifndef TORRENT_DISABLE_EXTENSIONS
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext);
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext);
#endif
void operator()();
void open_listen_port() throw();
void open_listen_port();
// if we are listening on an IPv6 interface
// this will return one of the IPv6 addresses on this
// machine, otherwise just an empty endpoint
tcp::endpoint get_ipv6_interface() const;
void async_accept(boost::shared_ptr<socket_acceptor> const& listener);
void async_accept();
void on_incoming_connection(boost::shared_ptr<socket_type> const& s
, boost::weak_ptr<socket_acceptor> listener, asio::error_code const& e);
, boost::weak_ptr<socket_acceptor> const& as, asio::error_code const& e);
// must be locked to access the data
// in this struct
@@ -251,13 +240,12 @@ namespace libtorrent
bool is_listening() const;
torrent_handle add_torrent(
boost::intrusive_ptr<torrent_info> ti
torrent_info const& ti
, fs::path const& save_path
, entry const& resume_data
, storage_mode_t storage_mode
, storage_constructor_type sc
, bool paused
, void* userdata);
, bool compact_mode
, int block_size
, storage_constructor_type sc);
torrent_handle add_torrent(
char const* tracker_url
@@ -265,12 +253,11 @@ namespace libtorrent
, char const* name
, fs::path const& save_path
, entry const& resume_data
, storage_mode_t storage_mode
, storage_constructor_type sc
, bool paused
, void* userdata);
, bool compact_mode
, int block_size
, storage_constructor_type sc);
void remove_torrent(torrent_handle const& h, int options);
void remove_torrent(torrent_handle const& h);
std::vector<torrent_handle> get_torrents();
@@ -286,21 +273,8 @@ namespace libtorrent
void set_max_connections(int limit);
void set_max_uploads(int limit);
int max_connections() const { return m_max_connections; }
int max_uploads() const { return m_max_uploads; }
int max_half_open_connections() const { return m_half_open.limit(); }
int num_uploads() const { return m_num_unchoked; }
int num_connections() const
{ return m_connections.size(); }
void unchoke_peer(peer_connection& c)
{
torrent* t = c.associated_torrent().lock().get();
TORRENT_ASSERT(t);
if (t->unchoke_peer(c))
++m_num_unchoked;
}
int num_uploads() const;
int num_connections() const;
session_status status() const;
void set_peer_id(peer_id const& id);
@@ -334,24 +308,6 @@ namespace libtorrent
{ return m_dht_proxy; }
#endif
#ifdef TORRENT_STATS
void log_buffer_usage()
{
int send_buffer_capacity = 0;
int used_send_buffer = 0;
for (connection_map::const_iterator i = m_connections.begin()
, end(m_connections.end()); i != end; ++i)
{
send_buffer_capacity += i->second->send_buffer_capacity();
used_send_buffer += i->second->send_buffer_size();
}
TORRENT_ASSERT(send_buffer_capacity >= used_send_buffer);
m_buffer_usage_logger << log_time() << " send_buffer_size: " << send_buffer_capacity << std::endl;
m_buffer_usage_logger << log_time() << " used_send_buffer: " << used_send_buffer << std::endl;
m_buffer_usage_logger << log_time() << " send_buffer_utilization: "
<< (used_send_buffer * 100.f / send_buffer_capacity) << std::endl;
}
#endif
void start_lsd();
void start_natpmp();
void start_upnp();
@@ -362,19 +318,11 @@ namespace libtorrent
// handles delayed alerts
alert_manager m_alerts;
std::pair<char*, int> allocate_buffer(int size);
void free_buffer(char* buf, int size);
void free_disk_buffer(char* buf);
// private:
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
// this pool is used to allocate and recycle send
// buffers from.
boost::pool<> m_send_buffers;
// this is where all active sockets are stored.
// the selector can sleep while there's no activity on
// them
@@ -390,9 +338,6 @@ namespace libtorrent
file_pool m_files;
// handles disk io requests asynchronously
// peers have pointers into the disk buffer
// pool, and must be destructed before this
// object.
disk_io_thread m_disk_thread;
// this is a list of half-open tcp connections
@@ -432,10 +377,8 @@ namespace libtorrent
// at startup
int m_key;
// the number of retries we make when binding the
// listen socket. For each retry the port number
// is incremented by one
int m_listen_port_retries;
// the range of ports we try to listen on
std::pair<int, int> m_listen_port_range;
// the ip-address of the interface
// we are supposed to listen on.
@@ -443,32 +386,17 @@ namespace libtorrent
// that we should let the os decide which
// interface to listen on
tcp::endpoint m_listen_interface;
// if we're listening on an IPv6 interface
// this is one of the non local IPv6 interfaces
// on this machine
tcp::endpoint m_ipv6_interface;
struct listen_socket_t
{
listen_socket_t(): external_port(0) {}
// this is typically set to the same as the local
// listen port. In case a NAT port forward was
// successfully opened, this will be set to the
// port that is open on the external (NAT) interface
// on the NAT box itself. This is the port that has
// to be published to peers, since this is the port
// the client is reachable through.
int external_port;
// this is typically set to the same as the local
// listen port. In case a NAT port forward was
// successfully opened, this will be set to the
// port that is open on the external (NAT) interface
// on the NAT box itself. This is the port that has
// to be published to peers, since this is the port
// the client is reachable through.
int m_external_listen_port;
// the actual socket
boost::shared_ptr<socket_acceptor> sock;
};
// since we might be listening on multiple interfaces
// we might need more than one listen socket
std::list<listen_socket_t> m_listen_sockets;
listen_socket_t setup_listener(tcp::endpoint ep, int retries);
boost::shared_ptr<socket_acceptor> m_listen_socket;
// the settings for the client
session_settings m_settings;
@@ -489,28 +417,6 @@ namespace libtorrent
int m_max_uploads;
int m_max_connections;
// the number of unchoked peers
int m_num_unchoked;
// this is initialized to the unchoke_interval
// session_setting and decreased every second.
// when it reaches zero, it is reset to the
// unchoke_interval and the unchoke set is
// recomputed.
int m_unchoke_time_scaler;
// works like unchoke_time_scaler but it
// is only decresed when the unchoke set
// is recomputed, and when it reaches zero,
// the optimistic unchoke is moved to another peer.
int m_optimistic_unchoke_time_scaler;
// works like unchoke_time_scaler. Each time
// it reaches 0, and all the connections are
// used, the worst connection will be disconnected
// from the torrent with the most peers
int m_disconnect_time_scaler;
// statistics gathered from all torrents.
stat m_stat;
@@ -541,9 +447,9 @@ namespace libtorrent
pe_settings m_pe_settings;
#endif
boost::intrusive_ptr<natpmp> m_natpmp;
boost::intrusive_ptr<upnp> m_upnp;
boost::intrusive_ptr<lsd> m_lsd;
boost::shared_ptr<natpmp> m_natpmp;
boost::shared_ptr<upnp> m_upnp;
boost::shared_ptr<lsd> m_lsd;
// the timer used to fire the second_tick
deadline_timer m_timer;
@@ -553,17 +459,13 @@ namespace libtorrent
// This implements a round robin.
int m_next_connect_torrent;
#ifndef NDEBUG
void check_invariant() const;
void check_invariant(const char *place = 0);
#endif
#ifdef TORRENT_STATS
// logger used to write bandwidth usage statistics
std::ofstream m_stats_logger;
int m_second_counter;
// used to log send buffer usage statistics
std::ofstream m_buffer_usage_logger;
// the number of send buffers that are allocated
int m_buffer_allocations;
#endif
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
boost::shared_ptr<logger> create_log(std::string const& name
@@ -581,7 +483,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
typedef std::list<boost::function<boost::shared_ptr<
torrent_plugin>(torrent*, void*)> > extension_list_t;
torrent_plugin>(torrent*)> > extension_list_t;
extension_list_t m_extensions;
#endif

View File

@@ -33,6 +33,9 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
#define TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
#include "libtorrent/socket.hpp"
#include "libtorrent/invariant_check.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/function.hpp>
@@ -41,17 +44,11 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/thread/mutex.hpp>
#include <deque>
#include "libtorrent/socket.hpp"
#include "libtorrent/invariant_check.hpp"
#include "libtorrent/assert.hpp"
using boost::weak_ptr;
using boost::shared_ptr;
using boost::intrusive_ptr;
using boost::bind;
//#define TORRENT_VERBOSE_BANDWIDTH_LIMIT
namespace libtorrent {
// the maximum block of bandwidth quota to
@@ -111,14 +108,14 @@ struct bandwidth_limit
void assign(int amount) throw()
{
TORRENT_ASSERT(amount > 0);
assert(amount > 0);
m_current_rate += amount;
m_quota_left += amount;
}
void use_quota(int amount) throw()
{
TORRENT_ASSERT(amount <= m_quota_left);
assert(amount <= m_quota_left);
m_quota_left -= amount;
}
@@ -129,7 +126,7 @@ struct bandwidth_limit
void expire(int amount) throw()
{
TORRENT_ASSERT(amount >= 0);
assert(amount >= 0);
m_current_rate -= amount;
}
@@ -165,7 +162,7 @@ private:
template<class T>
T clamp(T val, T ceiling, T floor) throw()
{
TORRENT_ASSERT(ceiling >= floor);
assert(ceiling >= floor);
if (val >= ceiling) return ceiling;
else if (val <= floor) return floor;
return val;
@@ -180,13 +177,12 @@ struct bandwidth_manager
, m_limit(bandwidth_limit::inf)
, m_current_quota(0)
, m_channel(channel)
, m_in_hand_out_bandwidth(false)
{}
void throttle(int limit) throw()
{
mutex_t::scoped_lock l(m_mutex);
TORRENT_ASSERT(limit >= 0);
assert(limit >= 0);
m_limit = limit;
}
@@ -204,9 +200,9 @@ struct bandwidth_manager
, bool non_prioritized) throw()
{
INVARIANT_CHECK;
TORRENT_ASSERT(blk > 0);
assert(blk > 0);
TORRENT_ASSERT(!peer->ignore_bandwidth_limits());
assert(!peer->ignore_bandwidth_limits());
// make sure this peer isn't already in line
// waiting for bandwidth
@@ -214,11 +210,11 @@ struct bandwidth_manager
for (typename queue_t::iterator i = m_queue.begin()
, end(m_queue.end()); i != end; ++i)
{
TORRENT_ASSERT(i->peer < peer || peer < i->peer);
assert(i->peer < peer || peer < i->peer);
}
#endif
TORRENT_ASSERT(peer->max_assignable_bandwidth(m_channel) > 0);
assert(peer->max_assignable_bandwidth(m_channel) > 0);
boost::shared_ptr<Torrent> t = peer->associated_torrent().lock();
m_queue.push_back(bw_queue_entry<PeerConnection>(peer, blk, non_prioritized));
if (!non_prioritized)
@@ -241,10 +237,8 @@ struct bandwidth_manager
i = j;
}
}
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " req_bandwidht. m_queue.size() = " << m_queue.size() << std::endl;
#endif
if (!m_queue.empty()) hand_out_bandwidth();
if (m_queue.size() == 1) hand_out_bandwidth();
}
#ifndef NDEBUG
@@ -257,7 +251,7 @@ struct bandwidth_manager
current_quota += i->amount;
}
TORRENT_ASSERT(current_quota == m_current_quota);
assert(current_quota == m_current_quota);
}
#endif
@@ -279,7 +273,7 @@ private:
m_history_timer.async_wait(bind(&bandwidth_manager::on_history_expire, this, _1));
#ifndef NDEBUG
}
catch (std::exception&) { TORRENT_ASSERT(false); }
catch (std::exception&) { assert(false); }
#endif
}
@@ -292,7 +286,7 @@ private:
if (e) return;
TORRENT_ASSERT(!m_history.empty());
assert(!m_history.empty());
ptime now(time_now());
while (!m_history.empty() && m_history.back().expires_at <= now)
@@ -300,7 +294,7 @@ private:
history_entry<PeerConnection, Torrent> e = m_history.back();
m_history.pop_back();
m_current_quota -= e.amount;
TORRENT_ASSERT(m_current_quota >= 0);
assert(m_current_quota >= 0);
intrusive_ptr<PeerConnection> c = e.peer;
shared_ptr<Torrent> t = e.tor.lock();
if (!c->is_disconnecting()) c->expire_bandwidth(m_channel, e.amount);
@@ -322,17 +316,13 @@ private:
}
catch (std::exception&)
{
TORRENT_ASSERT(false);
assert(false);
}
#endif
}
void hand_out_bandwidth() throw()
{
// if we're already handing out bandwidth, just return back
// to the loop further down on the callstack
if (m_in_hand_out_bandwidth) return;
m_in_hand_out_bandwidth = true;
#ifndef NDEBUG
try {
#endif
@@ -347,18 +337,10 @@ private:
// available bandwidth to hand out
int amount = limit - m_current_quota;
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " hand_out_bandwidht. m_queue.size() = " << m_queue.size()
<< " amount = " << amount
<< " limit = " << limit
<< " m_current_quota = " << m_current_quota << std::endl;
#endif
while (!m_queue.empty() && amount > 0)
{
TORRENT_ASSERT(amount == limit - m_current_quota);
assert(amount == limit - m_current_quota);
bw_queue_entry<PeerConnection> qe = m_queue.front();
TORRENT_ASSERT(qe.max_block_size > 0);
m_queue.pop_front();
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock();
@@ -366,7 +348,6 @@ private:
if (qe.peer->is_disconnecting())
{
t->expire_bandwidth(m_channel, qe.max_block_size);
TORRENT_ASSERT(amount == limit - m_current_quota);
continue;
}
@@ -380,7 +361,6 @@ private:
if (max_assignable == 0)
{
t->expire_bandwidth(m_channel, qe.max_block_size);
TORRENT_ASSERT(amount == limit - m_current_quota);
continue;
}
@@ -394,16 +374,17 @@ private:
// block size must be smaller for lower rates. This is because
// the history window is one second, and the block will be forgotten
// after one second.
int block_size = (std::min)(qe.peer->bandwidth_throttle(m_channel)
, limit / 10);
int block_size = (std::min)(qe.max_block_size
, (std::min)(qe.peer->bandwidth_throttle(m_channel)
, m_limit / 10));
if (block_size < min_bandwidth_block_size)
{
block_size = (std::min)(int(min_bandwidth_block_size), limit);
block_size = min_bandwidth_block_size;
}
else if (block_size > max_bandwidth_block_size)
{
if (limit == bandwidth_limit::inf)
if (m_limit == bandwidth_limit::inf)
{
block_size = max_bandwidth_block_size;
}
@@ -414,15 +395,11 @@ private:
// as possible
// TODO: move this calculcation to where the limit
// is changed
block_size = limit
/ (limit / max_bandwidth_block_size);
block_size = m_limit
/ (m_limit / max_bandwidth_block_size);
}
}
if (block_size > qe.max_block_size) block_size = qe.max_block_size;
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl;
#endif
if (amount < block_size / 2)
{
m_queue.push_front(qe);
@@ -434,22 +411,19 @@ private:
// than the max_bandwidth_block_size
int hand_out_amount = (std::min)((std::min)(block_size, max_assignable)
, amount);
TORRENT_ASSERT(hand_out_amount > 0);
TORRENT_ASSERT(amount == limit - m_current_quota);
assert(hand_out_amount > 0);
amount -= hand_out_amount;
TORRENT_ASSERT(hand_out_amount <= qe.max_block_size);
assert(hand_out_amount <= qe.max_block_size);
t->assign_bandwidth(m_channel, hand_out_amount, qe.max_block_size);
qe.peer->assign_bandwidth(m_channel, hand_out_amount);
add_history_entry(history_entry<PeerConnection, Torrent>(
qe.peer, t, hand_out_amount, now + bw_window_size));
TORRENT_ASSERT(amount == limit - m_current_quota);
}
#ifndef NDEBUG
}
catch (std::exception& e)
{ TORRENT_ASSERT(false); };
{ assert(false); };
#endif
m_in_hand_out_bandwidth = false;
}
@@ -482,11 +456,6 @@ private:
// this is the channel within the consumers
// that bandwidth is assigned to (upload or download)
int m_channel;
// this is true while we're in the hand_out_bandwidth loop
// to prevent recursive invocations to interfere
bool m_in_hand_out_bandwidth;
};
}

View File

@@ -79,8 +79,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/entry.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
#if defined(_MSC_VER)
namespace std
{
@@ -151,7 +149,7 @@ namespace libtorrent
template<class InIt>
void read_string(InIt& in, InIt end, int len, std::string& str)
{
TORRENT_ASSERT(len >= 0);
assert(len >= 0);
for (int i = 0; i < len; ++i)
{
if (in == end) throw invalid_encoding();
@@ -214,7 +212,7 @@ namespace libtorrent
{
++in; // 'i'
std::string val = read_until(in, end, 'e');
TORRENT_ASSERT(*in == 'e');
assert(*in == 'e');
++in; // 'e'
ret = entry(entry::int_t);
ret.integer() = boost::lexical_cast<entry::integer_type>(val);
@@ -233,7 +231,7 @@ namespace libtorrent
bdecode_recursive(in, end, e);
if (in == end) throw invalid_encoding();
}
TORRENT_ASSERT(*in == 'e');
assert(*in == 'e');
++in; // 'e'
} break;
@@ -251,7 +249,7 @@ namespace libtorrent
bdecode_recursive(in, end, e);
if (in == end) throw invalid_encoding();
}
TORRENT_ASSERT(*in == 'e');
assert(*in == 'e');
++in; // 'e'
} break;
@@ -261,7 +259,7 @@ namespace libtorrent
if (isdigit((unsigned char)*in))
{
std::string len_s = read_until(in, end, ':');
TORRENT_ASSERT(*in == ':');
assert(*in == ':');
++in; // ':'
int len = std::atoi(len_s.c_str());
ret = entry(entry::string_t);

View File

@@ -1,85 +0,0 @@
/*
Copyright (c) 2007, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
#define TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
#include "libtorrent/socket.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <list>
namespace libtorrent
{
bool is_local(address const& a);
bool is_loopback(address const& addr);
bool is_multicast(address const& addr);
bool is_any(address const& addr);
address guess_local_address(asio::io_service&);
typedef boost::function<void(udp::endpoint const& from
, char* buffer, int size)> receive_handler_t;
class broadcast_socket
{
public:
broadcast_socket(asio::io_service& ios, udp::endpoint const& multicast_endpoint
, receive_handler_t const& handler, bool loopback = true);
~broadcast_socket() { close(); }
void send(char const* buffer, int size, asio::error_code& ec);
void close();
private:
struct socket_entry
{
socket_entry(boost::shared_ptr<datagram_socket> const& s): socket(s) {}
boost::shared_ptr<datagram_socket> socket;
char buffer[1024];
udp::endpoint remote;
};
void on_receive(socket_entry* s, asio::error_code const& ec
, std::size_t bytes_transferred);
std::list<socket_entry> m_sockets;
udp::endpoint m_multicast_endpoint;
receive_handler_t m_on_receive;
};
}
#endif

View File

@@ -65,6 +65,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/alert.hpp"
#include "libtorrent/torrent_handle.hpp"
#include "libtorrent/torrent.hpp"
#include "libtorrent/allocate_resources.hpp"
#include "libtorrent/peer_request.hpp"
#include "libtorrent/piece_block_progress.hpp"
#include "libtorrent/config.hpp"
@@ -121,16 +122,8 @@ namespace libtorrent
msg_request,
msg_piece,
msg_cancel,
// DHT extension
msg_dht_port,
// FAST extension
msg_suggest_piece = 0xd,
msg_have_all,
msg_have_none,
msg_reject_request,
msg_allowed_fast,
// extension protocol message
// extension protocol message
msg_extended = 20,
num_supported_messages
@@ -181,17 +174,8 @@ namespace libtorrent
void on_request(int received);
void on_piece(int received);
void on_cancel(int received);
// DHT extension
void on_dht_port(int received);
// FAST extension
void on_suggest_piece(int received);
void on_have_all(int received);
void on_have_none(int received);
void on_reject_request(int received);
void on_allowed_fast(int received);
void on_extended(int received);
void on_extended_handshake();
@@ -208,7 +192,7 @@ namespace libtorrent
void write_cancel(peer_request const& r);
void write_bitfield(std::vector<bool> const& bitfield);
void write_have(int index);
void write_piece(peer_request const& r, char* buffer);
void write_piece(peer_request const& r, char const* buffer);
void write_handshake();
#ifndef TORRENT_DISABLE_EXTENSIONS
void write_extensions();
@@ -217,16 +201,7 @@ namespace libtorrent
void write_metadata(std::pair<int, int> req);
void write_metadata_request(std::pair<int, int> req);
void write_keepalive();
// DHT extension
void write_dht_port(int listen_port);
// FAST extension
void write_have_all();
void write_have_none();
void write_reject_request(peer_request const&);
void write_allow_fast(int piece);
void on_connected();
void on_metadata();
@@ -270,17 +245,8 @@ namespace libtorrent
// these functions encrypt the send buffer if m_rc4_encrypted
// is true, otherwise it passes the call to the
// peer_connection functions of the same names
void send_buffer(char* buf, int size);
void send_buffer(char* begin, char* end);
buffer::interval allocate_send_buffer(int size);
template <class Destructor>
void append_send_buffer(char* buffer, int size, Destructor const& destructor)
{
#ifndef TORRENT_DISABLE_ENCRYPTION
if (m_rc4_encrypted)
m_RC4_handler->encrypt(buffer, size);
#endif
peer_connection::append_send_buffer(buffer, size, destructor);
}
void setup_send();
// Returns offset at which bytestream (src, src + src_size)
@@ -342,8 +308,8 @@ namespace libtorrent
: start(s)
, length(l)
{
TORRENT_ASSERT(s >= 0);
TORRENT_ASSERT(l > 0);
assert(s >= 0);
assert(l > 0);
}
int start;
int length;
@@ -359,7 +325,6 @@ namespace libtorrent
bool m_supports_extensions;
#endif
bool m_supports_dht_port;
bool m_supports_fast;
#ifndef TORRENT_DISABLE_ENCRYPTION
// this is set to true after the encryption method has been
@@ -375,7 +340,7 @@ namespace libtorrent
int m_sync_bytes_read;
// hold information about latest allocated send buffer
// need to check for non zero (begin, end) for operations with this
// need to check for non zero (begin, end) for operations with this
buffer::interval m_enc_send_buffer;
// initialized during write_pe1_2_dhkey, and destroyed on

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2007, Arvid Norberg
Copyright (c) 2003 - 2005, Arvid Norberg, Daniel Wallin
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -32,167 +32,420 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef LIBTORRENT_BUFFER_HPP
#define LIBTORRENT_BUFFER_HPP
#include <memory>
#include <cstring>
//#define TORRENT_BUFFER_DEBUG
#include "libtorrent/invariant_check.hpp"
#include "libtorrent/assert.hpp"
#include <memory>
namespace libtorrent {
class buffer
{
public:
struct interval
{
interval(char* begin, char* end)
: begin(begin)
, end(end)
{}
struct interval
{
interval(char* begin, char* end)
: begin(begin)
, end(end)
{}
char operator[](int index) const
{
TORRENT_ASSERT(begin + index < end);
return begin[index];
}
char operator[](int index) const
{
assert(begin + index < end);
return begin[index];
}
int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }
int left() const { assert(end >= begin); return end - begin; }
char* begin;
char* end;
};
char* begin;
char* end;
};
struct const_interval
{
const_interval(char const* begin, char const* end)
: begin(begin)
, end(end)
{}
struct const_interval
{
const_interval(char const* begin, char const* end)
: begin(begin)
, end(end)
{}
char operator[](int index) const
{
TORRENT_ASSERT(begin + index < end);
return begin[index];
}
char operator[](int index) const
{
assert(begin + index < end);
return begin[index];
}
bool operator==(const const_interval& p_interval)
{
return (begin == p_interval.begin
&& end == p_interval.end);
}
bool operator==(const const_interval& p_interval)
{
return (begin == p_interval.begin
&& end == p_interval.end);
}
int left() const { TORRENT_ASSERT(end >= begin); return end - begin; }
int left() const { assert(end >= begin); return end - begin; }
char const* begin;
char const* end;
};
char const* begin;
char const* end;
};
buffer(std::size_t n = 0)
: m_begin(0)
, m_end(0)
, m_last(0)
{
if (n) resize(n);
}
typedef std::pair<const_interval, const_interval> interval_type;
buffer(buffer const& b)
: m_begin(0)
, m_end(0)
, m_last(0)
{
if (b.size() == 0) return;
resize(b.size());
std::memcpy(m_begin, b.begin(), b.size());
}
buffer(std::size_t n = 0);
~buffer();
buffer& operator=(buffer const& b)
{
resize(b.size());
std::memcpy(m_begin, b.begin(), b.size());
return *this;
}
interval allocate(std::size_t n);
void insert(char const* first, char const* last);
void erase(std::size_t n);
std::size_t size() const;
std::size_t capacity() const;
void reserve(std::size_t n);
interval_type data() const;
bool empty() const;
~buffer()
{
::operator delete (m_begin);
}
std::size_t space_left() const;
buffer::interval data() { return interval(m_begin, m_end); }
buffer::const_interval data() const { return const_interval(m_begin, m_end); }
void resize(std::size_t n)
{
reserve(n);
m_end = m_begin + n;
}
char const* raw_data() const
{
return m_first;
}
void insert(char* point, char const* first, char const* last)
{
std::size_t p = point - m_begin;
if (point == m_end)
{
resize(size() + last - first);
std::memcpy(m_begin + p, first, last - first);
return;
}
resize(size() + last - first);
std::memmove(m_begin + p + (last - first), m_begin + p, last - first);
std::memcpy(m_begin + p, first, last - first);
}
void erase(char* begin, char* end)
{
TORRENT_ASSERT(end <= m_end);
TORRENT_ASSERT(begin >= m_begin);
TORRENT_ASSERT(begin <= end);
if (end == m_end)
{
resize(begin - m_begin);
return;
}
std::memmove(begin, end, m_end - end);
m_end = begin + (m_end - end);
}
void clear() { m_end = m_begin; }
std::size_t size() const { return m_end - m_begin; }
std::size_t capacity() const { return m_last - m_begin; }
void reserve(std::size_t n)
{
if (n <= capacity()) return;
TORRENT_ASSERT(n > 0);
char* buf = (char*)::operator new(n);
std::size_t s = size();
std::memcpy(buf, m_begin, s);
::operator delete (m_begin);
m_begin = buf;
m_end = buf + s;
m_last = m_begin + n;
}
bool empty() const { return m_begin == m_end; }
char& operator[](std::size_t i) { TORRENT_ASSERT(i < size()); return m_begin[i]; }
char const& operator[](std::size_t i) const { TORRENT_ASSERT(i < size()); return m_begin[i]; }
char* begin() { return m_begin; }
char const* begin() const { return m_begin; }
char* end() { return m_end; }
char const* end() const { return m_end; }
void swap(buffer& b)
{
using std::swap;
swap(m_begin, b.m_begin);
swap(m_end, b.m_end);
swap(m_last, b.m_last);
}
#ifndef NDEBUG
void check_invariant() const;
#endif
private:
char* m_begin; // first
char* m_end; // one passed end of size
char* m_last; // one passed end of allocation
char* m_first;
char* m_last;
char* m_write_cursor;
char* m_read_cursor;
char* m_read_end;
bool m_empty;
#ifdef TORRENT_BUFFER_DEBUG
mutable std::vector<char> m_debug;
mutable int m_pending_copy;
#endif
};
inline buffer::buffer(std::size_t n)
: m_first((char*)::operator new(n))
, m_last(m_first + n)
, m_write_cursor(m_first)
, m_read_cursor(m_first)
, m_read_end(m_last)
, m_empty(true)
{
#ifdef TORRENT_BUFFER_DEBUG
m_pending_copy = 0;
#endif
}
inline buffer::~buffer()
{
::operator delete (m_first);
}
inline buffer::interval buffer::allocate(std::size_t n)
{
assert(m_read_cursor <= m_read_end || m_empty);
INVARIANT_CHECK;
#ifdef TORRENT_BUFFER_DEBUG
if (m_pending_copy)
{
std::copy(m_write_cursor - m_pending_copy, m_write_cursor
, m_debug.end() - m_pending_copy);
m_pending_copy = 0;
}
m_debug.resize(m_debug.size() + n);
m_pending_copy = n;
#endif
if (m_read_cursor < m_write_cursor || m_empty)
{
// ..R***W..
if (m_last - m_write_cursor >= (std::ptrdiff_t)n)
{
interval ret(m_write_cursor, m_write_cursor + n);
m_write_cursor += n;
m_read_end = m_write_cursor;
assert(m_read_cursor <= m_read_end);
if (n) m_empty = false;
return ret;
}
if (m_read_cursor - m_first >= (std::ptrdiff_t)n)
{
m_read_end = m_write_cursor;
interval ret(m_first, m_first + n);
m_write_cursor = m_first + n;
assert(m_read_cursor <= m_read_end);
if (n) m_empty = false;
return ret;
}
reserve(capacity() + n - (m_last - m_write_cursor));
assert(m_last - m_write_cursor >= (std::ptrdiff_t)n);
interval ret(m_write_cursor, m_write_cursor + n);
m_write_cursor += n;
m_read_end = m_write_cursor;
if (n) m_empty = false;
assert(m_read_cursor <= m_read_end);
return ret;
}
//**W...R**
if (m_read_cursor - m_write_cursor >= (std::ptrdiff_t)n)
{
interval ret(m_write_cursor, m_write_cursor + n);
m_write_cursor += n;
if (n) m_empty = false;
return ret;
}
reserve(capacity() + n - (m_read_cursor - m_write_cursor));
assert(m_read_cursor - m_write_cursor >= (std::ptrdiff_t)n);
interval ret(m_write_cursor, m_write_cursor + n);
m_write_cursor += n;
if (n) m_empty = false;
return ret;
}
inline void buffer::insert(char const* first, char const* last)
{
INVARIANT_CHECK;
std::size_t n = last - first;
#ifdef TORRENT_BUFFER_DEBUG
if (m_pending_copy)
{
std::copy(m_write_cursor - m_pending_copy, m_write_cursor
, m_debug.end() - m_pending_copy);
m_pending_copy = 0;
}
m_debug.insert(m_debug.end(), first, last);
#endif
if (space_left() < n)
{
reserve(capacity() + n);
}
m_empty = false;
char const* end = (m_last - m_write_cursor) < (std::ptrdiff_t)n ?
m_last : m_write_cursor + n;
std::size_t copied = end - m_write_cursor;
std::memcpy(m_write_cursor, first, copied);
m_write_cursor += copied;
if (m_write_cursor > m_read_end) m_read_end = m_write_cursor;
first += copied;
n -= copied;
if (n == 0) return;
assert(m_write_cursor == m_last);
m_write_cursor = m_first;
memcpy(m_write_cursor, first, n);
m_write_cursor += n;
}
inline void buffer::erase(std::size_t n)
{
INVARIANT_CHECK;
if (n == 0) return;
assert(!m_empty);
#ifndef NDEBUG
int prev_size = size();
#endif
assert(m_read_cursor <= m_read_end);
m_read_cursor += n;
if (m_read_cursor > m_read_end)
{
m_read_cursor = m_first + (m_read_cursor - m_read_end);
assert(m_read_cursor <= m_write_cursor);
}
m_empty = m_read_cursor == m_write_cursor;
assert(prev_size - n == size());
#ifdef TORRENT_BUFFER_DEBUG
m_debug.erase(m_debug.begin(), m_debug.begin() + n);
#endif
}
inline std::size_t buffer::size() const
{
// ...R***W.
if (m_read_cursor < m_write_cursor)
{
return m_write_cursor - m_read_cursor;
}
// ***W..R*
else
{
if (m_empty) return 0;
return (m_write_cursor - m_first) + (m_read_end - m_read_cursor);
}
}
inline std::size_t buffer::capacity() const
{
return m_last - m_first;
}
inline void buffer::reserve(std::size_t size)
{
std::size_t n = (std::size_t)(capacity() * 1.f);
if (n < size) n = size;
char* buf = (char*)::operator new(n);
char* old = m_first;
if (m_read_cursor < m_write_cursor)
{
// ...R***W.<>.
std::memcpy(
buf + (m_read_cursor - m_first)
, m_read_cursor
, m_write_cursor - m_read_cursor
);
m_write_cursor = buf + (m_write_cursor - m_first);
m_read_cursor = buf + (m_read_cursor - m_first);
m_read_end = m_write_cursor;
m_first = buf;
m_last = buf + n;
}
else
{
// **W..<>.R**
std::size_t skip = n - (m_last - m_first);
std::memcpy(buf, m_first, m_write_cursor - m_first);
std::memcpy(
buf + (m_read_cursor - m_first) + skip
, m_read_cursor
, m_last - m_read_cursor
);
m_write_cursor = buf + (m_write_cursor - m_first);
if (!m_empty)
{
m_read_cursor = buf + (m_read_cursor - m_first) + skip;
m_read_end = buf + (m_read_end - m_first) + skip;
}
else
{
m_read_cursor = m_write_cursor;
m_read_end = m_write_cursor;
}
m_first = buf;
m_last = buf + n;
}
::operator delete (old);
}
#ifndef NDEBUG
inline void buffer::check_invariant() const
{
assert(m_read_end >= m_read_cursor);
assert(m_last >= m_read_cursor);
assert(m_last >= m_write_cursor);
assert(m_last >= m_first);
assert(m_first <= m_read_cursor);
assert(m_first <= m_write_cursor);
#ifdef TORRENT_BUFFER_DEBUG
int a = m_debug.size();
int b = size();
(void)a;
(void)b;
assert(m_debug.size() == size());
#endif
}
#endif
inline buffer::interval_type buffer::data() const
{
INVARIANT_CHECK;
#ifdef TORRENT_BUFFER_DEBUG
if (m_pending_copy)
{
std::copy(m_write_cursor - m_pending_copy, m_write_cursor
, m_debug.end() - m_pending_copy);
m_pending_copy = 0;
}
#endif
// ...R***W.
if (m_read_cursor < m_write_cursor)
{
#ifdef TORRENT_BUFFER_DEBUG
assert(m_debug.size() == size());
assert(std::equal(m_debug.begin(), m_debug.end(), m_read_cursor));
#endif
return interval_type(
const_interval(m_read_cursor, m_write_cursor)
, const_interval(m_last, m_last)
);
}
// **W...R**
else
{
if (m_read_cursor == m_read_end)
{
#ifdef TORRENT_BUFFER_DEBUG
assert(m_debug.size() == size());
assert(std::equal(m_debug.begin(), m_debug.end(), m_first));
#endif
return interval_type(
const_interval(m_first, m_write_cursor)
, const_interval(m_last, m_last));
}
#ifdef TORRENT_BUFFER_DEBUG
assert(m_debug.size() == size());
assert(std::equal(m_debug.begin(), m_debug.begin() + (m_read_end
- m_read_cursor), m_read_cursor));
assert(std::equal(m_debug.begin() + (m_read_end - m_read_cursor), m_debug.end()
, m_first));
#endif
assert(m_read_cursor <= m_read_end || m_empty);
return interval_type(
const_interval(m_read_cursor, m_read_end)
, const_interval(m_first, m_write_cursor)
);
}
}
inline bool buffer::empty() const
{
return m_empty;
}
inline std::size_t buffer::space_left() const
{
if (m_empty) return m_last - m_first;
// ...R***W.
if (m_read_cursor < m_write_cursor)
{
return (m_last - m_write_cursor) + (m_read_cursor - m_first);
}
// ***W..R*
else
{
return m_read_cursor - m_write_cursor;
}
}
}

View File

@@ -1,192 +0,0 @@
/*
Copyright (c) 2007, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_CHAINED_BUFFER_HPP_INCLUDED
#define TORRENT_CHAINED_BUFFER_HPP_INCLUDED
#include <boost/function.hpp>
#include <asio/buffer.hpp>
#include <list>
#include <cstring>
namespace libtorrent
{
struct chained_buffer
{
chained_buffer(): m_bytes(0), m_capacity(0) {}
struct buffer_t
{
boost::function<void(char*)> free; // destructs the buffer
char* buf; // the first byte of the buffer
int size; // the total size of the buffer
char* start; // the first byte to send/receive in the buffer
int used_size; // this is the number of bytes to send/receive
};
bool empty() const { return m_bytes == 0; }
int size() const { return m_bytes; }
int capacity() const { return m_capacity; }
void pop_front(int bytes_to_pop)
{
TORRENT_ASSERT(bytes_to_pop <= m_bytes);
while (bytes_to_pop > 0 && !m_vec.empty())
{
buffer_t& b = m_vec.front();
if (b.used_size > bytes_to_pop)
{
b.start += bytes_to_pop;
b.used_size -= bytes_to_pop;
m_bytes -= bytes_to_pop;
TORRENT_ASSERT(m_bytes <= m_capacity);
TORRENT_ASSERT(m_bytes >= 0);
TORRENT_ASSERT(m_capacity >= 0);
break;
}
b.free(b.buf);
m_bytes -= b.used_size;
m_capacity -= b.size;
bytes_to_pop -= b.used_size;
TORRENT_ASSERT(m_bytes >= 0);
TORRENT_ASSERT(m_capacity >= 0);
TORRENT_ASSERT(m_bytes <= m_capacity);
m_vec.pop_front();
}
}
template <class D>
void append_buffer(char* buffer, int size, int used_size, D const& destructor)
{
TORRENT_ASSERT(size >= used_size);
buffer_t b;
b.buf = buffer;
b.size = size;
b.start = buffer;
b.used_size = used_size;
b.free = destructor;
m_vec.push_back(b);
m_bytes += used_size;
m_capacity += size;
TORRENT_ASSERT(m_bytes <= m_capacity);
}
// returns the number of bytes available at the
// end of the last chained buffer.
int space_in_last_buffer()
{
if (m_vec.empty()) return 0;
buffer_t& b = m_vec.back();
return b.size - b.used_size - (b.start - b.buf);
}
// tries to copy the given buffer to the end of the
// last chained buffer. If there's not enough room
// it returns false
bool append(char const* buf, int size)
{
char* insert = allocate_appendix(size);
if (insert == 0) return false;
std::memcpy(insert, buf, size);
return true;
}
// tries to allocate memory from the end
// of the last buffer. If there isn't
// enough room, returns 0
char* allocate_appendix(int size)
{
if (m_vec.empty()) return 0;
buffer_t& b = m_vec.back();
char* insert = b.start + b.used_size;
if (insert + size > b.buf + b.size) return 0;
b.used_size += size;
m_bytes += size;
TORRENT_ASSERT(m_bytes <= m_capacity);
return insert;
}
std::list<asio::const_buffer> const& build_iovec(int to_send)
{
m_tmp_vec.clear();
for (std::list<buffer_t>::iterator i = m_vec.begin()
, end(m_vec.end()); to_send > 0 && i != end; ++i)
{
if (i->used_size > to_send)
{
TORRENT_ASSERT(to_send > 0);
m_tmp_vec.push_back(asio::const_buffer(i->start, to_send));
break;
}
TORRENT_ASSERT(i->used_size > 0);
m_tmp_vec.push_back(asio::const_buffer(i->start, i->used_size));
to_send -= i->used_size;
}
return m_tmp_vec;
}
~chained_buffer()
{
for (std::list<buffer_t>::iterator i = m_vec.begin()
, end(m_vec.end()); i != end; ++i)
{
i->free(i->buf);
}
}
private:
// this is the list of all the buffers we want to
// send
std::list<buffer_t> m_vec;
// this is the number of bytes in the send buf.
// this will always be equal to the sum of the
// size of all buffers in vec
int m_bytes;
// the total size of all buffers in the chain
// including unused space
int m_capacity;
// this is the vector of buffers used when
// invoking the async write call
std::list<asio::const_buffer> m_tmp_vec;
};
}
#endif

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