Compare commits

..

1 Commits

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

167
ChangeLog
View File

@ -1,167 +0,0 @@
Deluge 0.5.7.1 (01 December 2007)
* Tweak full hd warning so that it only displays itself once per torrent that
it has to pause.
* Fixed crash and corruption of persistent.state while adding a duplicate
torrent. Also caused yet another invalid handle error.
* Increase tracker timeout
Deluge 0.5.7 (26 November 2007)
* Scrape support
* Manual force-recheck
* Add local peer discovery (aka local service discovery)
* Blocklist plugin will now display errors, instead of just crashing on a bad
list or wrong type
* Add torrent in paused state option
* Add advanced progress bar
* Fix bug in merging trackers
* Various updates to WebUI, including https support and advanced template by vonck7
* Add maximum connection attempts per second preference
* Fix bug where loaded plugins were forgotten if Deluge crashed
* Fix ratio bugs (hopefully for the last time)
* Add preference to only show file selection popup if torrent has multiple files
* Fix pause all and resume all bugs
* Fix client not loading if our website goes down (new version check failing)
* Allow torrent creation with no trackers
* Scheduler plugin revamp by Ben Klein
* Fix ETA from going backwards
* UI warning on full HD - no longer just silently pauses torrents
* Replace SimpleRSS with FlexRSS
* Add preference for the location of torrent files
* Add autoload folder
* Copy translator credits from Launchpad to our about->credits
* Differentiate between queued and paused torrents. Able to pause queued
torrents - patch by yobbobandana
* Show error when writing/permission problems occur
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
* Load Blocklist plugin last and have it not lock up the interface during
import
* Add full allocation to preferences for clarification
* Catch SIGINT, SIGHUP, SIGTERM and Gnome logoff to quit properly
* Add send local info to developers
* Fix up pieces, peers and files plugins
* UPnP fixes
* Add ExtraStats plugin
* FreeBSD full allocation fix
* Added per torrent max upload slots and max connections preferences
* A lot of other less visible improvements
Deluge 0.5.4 (06 August 2007)
* Tray message includes session totals
* Ticket #198 - Display peers countries in the Peers tab.
* Ticket #474 - Multiple password prompts displayed
* Pause all/resume all in tray menu
* Peers and Files tabs are now plugins
* New Location plugin
* Option to use a random port every time
* Proxy system redone - you can now specify different information for each
type of proxy (DHT, peer, tracker, web-seed)
* TorrentPieces plugin to view piece updates and show pieces table per file
* EventLogger plugin to view/log every activity
* SpeedLimiter plugin, which allows you to set speed limits on a per-torrent
basis
* New release alerts - Client will inform user if their version of deluge is
outdated
Deluge 0.5.3 (25 July 2007)
* Added ChangeLog
* Ticket #53 - Added files priorities within torrent
* Ticket #111 - Remember directory of last added torrent
* Ticket #232 - Added Move completed downloads to feature
* Ticket #245 - Added ability to select torrent files before starting
* Ticked #368 - Added ability to prioritize first and last pieces of files
in torrents
* Ticket #371 - Proper full storage allocation of files on reiser4 and
ntfs-3g filesystems
* Ticket #420 - Show size of torrent minus size of unselected files as Total
Size
* Ticket #405 - Properly start in tray when run deluge --tray
* Ticket #437 - Gracefully upgrade from old versions
* Picking a file to not download now checks for compact_mode status to prevent
all sorts of problems such as downloading pieces into the wrong file
* RSS plugin inclusion
* Added ability to queue new torrents above completed ones when
seeds are set to queue at the bottom
* Added availability and piece size display in details, availailability
column
* Added ability to automatically remove torrents when max share ratio is set
* Show text from clipboard in Add URL dialog only if it looks like an URL
* Added Torrent Notification plugin
* Added event handling callbacks for plugins
* Added ability to designate a torrent as private (in file selection dialog)
* Added merging trackers of duplicate torrents
* Details, Peers and Files tabs more responsible and their perfomance
greatly improved especially on torrents with many files and peers
* A lot of other less visible improvements
Deluge 0.5.2 (05 July 2007)
* ticket #6 - Torrent creation built into main client
* ticket #315 - Plugins implemented as modules
* ticket #310 - Configuration options for PEX and UPnP
* ticket #390 - Individual file progress shown in File tab
* The usual slew of improvements
Deluge 0.5.1 (11 June 2007)
* Peer Exchange
* ticket #254 - Encryption
* ticket #142 - UPnP + NATPMP
* Improved user interface
* Redesigned preferences dialog
* Proper startup and shutdown

40
HACKING
View File

@ -1,40 +0,0 @@
# Copyright (c) 2006 Marcos Pinto ('markybob') <markybob@gmail.com>
This is pretty much taken straight out of PEP 8, the "Style Guide for Python
Code" (http://www.python.org/dev/peps/pep-0008/)
More or less, if you try to submit a patch that doesn't follow this guide, odds
are your patch will be denied...unless it does some incredibly magnificient
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.
Use UTF-8 encoding
Every single import should be on its own line
Avoid extraneous whitespace in the following situations:
Yes: spam(ham[1], {eggs: 2})
No: spam( ham[ 1 ], { eggs: 2 } )
Yes: spam(1)
No: spam (1)
Yes: if x == 4: print x, y; x, y = y, x
No: if x == 4 : print x , y ; x , y = y , x
Yes: dict['key'] = list[index]
No: dict ['key'] = list [index]
Yes:
x = 1
y = 2
long_variable = 3
No:
x = 1
y = 2
long_variable = 3
Some more recommendations:
* "Don't repeat yourself (DRY). Every distinct concept and/or piece of
data should live in one, and only one, place. Redundancy is bad.
Normalization is good." (taken straight from django's Design philosophies)
* Try to use iterators/generators where applicable. The simplest change from
range to xrange is also good.
* In UI and deluge code for consistency we use notion of speed not rate.
Libtorrent mixes this usage and so do we on deluge-libtorrent boundary,
but all deluge only code should use speed.

12
LICENSE
View File

@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
@ -338,13 +338,3 @@ proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
In addition, as a special exception, the copyright holders give
permission to link the code of portions of this program with the OpenSSL
library.
You must obey the GNU General Public License in all respects for all of
the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete
this exception statement from your version. If you delete this exception
statement from all source files in the program, then also delete it here.

View File

@ -1,12 +1,10 @@
include LICENSE
include README
include README.Packagers
include Makefile
include deluge.desktop
include deluge.png
include deluge.xpm
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/ *

View File

@ -1,31 +0,0 @@
#
# Makefile for Deluge
#
PYVER=`python -c "import sys; print sys.version[:3]"`
PREFIX ?= /usr
DESTDIR ?= ./
all:
python setup.py build
tarball:
python setup.py sdist
mv dist/deluge-*.tar.gz $(DESTDIR)
install:
python setup.py install --prefix=$(PREFIX)
clean:
python setup.py clean
rm -rf ./build
rm msgfmt.pyc
find . -name *.pyc -exec rm {} \;
uninstall:
-rm $(PREFIX)/bin/deluge
-rm -r $(PREFIX)/lib/python${PYVER}/site-packages/deluge
-rm -r $(PREFIX)/lib/python${PYVER}/site-packages/deluge-*.egg-info
-rm -r $(PREFIX)/share/deluge
-find ${PREFIX}/share/locale -name deluge.mo -exec rm {} \;
-rm $(PREFIX)/share/applications/deluge.desktop
-rm $(PREFIX)/share/pixmaps/deluge.png

View File

@ -1,10 +0,0 @@
Metadata-Version: 1.0
Name: deluge
Version: 0.5.2
Summary: A bittorrent client written in PyGTK
Home-page: http://deluge-torrent.org
Author: Zach Tibbitts, Alon Zakai, Marcos Pinto, Alex Dedul, Andrew Resch
Author-email: zach@collegegeek.org, kripkensteiner@gmail.com, marcospinto@dipconsultants.com, rotmer@gmail.com, alonzakai@gmail.com
License: GPLv2
Description: UNKNOWN
Platform: UNKNOWN

101
README
View File

@ -1,102 +1,57 @@
==========================
Deluge BitTorrent Client
==========================
Deluge BitTorrent Client
Authors:
Zach Tibbitts, aka zachtib
Alon Zakai, aka kripkenstein
Marcos Pinto, aka markybob
Andrew Resch, aka andar
Alex Dedul, aka plisk
Homepage: http://deluge-torrent.org
==========================
Contact/Support:
==========================
We have two options available for support:
Our Forum, at http://forum.deluge-torrent.org
or
Our IRC Channel, at #deluge on Freenode
==========================
Installation Instructions:
==========================
First, make sure you have the proper build dependencies installed. On a normal
Debian or Ubuntu system, those dependencies are:
First, make sure you have the proper bulid
dependencies installed. On a normal Debian
or Ubuntu system, those dependencies are:
g++
make
python-all-dev
python-all version >= 2.4
python-dbus
python-gtk2 version >= 2.9
python-notify
python-pyopenssl
librsvg2-common
python-xdg
python-all
python-support
libboost-dev >= 1.33.1
libboost-dev
libboost-thread-dev
libboost-date-time-dev
libboost-filesystem-dev
libboost-serialization-dev
libssl-dev
libboost-program-options-dev
libboost-regex-dev
zlib1g-dev
But the names of the packages may vary depending on your OS / distro.
But the names of the packages may vary
depending on your OS / distro.
Once you have the needed libraries installed, build Deluge by running:
Once you have the needed libraries installed,
build Deluge by running:
$ make
python setup.py build
You shouldn't get any errors. Then run, as root (or by using sudo):
You shouldn't get any errors. Then run, as
root (or by using sudo):
$ make install
python setup.py install
and Deluge will be installed. By default, Deluge will be installed to the
prefix /usr. If you wish, you can install Deluge to a different prefix by
specifying it when you install it:
$ PREFIX=yourprefixhere make install
So, to install to /usr/local, run:
$ PREFIX=/usr/local make install
and Deluge will be installed.
You can then run Deluge by executing:
$ deluge
deluge
Notes:
==========================
Uninstallation/Upgrading:
==========================
If you wish to upgrade from the older Deluge version please remove it first,
then install the latest version as per "Installation Instructions". If you
installed via the tarball, cd into the unpacked source tarball and then run,
as root (or by using sudo):
$ make uninstall
If you installed via the deb package, run as root (or by using sudo:)
$ dpkg --purge remove deluge-torrent
Now install the latest version (and check out the additional notes).
==========================
Additional Notes:
==========================
1) On some distributions, boost libraries are renamed to have "-mt" at the end
(boost_thread_mt instead of boost_thread, for example), the "mt" indicating
"multithreaded". In some cases it appears the distros lack symlinks to connect
things. The solution is to either add symlinks from the short names to those
with "-mt", or to alter setup.py to look for the "-mt" versions.
2) After upgrading your Deluge installation, it may fail to start. If this
happens to you, you need to remove your ~/.config/deluge directory to allow
Deluge to rebuild it's configuration file.
1) On some distributions, boost libraries are
renamed to have "-mt" at the end (boost_thread_mt
instead of boost_thread, for example), the "mt"
indicating "multithreaded". In some cases it
appears the distros lack symlinks to connect
things. The solution is to either add symlinks
from the short names to those with "-mt", or to
alter setup.py to look for the "-mt" versions.

View File

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

3
TODO
View File

@ -1,3 +0,0 @@
for 0.5.7
* remap filenames
* copy over active torrents when user changes location of torrent files

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

@ -2,12 +2,11 @@
Version=1.0
Encoding=UTF-8
Name=Deluge BitTorrent Client
GenericName=BitTorrent Client
Comment=A GTK BitTorrent client written in Python and C++
Comment=Bittorrent client written in Python/PyGTK
Exec=deluge
Icon=deluge.png
Icon=deluge.xpm
Terminal=false
Type=Application
Categories=Network;
Categories=Application;Network
StartupNotify=true
MimeType=application/x-bittorrent;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

415
deluge.xpm Normal file
View File

@ -0,0 +1,415 @@
/* XPM */
static char * deluge_torrent_xpm[] = {
"32 32 380 2",
" c None",
". c #8893A8",
"+ c #8994A8",
"@ c #B0B7C5",
"# c #919BAE",
"$ c #737F98",
"% c #A3ABBB",
"& c #8E98AD",
"* c #AEB5C4",
"= c #858FA5",
"- c #5E6D89",
"; c #929CB0",
"> c #8794A9",
", c #8592AA",
"' c #919FB5",
") c #A5B0C3",
"! c #7688A4",
"~ c #7687A1",
"{ c #8A99B1",
"] c #768AA7",
"^ c #7E92AE",
"/ c #8397B3",
"( c #92A4BD",
"_ c #96A8C0",
": c #5B7295",
"< c #8B9DB7",
"[ c #6A83A4",
"} c #728BAD",
"| c #7791B3",
"1 c #7B95B6",
"2 c #7C96B8",
"3 c #95ABC6",
"4 c #829CBC",
"5 c #45618C",
"6 c #7F96B3",
"7 c #6483A9",
"8 c #6384AC",
"9 c #6B8BB3",
"0 c #7091B8",
"a c #7495BC",
"b c #7596BD",
"c c #7496BD",
"d c #95AECC",
"e c #6F91B9",
"f c #6081A9",
"g c #3C6292",
"h c #365989",
"i c #4B6B97",
"j c #5676A1",
"k c #5F81AB",
"l c #6E93BF",
"m c #7097C2",
"n c #7297C3",
"o c #8FADCE",
"p c #618AB7",
"q c #476D9D",
"r c #5A779F",
"s c #1B4075",
"t c #1F4377",
"u c #365785",
"v c #4A6791",
"w c #4D6B94",
"x c #5D80AA",
"y c #6C93BF",
"z c #779DC6",
"A c #84A6CB",
"B c #5382B6",
"C c #3A659A",
"D c #5C789F",
"E c #224579",
"F c #1E4277",
"G c #274A7C",
"H c #2E4F7F",
"I c #335483",
"J c #44628D",
"K c #557197",
"L c #526E95",
"M c #506F99",
"N c #668FBD",
"O c #7FA3CA",
"P c #7299C4",
"Q c #36639A",
"R c #4F6D97",
"S c #345484",
"T c #305181",
"U c #42618A",
"V c #4E6992",
"W c #4A678F",
"X c #4B6992",
"Y c #4B6994",
"Z c #5F7A9E",
"` c #5E779C",
" . c #597398",
".. c #527099",
"+. c #618ABA",
"@. c #84A6CD",
"#. c #5D89BB",
"$. c #375A89",
"%. c #4C6992",
"&. c #3A5986",
"*. c #536E94",
"=. c #577197",
"-. c #6F92BB",
";. c #759ECA",
">. c #739CCA",
",. c #759DC9",
"'. c #6880A4",
"). c #5C7699",
"!. c #4F6F98",
"~. c #618DBD",
"{. c #81A4CA",
"]. c #4B7CB3",
"^. c #274F84",
"/. c #5A759B",
"(. c #375784",
"_. c #577196",
":. c #5A7498",
"<. c #6F89AB",
"[. c #8BADD1",
"}. c #7EA5D0",
"|. c #7FA6D0",
"1. c #7CA4CF",
"2. c #7CA4CE",
"3. c #789FC7",
"4. c #6984A7",
"5. c #5A7398",
"6. c #5076A5",
"7. c #6791C0",
"8. c #7198C3",
"9. c #2D5081",
"0. c #25477A",
"a. c #4C6890",
"b. c #627A9D",
"c. c #657DA1",
"d. c #A0BBD7",
"e. c #89AED6",
"f. c #8BAFD7",
"g. c #8BB0D7",
"h. c #8AAED6",
"i. c #86ACD4",
"j. c #82A8D2",
"k. c #7CA3CF",
"l. c #749DC8",
"m. c #6984A6",
"n. c #567298",
"o. c #5786BA",
"p. c #779CC6",
"q. c #5583B7",
"r. c #295086",
"s. c #2C4E7F",
"t. c #345483",
"u. c #5B7498",
"v. c #5D7699",
"w. c #93AAC4",
"x. c #9EBDDD",
"y. c #96B8DD",
"z. c #97B9DE",
"A. c #94B7DC",
"B. c #90B3DA",
"C. c #8AAFD6",
"D. c #83A9D2",
"E. c #7AA2CE",
"F. c #6F95BF",
"G. c #667E9F",
"H. c #577FAF",
"I. c #5585B8",
"J. c #759AC5",
"K. c #3F6FA7",
"L. c #254A80",
"M. c #5C769C",
"N. c #3C5B87",
"O. c #60789C",
"P. c #B0C3D8",
"Q. c #A1C0E3",
"R. c #A3C2E4",
"S. c #A3C3E5",
"T. c #A2C2E4",
"U. c #9EBFE2",
"V. c #98BADE",
"W. c #91B4DA",
"X. c #88AED6",
"Y. c #759ECB",
"Z. c #6885AD",
"`. c #5780B0",
" + c #5383B8",
".+ c #7299C3",
"++ c #4675AB",
"@+ c #395A89",
"#+ c #46648F",
"$+ c #3E5D88",
"%+ c #617A9C",
"&+ c #637B9D",
"*+ c #BFD1E4",
"=+ c #ADCBEA",
"-+ c #B0CDEB",
";+ c #AFCCEB",
">+ c #ACCAE9",
",+ c #A7C6E6",
"'+ c #9FC0E2",
")+ c #8DB1D8",
"!+ c #82A9D2",
"~+ c #77A0CC",
"{+ c #6A94C4",
"]+ c #5F8DBF",
"^+ c #5C89BA",
"/+ c #5C85B4",
"(+ c #3F5E8B",
"_+ c #3B5A86",
":+ c #647C9E",
"<+ c #61799D",
"[+ c #C1D2E4",
"}+ c #BBD5F1",
"|+ c #BCD6F2",
"1+ c #BAD5F1",
"2+ c #B5D1EE",
"3+ c #AECBEA",
"4+ c #A5C4E5",
"5+ c #9BBCE0",
"6+ c #84AAD3",
"7+ c #78A0CC",
"8+ c #6B96C6",
"9+ c #5F8CBF",
"0+ c #5282B8",
"a+ c #4F7FB4",
"b+ c #668CB7",
"c+ c #43618D",
"d+ c #325382",
"e+ c #5E779B",
"f+ c #5F789A",
"g+ c #BACADC",
"h+ c #C9E0F9",
"i+ c #C7DFF8",
"j+ c #C3DCF6",
"k+ c #BCD7F2",
"l+ c #B3CFED",
"m+ c #A8C7E7",
"n+ c #9DBEE1",
"o+ c #6A96C5",
"p+ c #5D8BBE",
"q+ c #5081B7",
"r+ c #497BB2",
"s+ c #698DB7",
"t+ c #45638E",
"u+ c #2E5080",
"v+ c #25487B",
"w+ c #506B93",
"x+ c #647B9E",
"y+ c #9DAFC7",
"z+ c #D6E9FD",
"A+ c #D1E8FE",
"B+ c #CAE2FA",
"C+ c #C1DAF5",
"D+ c #A9C8E8",
"E+ c #6894C4",
"F+ c #5A89BC",
"G+ c #4D7EB5",
"H+ c #4577AF",
"I+ c #6B8DB5",
"J+ c #3B6090",
"K+ c #3D5D8A",
"L+ c #3C5B89",
"M+ c #1D4276",
"N+ c #647C9C",
"O+ c #657D9E",
"P+ c #C2D4E6",
"Q+ c #D3E9FF",
"R+ c #CEE5FC",
"S+ c #C2DBF5",
"T+ c #80A7D1",
"U+ c #729CC9",
"V+ c #6491C2",
"W+ c #5686BA",
"X+ c #497BB3",
"Y+ c #5580B3",
"Z+ c #5B7EAA",
"`+ c #335686",
" @ c #4D6993",
".@ c #26497B",
"+@ c #4C6990",
"@@ c #6B82A2",
"#@ c #7D92B0",
"$@ c #C1D4E9",
"%@ c #C0DAF4",
"&@ c #B2CFED",
"*@ c #7BA3CE",
"=@ c #6F99C7",
"-@ c #6390C0",
";@ c #5886B9",
">@ c #4A7BB2",
",@ c #698CB7",
"'@ c #4C6F9C",
")@ c #284C7F",
"!@ c #577299",
"~@ c #2F517F",
"{@ c #536E93",
"]@ c #7086A5",
"^@ c #7B8FAC",
"/@ c #9FB3CD",
"(@ c #B8D2EE",
"_@ c #91B5DB",
":@ c #85ABD4",
"<@ c #7CA3CD",
"[@ c #729AC8",
"}@ c #6791C1",
"|@ c #5A87BA",
"1@ c #5280B4",
"2@ c #7A97BB",
"3@ c #416290",
"4@ c #2F5080",
"5@ c #4F6B91",
"6@ c #687F9F",
"7@ c #7B8FAB",
"8@ c #8396B0",
"9@ c #8AA1BF",
"0@ c #8CACCE",
"a@ c #8FB2D8",
"b@ c #86AAD2",
"c@ c #7DA3CC",
"d@ c #749BC7",
"e@ c #6993C1",
"f@ c #5B88B9",
"g@ c #7999C0",
"h@ c #587AA5",
"i@ c #21416E",
"j@ c #516D96",
"k@ c #415F8A",
"l@ c #567196",
"m@ c #637B9E",
"n@ c #6F84A3",
"o@ c #778BA7",
"p@ c #758BAA",
"q@ c #7490B3",
"r@ c #749BC5",
"s@ c #6992C0",
"t@ c #799DC4",
"u@ c #7291B6",
"v@ c #46658C",
"w@ c #264878",
"x@ c #4F6C94",
"y@ c #42608C",
"z@ c #294B7D",
"A@ c #4A6790",
"B@ c #567095",
"C@ c #597599",
"D@ c #587398",
"E@ c #536F96",
"F@ c #4F6D95",
"G@ c #7690B4",
"H@ c #7090B7",
"I@ c #4A6991",
"J@ c #2B4871",
"K@ c #41608C",
"L@ c #59749A",
"M@ c #234679",
"N@ c #214578",
"O@ c #3A5A87",
"P@ c #47648F",
"Q@ c #667EA2",
"R@ c #7188A9",
"S@ c #4B6892",
"T@ c #395985",
"U@ c #1C314F",
"V@ c #2E4F7D",
"W@ c #395986",
"X@ c #526E96",
"Y@ c #58739A",
"Z@ c #5B759B",
"`@ c #6A82A5",
" # c #627CA0",
".# c #365887",
"+# c #324B69",
"@# c #344B69",
"## c #34537D",
"$# c #294C7C",
"%# c #315383",
"&# c #40618D",
"*# c #40638F",
"=# c #3B5C87",
"-# c #36537A",
";# c #2E4156",
" ",
" . ",
" + @ # ",
" $ % & * = ",
" - ; > , ' ) ! ",
" ~ { ] ^ / ( _ ",
" : < [ } | 1 2 3 4 ",
" 5 6 7 8 9 0 a b c d e ",
" 7 f g h i j k l m n o p ",
" q r s s s t u v w x y z A B ",
" C D E s F G H I J K L M N O P ",
" Q R S s T U V W X Y Z ` ...+.@.#. ",
" $.%.t &.*.=.r -.;.>.,.0 '.).!.~.{.]. ",
" ^./.F (._.:.<.[.}.|.}.1.2.3.4.5.6.7.8. ",
" 9.v 0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q. ",
" r.v s.t.u.v.w.x.y.z.z.A.B.C.D.E.F.G.H.I.J.K. ",
" L.M.s N.b.O.P.Q.R.S.T.U.V.W.X.|.Y.Z.`. +.+++ ",
" @+#+s $+%+&+*+=+-+;+>+,+'+z.)+!+~+{+]+ +^+/+ ",
" (+S s _+:+<+[+}+|+1+2+3+4+5+B.6+7+8+9+0+a+b+ ",
" c+T s d+e+f+g+h+i+j+k+l+m+n+W.6+~+o+p+q+r+s+ ",
" t+u+s v+w+x+y+z+A+B+C+2+D+n+B.D.Y.E+F+G+H+I+J+ ",
" K+L+s M+N.N+O+P+Q+R+S+2+m+5+)+T+U+V+W+X+Y+Z+ ",
" `+ @s s .@+@@@#@$@R+%@&@4+z.e.*@=@-@;@>@,@'@ ",
" )@!@t s s ~@{@]@^@/@(@=+'+_@:@<@[@}@|@1@2@3@ ",
" S #+s s s 4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@ ",
" i@j@u s s s G k@l@m@n@o@p@q@a r@s@t@u@v@ ",
" w@x@y@s s s s z@_+A@B@C@D@E@F@G@H@I@ ",
" J@K@L@y@M@s s N@z@S O@P@Q@R@S@T@ ",
" U@V@W@X@L@Y@Z@L@c.`@ #v .#+# ",
" @###$#%#&#*#=#-#;# ",
" ",
" "};

View File

@ -8,9 +8,8 @@
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<property name="website"></property>
<property name="website">http://deluge-torrent.org</property>
<property name="authors"></property>
<property name="translator-credits"></property>
<property name="documenters"></property>
<property name="artists"></property>
<child internal-child="vbox">

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,82 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.2.2 on Sun Jul 15 01:54:03 2007 by markybob@peg-->
<!--Generated with glade3 3.1.5 on Thu Feb 22 19:15:41 2007 by zach@notapowerbook-->
<glade-interface>
<widget class="GtkMenu" id="torrent_popup">
<property name="visible">True</property>
<child>
<widget class="GtkCheckMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="label" translatable="yes">Size</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="size_toggle"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="label" translatable="yes">Status</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="status_toggle"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem3">
<property name="visible">True</property>
<property name="label" translatable="yes">Seeders</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="seeders_toggle"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem4">
<property name="visible">True</property>
<property name="label" translatable="yes">Peers</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="peers_toggle"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem5">
<property name="visible">True</property>
<property name="label" translatable="yes">Download Speed</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="dl_toggle"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem6">
<property name="visible">True</property>
<property name="label" translatable="yes">Upload Speed</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="ul_toggle"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem7">
<property name="visible">True</property>
<property name="label" translatable="yes">Time Remaining</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="eta_toggle"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem8">
<property name="visible">True</property>
<property name="label" translatable="yes">Share Ratio</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="share_toggle"/>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="remove_torrent_dlg">
<property name="title" translatable="yes">Remove Torrent</property>
<property name="destroy_with_parent">True</property>
@ -15,103 +90,41 @@
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="spacing">10</property>
<child>
<widget class="GtkHBox" id="hbox1">
<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="spacing">3</property>
<child>
<widget class="GtkImage" id="image1">
<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-dialog-warning</property>
<property name="icon_size">6</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;span size="large"&gt;&lt;b&gt;Are you sure you want to remove the selected torrent(s) from Deluge?&lt;/b&gt;&lt;/span&gt;</property>
<property name="use_markup">True</property>
<property name="wrap">True</property>
</widget>
<packing>
<property name="padding">10</property>
<property name="position">1</property>
</packing>
</child>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Are you sure you want to remove the selected torrent(s) from Deluge?&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="padding">10</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment1">
<widget class="GtkCheckButton" id="data_also">
<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="left_padding">20</property>
<child>
<widget class="GtkCheckButton" id="data_also">
<property name="visible">True</property>
<property name="label" translatable="yes">Delete downloaded files</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
</child>
<property name="label" translatable="yes">Delete downloaded files</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<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>
<property name="bottom_padding">5</property>
<property name="left_padding">20</property>
<child>
<widget class="GtkCheckButton" id="torrent_also">
<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">Delete .torrent file</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="warning">
<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="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
</widget>
<packing>
<property name="position">3</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="position">1</property>
</packing>
</child>
@ -122,15 +135,14 @@
<child>
<widget class="GtkButton" id="button2">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-no</property>
<property name="label">gtk-no</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-yes</property>
<property name="label">gtk-yes</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
@ -197,7 +209,7 @@
<child>
<widget class="GtkImageMenuItem" id="menuitem12">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-preferences</property>
<property name="label" translatable="yes">gtk-preferences</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="preferences"/>
@ -227,105 +239,11 @@
<child>
<widget class="GtkImageMenuItem" id="menuitem14">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-quit</property>
<property name="label" translatable="yes">gtk-quit</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="quit"/>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="speed_dialog">
<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">5</property>
<property name="window_position">GTK_WIN_POS_MOUSE</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="skip_taskbar_hint">True</property>
<property name="decorated">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkHBox" id="hbox2">
<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="spacing">10</property>
<child>
<widget class="GtkLabel" id="spin_title">
<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>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_speed">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="is_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">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="activates_default">True</property>
<property name="xalign">1</property>
<property name="adjustment">0 -1 10000 1 10 10</property>
<property name="numeric">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="fill">False</property>
<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</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">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="no">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">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="no">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

731
glade/dgtkpref.glade Normal file
View File

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

View File

@ -1,120 +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 Wed Jun 27 17:27:11 2007 by markybob@peg-->
<glade-interface>
<widget class="GtkWindow" id="edittrackers">
<property name="width_request">300</property>
<property name="height_request">200</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">Edit Trackers</property>
<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="label1">
<property name="height_request">36</property>
<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">Tracker Editing</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<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_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkTextView" id="txt_tracker_list">
<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>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</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="GtkAspectFrame" id="aspectframe1">
<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_xalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="ratio">1</property>
<child>
<placeholder/>
</child>
</widget>
</child>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">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="no">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="cancel_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="ok_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">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="no">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="ok_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkAspectFrame" id="aspectframe2">
<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_xalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="ratio">1</property>
<child>
<placeholder/>
</child>
</widget>
<packing>
<property name="position">3</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -1,126 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkMenu" id="file_tab_menu">
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="open_file">
<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">_Open File</property>
<property name="use_underline">True</property>
<signal name="activate" handler="open_file"/>
<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-open</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="open_file_separator">
<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="select_all">
<property name="visible">True</property>
<property name="label" translatable="yes">Select All</property>
<property name="use_underline">True</property>
<signal name="activate" handler="select_all"/>
<child internal-child="image">
<widget class="GtkImage" id="image22">
<property name="visible">True</property>
<property name="stock">gtk-select-all</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="unselect_all">
<property name="visible">True</property>
<property name="label" translatable="yes">Unselect All</property>
<property name="use_underline">True</property>
<signal name="activate" handler="unselect_all"/>
<child internal-child="image">
<widget class="GtkImage" id="image23">
<property name="visible">True</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="priority_dont_download">
<property name="visible">True</property>
<property name="label" translatable="yes">Don't download</property>
<property name="use_underline">True</property>
<signal name="activate" handler="priority_dont_download"/>
<child internal-child="image">
<widget class="GtkImage" id="image24">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="priority_normal">
<property name="visible">True</property>
<property name="label" translatable="yes">Normal</property>
<property name="use_underline">True</property>
<signal name="activate" handler="priority_normal"/>
<child internal-child="image">
<widget class="GtkImage" id="image25">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="priority_high">
<property name="visible">True</property>
<property name="label" translatable="yes">High</property>
<property name="use_underline">True</property>
<signal name="activate" handler="priority_high"/>
<child internal-child="image">
<widget class="GtkImage" id="image26">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="priority_highest">
<property name="visible">True</property>
<property name="label" translatable="yes">Highest</property>
<property name="use_underline">True</property>
<signal name="activate" handler="priority_highest"/>
<child internal-child="image">
<widget class="GtkImage" id="image27">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkDialog" id="file_dialog">
<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">5</property>
<property name="title" translatable="yes">Deluge File Selection</property>
<property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
<property name="default_width">550</property>
<property name="default_height">550</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="spacing">1</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<widget class="GtkTreeView" id="file_view">
<property name="visible">True</property>
<property name="can_focus">True</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">2</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_setpriv">
<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">Torrent will not be distributed on the trackerless (DHT) network</property>
<property name="label" translatable="yes">Set the private flag</property>
<property name="response_id">0</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 internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button2">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkDialog" id="merge_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Deluge Merge Tracker Lists</property>
<property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
<property name="default_width">200</property>
<property name="default_height">50</property>
<property name="has_separator">False</property>
<property name="destroy_with_parent">True</property>
<property name="skip_taskbar_hint">True</property>
<property name="skip_pager_hint">True</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Torrent already detected in Deluge, would you like to merge the tracker lists?</property>
</widget>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button_cancel">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button_ok">
<property name="visible">True</property>
<property name="label" translatable="no">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

File diff suppressed because it is too large Load Diff

View File

@ -5,255 +5,64 @@
<widget class="GtkMenu" id="torrent_menu">
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="menu_resume">
<widget class="GtkImageMenuItem" id="menuitem5">
<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">_Force Recheck</property>
<property name="label" translatable="yes">Update Tracker</property>
<property name="use_underline">True</property>
<signal name="activate" handler="torrent_recheck"/>
<signal name="activate" handler="update_tracker"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image13">
<widget class="GtkImage" id="menu-item-image5">
<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-redo</property>
<property name="stock">gtk-refresh</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator">
<widget class="GtkImageMenuItem" id="menuitem6">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menu_resume">
<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">Re_sume</property>
<property name="label" translatable="yes">Queue Up</property>
<property name="use_underline">True</property>
<signal name="activate" handler="tor_start"/>
<signal name="activate" handler="queue_up"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image13">
<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-media-play</property>
<property name="stock">gtk-go-up</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menu_pause">
<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">_Pause</property>
<property name="label" translatable="yes">Queue Down</property>
<property name="use_underline">True</property>
<signal name="activate" handler="tor_pause"/>
<signal name="activate" handler="queue_down"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image14">
<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-media-pause</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator">
<widget class="GtkImageMenuItem" id="menuitem8">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem12">
<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">_Remove Torrent</property>
<property name="label" translatable="yes">Queue to Bottom</property>
<property name="use_underline">True</property>
<signal name="activate" handler="remove_torrent"/>
<signal name="activate" handler="queue_bottom"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image9">
<widget class="GtkImage" id="menu-item-image8">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-remove</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
<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="GtkMenuItem" id="menuitem3">
<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">_Tracker Options</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkImageMenuItem" id="menuitem5">
<property name="visible">True</property>
<property name="label" translatable="yes">_Update Tracker</property>
<property name="use_underline">True</property>
<signal name="activate" handler="update_tracker"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image5">
<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-refresh</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem13">
<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">_Edit Trackers</property>
<property name="use_underline">True</property>
<signal name="activate" handler="edit_trackers"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image12">
<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-edit</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem4">
<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">_Scrape Tracker</property>
<property name="use_underline">True</property>
<signal name="activate" handler="scrape_tracker"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image16">
<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-info</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_Queue</property>
<property name="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>
<child>
<widget class="GtkImageMenuItem" id="menu_queue_top">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_Top</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_top"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image10">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-goto-top</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menu_queue_up">
<property name="visible">True</property>
<property name="label" translatable="yes">_Up</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_up"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-go-up</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menu_queue_down">
<property name="visible">True</property>
<property name="label" translatable="yes">_Down</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_down"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image7">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menu_queue_bottom">
<property name="visible">True</property>
<property name="label" translatable="yes">_Bottom</property>
<property name="use_underline">True</property>
<signal name="activate" handler="queue_bottom"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image8">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-goto-bottom</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image11">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-sort-ascending</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_Open Containing Folder</property>
<property name="use_underline">True</property>
<signal name="activate" handler="open_folder_clicked"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image15">
<property name="stock">gtk-open</property>
<property name="stock">gtk-goto-bottom</property>
<property name="icon_size">1</property>
</widget>
</child>

View File

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkMenu" id="tray_menu">
<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="GtkCheckMenuItem" id="show_hide_window">
<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">_Show Deluge</property>
<property name="use_underline">True</property>
<signal name="activate" handler="show_hide_window_toggled"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem2">
<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">_Resume All</property>
<property name="use_underline">True</property>
<signal name="activate" handler="resume_all"/>
<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-media-play</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_Pause All</property>
<property name="use_underline">True</property>
<signal name="activate" handler="pause_all"/>
<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-media-pause</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
<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="add_torrent">
<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">_Add Torrent</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_torrent"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image1">
<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-add</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem3">
<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="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="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="download-limit-image">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="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="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="upload-limit-image">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="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="quit">
<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">_Quit</property>
<property name="use_underline">True</property>
<signal name="activate" handler="quit"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image4">
<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-quit</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget>
</glade-interface>

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.

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

@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <memory>
#include <queue>
#include <string>
#include <cassert>
#include <typeinfo>
#ifdef _MSC_VER
@ -43,24 +44,20 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif
#define TORRENT_MAX_ALERT_TYPES 10
namespace libtorrent {
@ -73,9 +70,9 @@ namespace libtorrent {
virtual ~alert();
// a timestamp is automatically created in the constructor
ptime timestamp() const;
boost::posix_time::ptime timestamp() const;
std::string const& msg() const;
const std::string& msg() const;
severity_t severity() const;
@ -84,7 +81,7 @@ namespace libtorrent {
private:
std::string m_msg;
severity_t m_severity;
ptime m_timestamp;
boost::posix_time::ptime m_timestamp;
};
class TORRENT_EXPORT alert_manager
@ -100,13 +97,10 @@ namespace libtorrent {
void set_severity(alert::severity_t severity);
bool should_post(alert::severity_t severity) const;
alert const* wait_for_alert(time_duration max_wait);
private:
std::queue<alert*> m_alerts;
alert::severity_t m_severity;
mutable boost::mutex m_mutex;
boost::condition m_condition;
};
struct TORRENT_EXPORT unhandled_alert : std::exception
@ -118,45 +112,57 @@ namespace libtorrent {
struct void_;
template<class Handler
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
template<
class Handler
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)
>
void handle_alert_dispatch(
const std::auto_ptr<alert>& alert_, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
const std::auto_ptr<alert>& alert_
, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
{
if (typeid_ == typeid(T0))
handler(*static_cast<T0*>(alert_.get()));
else
handle_alert_dispatch(alert_, handler, typeid_
, BOOST_PP_ENUM_SHIFTED_PARAMS(
TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
handle_alert_dispatch(
alert_
, handler
, typeid_
, BOOST_PP_ENUM_SHIFTED_PARAMS(TORRENT_MAX_ALERT_TYPES, p), (void_*)0
);
}
template<class Handler>
void handle_alert_dispatch(
const std::auto_ptr<alert>& alert_
, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
const std::auto_ptr<alert>& alert_
, const Handler& handler
, const std::type_info& typeid_
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
{
throw unhandled_alert();
}
} // namespace detail
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
template<
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(TORRENT_MAX_ALERT_TYPES, class T, detail::void_)
>
struct TORRENT_EXPORT handle_alert
{
template<class Handler>
handle_alert(const std::auto_ptr<alert>& alert_
, const Handler& handler)
handle_alert(
const std::auto_ptr<alert>& alert_
, const Handler& handler)
{
#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0
detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));
detail::handle_alert_dispatch(
alert_
, handler
, typeid(*alert_)
, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _)
);
#undef ALERT_POINTER_TYPE
}

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

@ -38,28 +38,17 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket.hpp"
#include "libtorrent/peer_connection.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
namespace libtorrent
{
struct TORRENT_EXPORT torrent_alert: alert
{
torrent_alert(torrent_handle const& h, alert::severity_t s
, std::string const& msg)
: alert(s, msg)
, handle(h)
{}
torrent_handle handle;
};
struct TORRENT_EXPORT tracker_alert: torrent_alert
struct TORRENT_EXPORT tracker_alert: alert
{
tracker_alert(torrent_handle const& h
, int times
, int status
, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
, times_in_row(times)
, status_code(status)
{}
@ -67,102 +56,85 @@ namespace libtorrent
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_alert(*this)); }
torrent_handle handle;
int times_in_row;
int status_code;
};
struct TORRENT_EXPORT tracker_warning_alert: torrent_alert
struct TORRENT_EXPORT tracker_warning_alert: alert
{
tracker_warning_alert(torrent_handle const& h
, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_warning_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT scrape_reply_alert: torrent_alert
{
scrape_reply_alert(torrent_handle const& h
, int incomplete_
, int complete_
, std::string const& msg)
: torrent_alert(h, alert::info, msg)
, incomplete(incomplete_)
, complete(complete_)
{}
int incomplete;
int complete;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new scrape_reply_alert(*this)); }
};
struct TORRENT_EXPORT scrape_failed_alert: torrent_alert
{
scrape_failed_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 scrape_failed_alert(*this)); }
};
struct TORRENT_EXPORT tracker_reply_alert: torrent_alert
struct TORRENT_EXPORT tracker_reply_alert: alert
{
tracker_reply_alert(torrent_handle const& h
, int np
, std::string const& msg)
: torrent_alert(h, alert::info, msg)
, num_peers(np)
: alert(alert::info, msg)
, handle(h)
{}
int num_peers;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_reply_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT tracker_announce_alert: torrent_alert
struct TORRENT_EXPORT tracker_announce_alert: alert
{
tracker_announce_alert(torrent_handle const& h, std::string const& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_announce_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT hash_failed_alert: torrent_alert
struct TORRENT_EXPORT hash_failed_alert: alert
{
hash_failed_alert(
torrent_handle const& h
, int index
, std::string const& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
, piece_index(index)
{ TORRENT_ASSERT(index >= 0);}
{ assert(index >= 0);}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new hash_failed_alert(*this)); }
torrent_handle handle;
int piece_index;
};
struct TORRENT_EXPORT peer_ban_alert: torrent_alert
struct TORRENT_EXPORT peer_ban_alert: alert
{
peer_ban_alert(tcp::endpoint const& pip, torrent_handle h, std::string const& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, ip(pip)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new peer_ban_alert(*this)); }
tcp::endpoint ip;
torrent_handle handle;
};
struct TORRENT_EXPORT peer_error_alert: alert
@ -180,7 +152,25 @@ namespace libtorrent
peer_id pid;
};
struct TORRENT_EXPORT invalid_request_alert: torrent_alert
struct TORRENT_EXPORT chat_message_alert: alert
{
chat_message_alert(
const torrent_handle& h
, const tcp::endpoint& sender
, const std::string& msg)
: alert(alert::critical, msg)
, handle(h)
, ip(sender)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new chat_message_alert(*this)); }
torrent_handle handle;
tcp::endpoint ip;
};
struct TORRENT_EXPORT invalid_request_alert: alert
{
invalid_request_alert(
peer_request const& r
@ -188,7 +178,8 @@ namespace libtorrent
, tcp::endpoint const& sender
, peer_id const& pid_
, std::string const& msg)
: torrent_alert(h, alert::debug, msg)
: alert(alert::debug, msg)
, handle(h)
, ip(sender)
, request(r)
, pid(pid_)
@ -197,128 +188,33 @@ namespace libtorrent
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new invalid_request_alert(*this)); }
torrent_handle handle;
tcp::endpoint ip;
peer_request request;
peer_id pid;
};
struct TORRENT_EXPORT torrent_finished_alert: torrent_alert
struct TORRENT_EXPORT torrent_finished_alert: alert
{
torrent_finished_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new torrent_finished_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT piece_finished_alert: torrent_alert
{
piece_finished_alert(
const torrent_handle& h
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::debug, msg)
, piece_index(piece_num)
{ TORRENT_ASSERT(piece_index >= 0);}
int piece_index;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new piece_finished_alert(*this)); }
};
struct TORRENT_EXPORT block_finished_alert: torrent_alert
{
block_finished_alert(
const torrent_handle& h
, int block_num
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::debug, msg)
, block_index(block_num)
, piece_index(piece_num)
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);}
int block_index;
int piece_index;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new block_finished_alert(*this)); }
};
struct TORRENT_EXPORT block_downloading_alert: torrent_alert
{
block_downloading_alert(
const torrent_handle& h
, char const* speedmsg
, int block_num
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::debug, msg)
, peer_speedmsg(speedmsg)
, block_index(block_num)
, piece_index(piece_num)
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);}
std::string peer_speedmsg;
int block_index;
int piece_index;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new block_downloading_alert(*this)); }
};
struct TORRENT_EXPORT storage_moved_alert: torrent_alert
{
storage_moved_alert(torrent_handle const& h, std::string const& path)
: torrent_alert(h, alert::warning, path)
{}
virtual std::auto_ptr<alert> clone() const
{ 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)
: torrent_alert(h, alert::warning, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ 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
struct TORRENT_EXPORT url_seed_alert: alert
{
url_seed_alert(
torrent_handle const& h
, const std::string& url_
const std::string& url_
, const std::string& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, url(url_)
{}
@ -328,115 +224,74 @@ namespace libtorrent
std::string url;
};
struct TORRENT_EXPORT file_error_alert: torrent_alert
struct TORRENT_EXPORT file_error_alert: alert
{
file_error_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::fatal, msg)
: alert(alert::fatal, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new file_error_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT metadata_failed_alert: torrent_alert
struct TORRENT_EXPORT metadata_failed_alert: alert
{
metadata_failed_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new metadata_failed_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT metadata_received_alert: torrent_alert
struct TORRENT_EXPORT metadata_received_alert: alert
{
metadata_received_alert(
const torrent_handle& h
, const std::string& msg)
: torrent_alert(h, alert::info, msg)
: alert(alert::info, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new metadata_received_alert(*this)); }
torrent_handle handle;
};
struct TORRENT_EXPORT listen_failed_alert: alert
{
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)
: alert(alert::warning, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new portmap_error_alert(*this)); }
};
struct TORRENT_EXPORT portmap_alert: alert
{
portmap_alert(const std::string& msg)
: alert(alert::info, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new portmap_alert(*this)); }
};
struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert
struct TORRENT_EXPORT fastresume_rejected_alert: alert
{
fastresume_rejected_alert(torrent_handle const& h
, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
: alert(alert::warning, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new fastresume_rejected_alert(*this)); }
};
struct TORRENT_EXPORT peer_blocked_alert: alert
{
peer_blocked_alert(address const& ip_
, std::string const& msg)
: alert(alert::info, msg)
, ip(ip_)
{}
address ip;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new peer_blocked_alert(*this)); }
torrent_handle handle;
};
}

View File

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

View File

@ -0,0 +1,71 @@
//
// asio.hpp
// ~~~~~~~~
//
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef 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_resolver.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_handler.hpp"
#include "asio/error.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_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/tcp.hpp"
#include "asio/ip/udp.hpp"
#include "asio/is_read_buffered.hpp"
#include "asio/is_write_buffered.hpp"
#include "asio/placeholders.hpp"
#include "asio/read.hpp"
#include "asio/read_until.hpp"
#include "asio/resolver_service.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_base.hpp"
#include "asio/strand.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/streambuf.hpp"
#include "asio/system_exception.hpp"
#include "asio/thread.hpp"
#include "asio/time_traits.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

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

View File

@ -2,7 +2,7 @@
// basic_deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -25,7 +25,6 @@
#include "asio/basic_io_object.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/error.hpp"
#include "asio/detail/throw_error.hpp"
namespace asio {
@ -36,11 +35,16 @@ namespace asio {
*
* Most applications will use the asio::deadline_timer typedef.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Examples
* @par Concepts:
* Async_Object, Error_Source.
*
* @sa @ref deadline_timer_reset
*
* @par Examples:
* Performing a blocking wait:
* @code
* // Construct a timer without setting an expiry time.
@ -56,7 +60,7 @@ namespace asio {
* @par
* Performing an asynchronous wait:
* @code
* void handler(const asio::error_code& error)
* void handler(const asio::error& error)
* {
* if (!error)
* {
@ -73,8 +77,190 @@ namespace asio {
* // Start an asynchronous wait.
* timer.async_wait(handler);
* @endcode
*
* @par Changing an active deadline_timer's expiry time
*/
template <typename Time_Type,
typename Time_Traits = asio::time_traits<Time_Type>,
typename Service = deadline_timer_service<Time_Type, Time_Traits> >
class basic_deadline_timer
: public basic_io_object<Service>
{
public:
/// The type used for reporting errors.
typedef asio::error error_type;
/// The time traits type.
typedef Time_Traits traits_type;
/// The time type.
typedef typename traits_type::time_type time_type;
/// The duration type.
typedef typename traits_type::duration_type duration_type;
/// Constructor.
/**
* This constructor creates a timer without setting an expiry time. The
* expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on.
*
* @param io_service The io_service object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*/
explicit basic_deadline_timer(asio::io_service& io_service)
: basic_io_object<Service>(io_service)
{
}
/// Constructor to set a particular expiry time as an absolute time.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_service The io_service object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
basic_deadline_timer(asio::io_service& io_service,
const time_type& expiry_time)
: basic_io_object<Service>(io_service)
{
this->service.expires_at(this->implementation, expiry_time);
}
/// Constructor to set a particular expiry time relative to now.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_service The io_service object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
basic_deadline_timer(asio::io_service& io_service,
const duration_type& expiry_time)
: basic_io_object<Service>(io_service)
{
this->service.expires_from_now(this->implementation, expiry_time);
}
/// Cancel any asynchronous operations that are waiting on the timer.
/**
* This function forces the completion of any pending asynchronous wait
* operations against the timer. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* Cancelling the timer does not change the expiry time.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t cancel()
{
return this->service.cancel(this->implementation);
}
/// Get the timer's expiry time as an absolute time.
/**
* This function may be used to obtain the timer's current expiry time.
* Whether the timer has expired or not does not affect this value.
*/
time_type expires_at() const
{
return this->service.expires_at(this->implementation);
}
/// Set the timer's expiry time as an absolute time.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* See @ref deadline_timer_reset for more information on altering the expiry
* time of an active timer.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t expires_at(const time_type& expiry_time)
{
return this->service.expires_at(this->implementation, expiry_time);
}
/// Get the timer's expiry time relative to now.
/**
* This function may be used to obtain the timer's current expiry time.
* Whether the timer has expired or not does not affect this value.
*/
duration_type expires_from_now() const
{
return this->service.expires_from_now(this->implementation);
}
/// Set the timer's expiry time relative to now.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* See @ref deadline_timer_reset for more information on altering the expiry
* time of an active timer.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t expires_from_now(const duration_type& expiry_time)
{
return this->service.expires_from_now(this->implementation, expiry_time);
}
/// Perform a blocking wait on the timer.
/**
* This function is used to wait for the timer to expire. This function
* blocks and does not return until the timer has expired.
*
* @throws asio::error Thrown on failure.
*/
void wait()
{
this->service.wait(this->implementation);
}
/// Start an asynchronous wait on the timer.
/**
* This function may be used to initiate an asynchronous wait against the
* timer. It always returns immediately.
*
* For each call to async_wait(), the supplied handler will be called exactly
* once. The handler will be called when:
*
* @li The timer has expired.
*
* @li The timer was cancelled, in which case the handler is passed the error
* code asio::error::operation_aborted.
*
* @param handler The handler to be called when the timer expires. Copies
* will be made of the handler as required. The function signature of the
* handler must be:
* @code void handler(
* const asio::error& error // Result of operation
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*/
template <typename Handler>
void async_wait(Handler handler)
{
this->service.async_wait(this->implementation, handler);
}
};
/**
* @page deadline_timer_reset Changing an active deadline_timer's expiry time
*
* Changing the expiry time of a timer while there are pending asynchronous
* waits causes those wait operations to be cancelled. To ensure that the action
@ -95,7 +281,7 @@ namespace asio {
* }
* }
*
* void on_timeout(const asio::error_code& e)
* void on_timeout(const asio::error& e)
* {
* if (e != asio::error::operation_aborted)
* {
@ -110,269 +296,11 @@ namespace asio {
* late and the wait handler has already been executed, or will soon be
* executed. If it returns 1 then the wait handler was successfully cancelled.
*
* @li If a wait handler is cancelled, the asio::error_code passed to
* it contains the value asio::error::operation_aborted.
* @li If a wait handler is cancelled, the asio::error passed to it
* contains the value asio::error::operation_aborted.
*
* @sa asio::basic_deadline_timer
*/
template <typename Time,
typename TimeTraits = asio::time_traits<Time>,
typename TimerService = deadline_timer_service<Time, TimeTraits> >
class basic_deadline_timer
: public basic_io_object<TimerService>
{
public:
/// The time traits type.
typedef TimeTraits traits_type;
/// The time type.
typedef typename traits_type::time_type time_type;
/// The duration type.
typedef typename traits_type::duration_type duration_type;
/// Constructor.
/**
* This constructor creates a timer without setting an expiry time. The
* expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on.
*
* @param io_service The io_service object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*/
explicit basic_deadline_timer(asio::io_service& io_service)
: basic_io_object<TimerService>(io_service)
{
}
/// Constructor to set a particular expiry time as an absolute time.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_service The io_service object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
basic_deadline_timer(asio::io_service& io_service,
const time_type& expiry_time)
: basic_io_object<TimerService>(io_service)
{
asio::error_code ec;
this->service.expires_at(this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
}
/// Constructor to set a particular expiry time relative to now.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_service The io_service object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
basic_deadline_timer(asio::io_service& io_service,
const duration_type& expiry_time)
: basic_io_object<TimerService>(io_service)
{
asio::error_code ec;
this->service.expires_from_now(this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
}
/// Cancel any asynchronous operations that are waiting on the timer.
/**
* This function forces the completion of any pending asynchronous wait
* operations against the timer. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* Cancelling the timer does not change the expiry time.
*
* @return The number of asynchronous operations that were cancelled.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t cancel()
{
asio::error_code ec;
std::size_t s = this->service.cancel(this->implementation, ec);
asio::detail::throw_error(ec);
return s;
}
/// Cancel any asynchronous operations that are waiting on the timer.
/**
* This function forces the completion of any pending asynchronous wait
* operations against the timer. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* Cancelling the timer does not change the expiry time.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t cancel(asio::error_code& ec)
{
return this->service.cancel(this->implementation, ec);
}
/// Get the timer's expiry time as an absolute time.
/**
* This function may be used to obtain the timer's current expiry time.
* Whether the timer has expired or not does not affect this value.
*/
time_type expires_at() const
{
return this->service.expires_at(this->implementation);
}
/// Set the timer's expiry time as an absolute time.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @return The number of asynchronous operations that were cancelled.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t expires_at(const time_type& expiry_time)
{
asio::error_code ec;
std::size_t s = this->service.expires_at(
this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
return s;
}
/// Set the timer's expiry time as an absolute time.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t expires_at(const time_type& expiry_time,
asio::error_code& ec)
{
return this->service.expires_at(this->implementation, expiry_time, ec);
}
/// Get the timer's expiry time relative to now.
/**
* This function may be used to obtain the timer's current expiry time.
* Whether the timer has expired or not does not affect this value.
*/
duration_type expires_from_now() const
{
return this->service.expires_from_now(this->implementation);
}
/// Set the timer's expiry time relative to now.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @return The number of asynchronous operations that were cancelled.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t expires_from_now(const duration_type& expiry_time)
{
asio::error_code ec;
std::size_t s = this->service.expires_from_now(
this->implementation, expiry_time, ec);
asio::detail::throw_error(ec);
return s;
}
/// Set the timer's expiry time relative to now.
/**
* This function sets the expiry time. Any pending asynchronous wait
* operations will be cancelled. The handler for each cancelled operation will
* be invoked with the asio::error::operation_aborted error code.
*
* @param expiry_time The expiry time to be used for the timer.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of asynchronous operations that were cancelled.
*/
std::size_t expires_from_now(const duration_type& expiry_time,
asio::error_code& ec)
{
return this->service.expires_from_now(
this->implementation, expiry_time, ec);
}
/// Perform a blocking wait on the timer.
/**
* This function is used to wait for the timer to expire. This function
* blocks and does not return until the timer has expired.
*
* @throws asio::system_error Thrown on failure.
*/
void wait()
{
asio::error_code ec;
this->service.wait(this->implementation, ec);
asio::detail::throw_error(ec);
}
/// Perform a blocking wait on the timer.
/**
* This function is used to wait for the timer to expire. This function
* blocks and does not return until the timer has expired.
*
* @param ec Set to indicate what error occurred, if any.
*/
void wait(asio::error_code& ec)
{
this->service.wait(this->implementation, ec);
}
/// Start an asynchronous wait on the timer.
/**
* This function may be used to initiate an asynchronous wait against the
* timer. It always returns immediately.
*
* For each call to async_wait(), the supplied handler will be called exactly
* once. The handler will be called when:
*
* @li The timer has expired.
*
* @li The timer was cancelled, in which case the handler is passed the error
* code asio::error::operation_aborted.
*
* @param handler The handler to be called when the timer expires. 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.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*/
template <typename WaitHandler>
void async_wait(WaitHandler handler)
{
this->service.async_wait(this->implementation, handler);
}
};
} // namespace asio

View File

@ -2,7 +2,7 @@
// basic_io_object.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -23,31 +23,17 @@
namespace asio {
/// Base class for all I/O objects.
template <typename IoObjectService>
template <typename Service>
class basic_io_object
: private noncopyable
{
public:
/// The type of the service that will be used to provide I/O operations.
typedef IoObjectService service_type;
typedef Service service_type;
/// The underlying implementation type of I/O object.
typedef typename service_type::implementation_type implementation_type;
/// (Deprecated: use 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& 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
@ -56,15 +42,15 @@ public:
* @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()
asio::io_service& io_service()
{
return service.get_io_service();
return service.io_service();
}
protected:
/// Construct a basic_io_object.
explicit basic_io_object(asio::io_service& io_service)
: service(asio::use_service<IoObjectService>(io_service))
: service(asio::use_service<Service>(io_service))
{
service.construct(implementation);
}

View File

@ -2,7 +2,7 @@
// basic_socket.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -19,8 +19,8 @@
#include "asio/basic_io_object.hpp"
#include "asio/error.hpp"
#include "asio/error_handler.hpp"
#include "asio/socket_base.hpp"
#include "asio/detail/throw_error.hpp"
namespace asio {
@ -29,18 +29,21 @@ namespace asio {
* The basic_socket class template provides functionality that is common to both
* stream-oriented and datagram-oriented sockets.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* Error_Source, IO_Object.
*/
template <typename Protocol, typename SocketService>
template <typename Protocol, typename Service>
class basic_socket
: public basic_io_object<SocketService>,
: public basic_io_object<Service>,
public socket_base
{
public:
/// The native representation of a socket.
typedef typename SocketService::native_type native_type;
typedef typename Service::native_type native_type;
/// The protocol type.
typedef Protocol protocol_type;
@ -48,8 +51,11 @@ public:
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
/// The type used for reporting errors.
typedef asio::error error_type;
/// A basic_socket is always the lowest layer.
typedef basic_socket<Protocol, SocketService> lowest_layer_type;
typedef basic_socket<Protocol, Service> lowest_layer_type;
/// Construct a basic_socket without opening it.
/**
@ -59,7 +65,7 @@ public:
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_socket(asio::io_service& io_service)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
}
@ -72,15 +78,13 @@ public:
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket(asio::io_service& io_service,
const protocol_type& protocol)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.open(this->implementation, protocol, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, protocol, throw_error());
}
/// Construct a basic_socket, opening it and binding it to the given local
@ -96,17 +100,15 @@ public:
* @param endpoint An endpoint on the local machine to which the socket will
* be bound.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket(asio::io_service& io_service,
const endpoint_type& endpoint)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.open(this->implementation, endpoint.protocol(), ec);
asio::detail::throw_error(ec);
this->service.bind(this->implementation, endpoint, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, endpoint.protocol(),
throw_error());
this->service.bind(this->implementation, endpoint, throw_error());
}
/// Construct a basic_socket on an existing native socket.
@ -120,15 +122,14 @@ public:
*
* @param native_socket A native socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
basic_socket(asio::io_service& io_service,
const protocol_type& protocol, const native_type& native_socket)
: basic_io_object<SocketService>(io_service)
: basic_io_object<Service>(io_service)
{
asio::error_code ec;
this->service.assign(this->implementation, protocol, native_socket, ec);
asio::detail::throw_error(ec);
this->service.assign(this->implementation, protocol, native_socket,
throw_error());
}
/// Get a reference to the lowest layer.
@ -151,9 +152,9 @@ public:
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* socket.open(asio::ip::tcp::v4());
@ -161,9 +162,7 @@ public:
*/
void open(const protocol_type& protocol = protocol_type())
{
asio::error_code ec;
this->service.open(this->implementation, protocol, ec);
asio::detail::throw_error(ec);
this->service.open(this->implementation, protocol, throw_error());
}
/// Open the socket using the specified protocol.
@ -172,23 +171,28 @@ public:
*
* @param protocol An object specifying which protocol is to be used.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* asio::error_code ec;
* socket.open(asio::ip::tcp::v4(), ec);
* if (ec)
* asio::error error;
* socket.open(asio::ip::tcp::v4(), asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code open(const protocol_type& protocol,
asio::error_code& ec)
template <typename Error_Handler>
void open(const protocol_type& protocol, Error_Handler error_handler)
{
return this->service.open(this->implementation, protocol, ec);
this->service.open(this->implementation, protocol, error_handler);
}
/// Assign an existing native socket to the socket.
@ -199,13 +203,12 @@ public:
*
* @param native_socket A native socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void assign(const protocol_type& protocol, const native_type& native_socket)
{
asio::error_code ec;
this->service.assign(this->implementation, protocol, native_socket, ec);
asio::detail::throw_error(ec);
this->service.assign(this->implementation, protocol, native_socket,
throw_error());
}
/// Assign an existing native socket to the socket.
@ -216,19 +219,19 @@ public:
*
* @param native_socket A native socket.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*/
asio::error_code assign(const protocol_type& protocol,
const native_type& native_socket, asio::error_code& ec)
template <typename Error_Handler>
void assign(const protocol_type& protocol, const native_type& native_socket,
Error_Handler error_handler)
{
return this->service.assign(this->implementation,
protocol, native_socket, ec);
}
/// Determine whether the socket is open.
bool is_open() const
{
return this->service.is_open(this->implementation);
this->service.assign(this->implementation, protocol, native_socket,
error_handler);
}
/// Close the socket.
@ -237,16 +240,11 @@ public:
* or connect operations will be cancelled immediately, and will complete
* with the asio::error::operation_aborted error.
*
* @throws asio::system_error Thrown on failure.
*
* @note For portable behaviour with respect to graceful closure of a
* connected socket, call shutdown() before closing the socket.
* @throws asio::error Thrown on failure.
*/
void close()
{
asio::error_code ec;
this->service.close(this->implementation, ec);
asio::detail::throw_error(ec);
this->service.close(this->implementation, throw_error());
}
/// Close the socket.
@ -255,26 +253,29 @@ public:
* or connect operations will be cancelled immediately, and will complete
* with the asio::error::operation_aborted error.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* socket.close(ec);
* if (ec)
* asio::error error;
* socket.close(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*
* @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)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return this->service.close(this->implementation, ec);
this->service.close(this->implementation, error_handler);
}
/// Get the native socket representation.
@ -294,13 +295,11 @@ public:
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*/
void cancel()
{
asio::error_code ec;
this->service.cancel(this->implementation, ec);
asio::detail::throw_error(ec);
this->service.cancel(this->implementation, throw_error());
}
/// Cancel all asynchronous operations associated with the socket.
@ -309,77 +308,17 @@ public:
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*/
asio::error_code cancel(asio::error_code& ec)
template <typename Error_Handler>
void cancel(Error_Handler error_handler)
{
return this->service.cancel(this->implementation, ec);
}
/// Determine whether the socket is at the out-of-band data mark.
/**
* This function is used to check whether the socket input is currently
* positioned at the out-of-band data mark.
*
* @return A bool indicating whether the socket is at the out-of-band data
* mark.
*
* @throws asio::system_error Thrown on failure.
*/
bool at_mark() const
{
asio::error_code ec;
bool b = this->service.at_mark(this->implementation, ec);
asio::detail::throw_error(ec);
return b;
}
/// Determine whether the socket is at the out-of-band data mark.
/**
* This function is used to check whether the socket input is currently
* positioned at the out-of-band data mark.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return A bool indicating whether the socket is at the out-of-band data
* mark.
*/
bool at_mark(asio::error_code& ec) const
{
return this->service.at_mark(this->implementation, ec);
}
/// Determine the number of bytes available for reading.
/**
* This function is used to determine the number of bytes that may be read
* without blocking.
*
* @return The number of bytes that may be read without blocking, or 0 if an
* error occurs.
*
* @throws asio::system_error Thrown on failure.
*/
std::size_t available() const
{
asio::error_code ec;
std::size_t s = this->service.available(this->implementation, ec);
asio::detail::throw_error(ec);
return s;
}
/// Determine the number of bytes available for reading.
/**
* This function is used to determine the number of bytes that may be read
* without blocking.
*
* @param ec Set to indicate what error occurred, if any.
*
* @return The number of bytes that may be read without blocking, or 0 if an
* error occurs.
*/
std::size_t available(asio::error_code& ec) const
{
return this->service.available(this->implementation, ec);
this->service.cancel(this->implementation, error_handler);
}
/// Bind the socket to the given local endpoint.
@ -390,9 +329,9 @@ public:
* @param endpoint An endpoint on the local machine to which the socket will
* be bound.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* socket.open(asio::ip::tcp::v4());
@ -402,9 +341,7 @@ public:
*/
void bind(const endpoint_type& endpoint)
{
asio::error_code ec;
this->service.bind(this->implementation, endpoint, ec);
asio::detail::throw_error(ec);
this->service.bind(this->implementation, endpoint, throw_error());
}
/// Bind the socket to the given local endpoint.
@ -415,25 +352,31 @@ public:
* @param endpoint An endpoint on the local machine to which the socket will
* be bound.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* socket.open(asio::ip::tcp::v4());
* asio::error_code ec;
* asio::error error;
* socket.bind(asio::ip::tcp::endpoint(
* asio::ip::tcp::v4(), 12345), ec);
* if (ec)
* asio::ip::tcp::v4(), 12345),
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code bind(const endpoint_type& endpoint,
asio::error_code& ec)
template <typename Error_Handler>
void bind(const endpoint_type& endpoint, Error_Handler error_handler)
{
return this->service.bind(this->implementation, endpoint, ec);
this->service.bind(this->implementation, endpoint, error_handler);
}
/// Connect the socket to the specified endpoint.
@ -449,9 +392,9 @@ public:
* @param peer_endpoint The remote endpoint to which the socket will be
* connected.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* asio::ip::tcp::endpoint endpoint(
@ -461,14 +404,7 @@ public:
*/
void connect(const endpoint_type& peer_endpoint)
{
asio::error_code ec;
if (!is_open())
{
this->service.open(this->implementation, peer_endpoint.protocol(), ec);
asio::detail::throw_error(ec);
}
this->service.connect(this->implementation, peer_endpoint, ec);
asio::detail::throw_error(ec);
this->service.connect(this->implementation, peer_endpoint, throw_error());
}
/// Connect the socket to the specified endpoint.
@ -484,34 +420,30 @@ public:
* @param peer_endpoint The remote endpoint to which the socket will be
* connected.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* asio::ip::tcp::endpoint endpoint(
* asio::ip::address::from_string("1.2.3.4"), 12345);
* asio::error_code ec;
* socket.connect(endpoint, ec);
* if (ec)
* asio::error error;
* socket.connect(endpoint, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code connect(const endpoint_type& peer_endpoint,
asio::error_code& ec)
template <typename Error_Handler>
void connect(const endpoint_type& peer_endpoint, Error_Handler error_handler)
{
if (!is_open())
{
if (this->service.open(this->implementation,
peer_endpoint.protocol(), ec))
{
return ec;
}
}
return this->service.connect(this->implementation, peer_endpoint, ec);
this->service.connect(this->implementation, peer_endpoint, error_handler);
}
/// Start an asynchronous connect.
@ -530,16 +462,16 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::error_code& error // Result of operation
* const asio::error& error // Result of operation
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_service::post().
*
* @par Example
* @par Example:
* @code
* void connect_handler(const asio::error_code& error)
* void connect_handler(const asio::error& error)
* {
* if (!error)
* {
@ -555,21 +487,9 @@ public:
* socket.async_connect(endpoint, connect_handler);
* @endcode
*/
template <typename ConnectHandler>
void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler)
template <typename Handler>
void async_connect(const endpoint_type& peer_endpoint, Handler handler)
{
if (!is_open())
{
asio::error_code ec;
if (this->service.open(this->implementation,
peer_endpoint.protocol(), ec))
{
this->get_io_service().post(
asio::detail::bind_handler(handler, ec));
return;
}
}
this->service.async_connect(this->implementation, peer_endpoint, handler);
}
@ -579,9 +499,9 @@ public:
*
* @param option The new option value to be set on the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa SettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -598,7 +518,7 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -607,12 +527,10 @@ public:
* socket.set_option(option);
* @endcode
*/
template <typename SettableSocketOption>
void set_option(const SettableSocketOption& option)
template <typename Socket_Option>
void set_option(const Socket_Option& option)
{
asio::error_code ec;
this->service.set_option(this->implementation, option, ec);
asio::detail::throw_error(ec);
this->service.set_option(this->implementation, option, throw_error());
}
/// Set an option on the socket.
@ -621,9 +539,14 @@ public:
*
* @param option The new option value to be set on the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @sa SettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -640,25 +563,24 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::ip::tcp::no_delay option(true);
* asio::error_code ec;
* socket.set_option(option, ec);
* if (ec)
* asio::error error;
* socket.set_option(option, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
template <typename SettableSocketOption>
asio::error_code set_option(const SettableSocketOption& option,
asio::error_code& ec)
template <typename Socket_Option, typename Error_Handler>
void set_option(const Socket_Option& option, Error_Handler error_handler)
{
return this->service.set_option(this->implementation, option, ec);
this->service.set_option(this->implementation, option, error_handler);
}
/// Get an option from the socket.
@ -667,9 +589,9 @@ public:
*
* @param option The option value to be obtained from the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa GettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -686,7 +608,7 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -696,12 +618,10 @@ public:
* bool is_set = option.get();
* @endcode
*/
template <typename GettableSocketOption>
void get_option(GettableSocketOption& option) const
template <typename Socket_Option>
void get_option(Socket_Option& option) const
{
asio::error_code ec;
this->service.get_option(this->implementation, option, ec);
asio::detail::throw_error(ec);
this->service.get_option(this->implementation, option, throw_error());
}
/// Get an option from the socket.
@ -710,9 +630,14 @@ public:
*
* @param option The option value to be obtained from the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @sa GettableSocketOption @n
* @sa Socket_Option @n
* asio::socket_base::broadcast @n
* asio::socket_base::do_not_route @n
* asio::socket_base::keep_alive @n
@ -729,26 +654,25 @@ public:
* asio::ip::multicast::hops @n
* asio::ip::tcp::no_delay
*
* @par Example
* @par Example:
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::ip::tcp::socket::keep_alive option;
* asio::error_code ec;
* socket.get_option(option, ec);
* if (ec)
* asio::error error;
* socket.get_option(option, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* bool is_set = option.get();
* @endcode
*/
template <typename GettableSocketOption>
asio::error_code get_option(GettableSocketOption& option,
asio::error_code& ec) const
template <typename Socket_Option, typename Error_Handler>
void get_option(Socket_Option& option, Error_Handler error_handler) const
{
return this->service.get_option(this->implementation, option, ec);
this->service.get_option(this->implementation, option, error_handler);
}
/// Perform an IO control command on the socket.
@ -757,13 +681,13 @@ public:
*
* @param command The IO control command to be performed on the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @sa IoControlCommand @n
* @sa IO_Control_Command @n
* asio::socket_base::bytes_readable @n
* asio::socket_base::non_blocking_io
*
* @par Example
* @par Example:
* Getting the number of bytes ready to read:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -773,12 +697,10 @@ public:
* std::size_t bytes_readable = command.get();
* @endcode
*/
template <typename IoControlCommand>
void io_control(IoControlCommand& command)
template <typename IO_Control_Command>
void io_control(IO_Control_Command& command)
{
asio::error_code ec;
this->service.io_control(this->implementation, command, ec);
asio::detail::throw_error(ec);
this->service.io_control(this->implementation, command, throw_error());
}
/// Perform an IO control command on the socket.
@ -787,32 +709,36 @@ public:
*
* @param command The IO control command to be performed on the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @sa IoControlCommand @n
* @sa IO_Control_Command @n
* asio::socket_base::bytes_readable @n
* asio::socket_base::non_blocking_io
*
* @par Example
* @par Example:
* Getting the number of bytes ready to read:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::ip::tcp::socket::bytes_readable command;
* asio::error_code ec;
* socket.io_control(command, ec);
* if (ec)
* asio::error error;
* socket.io_control(command, asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* std::size_t bytes_readable = command.get();
* @endcode
*/
template <typename IoControlCommand>
asio::error_code io_control(IoControlCommand& command,
asio::error_code& ec)
template <typename IO_Control_Command, typename Error_Handler>
void io_control(IO_Control_Command& command, Error_Handler error_handler)
{
return this->service.io_control(this->implementation, command, ec);
this->service.io_control(this->implementation, command, error_handler);
}
/// Get the local endpoint of the socket.
@ -821,9 +747,9 @@ public:
*
* @returns An object that represents the local endpoint of the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
@ -832,36 +758,41 @@ public:
*/
endpoint_type local_endpoint() const
{
asio::error_code ec;
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
asio::detail::throw_error(ec);
return ep;
return this->service.local_endpoint(this->implementation, throw_error());
}
/// Get the local endpoint of the socket.
/**
* This function is used to obtain the locally bound endpoint of the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @returns An object that represents the local endpoint of the socket.
* Returns a default-constructed endpoint object if an error occurred.
* Returns a default-constructed endpoint object if an error occurred and the
* error handler did not throw an exception.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
* if (ec)
* asio::error error;
* asio::ip::tcp::endpoint endpoint
* = socket.local_endpoint(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
endpoint_type local_endpoint(asio::error_code& ec) const
template <typename Error_Handler>
endpoint_type local_endpoint(Error_Handler error_handler) const
{
return this->service.local_endpoint(this->implementation, ec);
return this->service.local_endpoint(this->implementation, error_handler);
}
/// Get the remote endpoint of the socket.
@ -870,9 +801,9 @@ public:
*
* @returns An object that represents the remote endpoint of the socket.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
@ -881,36 +812,41 @@ public:
*/
endpoint_type remote_endpoint() const
{
asio::error_code ec;
endpoint_type ep = this->service.remote_endpoint(this->implementation, ec);
asio::detail::throw_error(ec);
return ep;
return this->service.remote_endpoint(this->implementation, throw_error());
}
/// Get the remote endpoint of the socket.
/**
* This function is used to obtain the remote endpoint of the socket.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @returns An object that represents the remote endpoint of the socket.
* Returns a default-constructed endpoint object if an error occurred.
* Returns a default-constructed endpoint object if an error occurred and the
* error handler did not throw an exception.
*
* @par Example
* @par Example:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
* if (ec)
* asio::error error;
* asio::ip::tcp::endpoint endpoint
* = socket.remote_endpoint(asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
endpoint_type remote_endpoint(asio::error_code& ec) const
template <typename Error_Handler>
endpoint_type remote_endpoint(Error_Handler error_handler) const
{
return this->service.remote_endpoint(this->implementation, ec);
return this->service.remote_endpoint(this->implementation, error_handler);
}
/// Disable sends or receives on the socket.
@ -920,9 +856,9 @@ public:
*
* @param what Determines what types of operation will no longer be allowed.
*
* @throws asio::system_error Thrown on failure.
* @throws asio::error Thrown on failure.
*
* @par Example
* @par Example:
* Shutting down the send side of the socket:
* @code
* asio::ip::tcp::socket socket(io_service);
@ -932,9 +868,7 @@ public:
*/
void shutdown(shutdown_type what)
{
asio::error_code ec;
this->service.shutdown(this->implementation, what, ec);
asio::detail::throw_error(ec);
this->service.shutdown(this->implementation, what, throw_error());
}
/// Disable sends or receives on the socket.
@ -944,25 +878,31 @@ public:
*
* @param what Determines what types of operation will no longer be allowed.
*
* @param ec Set to indicate what error occurred, if any.
* @param error_handler A handler to be called when the operation completes,
* to indicate whether or not an error has occurred. Copies will be made of
* the handler as required. The function signature of the handler must be:
* @code void error_handler(
* const asio::error& error // Result of operation
* ); @endcode
*
* @par Example
* @par Example:
* Shutting down the send side of the socket:
* @code
* asio::ip::tcp::socket socket(io_service);
* ...
* asio::error_code ec;
* socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
* if (ec)
* asio::error error;
* socket.shutdown(asio::ip::tcp::socket::shutdown_send,
* asio::assign_error(error));
* if (error)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code shutdown(shutdown_type what,
asio::error_code& ec)
template <typename Error_Handler>
void shutdown(shutdown_type what, Error_Handler error_handler)
{
return this->service.shutdown(this->implementation, what, ec);
this->service.shutdown(this->implementation, what, error_handler);
}
protected:

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// basic_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -45,8 +45,8 @@ public:
/// The type used to represent the put area as a list of buffers.
typedef implementation_defined mutable_buffers_type;
#else
typedef asio::const_buffers_1 const_buffers_type;
typedef asio::mutable_buffers_1 mutable_buffers_type;
typedef asio::const_buffer_container_1 const_buffers_type;
typedef asio::mutable_buffer_container_1 mutable_buffers_type;
#endif
/// Construct a buffer with a specified maximum size.

View File

@ -2,7 +2,7 @@
// buffer.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -26,28 +26,6 @@
#include <vector>
#include "asio/detail/pop_options.hpp"
#if defined(BOOST_MSVC)
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
# define ASIO_ENABLE_BUFFER_DEBUGGING
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
# endif // defined(_HAS_ITERATOR_DEBUGGING)
#endif // defined(BOOST_MSVC)
#if defined(__GNUC__)
# if defined(_GLIBCXX_DEBUG)
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
# define ASIO_ENABLE_BUFFER_DEBUGGING
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
# endif // defined(_GLIBCXX_DEBUG)
#endif // defined(__GNUC__)
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
# include "asio/detail/push_options.hpp"
# include <boost/function.hpp>
# include "asio/detail/pop_options.hpp"
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
namespace asio {
class mutable_buffer;
@ -83,21 +61,6 @@ public:
{
}
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
mutable_buffer(void* data, std::size_t size,
boost::function<void()> debug_check)
: data_(data),
size_(size),
debug_check_(debug_check)
{
}
const boost::function<void()>& get_debug_check() const
{
return debug_check_;
}
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
private:
friend void* asio::detail::buffer_cast_helper(
const mutable_buffer& b);
@ -106,20 +69,12 @@ private:
void* data_;
std::size_t size_;
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
boost::function<void()> debug_check_;
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
};
namespace detail {
inline void* buffer_cast_helper(const mutable_buffer& b)
{
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
if (b.size_ && b.debug_check_)
b.debug_check_();
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
return b.data_;
}
@ -134,10 +89,10 @@ inline std::size_t buffer_size_helper(const mutable_buffer& b)
/**
* @relates mutable_buffer
*/
template <typename PointerToPodType>
inline PointerToPodType buffer_cast(const mutable_buffer& b)
template <typename Pointer_To_Pod_Type>
inline Pointer_To_Pod_Type buffer_cast(const mutable_buffer& b)
{
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
return static_cast<Pointer_To_Pod_Type>(detail::buffer_cast_helper(b));
}
/// Get the number of bytes in a non-modifiable buffer.
@ -159,11 +114,7 @@ inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
return mutable_buffer();
char* new_data = buffer_cast<char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return mutable_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return mutable_buffer(new_data, new_size);
}
/// Create a new modifiable buffer that is offset from the start of another.
@ -176,16 +127,12 @@ inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
return mutable_buffer();
char* new_data = buffer_cast<char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return mutable_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return mutable_buffer(new_data, new_size);
}
/// Adapts a single modifiable buffer so that it meets the requirements of the
/// MutableBufferSequence concept.
class mutable_buffers_1
/// Mutable_Buffers concept.
class mutable_buffer_container_1
: public mutable_buffer
{
public:
@ -196,7 +143,7 @@ public:
typedef const mutable_buffer* const_iterator;
/// Construct to represent a single modifiable buffer.
explicit mutable_buffers_1(const mutable_buffer& b)
explicit mutable_buffer_container_1(const mutable_buffer& b)
: mutable_buffer(b)
{
}
@ -241,27 +188,9 @@ public:
const_buffer(const mutable_buffer& b)
: data_(asio::detail::buffer_cast_helper(b)),
size_(asio::detail::buffer_size_helper(b))
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, debug_check_(b.get_debug_check())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
{
}
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
const_buffer(const void* data, std::size_t size,
boost::function<void()> debug_check)
: data_(data),
size_(size),
debug_check_(debug_check)
{
}
const boost::function<void()>& get_debug_check() const
{
return debug_check_;
}
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
private:
friend const void* asio::detail::buffer_cast_helper(
const const_buffer& b);
@ -270,20 +199,12 @@ private:
const void* data_;
std::size_t size_;
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
boost::function<void()> debug_check_;
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
};
namespace detail {
inline const void* buffer_cast_helper(const const_buffer& b)
{
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
if (b.size_ && b.debug_check_)
b.debug_check_();
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
return b.data_;
}
@ -298,10 +219,10 @@ inline std::size_t buffer_size_helper(const const_buffer& b)
/**
* @relates const_buffer
*/
template <typename PointerToPodType>
inline PointerToPodType buffer_cast(const const_buffer& b)
template <typename Pointer_To_Pod_Type>
inline Pointer_To_Pod_Type buffer_cast(const const_buffer& b)
{
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
return static_cast<Pointer_To_Pod_Type>(detail::buffer_cast_helper(b));
}
/// Get the number of bytes in a non-modifiable buffer.
@ -323,11 +244,7 @@ inline const_buffer operator+(const const_buffer& b, std::size_t start)
return const_buffer();
const char* new_data = buffer_cast<const char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return const_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return const_buffer(new_data, new_size);
}
/// Create a new non-modifiable buffer that is offset from the start of another.
@ -340,16 +257,12 @@ inline const_buffer operator+(std::size_t start, const const_buffer& b)
return const_buffer();
const char* new_data = buffer_cast<const char*>(b) + start;
std::size_t new_size = buffer_size(b) - start;
return const_buffer(new_data, new_size
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
);
return const_buffer(new_data, new_size);
}
/// Adapts a single non-modifiable buffer so that it meets the requirements of
/// the ConstBufferSequence concept.
class const_buffers_1
/// the Const_Buffers concept.
class const_buffer_container_1
: public const_buffer
{
public:
@ -360,7 +273,7 @@ public:
typedef const const_buffer* const_iterator;
/// Construct to represent a single non-modifiable buffer.
explicit const_buffers_1(const const_buffer& b)
explicit const_buffer_container_1(const const_buffer& b)
: const_buffer(b)
{
}
@ -378,35 +291,6 @@ public:
}
};
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
namespace detail {
template <typename Iterator>
class buffer_debug_check
{
public:
buffer_debug_check(Iterator iter)
: iter_(iter)
{
}
~buffer_debug_check()
{
iter_ = Iterator();
}
void operator()()
{
*iter_;
}
private:
Iterator iter_;
};
} // namespace detail
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
/** @defgroup buffer asio::buffer
*
* @brief The asio::buffer function is used to create a buffer object to
@ -418,9 +302,9 @@ private:
* @code sock.write(asio::buffer(data, size)); @endcode
*
* In the above example, the return value of asio::buffer meets the
* requirements of the ConstBufferSequence concept so that it may be directly
* passed to the socket's write function. A buffer created for modifiable
* memory also meets the requirements of the MutableBufferSequence concept.
* requirements of the Const_Buffers concept so that it may be directly passed
* to the socket's write function. A buffer created for modifiable memory also
* meets the requirements of the Mutable_Buffers concept.
*
* An individual buffer may be created from a builtin array, std::vector or
* boost::array of POD elements. This helps prevent buffer overruns by
@ -437,7 +321,7 @@ private:
*
* To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
* buffer objects may be assigned into a container that supports the
* MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
* Mutable_Buffers (for read) or Const_Buffers (for write) concepts:
*
* @code
* char d1[128];
@ -459,108 +343,99 @@ private:
/*@{*/
/// Create a new modifiable buffer from an existing buffer.
inline mutable_buffers_1 buffer(const mutable_buffer& b)
inline mutable_buffer_container_1 buffer(const mutable_buffer& b)
{
return mutable_buffers_1(b);
return mutable_buffer_container_1(b);
}
/// Create a new modifiable buffer from an existing buffer.
inline mutable_buffers_1 buffer(const mutable_buffer& b,
inline mutable_buffer_container_1 buffer(const mutable_buffer& b,
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(buffer_cast<void*>(b),
buffer_size(b) < max_size_in_bytes
? buffer_size(b) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
? buffer_size(b) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer from an existing buffer.
inline const_buffers_1 buffer(const const_buffer& b)
inline const_buffer_container_1 buffer(const const_buffer& b)
{
return const_buffers_1(b);
return const_buffer_container_1(b);
}
/// Create a new non-modifiable buffer from an existing buffer.
inline const_buffers_1 buffer(const const_buffer& b,
inline const_buffer_container_1 buffer(const const_buffer& b,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(buffer_cast<const void*>(b),
buffer_size(b) < max_size_in_bytes
? buffer_size(b) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, b.get_debug_check()
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
? buffer_size(b) : max_size_in_bytes));
}
/// Create a new modifiable buffer that represents the given memory range.
inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
inline mutable_buffer_container_1 buffer(void* data, std::size_t size_in_bytes)
{
return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
return mutable_buffer_container_1(mutable_buffer(data, size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given memory range.
inline const_buffers_1 buffer(const void* data,
inline const_buffer_container_1 buffer(const void* data,
std::size_t size_in_bytes)
{
return const_buffers_1(const_buffer(data, size_in_bytes));
return const_buffer_container_1(const_buffer(data, size_in_bytes));
}
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(PodType (&data)[N])
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(Pod_Type (&data)[N])
{
return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
return mutable_buffer_container_1(mutable_buffer(data, N * sizeof(Pod_Type)));
}
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(PodType (&data)[N],
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(Pod_Type (&data)[N],
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(data,
N * sizeof(PodType) < max_size_in_bytes
? N * sizeof(PodType) : max_size_in_bytes));
N * sizeof(Pod_Type) < max_size_in_bytes
? N * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const PodType (&data)[N])
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const Pod_Type (&data)[N])
{
return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
return const_buffer_container_1(const_buffer(data, N * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const PodType (&data)[N],
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const Pod_Type (&data)[N],
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data,
N * sizeof(PodType) < max_size_in_bytes
? N * sizeof(PodType) : max_size_in_bytes));
N * sizeof(Pod_Type) < max_size_in_bytes
? N * sizeof(Pod_Type) : max_size_in_bytes));
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Borland C++ and Sun Studio think the overloads:
// Borland C++ thinks the overloads:
//
// unspecified buffer(boost::array<PodType, N>& array ...);
// unspecified buffer(boost::array<Pod_Type, N>& array ...);
//
// and
//
// unspecified buffer(boost::array<const PodType, N>& array ...);
// unspecified buffer(boost::array<const Pod_Type, N>& array ...);
//
// are ambiguous. This will be worked around by using a buffer_types traits
// class that contains typedefs for the appropriate buffer and container
// classes, based on whether PodType is const or non-const.
// classes, based on whether Pod_Type is const or non-const.
namespace detail {
@ -571,111 +446,109 @@ template <>
struct buffer_types_base<false>
{
typedef mutable_buffer buffer_type;
typedef mutable_buffers_1 container_type;
typedef mutable_buffer_container_1 container_type;
};
template <>
struct buffer_types_base<true>
{
typedef const_buffer buffer_type;
typedef const_buffers_1 container_type;
typedef const_buffer_container_1 container_type;
};
template <typename PodType>
template <typename Pod_Type>
struct buffer_types
: public buffer_types_base<boost::is_const<PodType>::value>
: public buffer_types_base<boost::is_const<Pod_Type>::value>
{
};
} // namespace detail
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
buffer(boost::array<PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline typename detail::buffer_types<Pod_Type>::container_type
buffer(boost::array<Pod_Type, N>& data)
{
typedef typename asio::detail::buffer_types<PodType>::buffer_type
typedef typename asio::detail::buffer_types<Pod_Type>::buffer_type
buffer_type;
typedef typename asio::detail::buffer_types<PodType>::container_type
typedef typename asio::detail::buffer_types<Pod_Type>::container_type
container_type;
return container_type(
buffer_type(data.c_array(), data.size() * sizeof(PodType)));
buffer_type(data.c_array(), data.size() * sizeof(Pod_Type)));
}
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
template <typename Pod_Type, std::size_t N>
inline typename detail::buffer_types<Pod_Type>::container_type
buffer(boost::array<Pod_Type, N>& data, std::size_t max_size_in_bytes)
{
typedef typename asio::detail::buffer_types<PodType>::buffer_type
typedef typename asio::detail::buffer_types<Pod_Type>::buffer_type
buffer_type;
typedef typename asio::detail::buffer_types<PodType>::container_type
typedef typename asio::detail::buffer_types<Pod_Type>::container_type
container_type;
return container_type(
buffer_type(data.c_array(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(boost::array<Pod_Type, N>& data)
{
return mutable_buffers_1(
mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
return mutable_buffer_container_1(
mutable_buffer(data.c_array(), data.size() * sizeof(Pod_Type)));
}
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
template <typename Pod_Type, std::size_t N>
inline mutable_buffer_container_1 buffer(boost::array<Pod_Type, N>& data,
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(data.c_array(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(boost::array<const Pod_Type, N>& data)
{
return const_buffers_1(
const_buffer(data.data(), data.size() * sizeof(PodType)));
return const_buffer_container_1(
const_buffer(data.data(), data.size() * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(boost::array<const Pod_Type, N>& data,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data.data(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const boost::array<Pod_Type, N>& data)
{
return const_buffers_1(
const_buffer(data.data(), data.size() * sizeof(PodType)));
return const_buffer_container_1(
const_buffer(data.data(), data.size() * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
template <typename Pod_Type, std::size_t N>
inline const_buffer_container_1 buffer(const boost::array<Pod_Type, N>& data,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data.data(),
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new modifiable buffer that represents the given POD vector.
@ -683,17 +556,11 @@ inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
template <typename Pod_Type, typename Allocator>
inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data)
{
return mutable_buffers_1(
mutable_buffer(&data[0], data.size() * sizeof(PodType)
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
return mutable_buffer_container_1(
mutable_buffer(&data[0], data.size() * sizeof(Pod_Type)));
}
/// Create a new modifiable buffer that represents the given POD vector.
@ -701,20 +568,14 @@ inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
template <typename Pod_Type, typename Allocator>
inline mutable_buffer_container_1 buffer(std::vector<Pod_Type, Allocator>& data,
std::size_t max_size_in_bytes)
{
return mutable_buffers_1(
return mutable_buffer_container_1(
mutable_buffer(&data[0],
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given POD vector.
@ -722,18 +583,12 @@ inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline const_buffers_1 buffer(
const std::vector<PodType, Allocator>& data)
template <typename Pod_Type, typename Allocator>
inline const_buffer_container_1 buffer(
const std::vector<Pod_Type, Allocator>& data)
{
return const_buffers_1(
const_buffer(&data[0], data.size() * sizeof(PodType)
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::const_iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
return const_buffer_container_1(
const_buffer(&data[0], data.size() * sizeof(Pod_Type)));
}
/// Create a new non-modifiable buffer that represents the given POD vector.
@ -741,20 +596,14 @@ inline const_buffers_1 buffer(
* @note The buffer is invalidated by any vector operation that would also
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline const_buffers_1 buffer(
const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
template <typename Pod_Type, typename Allocator>
inline const_buffer_container_1 buffer(
const std::vector<Pod_Type, Allocator>& data, std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(&data[0],
data.size() * sizeof(PodType) < max_size_in_bytes
? data.size() * sizeof(PodType) : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<
typename std::vector<PodType, Allocator>::const_iterator
>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
data.size() * sizeof(Pod_Type) < max_size_in_bytes
? data.size() * sizeof(Pod_Type) : max_size_in_bytes));
}
/// Create a new non-modifiable buffer that represents the given string.
@ -762,13 +611,9 @@ inline const_buffers_1 buffer(
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
inline const_buffers_1 buffer(const std::string& data)
inline const_buffer_container_1 buffer(const std::string& data)
{
return const_buffers_1(const_buffer(data.data(), data.size()
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
return const_buffer_container_1(const_buffer(data.data(), data.size()));
}
/// Create a new non-modifiable buffer that represents the given string.
@ -776,17 +621,13 @@ inline const_buffers_1 buffer(const std::string& data)
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
inline const_buffers_1 buffer(const std::string& data,
inline const_buffer_container_1 buffer(const std::string& data,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
return const_buffer_container_1(
const_buffer(data.data(),
data.size() < max_size_in_bytes
? data.size() : max_size_in_bytes
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
));
? data.size() : max_size_in_bytes));
}
/*@}*/

View File

@ -2,7 +2,7 @@
// buffered_read_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -40,12 +40,13 @@ namespace asio {
* The buffered_read_stream class template can be used to add buffering to the
* synchronous and asynchronous read operations of a stream.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, Sync_Read_Stream, SyncWriteStream.
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
* Sync_Read_Stream, Sync_Write_Stream.
*/
template <typename Stream>
class buffered_read_stream
@ -58,6 +59,9 @@ public:
/// The type of the lowest layer.
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
/// The type used for reporting errors.
typedef typename next_layer_type::error_type error_type;
#if defined(GENERATING_DOCUMENTATION)
/// The default buffer size.
static const std::size_t default_buffer_size = implementation_defined;
@ -93,17 +97,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.
@ -113,33 +110,33 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return next_layer_.close(ec);
next_layer_.close(error_handler);
}
/// Write the given data to the stream. Returns the number of bytes written.
/// Throws an exception on failure.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t write_some(const Const_Buffers& buffers)
{
return next_layer_.write_some(buffers);
}
/// Write the given data to the stream. Returns the number of bytes written,
/// or 0 if an error occurred.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Const_Buffers, typename Error_Handler>
std::size_t write_some(const Const_Buffers& buffers,
Error_Handler error_handler)
{
return next_layer_.write_some(buffers, ec);
return next_layer_.write_some(buffers, error_handler);
}
/// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_write_some(const Const_Buffers& buffers, Handler handler)
{
next_layer_.async_write_some(buffers, handler);
}
@ -160,8 +157,10 @@ public:
}
/// Fill the buffer with some data. Returns the number of bytes placed in the
/// buffer as a result of the operation, or 0 if an error occurred.
std::size_t fill(asio::error_code& ec)
/// buffer as a result of the operation, or 0 if an error occurred and the
/// error handler did not throw.
template <typename Error_Handler>
std::size_t fill(Error_Handler error_handler)
{
detail::buffer_resize_guard<detail::buffered_stream_storage>
resize_guard(storage_);
@ -170,18 +169,18 @@ public:
storage_.resize(previous_size + next_layer_.read_some(buffer(
storage_.data() + previous_size,
storage_.size() - previous_size),
ec));
error_handler));
resize_guard.commit();
return storage_.size() - previous_size;
}
template <typename ReadHandler>
template <typename Handler>
class fill_handler
{
public:
fill_handler(asio::io_service& io_service,
detail::buffered_stream_storage& storage,
std::size_t previous_size, ReadHandler handler)
std::size_t previous_size, Handler handler)
: io_service_(io_service),
storage_(storage),
previous_size_(previous_size),
@ -189,24 +188,24 @@ public:
{
}
void operator()(const asio::error_code& ec,
std::size_t bytes_transferred)
template <typename Error>
void operator()(const Error& e, std::size_t bytes_transferred)
{
storage_.resize(previous_size_ + bytes_transferred);
io_service_.dispatch(detail::bind_handler(
handler_, ec, bytes_transferred));
handler_, e, bytes_transferred));
}
private:
asio::io_service& io_service_;
detail::buffered_stream_storage& storage_;
std::size_t previous_size_;
ReadHandler handler_;
Handler handler_;
};
/// Start an asynchronous fill.
template <typename ReadHandler>
void async_fill(ReadHandler handler)
template <typename Handler>
void async_fill(Handler handler)
{
std::size_t previous_size = storage_.size();
storage_.resize(storage_.capacity());
@ -214,14 +213,13 @@ public:
buffer(
storage_.data() + previous_size,
storage_.size() - previous_size),
fill_handler<ReadHandler>(get_io_service(),
storage_, previous_size, handler));
fill_handler<Handler>(io_service(), storage_, previous_size, handler));
}
/// Read some data from the stream. Returns the number of bytes read. Throws
/// an exception on failure.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t read_some(const Mutable_Buffers& buffers)
{
if (storage_.empty())
fill();
@ -229,24 +227,23 @@ public:
}
/// Read some data from the stream. Returns the number of bytes read or 0 if
/// an error occurred.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// an error occurred and the error handler did not throw an exception.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t read_some(const Mutable_Buffers& buffers,
Error_Handler error_handler)
{
ec = asio::error_code();
if (storage_.empty() && !fill(ec))
if (storage_.empty() && !fill(error_handler))
return 0;
return copy(buffers);
}
template <typename MutableBufferSequence, typename ReadHandler>
template <typename Mutable_Buffers, typename Handler>
class read_some_handler
{
public:
read_some_handler(asio::io_service& io_service,
detail::buffered_stream_storage& storage,
const MutableBufferSequence& buffers, ReadHandler handler)
const Mutable_Buffers& buffers, Handler handler)
: io_service_(io_service),
storage_(storage),
buffers_(buffers),
@ -254,12 +251,12 @@ public:
{
}
void operator()(const asio::error_code& ec, std::size_t)
void operator()(const error_type& e, std::size_t)
{
if (ec || storage_.empty())
if (e || storage_.empty())
{
std::size_t length = 0;
io_service_.dispatch(detail::bind_handler(handler_, ec, length));
io_service_.dispatch(detail::bind_handler(handler_, e, length));
}
else
{
@ -268,8 +265,8 @@ public:
std::size_t bytes_avail = storage_.size();
std::size_t bytes_copied = 0;
typename MutableBufferSequence::const_iterator iter = buffers_.begin();
typename MutableBufferSequence::const_iterator end = buffers_.end();
typename Mutable_Buffers::const_iterator iter = buffers_.begin();
typename Mutable_Buffers::const_iterator end = buffers_.end();
for (; iter != end && bytes_avail > 0; ++iter)
{
std::size_t max_length = buffer_size(*iter);
@ -282,40 +279,38 @@ public:
}
storage_.consume(bytes_copied);
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
io_service_.dispatch(detail::bind_handler(handler_, e, bytes_copied));
}
}
private:
asio::io_service& io_service_;
detail::buffered_stream_storage& storage_;
MutableBufferSequence buffers_;
ReadHandler handler_;
Mutable_Buffers buffers_;
Handler handler_;
};
/// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
{
if (storage_.empty())
{
async_fill(read_some_handler<MutableBufferSequence, ReadHandler>(
get_io_service(), storage_, buffers, handler));
async_fill(read_some_handler<Mutable_Buffers, Handler>(
io_service(), storage_, buffers, handler));
}
else
{
std::size_t length = copy(buffers);
get_io_service().post(detail::bind_handler(
handler, asio::error_code(), length));
io_service().post(detail::bind_handler(handler, 0, length));
}
}
/// Peek at the incoming data on the stream. Returns the number of bytes read.
/// Throws an exception on failure.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t peek(const Mutable_Buffers& buffers)
{
if (storage_.empty())
fill();
@ -323,13 +318,11 @@ public:
}
/// Peek at the incoming data on the stream. Returns the number of bytes read,
/// or 0 if an error occurred.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
{
ec = asio::error_code();
if (storage_.empty() && !fill(ec))
if (storage_.empty() && !fill(error_handler))
return 0;
return peek_copy(buffers);
}
@ -341,25 +334,25 @@ public:
}
/// Determine the amount of data that may be read without blocking.
std::size_t in_avail(asio::error_code& ec)
template <typename Error_Handler>
std::size_t in_avail(Error_Handler error_handler)
{
ec = asio::error_code();
return storage_.size();
}
private:
/// Copy data out of the internal buffer to the specified target buffer.
/// Returns the number of bytes copied.
template <typename MutableBufferSequence>
std::size_t copy(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t copy(const Mutable_Buffers& buffers)
{
using namespace std; // For memcpy.
std::size_t bytes_avail = storage_.size();
std::size_t bytes_copied = 0;
typename MutableBufferSequence::const_iterator iter = buffers.begin();
typename MutableBufferSequence::const_iterator end = buffers.end();
typename Mutable_Buffers::const_iterator iter = buffers.begin();
typename Mutable_Buffers::const_iterator end = buffers.end();
for (; iter != end && bytes_avail > 0; ++iter)
{
std::size_t max_length = buffer_size(*iter);
@ -377,16 +370,16 @@ private:
/// Copy data from the internal buffer to the specified target buffer, without
/// removing the data from the internal buffer. Returns the number of bytes
/// copied.
template <typename MutableBufferSequence>
std::size_t peek_copy(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t peek_copy(const Mutable_Buffers& buffers)
{
using namespace std; // For memcpy.
std::size_t bytes_avail = storage_.size();
std::size_t bytes_copied = 0;
typename MutableBufferSequence::const_iterator iter = buffers.begin();
typename MutableBufferSequence::const_iterator end = buffers.end();
typename Mutable_Buffers::const_iterator iter = buffers.begin();
typename Mutable_Buffers::const_iterator end = buffers.end();
for (; iter != end && bytes_avail > 0; ++iter)
{
std::size_t max_length = buffer_size(*iter);

View File

@ -2,7 +2,7 @@
// buffered_read_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// buffered_stream.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -36,12 +36,13 @@ namespace asio {
* The buffered_stream class template can be used to add buffering to the
* synchronous and asynchronous read and write operations of a stream.
*
* @par Thread Safety
* @par Thread Safety:
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
* Async_Object, Async_Read_Stream, Async_Write_Stream, Error_Source, Stream,
* Sync_Read_Stream, Sync_Write_Stream.
*/
template <typename Stream>
class buffered_stream
@ -54,6 +55,9 @@ public:
/// The type of the lowest layer.
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
/// The type used for reporting errors.
typedef typename next_layer_type::error_type error_type;
/// Construct, passing the specified argument to initialise the next layer.
template <typename Arg>
explicit buffered_stream(Arg& a)
@ -83,17 +87,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.
@ -103,9 +100,10 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
template <typename Error_Handler>
void close(Error_Handler error_handler)
{
return stream_impl_.close(ec);
stream_impl_.close(error_handler);
}
/// Flush all data from the buffer to the next layer. Returns the number of
@ -118,41 +116,41 @@ public:
/// Flush all data from the buffer to the next layer. Returns the number of
/// bytes written to the next layer on the last write operation, or 0 if an
/// error occurred.
std::size_t flush(asio::error_code& ec)
/// error occurred and the error handler did not throw.
template <typename Error_Handler>
std::size_t flush(Error_Handler error_handler)
{
return stream_impl_.next_layer().flush(ec);
return stream_impl_.next_layer().flush(error_handler);
}
/// Start an asynchronous flush.
template <typename WriteHandler>
void async_flush(WriteHandler handler)
template <typename Handler>
void async_flush(Handler handler)
{
return stream_impl_.next_layer().async_flush(handler);
}
/// Write the given data to the stream. Returns the number of bytes written.
/// Throws an exception on failure.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers)
template <typename Const_Buffers>
std::size_t write_some(const Const_Buffers& buffers)
{
return stream_impl_.write_some(buffers);
}
/// Write the given data to the stream. Returns the number of bytes written,
/// or 0 if an error occurred.
template <typename ConstBufferSequence>
std::size_t write_some(const ConstBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Const_Buffers, typename Error_Handler>
std::size_t write_some(const Const_Buffers& buffers,
Error_Handler error_handler)
{
return stream_impl_.write_some(buffers, ec);
return stream_impl_.write_some(buffers, error_handler);
}
/// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
template <typename Const_Buffers, typename Handler>
void async_write_some(const Const_Buffers& buffers, Handler handler)
{
stream_impl_.async_write_some(buffers, handler);
}
@ -165,60 +163,60 @@ public:
}
/// Fill the buffer with some data. Returns the number of bytes placed in the
/// buffer as a result of the operation, or 0 if an error occurred.
std::size_t fill(asio::error_code& ec)
/// buffer as a result of the operation, or 0 if an error occurred and the
/// error handler did not throw.
template <typename Error_Handler>
std::size_t fill(Error_Handler error_handler)
{
return stream_impl_.fill(ec);
return stream_impl_.fill(error_handler);
}
/// Start an asynchronous fill.
template <typename ReadHandler>
void async_fill(ReadHandler handler)
template <typename Handler>
void async_fill(Handler handler)
{
stream_impl_.async_fill(handler);
}
/// Read some data from the stream. Returns the number of bytes read. Throws
/// an exception on failure.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t read_some(const Mutable_Buffers& buffers)
{
return stream_impl_.read_some(buffers);
}
/// Read some data from the stream. Returns the number of bytes read or 0 if
/// an error occurred.
template <typename MutableBufferSequence>
std::size_t read_some(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// an error occurred and the error handler did not throw an exception.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t read_some(const Mutable_Buffers& buffers,
Error_Handler error_handler)
{
return stream_impl_.read_some(buffers, ec);
return stream_impl_.read_some(buffers, error_handler);
}
/// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
template <typename Mutable_Buffers, typename Handler>
void async_read_some(const Mutable_Buffers& buffers, Handler handler)
{
stream_impl_.async_read_some(buffers, handler);
}
/// Peek at the incoming data on the stream. Returns the number of bytes read.
/// Throws an exception on failure.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers)
template <typename Mutable_Buffers>
std::size_t peek(const Mutable_Buffers& buffers)
{
return stream_impl_.peek(buffers);
}
/// Peek at the incoming data on the stream. Returns the number of bytes read,
/// or 0 if an error occurred.
template <typename MutableBufferSequence>
std::size_t peek(const MutableBufferSequence& buffers,
asio::error_code& ec)
/// or 0 if an error occurred and the error handler did not throw.
template <typename Mutable_Buffers, typename Error_Handler>
std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler)
{
return stream_impl_.peek(buffers, ec);
return stream_impl_.peek(buffers, error_handler);
}
/// Determine the amount of data that may be read without blocking.
@ -228,9 +226,10 @@ public:
}
/// Determine the amount of data that may be read without blocking.
std::size_t in_avail(asio::error_code& ec)
template <typename Error_Handler>
std::size_t in_avail(Error_Handler error_handler)
{
return stream_impl_.in_avail(ec);
return stream_impl_.in_avail(error_handler);
}
private:

View File

@ -2,7 +2,7 @@
// buffered_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

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

View File

@ -2,7 +2,7 @@
// buffered_write_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// completion_condition.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -71,28 +71,6 @@ private:
/// Return a completion condition function object that indicates that a read or
/// write operation should continue until all of the data has been transferred,
/// or until an error occurs.
/**
* This function is used to create an object, of unspecified type, that meets
* CompletionCondition requirements.
*
* @par Example
* Reading until a buffer is full:
* @code
* boost::array<char, 128> buf;
* asio::error_code ec;
* std::size_t n = asio::read(
* sock, asio::buffer(buf),
* asio::transfer_all(), ec);
* if (ec)
* {
* // An error occurred.
* }
* else
* {
* // n == 128
* }
* @endcode
*/
#if defined(GENERATING_DOCUMENTATION)
unspecified transfer_all();
#else
@ -105,28 +83,6 @@ inline detail::transfer_all_t transfer_all()
/// Return a completion condition function object that indicates that a read or
/// write operation should continue until a minimum number of bytes has been
/// transferred, or until an error occurs.
/**
* This function is used to create an object, of unspecified type, that meets
* CompletionCondition requirements.
*
* @par Example
* Reading until a buffer is full or contains at least 64 bytes:
* @code
* boost::array<char, 128> buf;
* asio::error_code ec;
* std::size_t n = asio::read(
* sock, asio::buffer(buf),
* asio::transfer_at_least(64), ec);
* if (ec)
* {
* // An error occurred.
* }
* else
* {
* // n >= 64 && n <= 128
* }
* @endcode
*/
#if defined(GENERATING_DOCUMENTATION)
unspecified transfer_at_least(std::size_t minimum);
#else

View File

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

View File

@ -2,7 +2,7 @@
// deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -28,30 +28,18 @@
#include "asio/detail/epoll_reactor.hpp"
#include "asio/detail/kqueue_reactor.hpp"
#include "asio/detail/select_reactor.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/win_iocp_io_service.hpp"
namespace asio {
/// Default service implementation for a timer.
template <typename TimeType,
typename TimeTraits = asio::time_traits<TimeType> >
template <typename Time_Type,
typename Time_Traits = asio::time_traits<Time_Type> >
class deadline_timer_service
#if defined(GENERATING_DOCUMENTATION)
: public asio::io_service::service
#else
: public asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >
#endif
{
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static asio::io_service::id id;
#endif
/// The time traits type.
typedef TimeTraits traits_type;
typedef Time_Traits traits_type;
/// The time type.
typedef typename traits_type::time_type time_type;
@ -63,16 +51,13 @@ private:
// The type of the platform-specific implementation.
#if defined(ASIO_HAS_IOCP)
typedef detail::deadline_timer_service<
traits_type, detail::win_iocp_io_service> service_impl_type;
traits_type, detail::select_reactor<true> > service_impl_type;
#elif defined(ASIO_HAS_EPOLL)
typedef detail::deadline_timer_service<
traits_type, detail::epoll_reactor<false> > service_impl_type;
#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;
@ -88,8 +73,7 @@ public:
/// Construct a new timer service for the specified io_service.
explicit deadline_timer_service(asio::io_service& io_service)
: asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >(io_service),
: asio::io_service::service(io_service),
service_impl_(asio::use_service<service_impl_type>(io_service))
{
}
@ -112,9 +96,9 @@ public:
}
/// Cancel any asynchronous wait operations associated with the timer.
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
std::size_t cancel(implementation_type& impl)
{
return service_impl_.cancel(impl, ec);
return service_impl_.cancel(impl);
}
/// Get the expiry time for the timer as an absolute time.
@ -125,9 +109,9 @@ public:
/// Set the expiry time for the timer as an absolute time.
std::size_t expires_at(implementation_type& impl,
const time_type& expiry_time, asio::error_code& ec)
const time_type& expiry_time)
{
return service_impl_.expires_at(impl, expiry_time, ec);
return service_impl_.expires_at(impl, expiry_time);
}
/// Get the expiry time for the timer relative to now.
@ -138,20 +122,20 @@ public:
/// Set the expiry time for the timer relative to now.
std::size_t expires_from_now(implementation_type& impl,
const duration_type& expiry_time, asio::error_code& ec)
const duration_type& expiry_time)
{
return service_impl_.expires_from_now(impl, expiry_time, ec);
return service_impl_.expires_from_now(impl, expiry_time);
}
// Perform a blocking wait on the timer.
void wait(implementation_type& impl, asio::error_code& ec)
void wait(implementation_type& impl)
{
service_impl_.wait(impl, ec);
service_impl_.wait(impl);
}
// Start an asynchronous wait on the timer.
template <typename WaitHandler>
void async_wait(implementation_type& impl, WaitHandler handler)
template <typename Handler>
void async_wait(implementation_type& impl, Handler handler)
{
service_impl_.async_wait(impl, handler);
}

View File

@ -2,7 +2,7 @@
// bind_handler.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// buffer_resize_guard.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// buffered_stream_storage.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// call_stack.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

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

View File

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

View File

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

View File

@ -1,647 +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 = add_pending_event_change(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;
interrupter_.interrupt();
}
}
// 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 = add_pending_event_change(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;
interrupter_.interrupt();
}
}
// 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 = add_pending_event_change(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;
interrupter_.interrupt();
}
}
// 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 = add_pending_event_change(descriptor);
ev.events = POLLOUT | POLLPRI | POLLERR | POLLHUP;
if (read_op_queue_.has_operation(descriptor))
ev.events |= POLLIN;
interrupter_.interrupt();
}
}
// 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 = add_pending_event_change(descriptor);
ev.events = POLLREMOVE;
interrupter_.interrupt();
// 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;
}
// Write the pending event registration changes to the /dev/poll descriptor.
std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size();
errno = 0;
int result = ::write(dev_poll_fd_,
&pending_event_changes_[0], events_size);
if (result != static_cast<int>(events_size))
{
for (std::size_t i = 0; i < pending_event_changes_.size(); ++i)
{
int descriptor = pending_event_changes_[i].fd;
asio::error_code ec = asio::error_code(
errno, asio::error::get_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);
}
}
pending_event_changes_.clear();
pending_event_change_index_.clear();
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::get_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::get_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();
}
// Add a pending event entry for the given descriptor.
::pollfd& add_pending_event_change(int descriptor)
{
hash_map<int, std::size_t>::iterator iter
= pending_event_change_index_.find(descriptor);
if (iter == pending_event_change_index_.end())
{
std::size_t index = pending_event_changes_.size();
pending_event_changes_.reserve(pending_event_changes_.size() + 1);
pending_event_change_index_.insert(std::make_pair(descriptor, index));
pending_event_changes_.push_back(::pollfd());
pending_event_changes_[index].fd = descriptor;
pending_event_changes_[index].revents = 0;
return pending_event_changes_[index];
}
else
{
return pending_event_changes_[iter->second];
}
}
// Mutex to protect access to internal data.
asio::detail::mutex mutex_;
// The /dev/poll file descriptor.
int dev_poll_fd_;
// Vector of /dev/poll events waiting to be written to the descriptor.
std::vector< ::pollfd> pending_event_changes_;
// Hash map to associate a descriptor with a pending event change index.
hash_map<int, std::size_t> pending_event_change_index_;
// 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

@ -2,7 +2,7 @@
// epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -30,9 +30,8 @@
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/io_service.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/hash_map.hpp"
#include "asio/detail/mutex.hpp"
@ -40,7 +39,6 @@
#include "asio/detail/thread.hpp"
#include "asio/detail/reactor_op_queue.hpp"
#include "asio/detail/select_interrupter.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/signal_blocker.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/timer_queue.hpp"
@ -50,12 +48,12 @@ namespace detail {
template <bool Own_Thread>
class epoll_reactor
: public asio::detail::service_base<epoll_reactor<Own_Thread> >
: public asio::io_service::service
{
public:
// Constructor.
epoll_reactor(asio::io_service& io_service)
: asio::detail::service_base<epoll_reactor<Own_Thread> >(io_service),
: asio::io_service::service(io_service),
mutex_(),
epoll_fd_(do_epoll_create()),
wait_in_progress_(false),
@ -141,7 +139,7 @@ public:
return;
if (!read_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (read_op_queue_.enqueue_operation(descriptor, handler))
@ -155,13 +153,10 @@ 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::get_system_category());
read_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
read_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -177,7 +172,7 @@ public:
return;
if (!write_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (write_op_queue_.enqueue_operation(descriptor, handler))
@ -191,13 +186,10 @@ 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::get_system_category());
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -223,13 +215,10 @@ 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::get_system_category());
except_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -257,14 +246,11 @@ 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::get_system_category());
write_op_queue_.dispatch_all_operations(descriptor, ec);
except_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
except_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -310,21 +296,6 @@ public:
timer_queues_.push_back(&timer_queue);
}
// Remove a timer queue from the reactor.
template <typename Time_Traits>
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(mutex_);
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
if (timer_queues_[i] == &timer_queue)
{
timer_queues_.erase(timer_queues_.begin() + i);
return;
}
}
}
// Schedule a timer in the given timer queue to expire at the specified
// absolute time. The handler object will be invoked when the timer expires.
template <typename Time_Traits, typename Handler>
@ -343,10 +314,7 @@ public:
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;
return timer_queue.cancel_timer(token);
}
private:
@ -362,13 +330,16 @@ private:
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);
// Clean up operations. We must not hold the lock since the operations may
// make calls back into this reactor.
lock.unlock();
read_op_queue_.cleanup_operations();
write_op_queue_.cleanup_operations();
except_op_queue_.cleanup_operations();
return;
}
@ -377,7 +348,12 @@ private:
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
&& except_op_queue_.empty() && all_timer_queues_are_empty())
{
cleanup_operations_and_timers(lock);
// Clean up operations. We must not hold the lock since the operations may
// make calls back into this reactor.
lock.unlock();
read_op_queue_.cleanup_operations();
write_op_queue_.cleanup_operations();
except_op_queue_.cleanup_operations();
return;
}
@ -405,42 +381,40 @@ private:
}
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 & (EPOLLPRI | EPOLLERR | EPOLLHUP))
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
else
more_except = except_op_queue_.has_operation(descriptor);
if (events[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
else
more_reads = read_op_queue_.has_operation(descriptor);
if (events[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
else
more_writes = write_op_queue_.has_operation(descriptor);
if ((events[i].events == EPOLLHUP)
&& !more_except && !more_reads && !more_writes)
if (events[i].events & (EPOLLERR | EPOLLHUP))
{
// 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.
except_op_queue_.dispatch_all_operations(descriptor, 0);
read_op_queue_.dispatch_all_operations(descriptor, 0);
write_op_queue_.dispatch_all_operations(descriptor, 0);
epoll_event ev = { 0, { 0 } };
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
ev.events = 0;
ev.data.fd = descriptor;
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
}
else
{
bool more_reads = false;
bool more_writes = false;
bool more_except = false;
// Exception operations must be processed first to ensure that any
// out-of-band data is read before normal data.
if (events[i].events & EPOLLPRI)
more_except = except_op_queue_.dispatch_operation(descriptor, 0);
else
more_except = except_op_queue_.has_operation(descriptor);
if (events[i].events & EPOLLIN)
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
else
more_reads = read_op_queue_.has_operation(descriptor);
if (events[i].events & EPOLLOUT)
more_writes = write_op_queue_.dispatch_operation(descriptor, 0);
else
more_writes = write_op_queue_.has_operation(descriptor);
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLERR | EPOLLHUP;
if (more_reads)
@ -451,15 +425,12 @@ private:
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::get_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);
int error = errno;
read_op_queue_.dispatch_all_operations(descriptor, error);
write_op_queue_.dispatch_all_operations(descriptor, error);
except_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -468,17 +439,19 @@ private:
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);
// Clean up operations. We must not hold the lock since the operations may
// make calls back into this reactor.
lock.unlock();
read_op_queue_.cleanup_operations();
write_op_queue_.cleanup_operations();
except_op_queue_.cleanup_operations();
}
// Run the select loop in the thread.
@ -515,11 +488,8 @@ private:
int fd = epoll_create(epoll_size);
if (fd == -1)
{
boost::throw_exception(
asio::system_error(
asio::error_code(errno,
asio::error::get_system_category()),
"epoll"));
system_exception e("epoll", errno);
boost::throw_exception(e);
}
return fd;
}
@ -556,8 +526,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
{
@ -577,22 +546,6 @@ private:
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_;
@ -617,10 +570,6 @@ private:
// 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_;

View File

@ -2,7 +2,7 @@
// epoll_reactor_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// event.hpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// handler_alloc_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// handler_invoke_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

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

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

View File

@ -2,7 +2,7 @@
// io_control.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -90,7 +90,7 @@ public:
// Construct with a specific command value.
bytes_readable(std::size_t value)
: value_(static_cast<detail::ioctl_arg_type>(value))
: value_(value)
{
}

View File

@ -2,7 +2,7 @@
// kqueue_reactor.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -33,16 +33,14 @@
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/io_service.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/task_io_service.hpp"
#include "asio/detail/thread.hpp"
#include "asio/detail/reactor_op_queue.hpp"
#include "asio/detail/select_interrupter.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/signal_blocker.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/timer_queue.hpp"
@ -57,13 +55,12 @@ namespace detail {
template <bool Own_Thread>
class kqueue_reactor
: public asio::detail::service_base<kqueue_reactor<Own_Thread> >
: public asio::io_service::service
{
public:
// Constructor.
kqueue_reactor(asio::io_service& io_service)
: asio::detail::service_base<
kqueue_reactor<Own_Thread> >(io_service),
: asio::io_service::service(io_service),
mutex_(),
kqueue_fd_(do_kqueue_create()),
wait_in_progress_(false),
@ -141,7 +138,7 @@ public:
return;
if (!read_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (read_op_queue_.enqueue_operation(descriptor, handler))
@ -150,9 +147,8 @@ public:
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno,
asio::error::get_system_category());
read_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
read_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -168,7 +164,7 @@ public:
return;
if (!write_op_queue_.has_operation(descriptor))
if (handler(asio::error_code()))
if (handler(0))
return;
if (write_op_queue_.enqueue_operation(descriptor, handler))
@ -177,9 +173,8 @@ public:
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno,
asio::error::get_system_category());
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -203,9 +198,8 @@ public:
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno,
asio::error::get_system_category());
except_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -227,9 +221,8 @@ public:
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno,
asio::error::get_system_category());
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
@ -242,10 +235,9 @@ public:
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code ec(errno,
asio::error::get_system_category());
except_op_queue_.dispatch_all_operations(descriptor, ec);
write_op_queue_.dispatch_all_operations(descriptor, ec);
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
}
@ -293,21 +285,6 @@ public:
timer_queues_.push_back(&timer_queue);
}
// Remove a timer queue from the reactor.
template <typename Time_Traits>
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(mutex_);
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
if (timer_queues_[i] == &timer_queue)
{
timer_queues_.erase(timer_queues_.begin() + i);
return;
}
}
}
// Schedule a timer in the given timer queue to expire at the specified
// absolute time. The handler object will be invoked when the timer expires.
template <typename Time_Traits, typename Handler>
@ -326,10 +303,7 @@ public:
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;
return timer_queue.cancel_timer(token);
}
private:
@ -345,13 +319,16 @@ private:
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);
// Clean up operations. We must not hold the lock since the operations may
// make calls back into this reactor.
lock.unlock();
read_op_queue_.cleanup_operations();
write_op_queue_.cleanup_operations();
except_op_queue_.cleanup_operations();
return;
}
@ -360,7 +337,12 @@ private:
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
&& except_op_queue_.empty() && all_timer_queues_are_empty())
{
cleanup_operations_and_timers(lock);
// Clean up operations. We must not hold the lock since the operations may
// make calls back into this reactor.
lock.unlock();
read_op_queue_.cleanup_operations();
write_op_queue_.cleanup_operations();
except_op_queue_.cleanup_operations();
return;
}
@ -396,24 +378,21 @@ private:
bool more_except = false;
if (events[i].flags & EV_ERROR)
{
asio::error_code error(
events[i].data, asio::error::get_system_category());
int error = events[i].data;
except_op_queue_.dispatch_all_operations(descriptor, error);
read_op_queue_.dispatch_all_operations(descriptor, error);
}
else if (events[i].flags & EV_OOBAND)
{
asio::error_code error;
more_except = except_op_queue_.dispatch_operation(descriptor, error);
more_except = except_op_queue_.dispatch_operation(descriptor, 0);
if (events[i].data > 0)
more_reads = read_op_queue_.dispatch_operation(descriptor, error);
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
else
more_reads = read_op_queue_.has_operation(descriptor);
}
else
{
asio::error_code error;
more_reads = read_op_queue_.dispatch_operation(descriptor, error);
more_reads = read_op_queue_.dispatch_operation(descriptor, 0);
more_except = except_op_queue_.has_operation(descriptor);
}
@ -427,8 +406,7 @@ private:
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code error(errno,
asio::error::get_system_category());
int error = errno;
except_op_queue_.dispatch_all_operations(descriptor, error);
read_op_queue_.dispatch_all_operations(descriptor, error);
}
@ -439,14 +417,12 @@ private:
bool more_writes = false;
if (events[i].flags & EV_ERROR)
{
asio::error_code error(
events[i].data, asio::error::get_system_category());
int error = events[i].data;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
else
{
asio::error_code error;
more_writes = write_op_queue_.dispatch_operation(descriptor, error);
more_writes = write_op_queue_.dispatch_operation(descriptor, 0);
}
// Update the descriptor in the kqueue.
@ -457,8 +433,7 @@ private:
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
{
asio::error_code error(errno,
asio::error::get_system_category());
int error = errno;
write_op_queue_.dispatch_all_operations(descriptor, error);
}
}
@ -468,17 +443,19 @@ private:
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 (std::size_t i = 0; i < pending_cancellations_.size(); ++i)
cancel_ops_unlocked(pending_cancellations_[i]);
pending_cancellations_.clear();
cleanup_operations_and_timers(lock);
// Clean up operations. We must not hold the lock since the operations may
// make calls back into this reactor.
lock.unlock();
read_op_queue_.cleanup_operations();
write_op_queue_.cleanup_operations();
except_op_queue_.cleanup_operations();
}
// Run the select loop in the thread.
@ -512,11 +489,8 @@ private:
int fd = kqueue();
if (fd == -1)
{
boost::throw_exception(
asio::system_error(
asio::error_code(errno,
asio::error::get_system_category()),
"kqueue"));
system_exception e("kqueue", errno);
boost::throw_exception(e);
}
return fd;
}
@ -565,7 +539,7 @@ private:
// Cancel all operations associated with the given descriptor. The do_cancel
// function of the handler objects will be invoked. This function does not
// acquire the kqueue_reactor's mutex.
// acquire the epoll_reactor's mutex.
void cancel_ops_unlocked(socket_type descriptor)
{
bool interrupt = read_op_queue_.cancel_operations(descriptor);
@ -575,32 +549,16 @@ private:
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 kqueue file descriptor.
// The epoll file descriptor.
int kqueue_fd_;
// Whether the kqueue wait call is currently in progress
bool wait_in_progress_;
// The interrupter is used to break a blocking kevent call.
// The interrupter is used to break a blocking epoll_wait call.
select_interrupter interrupter_;
// The queue of read operations.
@ -615,10 +573,6 @@ private:
// 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_;

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// mutex.hpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// noncopyable.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// null_event.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -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

@ -2,7 +2,7 @@
// null_mutex.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// null_signal_blocker.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// null_thread.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -28,7 +28,7 @@
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
@ -42,8 +42,7 @@ public:
template <typename Function>
null_thread(Function f)
{
asio::system_error e(
asio::error::operation_not_supported, "thread");
system_exception e("thread", asio::error::not_supported);
boost::throw_exception(e);
}

View File

@ -2,7 +2,7 @@
// null_tss_ptr.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// old_win_sdk_compat.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -24,9 +24,9 @@
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
// Guess whether we are building against on old Platform SDK.
#if !defined(IN6ADDR_ANY_INIT)
#if !defined(IPPROTO_IPV6)
#define ASIO_HAS_OLD_WIN_SDK 1
#endif // !defined(IN6ADDR_ANY_INIT)
#endif // !defined(IPPROTO_IPV6)
#if defined(ASIO_HAS_OLD_WIN_SDK)
@ -164,10 +164,6 @@ struct addrinfo_emulation
# define IPPROTO_IPV6 41
#endif
#if !defined(IPV6_UNICAST_HOPS)
# define IPV6_UNICAST_HOPS 4
#endif
#if !defined(IPV6_MULTICAST_IF)
# define IPV6_MULTICAST_IF 9
#endif
@ -309,11 +305,6 @@ inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a)
#endif // defined(ASIO_HAS_OLD_WIN_SDK)
// Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY.
#if !defined(IPV6_V6ONLY)
# define IPV6_V6ONLY 27
#endif
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#include "asio/detail/pop_options.hpp"

View File

@ -2,7 +2,7 @@
// pipe_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -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,13 +46,6 @@ public:
write_descriptor_ = pipe_fds[1];
::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
}
else
{
asio::error_code ec(errno,
asio::error::get_system_category());
asio::system_error e(ec, "pipe_select_interrupter");
boost::throw_exception(e);
}
}
// Destructor.

View File

@ -2,7 +2,7 @@
// pop_options.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// posix_event.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -24,13 +24,11 @@
#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/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
@ -44,13 +42,18 @@ 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::get_system_category()),
"event");
system_exception e("event", error);
boost::throw_exception(e);
}
error = ::pthread_cond_init(&cond_, 0);
if (error != 0)
{
::pthread_mutex_destroy(&mutex_);
system_exception e("event", error);
boost::throw_exception(e);
}
}
@ -59,37 +62,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

@ -2,7 +2,7 @@
// posix_fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -31,7 +31,6 @@ public:
posix_fd_set_adapter()
: max_descriptor_(invalid_socket)
{
using namespace std; // Needed for memset on Solaris.
FD_ZERO(&fd_set_);
}
@ -58,7 +57,7 @@ public:
}
private:
mutable fd_set fd_set_;
fd_set fd_set_;
socket_type max_descriptor_;
};

View File

@ -2,7 +2,7 @@
// posix_mutex.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -28,16 +28,13 @@
#include <pthread.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/system_exception.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/scoped_lock.hpp"
namespace asio {
namespace detail {
class posix_event;
class posix_mutex
: private noncopyable
{
@ -50,10 +47,7 @@ public:
int error = ::pthread_mutex_init(&mutex_, 0);
if (error != 0)
{
asio::system_error e(
asio::error_code(error,
asio::error::get_system_category()),
"mutex");
system_exception e("mutex", error);
boost::throw_exception(e);
}
}
@ -70,10 +64,7 @@ public:
int error = ::pthread_mutex_lock(&mutex_);
if (error != 0)
{
asio::system_error e(
asio::error_code(error,
asio::error::get_system_category()),
"mutex");
system_exception e("mutex", error);
boost::throw_exception(e);
}
}
@ -84,16 +75,12 @@ public:
int error = ::pthread_mutex_unlock(&mutex_);
if (error != 0)
{
asio::system_error e(
asio::error_code(error,
asio::error::get_system_category()),
"mutex");
system_exception e("mutex", error);
boost::throw_exception(e);
}
}
private:
friend class posix_event;
::pthread_mutex_t mutex_;
};

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