Compare commits

...

661 Commits

Author SHA1 Message Date
fb308d5dca tag 0.5.8.1 2008-01-20 06:05:28 +00:00
3618b4bfe8 sync lang files 2008-01-19 04:56:48 +00:00
fe01d8c55f version updates and todo/changelog update 2008-01-19 04:54:09 +00:00
263387c6c9 fix saving fast resume on checking torrents 2008-01-19 04:53:36 +00:00
379eac85c4 lt sync 1955 2008-01-19 04:52:22 +00:00
d2f6a99778 Catch all exceptions during interactive_add_torrent. 2008-01-18 04:46:39 +00:00
4a7e0a578b Try catching more exceptions in the core. 2008-01-18 04:37:33 +00:00
8fadfb8254 Prevent the use of an invalid unique_id from throwing an exception
during get_torrent_state().
2008-01-18 03:40:38 +00:00
1c3c5b76b0 fast resume oops2 2008-01-17 12:22:27 +00:00
ac80dd4d59 fast resume oops 2008-01-17 12:18:11 +00:00
d1eb4bc8d6 use pieces wanted instead of total pieces to draw adv progress bar 2008-01-16 02:19:15 +00:00
790eda0f2c lt sync 1947 2008-01-15 08:46:24 +00:00
cc81e1073d Catch 'address already in use' error when trying to use a port that is
in use by another program.  We now try to use a range of 40000-60000 
when this error occurs.
2008-01-14 08:04:28 +00:00
642663604f Fix possible issue if pref 'choose_directory_dialog_path' is None. 2008-01-14 05:13:21 +00:00
6b68ac9ad7 Attempt to fix issue where all the columns start very small. 2008-01-13 10:58:52 +00:00
1de14a1ce0 Fix issue with removing items while iterating through the self.state
dictionary.
2008-01-13 08:32:46 +00:00
0d793e7f89 Attempt to load the state in a safe manner. 2008-01-13 08:10:35 +00:00
2e0be83732 lt sync 1938 2008-01-13 06:24:52 +00:00
dc60e26c59 use die instead of save_yourself and add arg to shutdown func 2008-01-13 05:00:04 +00:00
dbe41a3cd5 lt sync 1929 2008-01-11 20:25:08 +00:00
49c09bf297 Catch exception in calc_free_space(). 2008-01-10 12:12:30 +00:00
8f675ebacf lt bandwidth limiter mutex fix 2008-01-10 06:23:53 +00:00
c7f3323d3e remove browser 2008-01-10 02:16:34 +00:00
c763d82306 2008-01-09 21:41:07 +00:00
ee4d054582 fix pausing of checking torrents 2008-01-09 21:16:13 +00:00
cb64ecb282 update, then present, not the other way around 2008-01-09 18:05:24 +00:00
fcfdcd6b06 tweak new release pref 2008-01-09 08:18:35 +00:00
77f542b925 more tab work 2008-01-09 04:02:13 +00:00
068e4008c6 update todo and initial stages of browser tab support 2008-01-08 06:01:34 +00:00
70497c074e fix win32 problems with rt 2008-01-08 06:00:37 +00:00
7b39f7adf5 lt sync 1912 2008-01-08 05:59:58 +00:00
e0fc7f3d2e fix #647 2008-01-07 23:25:10 +00:00
7d781568ea remove rt from win32 2008-01-07 21:43:44 +00:00
dcefa152c0 sync rest 2008-01-07 01:36:35 +00:00
294e1f6b76 lt sync 2008-01-07 01:36:09 +00:00
d76ed8cfba remove old files 2008-01-06 20:08:36 +00:00
62b9a9170a 2008-01-06 20:02:44 +00:00
8c67f97631 2008-01-06 20:02:16 +00:00
3997c235be 2008-01-06 20:00:13 +00:00
c6eb180e66 2008-01-06 19:58:20 +00:00
b31fa3a6df 2008-01-06 19:57:16 +00:00
22225963d5 2008-01-06 19:56:11 +00:00
9741cbbda0 2008-01-06 19:54:53 +00:00
65d007c681 browser and search are now plugins 2008-01-06 19:53:47 +00:00
d15a03bce1 test 2008-01-06 19:52:56 +00:00
0e82847ae0 fix cast oops, add youtorrent to search, catch fastresume error 2008-01-05 00:13:50 +00:00
d497a971db fix cast oops 2008-01-04 23:59:54 +00:00
3baecc13d3 save fastresume every minute 2008-01-04 23:30:25 +00:00
0ca8b5887b lt sync 2008-01-03 19:08:52 +00:00
76e9cb3e76 remove needless casts for performance 2008-01-03 02:43:54 +00:00
c7fcbd40e3 Remove some needless 'casts' in common.py to slightly improve
performance.
2008-01-03 02:30:40 +00:00
9a3a96a31f py2.4 fix - thresh 2008-01-03 00:57:36 +00:00
72f49e3557 add rt/crypto to libraries - thresh 2008-01-03 00:52:08 +00:00
7e49e9acc4 tweak windows build preprocessors 2008-01-01 03:56:50 +00:00
ff0ade61b0 tweak vista shutdown 2008-01-01 02:36:06 +00:00
9972471231 lt sync 2007-12-31 10:44:40 +00:00
42f4d55db2 tweak version 2007-12-31 10:43:37 +00:00
2d27cede5f asio sync 2007-12-31 07:11:07 +00:00
4d4b30700a sort by seeds in piratebay search 2007-12-30 22:02:05 +00:00
736afd6a19 add /seeds to mininova search 2007-12-30 22:00:08 +00:00
91fa4df798 fix new release 2007-12-30 02:58:47 +00:00
150609e8c8 lang sync 2007-12-29 22:01:26 +00:00
aeb1b9bac2 allow higher ports in proxies 2007-12-29 21:27:52 +00:00
d1a5490e6b handle events before apply_queue 2007-12-29 18:40:01 +00:00
7ac3421e31 Remove pointless '+0.5' from update timer. 2007-12-29 05:37:21 +00:00
3b2d205866 alter signal handling shutdown 2007-12-29 05:04:35 +00:00
c067cbe4bd tweak import of gnome.ui 2007-12-29 04:52:14 +00:00
fb222ce57f remove no-longer needed freebsd fix 2007-12-29 04:04:08 +00:00
c21f650c45 fix handling of invalid torrents 2007-12-29 03:16:30 +00:00
ea7fdc3bc1 tweak pause/resume 2007-12-29 01:39:58 +00:00
eeb2c26002 tweaks and lt sync 2007-12-28 23:35:11 +00:00
4156788296 2007-12-27 17:41:01 +00:00
2dec88e5c2 makefile fix 2007-12-27 17:40:35 +00:00
5eeabadc88 lt fixes 2007-12-27 06:19:51 +00:00
85fb85cf13 fix association with svn builds 2007-12-27 05:52:38 +00:00
d3492be2c2 fix having two instances of deluge running when fixing environment variables 2007-12-27 01:50:56 +00:00
c6f69d47e2 fix ubuntu and separate config dir issues 2007-12-27 00:45:11 +00:00
ea953f54b1 fix debug 2007-12-26 22:17:43 +00:00
eea8ff8e98 try to fix ubuntu again 2007-12-26 22:17:23 +00:00
cd74538adf check for bookmark first 2007-12-26 21:09:04 +00:00
7e748a1306 fix config error 2007-12-26 20:10:15 +00:00
ab8e6e6bde fix freebsd oops 2007-12-26 20:07:44 +00:00
2465c5d214 try to fix adding torrents when overwriting env variables 2007-12-26 20:06:38 +00:00
5828ee03e9 account for freebsd path for gtkmozembed 2007-12-26 19:48:48 +00:00
a29c735acd tweak last 2007-12-26 19:28:43 +00:00
dacebd2eec use external browser always for active port test 2007-12-26 19:27:52 +00:00
659c1c5f34 warning popup instead of crash if importing browser fails 2007-12-26 18:53:58 +00:00
d647031bee tweak new version 2007-12-25 23:45:55 +00:00
02ad4098bc fix update alert 2007-12-25 17:39:58 +00:00
f7952eaa7f remove restart notice in prefs for browser 2007-12-25 07:50:14 +00:00
5a3527611d fix browser icon without restart 2007-12-25 07:48:31 +00:00
3c0d9279eb add missing lt changes to changelog 2007-12-25 07:32:33 +00:00
3d794b6983 update changelog and version numbers for rc2 release 2007-12-25 07:27:23 +00:00
9b52e63f5b fix icon size in search 2007-12-25 03:34:57 +00:00
214042af9a tweak launching of frames externally 2007-12-25 03:31:34 +00:00
3fb919b99d fix oops in notification 2007-12-25 03:02:07 +00:00
653dcb046e minor glade tweak 2007-12-25 02:25:50 +00:00
445f3840b2 add buttons to launch main/footer frames into an external browser 2007-12-25 02:24:06 +00:00
c748419fa9 webui sync 2007-12-24 22:52:04 +00:00
431664fec4 lt sync 2007-12-24 22:27:26 +00:00
77d4fefba9 remove filelist from notification list 2007-12-24 09:12:23 +00:00
3ba156632f fix flexrss before blocklist 2007-12-24 04:47:34 +00:00
4ee8fd8394 tweak message 2007-12-24 04:44:08 +00:00
5b1a381389 change add torrent to ctrl+n and remove browser icon when not selected in preferences 2007-12-23 23:52:15 +00:00
b59de9aa8b fix shrinking of main window 2007-12-23 06:48:14 +00:00
4149e1d285 sync trunk 2007-12-23 02:42:22 +00:00
8d12fe6312 testing 2007-12-22 22:50:28 +00:00
75684cde8d fix up webui 2007-12-22 19:58:46 +00:00
5ccca41ea6 2007-12-22 08:36:15 +00:00
23d13a2cfd revert last 2007-12-22 08:20:17 +00:00
b803d39d63 webui sync r168 2007-12-22 08:15:51 +00:00
93d0ab797b lt fix - fix to bound check piece index before use in incoming_allowed_fast 2007-12-19 07:06:10 +00:00
9251a82259 lt fix - added missing include guard to disk_io_thread.hpp 2007-12-17 23:55:31 +00:00
53702b378e lt fix - fixed typo in plugin 2007-12-16 22:54:18 +00:00
3e9eff9b16 lt piece picker fix 2007-12-16 06:35:45 +00:00
3dd3d22fd0 catch (more) delete 2007-12-15 18:40:03 +00:00
c6ff9e43b7 catch delete 2007-12-15 18:14:20 +00:00
c8507b4c28 fix lt assert 2007-12-14 08:44:31 +00:00
8821113742 fix column saving 2007-12-14 02:21:02 +00:00
2317bb4d52 change tabs to spaces 2007-12-14 01:23:09 +00:00
0ed3bda526 proper paths for cross platfrom 2007-12-14 01:19:39 +00:00
3fd1434b04 tweak path to icon 2007-12-14 01:02:42 +00:00
71cf5198d4 launchpad lang sync 2007-12-13 06:36:16 +00:00
22ddf86a4d add web seed to torrent creator in changelog 2007-12-13 06:25:51 +00:00
fa7a785aab update changelog 2007-12-13 05:08:56 +00:00
202b3019a3 fix total uploaded 2007-12-13 04:50:27 +00:00
5eb2e95dd4 change trunk version # 2007-12-13 04:44:40 +00:00
b800545ca1 lt - attempt to fix potential deadlock in disk_io_thread 2007-12-13 04:13:29 +00:00
bf037ab3d6 tweak init script 2007-12-12 23:20:30 +00:00
79b0f67760 lt bug fixes 2007-12-12 20:23:31 +00:00
657055cab1 change shutdown from using abort 2007-12-12 20:22:15 +00:00
9eaf2e602a fix seeding ratio stop on finished torrents 2007-12-11 01:08:49 +00:00
c35a13b227 set half-open connection lower on ms' retarded windows 2007-12-10 22:24:45 +00:00
54155670b5 dht fix 2007-12-10 20:57:25 +00:00
43c09af8b1 fix zombie fix oops 2007-12-09 19:05:17 +00:00
d355a42af8 bandwidth manager fix 2007-12-09 18:50:22 +00:00
91531deb6d no more zombie processes when launching external apps 2007-12-09 04:31:39 +00:00
f73e9be9c9 increase tracker stop timeout 2007-12-09 04:31:18 +00:00
0f8199dbab close upnp on close 2007-12-07 22:02:34 +00:00
04ad4ae7be launchpad language sync 2007-12-06 02:53:18 +00:00
68f9a3f265 webui sync r165 2007-12-05 22:06:31 +00:00
2324fdca83 dht abuse prevention in lt 2007-12-05 19:04:27 +00:00
db80d433b6 revert svg for windows 2007-12-03 18:10:15 +00:00
b4795cc362 windows now supports svg icons 2007-12-03 16:45:11 +00:00
d849684e8b fix about dialog focus in windows 2007-12-03 15:58:05 +00:00
b079f1b755 fix alignment 2007-12-03 14:43:10 +00:00
c7067c93d2 close daemon in vista, too 2007-12-03 13:14:27 +00:00
d45b859705 tweak height 2007-12-02 22:55:55 +00:00
856420c640 add web seeds to torrent creator 2007-12-02 22:36:02 +00:00
4f55d7dfc6 fix date in changelog 2007-12-01 18:31:05 +00:00
27bc2a72b0 tweak full hd warning - disable it in libtorrent 2007-12-01 06:45:43 +00:00
4037479119 update changelogs and up trunk version 2007-12-01 04:20:47 +00:00
a0af136b81 remove unneeded makefiles 2007-12-01 04:14:24 +00:00
f757efde4d sync lt to rc_0_13 branch 2007-12-01 04:07:11 +00:00
cfe1bd241d fix duplicant_torrent and libtorrent bugfixes 2007-12-01 03:54:42 +00:00
2eb3868115 increase tracker timeout 2007-12-01 03:24:36 +00:00
5b71f1f6d9 up trunk version number post release 2007-11-27 23:16:11 +00:00
7d5e079336 remove webui example template 2007-11-27 21:35:16 +00:00
039c5591ed sync languages for release 2007-11-27 19:18:55 +00:00
e00fece477 fix portuguese encryption translation 2007-11-27 18:56:31 +00:00
fb5d4c8e55 gtk stock non translatable again 2007-11-27 18:10:36 +00:00
36a5440858 webui button fix from vonck 2007-11-26 23:21:34 +00:00
b3ab64182e webui rev161 2007-11-26 19:43:51 +00:00
47acfd93ea try to catch invalid_handle in add_torrent 2007-11-26 18:56:17 +00:00
9ec83822a0 tweak replace_tracker in core.py 2007-11-26 17:31:22 +00:00
d288e39a54 tweak try/catch again 2007-11-26 17:03:04 +00:00
8c5355498c tweak boost library variables 2007-11-26 16:42:07 +00:00
4dad638a41 webui tweaks rev 160 2007-11-26 16:06:55 +00:00
1698c57f58 tweak get_index_from_unique_id 2007-11-26 06:07:47 +00:00
f96cc8e56a fix typo 2007-11-26 05:57:31 +00:00
675a286f8a make sure simplerss does not load 2007-11-26 05:40:24 +00:00
0d51bb250e fix indent 2007-11-26 04:57:28 +00:00
8f6bb96df0 add catch to get_index_from_unique_id 2007-11-26 04:48:11 +00:00
32fc9bbf07 tweak last 2007-11-26 02:20:40 +00:00
b7983a5ab4 catch invalid_handle on add_torrent 2007-11-26 02:04:55 +00:00
776ed5a9d8 another attempt for invalid handle 2007-11-26 00:59:28 +00:00
6595fe0621 fix webseed 2007-11-26 00:17:48 +00:00
fd7d1ce675 try to catch invalid handle in deluge_core 2007-11-25 23:59:19 +00:00
e0367895b7 torrent info labels selectable 2007-11-25 22:02:44 +00:00
1e65e4e396 Apply logfile patch for Windows build from Slurdge. 2007-11-25 12:16:29 +00:00
51bc2329c2 use system setting for toolbar text/icon style 2007-11-25 01:51:00 +00:00
5c7031ab80 cleanup trackers replace 2007-11-25 01:11:19 +00:00
9c3929f15e dont die if plugin in prefs.state is not found on the filesystem 2007-11-24 22:46:43 +00:00
ee409d71c5 fix add torrent in webui 2007-11-24 20:39:55 +00:00
9777d4e00c skip taskbar fix for win 2007-11-24 19:54:00 +00:00
7e9576a947 language files sync 2007-11-24 19:30:42 +00:00
1b0f7e89c1 asio fix for win32 2007-11-24 18:39:00 +00:00
fbf7564d42 up version number for rc release 2007-11-24 16:55:33 +00:00
0b2faf6ee1 add python-pyopenssl to README depend list 2007-11-24 16:31:02 +00:00
cda1b3aa98 update webui, show error on permission failure, differentiate queued vs paused 2007-11-24 16:22:49 +00:00
ced47db339 tweak full hd dialog when adding a new torrent 2007-11-24 05:00:08 +00:00
b221e7ac82 tweak full hd dialog 2007-11-24 04:58:57 +00:00
19f38da504 tweak tooltip 2007-11-24 03:56:11 +00:00
54aca23618 update changelog 2007-11-24 03:52:59 +00:00
dde291d6dd add connection_speed setting 2007-11-24 03:51:11 +00:00
adb7bcdf38 set max_half_open default to 20 if not on a windows system 2007-11-24 03:12:18 +00:00
ceaec1897d update changelog 2007-11-24 03:02:07 +00:00
e701fa28ba fix merge trackers 2007-11-24 02:58:23 +00:00
5701324e00 dont pause prior to move_storage 2007-11-24 01:58:54 +00:00
71bee41ff0 ipv6 listen fix 2007-11-23 23:23:41 +00:00
54bba4d74c fix for when lsd/natpmp/upnp are started twice 2007-11-23 21:18:26 +00:00
063fe8fe2d default not to use upnp 2007-11-22 23:19:14 +00:00
2cb306ca86 new languages - bs, nds and hi 2007-11-22 23:18:14 +00:00
e617c1d3b7 remove dumb tb_middle and tb_right 2007-11-22 23:17:45 +00:00
bb03e2ff6a deal with stupid gutsy sometimes not being able to connect to dbus 2007-11-22 22:26:06 +00:00
4b7d40ed49 lang sync 2007-11-22 17:29:21 +00:00
cc0d1502cc revert webui 2007-11-22 04:20:42 +00:00
74f739a693 identify miro client 2007-11-22 02:42:07 +00:00
22317356c5 plugin name translations 2007-11-22 00:02:06 +00:00
037be4d170 tweak local setting 2007-11-21 23:42:35 +00:00
d918302e3e sync webui rev 143 2007-11-21 22:32:18 +00:00
fde0c836aa re-add features that our isp lost in the backup 2007-11-21 22:18:11 +00:00
d9a783118a fast resume fix 2007-11-20 03:37:15 +00:00
3e6b577b1b fix blocklist load on start 2007-11-20 01:59:51 +00:00
19ee80cfab pause torrent before fastresume save if in compact mode 2007-11-20 01:21:22 +00:00
7b6ece4a2c lt update 2007-11-19 18:21:36 +00:00
a0b2638ffb fix category 2007-11-19 16:24:42 +00:00
8b4053dd2e fix wizard apply_prefs mess 2007-11-19 15:17:24 +00:00
9afc4ce936 lt sync 1746 2007-11-19 14:14:22 +00:00
1ae6dbf871 allow creation of torrents without trackers 2007-11-19 12:51:46 +00:00
3d1cd9bf00 update lang template 2007-11-19 02:29:22 +00:00
15983c8901 fix typo 2007-11-19 02:10:57 +00:00
7bdf7e9d1e fix eta 2007-11-19 00:43:33 +00:00
34e0a0e839 tweak pause/resume all 2007-11-19 00:27:56 +00:00
1c369bce31 same 2007-11-18 23:46:33 +00:00
9b88b8d61f tweak set_user_pause 2007-11-18 23:45:16 +00:00
423cce7c56 fix oops in last 2007-11-18 23:29:47 +00:00
43ad15b3b2 fix pause all / resume all problems 2007-11-18 23:22:36 +00:00
5a01eec297 add proper preferences for selection popup 2007-11-18 22:57:10 +00:00
06e8a0c6b9 update changelog 2007-11-18 22:27:40 +00:00
b0f991b43c only popup file selection if torrent has more than 1 file 2007-11-18 22:20:22 +00:00
61a4842bed remove remap 2007-11-18 22:09:21 +00:00
06eaabc45f update desktop file 2007-11-18 19:42:46 +00:00
553bdcc3a6 remove lsd...damnit 2007-11-18 09:17:55 +00:00
3eab9473bf lt fix 1737 2007-11-18 09:10:23 +00:00
3a77185e1e reanable lsd with custom fix to lt 2007-11-18 05:18:12 +00:00
63fa4601fb force recheck fix 2007-11-18 04:49:25 +00:00
77f6be5aac disable lsd 2007-11-18 04:30:18 +00:00
f5f7f04e1e fix lsd 2007-11-18 04:13:41 +00:00
8e22078402 fixes for gcc-4.3 2007-11-18 02:16:31 +00:00
d0d2e59192 fix last oops 2007-11-18 00:37:30 +00:00
b793646437 use sysconfig for libdir 2007-11-18 00:35:52 +00:00
51eceeae3a redo -mt detection 2007-11-18 00:09:48 +00:00
dba9a65749 remove separate libtorrent comment 2007-11-17 20:47:46 +00:00
bbbc8024e5 fix for opensuse 10.3 being retarded 2007-11-17 20:13:00 +00:00
989abbc531 multiple torrents update tracker 2007-11-17 19:53:56 +00:00
dc2f24344c asio sync 2007-11-17 12:22:22 +00:00
732c3d8674 lt sync 1732 2007-11-17 11:45:19 +00:00
4ff0a04608 disable lsd for now 2007-11-17 11:39:05 +00:00
1163096a70 remove abort 2007-11-17 11:21:09 +00:00
e47f0a756e remove locations plugin 2007-11-17 10:46:59 +00:00
709b2a04a3 tweaks to shutdown 2007-11-17 10:29:31 +00:00
94a159a66f remove uneffective hide 2007-11-17 09:58:52 +00:00
de8b55c9ed fix plugins on restart 2007-11-17 09:15:08 +00:00
85f9b8bf41 more scheduler fixes/tweaks from ben 2007-11-17 09:12:12 +00:00
0c83ffc391 code cleanup on advanced progress bar and clear adv bar on torrent removal 2007-11-17 09:10:24 +00:00
0c5c099097 save plugin state on plugin enable/disable, instead of on shutdown. remembers active plugins in case of a crash 2007-11-17 08:14:27 +00:00
e4ab021d20 set proper transient for other speed dialog 2007-11-17 07:55:44 +00:00
e21da8636e tweak remap dialog size 2007-11-17 05:57:51 +00:00
f40e5522bd cleanup 2007-11-17 04:12:41 +00:00
7e175dd4c0 remap files update 2007-11-17 03:21:34 +00:00
b764486bff deal with blank trackers in force recheck and between sessions 2007-11-16 20:56:50 +00:00
5a90e14794 edit empty trackers fix 2007-11-16 20:11:58 +00:00
2a8d36029e Fix memory leak. 2007-11-16 08:27:34 +00:00
052894e805 readd advanced progress bar and beginnings of remap_files 2007-11-16 08:08:33 +00:00
0b582261ec lt sync 1727 2007-11-16 00:52:10 +00:00
b95e3c4988 hopefully fix shutdown hang and tweak win compile 2007-11-15 04:38:35 +00:00
abc9534f7f Add --config switch to specify the config directory on startup. Patch
from slurdge.
2007-11-14 23:40:05 +00:00
2b519730bc remove remnant of adv progress bar 2007-11-14 02:07:20 +00:00
edfd988cf9 add torrent in paused state option 2007-11-13 23:15:17 +00:00
f7a1db3be7 remove advanced progress bar 2007-11-13 20:30:55 +00:00
de2f265c2a update todo 2007-11-13 04:33:57 +00:00
97f2f244ae fixes to scheduler from ben 2007-11-13 03:18:44 +00:00
c4c8539401 small ui tweaks 2007-11-12 22:43:45 +00:00
fced9a2c71 dont crash on empty tracker list 2007-11-12 22:39:59 +00:00
ebe0ac39d9 update todo 2007-11-12 22:23:26 +00:00
2e86ebc6ee copy translator credits from launchpad to our about->credits 2007-11-12 21:59:54 +00:00
fd817f5e76 only show queue arrows if there are two or more torrents loaded 2007-11-12 19:59:46 +00:00
70b7c120bc scheduler revamp by ben klein 2007-11-12 08:37:20 +00:00
091b57d65f tweak webseed glade file 2007-11-12 07:36:00 +00:00
31b05cfaa9 tweak last 2007-11-12 06:25:19 +00:00
d7c7222d4f fix wizard not working if firstrun file is already created 2007-11-12 05:49:26 +00:00
efc8179261 cancels more async operations on shutdown 2007-11-11 20:55:48 +00:00
3400c444a8 adding add torrent in pause state to TODO 2007-11-11 03:37:14 +00:00
b6ff01e7c7 update pot file 2007-11-11 01:37:41 +00:00
89533158e6 revert back to delete m_ses and no abort 2007-11-11 00:20:06 +00:00
3eb3ab5b6b dont delete m_ses 2007-11-11 00:04:46 +00:00
812eeb024e revert queue 2007-11-10 19:57:51 +00:00
56e8db547c cleaning up tabs/spaces 2007-11-10 18:56:18 +00:00
6a51a4b9ed tweak last 2007-11-10 08:16:43 +00:00
d3fe619f11 fix queue oops 2007-11-10 08:12:23 +00:00
8886ee9a59 tweak adv progress bar border 2007-11-10 07:50:16 +00:00
5c75c5192f fix oops 2007-11-10 07:29:10 +00:00
e7a789e453 fix ident/tabs 2007-11-10 07:28:36 +00:00
6e58e5113f fix toolbar 2007-11-10 07:13:34 +00:00
2c48226cdc fix oops 2007-11-10 05:11:25 +00:00
d1f2aed58b add advanced progress bar option - modified extensively from patch by arnab 2007-11-10 05:10:28 +00:00
6da46bc546 Add separate preference for max downloading torrents and max seeding torrents 2007-11-10 02:46:27 +00:00
b645417689 tweak save_upmem 2007-11-09 22:32:18 +00:00
da9bf950a7 remember file priorities in force recheck 2007-11-09 21:54:10 +00:00
4e8d9b6e6d tweak shutdown 2007-11-09 21:07:14 +00:00
576b81e910 clean force recheck 2007-11-09 20:36:02 +00:00
24b6def6bd little code cleanup 2007-11-09 01:12:42 +00:00
1f24972c9d use lazy_bitfield 2007-11-08 22:13:47 +00:00
14c34684dc change force recheck to redo 2007-11-08 07:41:11 +00:00
1bc07d2d8e add total seeding torrents to todo 2007-11-08 07:28:29 +00:00
8bf1c1e60a fix recheck oops 2007-11-08 04:22:39 +00:00
8b13d85bdc fix queue 2007-11-08 04:21:34 +00:00
4eb0e558a8 update changelog 2007-11-08 03:18:43 +00:00
2dfb02e062 fix eta from going backwards 2007-11-08 03:17:26 +00:00
92c9d28d0c call it peer exchange, not utorrent peer exchange 2007-11-08 03:07:27 +00:00
554ad73aa1 tweak glade file 2007-11-08 03:05:03 +00:00
d94694fc73 add local discovery of peers 2007-11-08 02:44:22 +00:00
e2e507b94b warning fix 2007-11-07 03:09:42 +00:00
8d6b749a5d add flex to changelog 2007-11-07 02:00:04 +00:00
23c83e6bb1 again 2007-11-07 01:06:36 +00:00
6d70add980 tweak shutdown 2007-11-07 00:24:23 +00:00
6b3065d2cf sync webui 127 2007-11-06 23:34:23 +00:00
047a32ef9f testing some shutdown tweaks 2007-11-06 22:27:07 +00:00
ab9a3f778f cia test 2007-11-06 22:05:34 +00:00
179b5f8c55 add hd warning to changelog 2007-11-06 21:32:15 +00:00
f9e5157d6e ui warning of out of hd space 2007-11-06 21:30:12 +00:00
86732c72d0 get duplicate error again 2007-11-06 21:04:34 +00:00
09798cd394 raise error 2007-11-06 20:46:11 +00:00
0998506f9f make gtk-stock strings not translatable 2007-11-06 20:19:37 +00:00
5f21c9d276 try to solve unicode problem 2007-11-06 19:24:26 +00:00
8050c3f8a6 add torrent notification plugin as default 2007-11-06 08:20:40 +00:00
4b21cc6bf1 add ratio fix to changelog 2007-11-06 04:20:42 +00:00
c244b29a03 tweak changelog 2007-11-06 04:16:37 +00:00
9ac2b85068 fix queue in force recheck 2007-11-06 04:09:40 +00:00
5383d6d197 remove debug print 2007-11-06 03:45:19 +00:00
9b170fe759 remove stupid raise 2007-11-06 03:38:44 +00:00
a624ff5557 tweak uploaded memory in force-recheck 2007-11-06 02:51:23 +00:00
1d36020f9d make force-recheck remember trackers and upload memory 2007-11-06 02:25:21 +00:00
cdb6450d48 remove unneeded code 2007-11-05 23:42:00 +00:00
ca51b3eeff tweak to get uid after force recheck 2007-11-05 23:33:47 +00:00
b48956397f update todo 2007-11-05 23:30:34 +00:00
319bc25cd5 manual force-recheck 2007-11-05 22:34:05 +00:00
e202a79dc3 update lang for last 2007-11-05 17:19:01 +00:00
63ac691e64 remove simplerss and add flexrss 2007-11-05 17:17:30 +00:00
a769af2262 add progress bar to todo 2007-11-05 01:32:49 +00:00
0dcc01c942 implement autoload directory preference 2007-11-05 01:05:34 +00:00
580d2a2e84 add preference for torrent files location 2007-11-04 23:55:37 +00:00
91d8ad33ae add error management to blocklist plugin 2007-11-04 22:33:55 +00:00
67e79250d2 piece picker assert fix 2007-11-04 21:32:07 +00:00
0898680adc lt update 1719 2007-11-02 23:43:09 +00:00
b64bbf1e76 tweak bindings 2007-11-02 22:24:52 +00:00
330b4c2115 no need to save config here since interface does it before passing it over 2007-11-02 21:25:14 +00:00
8adff80407 fix plugin oops 2007-11-02 20:40:26 +00:00
a09c03dafd quicker window shutdown 2007-11-02 20:00:58 +00:00
3610c30a25 minor tweak 2007-11-02 19:53:18 +00:00
9ecb8a388d revert libtorrent updates 2007-11-02 19:08:15 +00:00
3733b91d32 fix ratio and remember trackers 2007-11-02 18:33:37 +00:00
b144525cab lt exception tweaks 1719 2007-11-02 02:29:33 +00:00
2eec0a766d lt sync 1717 2007-11-02 00:49:26 +00:00
b3cdf1371c use full alloc 2007-11-01 22:40:04 +00:00
bd8329e971 only set_icon when not in windows 2007-11-01 22:32:46 +00:00
3c94a2039d fix dos format 2007-11-01 05:49:06 +00:00
c446d60ecd fix minor oops 2007-10-31 11:40:56 +00:00
3ab044409f fixing up libtorrent and tagging 0.5.6.2 2007-10-31 07:49:48 +00:00
5ad442341f use try in case pygame isnt installed 2007-10-31 05:46:49 +00:00
a4373ef156 use try in case pynotify isnt installed 2007-10-31 05:45:07 +00:00
9604c3ff09 update changelog 2007-10-31 04:23:37 +00:00
64aeb867a4 make sound not sensitive on windows 2007-10-31 03:52:55 +00:00
99065bf452 webui sync 117 2007-10-31 03:46:36 +00:00
2a9455e50a lt sync 1710 2007-10-31 02:00:53 +00:00
15d39eeb54 fix total_size 2007-10-29 23:41:44 +00:00
cf2c4a50f4 webui sync 115 2007-10-29 20:01:37 +00:00
054f7e5721 fix max upload for 256k 2007-10-29 05:46:49 +00:00
6520e618c2 forget reloading saved trackers 2007-10-29 03:54:09 +00:00
c059d5162b sync asio 2007-10-29 03:10:12 +00:00
9b59c0507e fix hang on shutdown 2007-10-29 01:01:48 +00:00
4cca79c764 2007-10-29 00:16:42 +00:00
2bac676de7 update todo 2007-10-28 23:20:44 +00:00
f21eb1c3f4 Fix plugin sub-dir code to work in Windows. 2007-10-28 10:34:40 +00:00
925416dded try to fix persistent.state pooping 2007-10-28 02:00:47 +00:00
cd2f45da92 sync webui 112 and translate 2007-10-28 01:35:27 +00:00
019ea1f601 make webui name/description translatable 2007-10-28 00:55:43 +00:00
2949ab545d fix crash on exit 2007-10-27 22:07:57 +00:00
3ed1de43c2 fix bug which made set_max_connections not work 2007-10-27 21:22:54 +00:00
902e8a2526 lt sync 1900 2007-10-26 20:28:03 +00:00
dead0864ad better way to show number of connections 2007-10-26 20:10:29 +00:00
9bd76e077a update changelog 2007-10-26 03:20:43 +00:00
eec0be17f9 add piece size 2048 and make default piece size 256kb 2007-10-26 03:19:30 +00:00
0a0183b0b9 add description to about dialog 2007-10-26 02:56:52 +00:00
d320f2aebe update todo for 0.5.7 2007-10-26 01:48:00 +00:00
38471aa832 upnp/lsd/natpmp fixes 1699 2007-10-26 01:38:04 +00:00
4bb1f06fd3 lt sync 1694 2007-10-25 22:20:56 +00:00
cbeb2c6e6c add new languages 2007-10-25 22:20:38 +00:00
2b12b10f8c update version numbers in trunk 2007-10-25 01:15:46 +00:00
557d90987c dont show 0.0kbps by Arnab 2007-10-25 01:10:20 +00:00
dbbace5f23 piece picker priority fix 2007-10-24 00:30:21 +00:00
a534f23661 update webui version num and add missed file 2007-10-23 22:30:37 +00:00
a28e33b809 sync with webui rev87 2007-10-23 22:16:37 +00:00
ac00fef1d4 only replace tracker if handle is valid 2007-10-23 22:14:22 +00:00
f436cbff64 hopefully fix segfault 2007-10-23 22:02:15 +00:00
74e5e49ee1 try to catch replace trackers error 2007-10-23 20:51:15 +00:00
1bf007907c tweak last attribute except 2007-10-23 07:35:23 +00:00
0bec032638 fix last 2007-10-23 06:49:27 +00:00
d17f6ee274 fix attribute error 2007-10-23 06:45:21 +00:00
571ecbdfac have name column expand 2007-10-23 06:35:46 +00:00
92c4adc4c1 sync language files with launchpad for release 2007-10-23 03:36:01 +00:00
80f941a249 tweak ratio fix 2007-10-23 03:32:58 +00:00
c04ae40cf1 catch attributeerror to fix upgrade issue 2007-10-23 03:26:28 +00:00
3eacd3e2d6 remove unnecessary eval 2007-10-23 03:10:04 +00:00
7d680bdd3a ratio fix 2007-10-23 02:43:21 +00:00
79e9e1de53 fixed issue when calling close on an uninstantiated variant_stream + variant_stream cleanup (removed unncessesary templates) 2007-10-22 23:56:03 +00:00
5d4a69d852 lt sync 1688 2007-10-22 22:33:08 +00:00
2e5eb2b885 try to fix a race condition 2007-10-22 20:35:32 +00:00
f2c036650c fix deleting of subfolders 2007-10-21 00:51:13 +00:00
0b4b409a53 fix edited tracker list not being persistent 2007-10-20 23:37:36 +00:00
58be40da1e set some fields as insensitive which arent valid on win32 2007-10-18 23:25:26 +00:00
589c007386 windows tweaks to prevent error on win32 2007-10-18 23:15:52 +00:00
c70721aeac fix for some invariant checks 2007-10-18 06:19:20 +00:00
1ddbf05b92 set file browser fields in deluge's preferences insensitive when in win32 2007-10-17 03:17:59 +00:00
cc77df8216 make torrentfile pref field insensitive when on win32 to avoid confusing windows users 2007-10-17 03:12:26 +00:00
5fb1987b1b collect network information when not in the networkgraph plugin tab 2007-10-17 02:54:05 +00:00
aef72f74a2 2007-10-16 17:05:25 +00:00
3dc0b25876 win32 translations fix 2007-10-16 16:48:26 +00:00
d07d25e189 fix fastresume oops 2007-10-16 02:26:49 +00:00
664877a7e6 update changelog 2007-10-16 01:23:29 +00:00
9d75b5f306 fix fastresume 2007-10-16 01:18:08 +00:00
891a9955ad oops value switch 2007-10-16 01:13:58 +00:00
8444cb852c have thread/process selection inactive until fixed. now we automatically choose which method based on platform 2007-10-16 01:12:50 +00:00
20f580014b sync lang 2007-10-15 21:21:26 +00:00
382f4b0f1a remove no longer needed alert 2007-10-15 19:37:17 +00:00
8f030fb112 fixed issue with failing async_accept on windows 2007-10-15 19:34:24 +00:00
1690fd846b intrusive_ptr_base fix 2007-10-15 18:09:24 +00:00
871d0d15c6 fix webui kill if already running 2007-10-15 17:03:46 +00:00
27d7e80658 clarify popup message 2007-10-15 15:50:24 +00:00
dad79748fa catch exception in last 2007-10-15 15:02:56 +00:00
3169b460f0 remove fastresume after adding torrent that's not a seed 2007-10-15 13:22:27 +00:00
b403530fab fast reconnect fixes 2007-10-15 05:34:32 +00:00
7d98d49803 account for xp, which has a higher half-open allotment 2007-10-15 01:53:42 +00:00
f20d0485c3 windows sucks. vista home has a limit of 5 half-open connections, so we set our windows limit to 4 to be save 2007-10-15 01:40:37 +00:00
3fd9a0dc05 fix links/enclosures 2007-10-15 01:36:32 +00:00
715874df58 tweak last 2007-10-15 00:20:48 +00:00
87fe5fe4ad fix start/stop 2007-10-15 00:14:01 +00:00
b6dd803a95 really kill 2007-10-14 23:26:55 +00:00
30b5967f12 if already running on init, kill 2007-10-14 23:07:20 +00:00
f54f2a50ec make default run in thread if in windows and default not in thread if not in windows 2007-10-14 21:48:40 +00:00
3947a75336 fix module error 2007-10-14 20:27:32 +00:00
71a5c79c15 tweak another total_done to total_wanted_done 2007-10-14 19:47:56 +00:00
dbe83d4ede make sure we only accept folders as plugins 2007-10-14 17:35:08 +00:00
375a7fdc64 Fix CONFIG_DIR issues on windows when ~ does not expand. 2007-10-14 13:42:58 +00:00
528e8c7625 rename up/down limits 2007-10-14 05:53:50 +00:00
b612f3663f re-add ratio to todo 2007-10-14 05:49:24 +00:00
ce8e47fae3 apply scheduler prefs onload 2007-10-14 04:51:05 +00:00
e4f5d822de use total_wanted instead of total_size in checking free space 2007-10-14 04:46:11 +00:00
20ffbf122e remove plugins and preferences from tray menu 2007-10-14 04:31:06 +00:00
7585642a98 apply_prefs in locations plugin 2007-10-14 04:08:16 +00:00
fe67907a5d add progress bars to files plugin - yobbobandana 2007-10-14 03:55:53 +00:00
7fa861f83a update changelog 2007-10-14 02:38:02 +00:00
0a6d638c59 add popup warning for clear :p 2007-10-14 02:34:57 +00:00
c14d4dd23a rename clear button 2007-10-13 23:33:26 +00:00
0eb88197c7 use libtorrent to remove files, which solves the problem of us deleting files that werent part of the torrent and other minor issues 2007-10-13 23:23:44 +00:00
a7868ed3fd revert upload memory change for now 2007-10-13 18:30:12 +00:00
a1d757dfbf tweak default path 2007-10-12 20:48:47 +00:00
1251a671bd add missing bracket 2007-10-12 18:39:04 +00:00
6e4528875e scheduler todo 2007-10-12 16:59:31 +00:00
734fa157b4 fixed so that peers only get one fast-reconnect 2007-10-12 01:30:10 +00:00
370578119e hopefully fix 'losing' port in windows 2007-10-12 00:35:05 +00:00
3a23ad301a asio sync 2007-10-11 19:22:07 +00:00
8687aab7b6 association done 2007-10-11 18:05:34 +00:00
81861afa64 windows association 2007-10-11 06:11:48 +00:00
30d357d797 save uploaded_memory every minute 2007-10-11 03:47:40 +00:00
106e98a15b new 0.5.x todo file 2007-10-11 03:28:23 +00:00
991467790b fix indent oops 2007-10-10 19:49:45 +00:00
5a813106ba fix typo 2007-10-10 19:43:03 +00:00
daaa79360a fix priority...hopefully 2007-10-10 16:26:19 +00:00
dabe429108 tooltip tweak 2007-10-10 05:11:29 +00:00
ff2483af90 parole mode improvement. Doesn't clear out the request queue when choked by a peer on parole anymore 2007-10-10 02:39:01 +00:00
a45c49d037 fix deconstructor order issue 2007-10-10 02:14:01 +00:00
a54432d0cf again 2007-10-10 02:06:13 +00:00
8464c9c0f6 small tweak to deluge_core max_half_open 2007-10-10 02:03:34 +00:00
94ca1789d5 add max half-open connections 2007-10-10 01:56:05 +00:00
7196070f59 updating changelog 2007-10-10 01:29:08 +00:00
bd02f837bb first attempt at switching over to new storage allocation 2007-10-09 21:22:42 +00:00
4ff8458b3f tweak file manager drop down 2007-10-08 21:21:52 +00:00
4de4fce8ec another vista try 2007-10-08 19:24:31 +00:00
ad239210dd stderr/stdout win32 2007-10-08 16:57:00 +00:00
4892cf3df2 fix last 2007-10-08 16:37:32 +00:00
df158d88cb tweak again 2007-10-08 03:41:06 +00:00
a0031240fb fix tooltip 2007-10-08 03:33:53 +00:00
54f0e6b91f fixed dead lock and fixed a problem in recent shutdown cleanup 2007-10-07 23:54:04 +00:00
a21b852e07 multiple sizes in ico file 2007-10-07 23:45:01 +00:00
fc12ade03a account for '-1', oops 2007-10-07 22:47:24 +00:00
1addf2541a speedlimiter fixes 2007-10-07 22:38:28 +00:00
d8482a3fc9 better shutdown sequence in lt 2007-10-07 21:03:25 +00:00
bf8727f7bf webui rev-80 2007-10-07 04:56:01 +00:00
278c6c9f3e fixes files that were left open in write mode by mistake, policy invariant check fix, fixed static assert being hit 2007-10-07 03:41:56 +00:00
cd175ebe9a libtorrent build fix 2007-10-06 17:32:41 +00:00
5541700881 increase width a little so larger fit a bit better 2007-10-06 05:37:54 +00:00
19621315c6 lt sync 1649 2007-10-06 04:22:06 +00:00
1489ef5bc0 i need coffee 2007-10-05 21:29:29 +00:00
a335153e0e rename error 2007-10-05 21:25:48 +00:00
a90069b5d0 backslashes should not be needed, since the we're using expanduser in conjunction with specifying a dir ('deluge') after it 2007-10-05 21:22:56 +00:00
24fbfccfb0 webui-rev73 2007-10-05 21:16:46 +00:00
20d63448cb webui rev 57 2007-10-04 21:49:29 +00:00
b8a8757076 fix storage of banned peers lt 1645 2007-10-04 21:14:32 +00:00
c80a2e822b lt 1643 2007-10-04 15:31:23 +00:00
d6fb920382 accidentaly reverted disk io priority fix, so here it is again 2007-10-04 00:09:45 +00:00
4e5a6d61dc moved block_downloading_alert, block_finished_alert and piece_finished_alert to debug level...yay performance 2007-10-04 00:07:26 +00:00
53f4a55711 disk io priority fix 2007-10-03 22:46:30 +00:00
3273dddb8a fix http connection and storage bug 2007-10-03 22:24:22 +00:00
d55fff555c storage fix 2007-10-03 18:33:32 +00:00
9ed93af6b2 handles case where a request in the allow fast set is rejected and saves banned peers in resume data 2007-10-03 18:08:17 +00:00
b2ae9f1db1 revert last webui 2007-10-03 02:40:30 +00:00
3211dc9019 fixed potential race condition when removing a torrent that was just added 2007-10-03 01:58:50 +00:00
8fa2f73434 webui rev 64 update 2007-10-03 00:05:09 +00:00
5cda3e71fa fix policy bug 2007-10-02 23:09:04 +00:00
a101b4c1c9 policy now has a map of peers instead of a flat list, makes it more efficient to do lookups 2007-10-02 19:58:10 +00:00
13a0630875 windows fixes for lt 2007-10-01 22:56:48 +00:00
7b5fb39d7f fix for boost 1.33.1 in last commit 2007-10-01 08:59:16 +00:00
2e0d50407b lt sync 1623 2007-10-01 08:46:09 +00:00
e833a2d75e remove regex dep since asio requirement for it has been removed 2007-10-01 07:31:04 +00:00
190a2de73e remove unneeded asio files 2007-10-01 07:30:20 +00:00
563c437675 add new boost regex dependency 2007-10-01 07:18:48 +00:00
5bb79f682c update list of files to be translated 2007-10-01 06:09:08 +00:00
107b044fba remove invalid inline 2007-10-01 02:23:38 +00:00
fa9bf5afc8 add valid fast check 2007-10-01 02:20:03 +00:00
fd7140b15e add key and unlimited notice 2007-10-01 01:45:33 +00:00
6445d1cc26 tweak glade file 2007-09-30 23:48:39 +00:00
2e398cb212 fix scheduler plugin 2007-09-30 22:27:08 +00:00
47fe9bd11f set parent for add torrent dialog 2007-09-30 21:13:37 +00:00
b9f543682b remove unneccessary import 2007-09-30 19:56:34 +00:00
3de1cb9938 sync lt and asio 1615 and upload version # of plugin 2007-09-30 18:32:19 +00:00
c0d8bf2d7f fix tray password resetting itself sometimes 2007-09-30 09:12:38 +00:00
999e18e4be update changelog 2007-09-30 08:54:09 +00:00
45f5fef825 encrypted passwords for tray lock with backwards compatibility for old method to ease upgrade 2007-09-30 08:52:56 +00:00
5d62060bd8 sync webui to rev56 2007-09-30 08:20:14 +00:00
b16930ea4c clean up adding via url and make enter submit it instead of having to click ok 2007-09-30 03:49:30 +00:00
1d8b9cb402 fix windows_check() 2007-09-29 07:01:26 +00:00
53e65e9554 sync webui plugin with rev48 2007-09-29 06:39:06 +00:00
9a050065a9 - 2007-09-28 01:50:21 +00:00
72d868ff79 WebUi Plugin - rev40 2007-09-28 01:47:12 +00:00
d36ec723ac modification to setup.py to allow for subdirs in plugins 2007-09-28 01:45:17 +00:00
0858836a67 modification to setup.py to allow for subdirs in plugins 2007-09-28 01:45:03 +00:00
b02ef923ff again 2007-09-27 16:26:44 +00:00
918da976cb explorer fix 2007-09-27 16:24:40 +00:00
c4b5101189 patch for slurdge 2007-09-27 14:40:39 +00:00
e74c62d307 handle launching explorer on windows a bit better 2007-09-27 07:56:28 +00:00
283f30f884 add double-click torrent to changelog 2007-09-27 03:55:22 +00:00
691cf5b34f double-click on torrent opens up containing folder and fix about dialog 'bug' on windows 2007-09-27 03:54:12 +00:00
e4effa22b1 fix enc level order 2007-09-27 03:01:25 +00:00
ed33fa1eb6 update changelog 2007-09-27 01:40:27 +00:00
c1d3fbc3f3 deal with windows systray limitation 2007-09-27 01:25:18 +00:00
2738bb2835 remove wrong space 2007-09-26 21:46:11 +00:00
71809e968c use cPickle 2007-09-26 20:19:18 +00:00
8b35caa3c8 country fix 2007-09-26 20:15:46 +00:00
2c1bed04ca Revert last commit. Did not build. 2007-09-26 11:18:34 +00:00
6bcafc02e3 country optimization 2007-09-26 07:13:04 +00:00
5d4931c94b save fastresume on pause 2007-09-25 21:07:12 +00:00
9ac92ca982 remove fastresume file when a torrent is unpaused 2007-09-25 21:02:22 +00:00
8a723474ed bdist_rpm fixes 2007-09-25 19:32:56 +00:00
4d05a9dfc9 temp fix to prevent plugin from crashing deluge 2007-09-25 15:36:14 +00:00
c3e960aa86 fixes problem with torrents that have a name.utf-8 entry 2007-09-24 19:38:27 +00:00
33a99c140e Change directory to that of the .exe if in Windows. 2007-09-24 10:37:14 +00:00
44240b194e lt tracker request url ampersand fix, endpoint to string conversion fix. 1602 2007-09-23 23:45:41 +00:00
b209d268f2 fix icon path 2007-09-23 08:18:20 +00:00
f5868df3ad ipv6 fix, race condition fix, varient_stream fixes 2007-09-22 17:50:59 +00:00
f62bf99941 fix various py_none returns 2007-09-21 20:29:40 +00:00
ddc1ee6295 enum fixes and ipv6 update 2007-09-20 16:28:41 +00:00
f673833fe9 proper path to try to fix windows bug #6 2007-09-19 21:01:06 +00:00
cd10e9bbaa many fixes in libtorrent sync 1586 2007-09-19 20:39:29 +00:00
760acc8f30 more asserts to bandwidth limiter 2007-09-19 02:45:29 +00:00
25146891ff disable loopback for upnp 2007-09-18 02:33:04 +00:00
a93c236e0e libtorrent upnp fix, compilation fix 1577 2007-09-17 19:48:16 +00:00
4fbef5d94a update changelog 2007-09-17 10:36:41 +00:00
2037ceba69 again, to prevent upgrade problems, disable torrentpieces from being shown as available 2007-09-17 10:36:09 +00:00
3e5ad3e60d disable torrent pieces plugin from loading to prevent upgrade problems now that its been removed 2007-09-17 10:30:29 +00:00
a026f0472d update changelog 2007-09-17 10:24:42 +00:00
9d85580029 pause torrent before move and resume afterwards 2007-09-17 09:55:48 +00:00
e4e4ded874 move pause code in blocklist plugin 2007-09-17 03:56:42 +00:00
dcfb14d7e5 piece picker fix 1568 2007-09-17 01:13:06 +00:00
3f89fd2753 libtorrent sync 1567, for many fixes, including upnp and run conditions 2007-09-16 07:56:11 +00:00
2e461091dd clean up statvfs 2007-09-15 15:51:19 +00:00
82e7eb2e32 Add licenses for libtorrent and asio. 2007-09-15 07:21:34 +00:00
444ac9ec99 add windows notice 2007-09-14 22:42:07 +00:00
36cd2cda98 again 2007-09-14 22:30:00 +00:00
389f9d94a2 fix last, oops 2007-09-14 22:27:36 +00:00
63e4724a8c add warning for failed launch in win32 2007-09-14 22:23:38 +00:00
dc71d16ac1 add try/except for startfile 2007-09-14 22:18:06 +00:00
491e7ea0d6 window tweak for torrentfiles 2007-09-14 22:13:09 +00:00
da60769933 windows tweaks 2007-09-14 22:09:44 +00:00
ccf5f91dc2 again 2007-09-14 19:28:06 +00:00
05b105276e tweak last 2007-09-14 19:26:29 +00:00
eb7db72965 try to catch windows shutdown so we exit properly and dont lose data 2007-09-14 19:21:55 +00:00
47cac3dc4a add basic vista support 2007-09-14 19:08:01 +00:00
c1e4364c1d i like pie 2007-09-14 18:29:57 +00:00
7ad2b9ec6a change for building on windows 2007-09-14 18:26:53 +00:00
4bc18ed940 Fix deprecated add_torrent() method call. 2007-09-14 06:53:24 +00:00
ff073dc4fb fix race condition (rev 1561) 2007-09-14 03:09:05 +00:00
b7f0447228 reupping asio and some lt fixes 2007-09-12 22:43:51 +00:00
b0fdc2fab8 upnp on by default 2007-09-12 22:11:50 +00:00
c857b1fbbf upnp fixes 2007-09-12 21:37:33 +00:00
08ea29aa4c only kill our daemon, not potentially others...unlikely as it may be 2007-09-12 20:55:51 +00:00
0d356ff79a peers and files on my default 2007-09-12 03:14:41 +00:00
bd5cd655a1 remove torrentpieces. blah 2007-09-12 02:55:51 +00:00
116c79ba3f cleanup and kill dbus-daemon on close when in win32 2007-09-12 01:42:37 +00:00
63501ebe5b increase the maximum buffer size on bottled http_requests 2007-09-11 22:37:58 +00:00
f4bd67c320 pause torrents during blocklist loading and then resume the ones that werent paused to begin with 2007-09-11 21:55:49 +00:00
d793835a7e add try/except to catch crash if the plugin configuration window is closed 2007-09-11 21:27:50 +00:00
120b3335b4 tweaks so torrentnotification plugin doesnt crash win32 client 2007-09-11 19:20:41 +00:00
4c5a53b982 cut unnecessary import 2007-09-11 01:16:29 +00:00
ca4305c0a9 cleaning up win32 calc_free_space 2007-09-11 01:13:17 +00:00
c2b3109d0a make calc_free_space work with win32 2007-09-10 23:13:21 +00:00
f880a05e14 again 2007-09-10 21:26:21 +00:00
fd5f99630f fix last 2007-09-10 21:24:17 +00:00
5929d1ad53 install path for windows 2007-09-10 21:22:10 +00:00
c6cb4a20c8 listen port refactoring 2007-09-10 20:52:42 +00:00
c2b9a5eaaa listen port tweak 2007-09-10 17:15:48 +00:00
dcf3cac453 clarify lack of svg use in win32 2007-09-10 17:00:04 +00:00
aef7f31f5c changelog updates 2007-09-10 16:44:44 +00:00
6064706d6c windows build touchups 2007-09-10 16:44:35 +00:00
f2e78f407c freebsd build fix 2007-09-10 16:44:04 +00:00
10a34b0951 deal with windows icons 2007-09-10 09:59:12 +00:00
f7039bdc0a i need sleep 2007-09-10 09:23:36 +00:00
aff7718e21 add ico to ease future packaging 2007-09-10 09:21:25 +00:00
889a025396 add file 2007-09-10 09:19:41 +00:00
1ef898ba37 add missing file 2007-09-10 08:52:32 +00:00
9a18581b20 merge in win32 changes to setup file 2007-09-10 08:51:21 +00:00
8b7419eb51 set half open connections to 8 on windows 2007-09-10 08:48:18 +00:00
02720ddcd9 libtorrent various fixes including upnp 2007-09-10 06:46:41 +00:00
47e47ac9cc use theme for tray icon, not hard-coded 2007-09-09 20:46:59 +00:00
93f928baac update dependencies 2007-09-09 16:02:52 +00:00
af4c9c0ea8 Updated Scheduler plugin to work with current trunk. 2007-09-09 12:07:20 +00:00
8142c69e2a Revert last change as it doesn't seem to fix the issue. 2007-09-09 12:03:03 +00:00
f164cfd2cb Fix issue of port not being closed properly on exit. 2007-09-09 11:31:09 +00:00
af177749ff icon revamp for freedesktop.org specs and to use svg instead of png inside deluge 2007-09-09 01:06:29 +00:00
1abb7c161d session_impl and connection_queue fixes 2007-09-08 19:05:43 +00:00
1b6a8925eb tweak for win python bug 2007-09-08 18:47:31 +00:00
a91c00c247 move explorer to end of list to not mess up current pref settings 2007-09-08 01:32:35 +00:00
cfe44a3ad9 add ms explorer to file manager list 2007-09-08 01:30:03 +00:00
eac5b42336 remove no longer needed exec_deluge_command 2007-09-08 01:03:34 +00:00
f5951ef7b7 move update.py to common 2007-09-08 01:00:51 +00:00
83474930fd touchup 2007-09-07 22:21:05 +00:00
3aedc14399 move send info into common 2007-09-07 21:26:50 +00:00
de0f454879 use thread for browser calls 2007-09-07 21:02:22 +00:00
20bbb09f4f locales tweak 2007-09-07 09:38:53 +00:00
e8e6f5bd4b hide tray icon on close for the benefit of windows 2007-09-07 06:31:09 +00:00
58bcb2abb9 ticket #520 switch LC_ALL to LC_MESSAGES 2007-09-06 20:48:22 +00:00
402bd70816 asio sync with upstream 2007-09-06 20:27:50 +00:00
f8029692bf windows locale skipping 2007-09-06 20:07:12 +00:00
2ffbbe1eb8 more piece picker fixes for libtorrent 2007-09-06 19:36:40 +00:00
5c072322e3 piece picker fixes in libtorrent 2007-09-06 01:36:16 +00:00
5b57463125 remove incorrect assert 2007-09-05 22:50:57 +00:00
63621be3ee add private flag to torrentcreator 2007-09-05 17:35:44 +00:00
87d58cd0e1 firstlast fix by andar 2007-09-05 13:25:46 +00:00
1914cbea3e remove unneeded try 2007-09-05 01:43:55 +00:00
83042205ab pref for show 18px flag on by default 2007-09-05 01:29:59 +00:00
899dd558c9 libtorrent sync 1531 and alter deluge_core to deal with api changes in libtorrent 2007-09-04 19:51:15 +00:00
d7363ffb5f path fix 2007-09-04 18:12:16 +00:00
26dd7a83cf win config dir touchup 2007-09-04 16:57:04 +00:00
1ac7e0eaab prio range fix from andar 2007-09-04 16:40:40 +00:00
692cd471f1 xdg.BaseDirectory fix for windows 2007-09-04 16:34:58 +00:00
11f033db48 revert last until further testing 2007-09-04 07:13:06 +00:00
0e3f5672a5 libtorrent sync 1531 2007-09-04 04:01:19 +00:00
f1fde2dcf0 if statement for sighup in win32 2007-09-04 01:09:15 +00:00
9af94bda88 Fix typo in Wizard: 10mbit should have read 100mbit. 2007-09-03 11:33:27 +00:00
3f60aa4c73 changing version number of trunk to reflect next release 2007-09-03 09:16:00 +00:00
430 changed files with 115870 additions and 54076 deletions

127
ChangeLog
View File

@ -1,4 +1,129 @@
Deluge 0.5.5 (xx August 2007)
Deluge 0.5.8.1 (18 Januarary 2007)
* Catch various exceptions from possibly corrupted persistent.state
* Use pieces wanted instead of total pieces to draw adv progress bar
* Properly catch 'address already in use' error when trying to use a port that is in use
* Attempt to fix issue where all the columns start very small
* Change how we handle fastresume - should prevent rechecking
* New theme for windows
* Performance enhancements by removing needless casts
* Search is now a plugin
* Browser removed
Deluge 0.5.8 (29 December 2007)
* Fix handling of corrupt torrent files
* Fix having two instances of Deluge running on Ubuntu
Deluge 0.5.8RC2 (25 December 2007)
* Change add torrent to ctrl+n
* Change notification plugin to not show the file list, but only the torrent
name
* Allow removal of browser icon from toolbar
* Add buttons to browser to launch the main and footer frames into an
external browser
* Fix removing torrents from deluge template of webui - vonck7
* Set the advanced webui template as default
* Cut down significantly on the memory usage of the blocklist plugin
* Fix some UPnP bugs
* Fix "New version" alert from freezing sometimes
* Prioritizes local peers over non-local ones when finding connect
* Wish everyone a happy holiday :)
Deluge 0.5.8RC1 (22 December 2007)
* Key bindings:
ctrl+a adds a torrent
ctrl+l adds a torrent via URL
ctrl+p pauses torrent(s)
ctrl+r resumes torrent(s)
delete removes torrent(s)
* Fix total uploaded display bug
* Fix seeding ratio stop on finished torrents
* Fix zombie processes from occuring
* Fix saying goodbye to trackers
* Increase auto remove ratio to 100
* Fix problem on Windows with filenames that have special characters
* Fix saving of which columns to show
* Fix init script error on exotic systems
* Add web seed to Torrent Creator plugin
* TorrentSearch is now built-in
* Add internal anonymizing browser - Key bindings for that are as follows:
ctrl+l focus on location bar
ctrl+k focus on search bar
ctrl+r refreshes current page
ctrl+enter adds 'www.' and '.com' to url string
shift+enter adds 'www.' and '.net' to url string
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

View File

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

View File

@ -13,7 +13,7 @@ tarball:
mv dist/deluge-*.tar.gz $(DESTDIR)
install:
python setup.py install --prefix=$(PREFIX)
python setup.py install --prefix=$(PREFIX) && /usr/bin/update-desktop-database;
clean:
python setup.py clean

6
README
View File

@ -33,7 +33,11 @@ make
python-all-dev
python-all version >= 2.4
python-dbus
python-gnome2-extras
python-gtk2 version >= 2.9
python-notify
python-pyopenssl
librsvg2-common
python-xdg
python-support
libboost-dev >= 1.33.1
@ -48,7 +52,7 @@ But the names of the packages may vary depending on your OS / distro.
Once you have the needed libraries installed, build Deluge by running:
$ make
$ make
You shouldn't get any errors. Then run, as root (or by using sudo):

1
TODO Normal file
View File

@ -0,0 +1 @@

5
createicons.sh Executable file
View File

@ -0,0 +1,5 @@
#!/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,11 +2,12 @@
Version=1.0
Encoding=UTF-8
Name=Deluge BitTorrent Client
Comment=Bittorrent client written in PyGTK
GenericName=BitTorrent Client
Comment=A GTK BitTorrent client written in Python and C++
Exec=deluge
Icon=deluge.png
Terminal=false
Type=Application
Categories=Application;Network
Categories=Network;
StartupNotify=true
MimeType=application/x-bittorrent;

View File

@ -1,16 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.1.5 on Thu Feb 22 19:13:48 2007 by zach@notapowerbook-->
<!--Generated with glade3 3.4.0 on Mon Dec 3 09:53:08 2007 -->
<glade-interface>
<widget class="GtkAboutDialog" id="aboutdialog">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="border_width">5</property>
<property name="modal">True</property>
<property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
<property name="destroy_with_parent">True</property>
<property name="skip_taskbar_hint">True</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<property name="website"></property>
<property name="authors"></property>
<property name="translator-credits"></property>
<property name="documenters"></property>
<property name="artists"></property>
<child internal-child="vbox">

View File

@ -12,6 +12,12 @@
<property name="visible">True</property>
<property name="n_rows">4</property>
<property name="n_columns">3</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkVPaned" id="vpaned1">
<property name="visible">True</property>
@ -85,6 +91,22 @@
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="spacing">5</property>
<child>
<widget class="GtkViewport" id="advanced_progressbar">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkDrawingArea" id="custom_progress">
<property name="height_request">25</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>
<signal name="expose_event" handler="paint_customprogress"/>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkProgressBar" id="progressbar">
<property name="visible">True</property>
@ -93,6 +115,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
@ -102,277 +125,18 @@
<property name="n_columns">4</property>
<property name="row_spacing">5</property>
<child>
<widget class="GtkLabel" id="summary_total_downloaded">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_download_speed">
<widget class="GtkLabel" id="summary_availability">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_total_uploaded">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_upload_speed">
<property name="visible">True</property>
<property name="xalign">0</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>
<child>
<widget class="GtkLabel" id="summary_seeders">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_peers">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_share_ratio">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_eta">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Downloaded:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Uploaded:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment6">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Seeders:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment7">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Share Ratio:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment8">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Speed:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment9">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Speed:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</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="GtkAlignment" id="alignment10">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Peers:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</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>
<child>
<widget class="GtkAlignment" id="alignment11">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;ETA:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</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>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label12">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;Pieces:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</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>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="summary_pieces">
<property name="visible">True</property>
<property name="xalign">0</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="y_options"></property>
</packing>
</child>
<child>
@ -399,24 +163,283 @@
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_availability">
<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>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="summary_pieces">
<property name="visible">True</property>
<property name="xalign">0</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>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label12">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">1</property>
<property name="label" translatable="yes">&lt;b&gt;Pieces:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment11">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;ETA:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</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>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment10">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Peers:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</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>
<child>
<widget class="GtkAlignment" id="alignment9">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Speed:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</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="GtkAlignment" id="alignment8">
<property name="visible">True</property>
<property name="left_padding">15</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Speed:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment7">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Share Ratio:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment6">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Seeders:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Uploaded:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Downloaded:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="summary_eta">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"></property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_share_ratio">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_peers">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_seeders">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_upload_speed">
<property name="visible">True</property>
<property name="xalign">0</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>
<child>
<widget class="GtkLabel" id="summary_total_uploaded">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_download_speed">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary_total_downloaded">
<property name="visible">True</property>
<property name="xalign">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
</widget>
@ -463,6 +486,7 @@
<widget class="GtkLabel" id="summary_torrent_path">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -498,6 +522,7 @@
<widget class="GtkLabel" id="summary_total_size">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -532,6 +557,7 @@
<widget class="GtkLabel" id="summary_num_files">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -547,6 +573,7 @@
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -560,6 +587,7 @@
<widget class="GtkLabel" id="summary_tracker_status">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -593,6 +621,7 @@
<widget class="GtkLabel" id="summary_next_announce">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -629,6 +658,7 @@
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="wrap_mode">PANGO_WRAP_WORD_CHAR</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -740,7 +770,6 @@
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="reorderable">True</property>
</packing>
</child>
@ -751,7 +780,6 @@
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -859,7 +887,7 @@
<widget class="GtkImageMenuItem" id="menuitem6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">gtk-select-all</property>
<property name="label">gtk-select-all</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="select_all_torrents"/>
@ -1037,6 +1065,81 @@
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menuitem2_menu">
<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="tooltip" translatable="yes">Donate to Deluge Development</property>
<property name="label" translatable="yes">_Donate</property>
<property name="use_underline">True</property>
<signal name="activate" handler="launch_donate"/>
<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-yes</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem10">
<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">_Homepage</property>
<property name="use_underline">True</property>
<signal name="activate" handler="launch_homepage"/>
<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-home</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem11">
<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">_FAQ</property>
<property name="use_underline">True</property>
<signal name="activate" handler="launch_faq"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image9">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-dialog-question</property>
<property name="icon_size">1</property>
</widget>
</child>
</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">_Community</property>
<property name="use_underline">True</property>
<signal name="activate" handler="launch_community"/>
<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-info</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem5">
<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="menuitem3">
<property name="visible">True</property>
@ -1104,38 +1207,11 @@
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkToolbar" id="tb_right">
<property name="visible">True</property>
<property name="show_arrow">False</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>
<property name="x_options"></property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkToolbar" id="tb_middle">
<property name="visible">True</property>
<property name="show_arrow">False</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">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkToolbar" id="tb_left">
<property name="visible">True</property>
<property name="show_arrow">False</property>
<property name="icon_size">GTK_ICON_SIZE_SMALL_TOOLBAR</property>
<property name="icon_size_set">True</property>
<child>
<widget class="GtkToolButton" id="toolbutton_add">
<property name="visible">True</property>
@ -1166,7 +1242,7 @@
<child>
<widget class="GtkToolButton" id="toolbutton_clear">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Clear Finished Torrents</property>
<property name="tooltip" translatable="yes">Clear Seeding Torrents</property>
<property name="label" translatable="yes">Clear</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-clear</property>
@ -1189,7 +1265,7 @@
<widget class="GtkToolButton" id="toolbutton_resume">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="tooltip" translatable="yes">Start or Pause torrent</property>
<property name="tooltip" translatable="yes">Start or Resume Torrent</property>
<property name="label" translatable="yes">Resume</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-media-play</property>
@ -1203,6 +1279,7 @@
<widget class="GtkToolButton" id="toolbutton_pause">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip" translatable="yes">Pause Torrent</property>
<property name="label" translatable="yes">Pause</property>
<property name="stock_id">gtk-media-pause</property>
<signal name="clicked" handler="tor_pause"/>
@ -1273,6 +1350,15 @@
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkSeparatorToolItem" id="separatortoolitem1">
<property name="visible">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">False</property>
</packing>
</child>
</widget>
<packing>
<property name="top_attach">1</property>

View File

@ -1,11 +1,12 @@
<?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 Aug 8 23:27:43 2007 by markybob@peg-->
<!--Generated with glade3 3.4.1 on Sat Jan 5 23:06:01 2008 -->
<glade-interface>
<widget class="GtkDialog" id="remove_torrent_dlg">
<property name="title" translatable="yes">Remove Torrent</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</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>
@ -235,14 +236,13 @@
</child>
</widget>
<widget class="GtkDialog" id="speed_dialog">
<property name="app_paintable">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="border_width">5</property>
<property name="title" translatable="yes">Speed</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</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="skip_pager_hint">True</property>
<property name="decorated">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">

View File

@ -64,7 +64,7 @@
<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">gtk-cancel</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"/>
@ -81,7 +81,7 @@
<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">gtk-ok</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"/>

View File

@ -57,7 +57,7 @@
<child>
<widget class="GtkButton" id="button2">
<property name="visible">True</property>
<property name="label">gtk-cancel</property>
<property name="label" translatable="no">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
@ -65,7 +65,7 @@
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="label">gtk-ok</property>
<property name="label" translatable="no">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>

View File

@ -31,7 +31,7 @@
<child>
<widget class="GtkButton" id="button_cancel">
<property name="visible">True</property>
<property name="label">gtk-cancel</property>
<property name="label" translatable="no">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
@ -39,7 +39,7 @@
<child>
<widget class="GtkButton" id="button_ok">
<property name="visible">True</property>
<property name="label">gtk-ok</property>
<property name="label" translatable="no">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>

View File

@ -3,7 +3,7 @@
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkDialog" id="pref_dialog">
<property name="width_request">500</property>
<property name="width_request">516</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">5</property>
<property name="title" translatable="yes">Deluge Preferences</property>
@ -57,6 +57,7 @@
<property name="visible">True</property>
<property name="label" translatable="yes">Ask where to save each download</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
@ -65,7 +66,7 @@
<widget class="GtkTable" id="table3">
<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">1</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkRadioButton" id="radio_save_all_to">
@ -74,6 +75,7 @@
<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">Store all downloads in:</property>
<property name="label" translatable="yes">Store all downloads in:</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
@ -94,6 +96,32 @@
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label38">
<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="xalign">0</property>
<property name="label" translatable="yes">Store all torrent files in:</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkFileChooserButton" id="torrent_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>
<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>
</widget>
<packing>
<property name="position">1</property>
@ -120,6 +148,75 @@
<property name="padding">2</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame20">
<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>
<child>
<widget class="GtkAlignment" id="alignment34">
<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">12</property>
<child>
<widget class="GtkTable" id="table11">
<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">1</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkAlignment" id="alignment36">
<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="autoload_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="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_autoload">
<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">Autoload all torrent files in:</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label40">
<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">&lt;b&gt;Autoload&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame6">
<property name="visible">True</property>
@ -150,16 +247,22 @@
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_torrents">
<widget class="GtkAlignment" id="alignment35">
<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="xalign">1</property>
<property name="adjustment">-1 -1 1000 1 10 10</property>
<property name="climb_rate">1</property>
<property name="snap_to_ticks">True</property>
<property name="update_policy">GTK_UPDATE_IF_VALID</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="xalign">1</property>
<property name="adjustment">-1 -1 1000 1 10 10</property>
<property name="climb_rate">1</property>
<property name="snap_to_ticks">True</property>
<property name="update_policy">GTK_UPDATE_IF_VALID</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
@ -176,14 +279,38 @@
<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">Enable selecting files for torrents before loading</property>
<property name="label" translatable="yes">Enable selecting files for torrents before loading</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="toggle_ui"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment39">
<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">10</property>
<child>
<widget class="GtkCheckButton" id="chk_enable_multi_only">
<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">Enable selecting files for torrents before loading</property>
<property name="label" translatable="yes">Only show if torrent has more than 1 file</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_prioritize_first_last_pieces">
<property name="visible">True</property>
@ -191,12 +318,27 @@
<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">Prioritize first and last pieces of files in torrent</property>
<property name="label" translatable="yes">Prioritize first and last pieces of files in torrent</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_paused">
<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">Start torrents in paused state</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="position">4</property>
</packing>
</child>
</widget>
@ -218,7 +360,7 @@
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
<child>
@ -301,7 +443,7 @@
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
</widget>
@ -309,9 +451,6 @@
</widget>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label11">
@ -320,7 +459,6 @@
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -641,8 +779,8 @@
<widget class="GtkCheckButton" id="chk_utpex">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip" translatable="yes">µTorrent Peer-Exchange</property>
<property name="label" translatable="yes">µTorrent-PeX</property>
<property name="tooltip" translatable="yes">Peer Exchange</property>
<property name="label" translatable="yes">Peer Exchange</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="active">True</property>
@ -653,6 +791,19 @@
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="chk_lsd">
<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">Local Peer Discovery</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="position">3</property>
</packing>
</child>
</widget>
</child>
</widget>
@ -770,11 +921,18 @@ Forced</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="combo_enclevel">
<widget class="GtkAlignment" id="alignment37">
<property name="visible">True</property>
<property name="items" translatable="yes">Handshake
Either
Full Stream</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">7</property>
<child>
<widget class="GtkComboBox" id="combo_enclevel">
<property name="visible">True</property>
<property name="items" translatable="yes">Handshake
Full Stream
Either</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">6</property>
@ -818,7 +976,6 @@ Full Stream</property>
</widget>
<packing>
<property name="position">1</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -829,7 +986,6 @@ Full Stream</property>
<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>
@ -910,7 +1066,7 @@ Full Stream</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="xalign">1</property>
<property name="adjustment">0 0 10 0.050000000745099998 10 9</property>
<property name="adjustment">0 0 100 0.050000000745099998 10 9</property>
<property name="climb_rate">1</property>
<property name="digits">2</property>
<property name="snap_to_ticks">True</property>
@ -969,7 +1125,6 @@ Full Stream</property>
</widget>
<packing>
<property name="position">2</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -981,7 +1136,6 @@ Full Stream</property>
<packing>
<property name="type">tab</property>
<property name="position">2</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -1017,8 +1171,45 @@ Full Stream</property>
<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">4</property>
<property name="n_rows">6</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkSpinButton" id="spin_max_half_open">
<property name="visible">True</property>
<property name="can_focus">True</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="xalign">1</property>
<property name="adjustment">-1 -1 9000 1 10 10</property>
<property name="climb_rate">1</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">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment33">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="right_padding">10</property>
<child>
<widget class="GtkLabel" id="label39">
<property name="visible">True</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="xalign">0</property>
<property name="label" translatable="yes">Maximum Half-Open Connections:</property>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment18">
<property name="visible">True</property>
@ -1113,6 +1304,7 @@ Full Stream</property>
<property name="xalign">1</property>
<property name="adjustment">0 -1 9000 1 10 10</property>
<property name="climb_rate">1</property>
<property name="digits">1</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1130,6 +1322,7 @@ Full Stream</property>
<property name="xalign">1</property>
<property name="adjustment">0 -1 9000 1 10 10</property>
<property name="climb_rate">1</property>
<property name="digits">1</property>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1156,6 +1349,35 @@ Full Stream</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label43">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">The maximum number of connection attempts per second. A high value may crash some cheap routers. Set -1 for unlimited.</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Maximum Connection Attempts per Second:</property>
</widget>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_connection_speed">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip" translatable="yes">The maximum number of connection attempts per second. A high value may crash some cheap routers. Set -1 for unlimited.</property>
<property name="xalign">1</property>
<property name="adjustment">-1 -1 9000 1 10 10</property>
<property name="climb_rate">1</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
</widget>
</child>
</widget>
@ -1204,6 +1426,7 @@ Full Stream</property>
<widget class="GtkLabel" id="label31">
<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 per torrent. Set -1 for unlimited.</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Maximum Connections:</property>
</widget>
@ -1218,6 +1441,7 @@ Full Stream</property>
<widget class="GtkLabel" id="label33">
<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 per torrent. Set -1 for unlimited.</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Maximum Upload Slots:</property>
</widget>
@ -1287,7 +1511,6 @@ Full Stream</property>
</widget>
<packing>
<property name="position">3</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -1299,7 +1522,6 @@ Full Stream</property>
<packing>
<property name="type">tab</property>
<property name="position">3</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -1485,7 +1707,7 @@ HTTP W/ Auth</property>
<property name="sensitive">False</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">8080 0 10000 1 10 10</property>
<property name="adjustment">8080 0 65000 1 10 10</property>
</widget>
<packing>
<property name="left_attach">3</property>
@ -1680,7 +1902,7 @@ HTTP W/ Auth</property>
<property name="sensitive">False</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">8080 0 10000 1 10 10</property>
<property name="adjustment">8080 0 65000 1 10 10</property>
</widget>
<packing>
<property name="left_attach">3</property>
@ -1875,7 +2097,7 @@ HTTP W/ Auth</property>
<property name="sensitive">False</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">8080 0 10000 1 10 10</property>
<property name="adjustment">8080 0 65000 1 10 10</property>
</widget>
<packing>
<property name="left_attach">3</property>
@ -2070,7 +2292,7 @@ HTTP W/ Auth</property>
<property name="sensitive">False</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">8080 0 10000 1 10 10</property>
<property name="adjustment">8080 0 65000 1 10 10</property>
</widget>
<packing>
<property name="left_attach">3</property>
@ -2110,7 +2332,6 @@ HTTP W/ Auth</property>
</widget>
<packing>
<property name="position">4</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -2122,7 +2343,6 @@ HTTP W/ Auth</property>
<packing>
<property name="type">tab</property>
<property name="position">4</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -2149,6 +2369,7 @@ HTTP W/ Auth</property>
<property name="visible">True</property>
<property name="label" translatable="yes">Enable system tray icon</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
@ -2165,6 +2386,7 @@ HTTP W/ Auth</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">Minimize to tray on close</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
@ -2184,6 +2406,7 @@ HTTP W/ Auth</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">Start in tray</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
@ -2208,43 +2431,51 @@ HTTP W/ Auth</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Password protect system tray</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="toggle_ui"/>
</widget>
</child>
<child>
<widget class="GtkHBox" id="hbox17">
<widget class="GtkAlignment" id="alignment17">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="left_padding">5</property>
<child>
<widget class="GtkAlignment" id="alignment17">
<widget class="GtkHBox" id="hbox17">
<property name="visible">True</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label3">
<widget class="GtkAlignment" id="alignment17">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Password:</property>
<property name="right_padding">5</property>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Password:</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="txt_tray_passwd">
<property name="visible">True</property>
<property name="sensitive">False</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="visibility">False</property>
<property name="width_chars">16</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="txt_tray_passwd">
<property name="visible">True</property>
<property name="sensitive">False</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="visibility">False</property>
<property name="width_chars">16</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
@ -2301,10 +2532,59 @@ HTTP W/ Auth</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkAlignment" id="alignment27">
<widget class="GtkRadioButton" id="radio_open_folder_custom">
<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">Custom:</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">radio_open_folder_stock</property>
<signal name="focus_in_event" handler="on_radio_open_folder_custom_focus_in_event"/>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radio_open_folder_stock">
<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">Open folder with:</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
</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>
<property name="left_padding">40</property>
<property name="left_padding">6</property>
<child>
<widget class="GtkComboBox" id="combo_file_manager">
<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">Auto-detect (xdg-open)
Konqueror
Nautilus
Thunar</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment24">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="left_padding">6</property>
<child>
<widget class="GtkEntry" id="txt_open_folder_location">
<property name="visible">True</property>
@ -2321,76 +2601,6 @@ HTTP W/ Auth</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment26">
<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">40</property>
<child>
<widget class="GtkComboBoxEntry" id="combo_file_manager">
<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">Auto-detect (xdg-open)
Konqueror
Nautilus
Thunar</property>
<child internal-child="entry">
<widget class="GtkEntry" id="comboboxentry-entry3">
<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="editable">False</property>
<signal name="focus_in_event" handler="on_combo_file_manager_entry_focus_in_event"/>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment25">
<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_open_folder_custom">
<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">Custom:</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">radio_open_folder_stock</property>
<signal name="focus_in_event" handler="on_radio_open_folder_custom_focus_in_event"/>
</widget>
</child>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment24">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkRadioButton" id="radio_open_folder_stock">
<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">Open folder with:</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
@ -2405,7 +2615,7 @@ Thunar</property>
<widget class="GtkLabel" id="label36">
<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">&lt;b&gt;Desktop File Manager&lt;/b&gt;</property>
<property name="label" translatable="yes">&lt;b&gt;Desktop File Manager&lt;/b&gt; - only for non-Windows platforms</property>
<property name="use_markup">True</property>
</widget>
<packing>
@ -2421,52 +2631,33 @@ Thunar</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame3">
<widget class="GtkFrame" id="frame21">
<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>
<child>
<widget class="GtkAlignment" id="alignment3">
<widget class="GtkAlignment" id="alignment38">
<property name="visible">True</property>
<property name="top_padding">2</property>
<property name="bottom_padding">2</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">12</property>
<child>
<widget class="GtkHBox" id="hbox16">
<widget class="GtkCheckButton" id="chk_use_advanced_bar">
<property name="visible">True</property>
<property name="spacing">15</property>
<child>
<widget class="GtkLabel" id="label28">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">GUI update interval (seconds)</property>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spin_gui">
<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.5 0.5 5 0.5 0.5 1</property>
<property name="climb_rate">1</property>
<property name="digits">1</property>
<property name="snap_to_ticks">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<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 the advanced progress bar (uses slightly more CPU/RAM)</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label4">
<widget class="GtkLabel" id="label41">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Performance&lt;/b&gt;</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">&lt;b&gt;Detailed Progress Bar&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
@ -2477,7 +2668,6 @@ Thunar</property>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">2</property>
</packing>
</child>
@ -2579,7 +2769,6 @@ information is sent.</property>
</widget>
<packing>
<property name="position">5</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -2591,7 +2780,6 @@ information is sent.</property>
<packing>
<property name="type">tab</property>
<property name="position">5</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -2681,7 +2869,7 @@ information is sent.</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="yes">gtk-preferences</property>
<property name="label">gtk-preferences</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="plugin_pref"/>
@ -2703,7 +2891,6 @@ information is sent.</property>
</widget>
<packing>
<property name="position">6</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -2715,7 +2902,6 @@ information is sent.</property>
<packing>
<property name="type">tab</property>
<property name="position">6</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -2758,3 +2944,4 @@ information is sent.</property>
</child>
</widget>
</glade-interface>

View File

@ -4,6 +4,28 @@
<glade-interface>
<widget class="GtkMenu" id="torrent_menu">
<property name="visible">True</property>
<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">_Force Recheck</property>
<property name="use_underline">True</property>
<signal name="activate" handler="torrent_recheck"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image13">
<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="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="menu_resume">
<property name="visible">True</property>
@ -43,44 +65,6 @@
<property name="visible">True</property>
</widget>
</child>
<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="GtkSeparatorMenuItem" id="separator">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem12">
<property name="visible">True</property>
@ -104,6 +88,75 @@
<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>

View File

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

View File

@ -1,13 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.2.2 on Fri Aug 31 14:41:52 2007 by markybob@peg-->
<!--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">320</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"/>
@ -222,15 +224,153 @@
<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">5</property>
<property name="n_rows">6</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkLabel" id="label11">
<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>
<property name="label" translatable="yes">Your Upload Line Speed:</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>
@ -260,7 +400,7 @@
20Mbit
40Mbit
50Mbit
10Mbit</property>
100Mbit</property>
<signal name="changed" handler="toggle"/>
</widget>
</child>
@ -273,73 +413,61 @@
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment10">
<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="GtkSpinButton" id="spin_max_connections_global">
<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="adjustment">0 -1 9000 1 10 10</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">1</property>
<property name="bottom_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="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="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="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="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="alignment8">
<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>
@ -347,7 +475,8 @@
<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 -1 100 1 10 10</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>
@ -360,82 +489,6 @@
<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="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="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="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="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="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="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="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>
</widget>
<packing>
<property name="position">1</property>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -0,0 +1,402 @@
<?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>

After

Width:  |  Height:  |  Size: 15 KiB

25
libtorrent/AUTHORS Normal file
View File

@ -0,0 +1,25 @@
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.

28
libtorrent/COPYING Normal file
View File

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

View File

@ -36,7 +36,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <memory>
#include <queue>
#include <string>
#include <cassert>
#include <typeinfo>
#ifdef _MSC_VER
@ -44,6 +43,7 @@ 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>
@ -56,6 +56,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
@ -99,10 +100,13 @@ 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

View File

@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket.hpp"
#include "libtorrent/peer_connection.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
namespace libtorrent
{
@ -81,6 +82,35 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new tracker_warning_alert(*this)); }
};
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
{
tracker_reply_alert(torrent_handle const& h
@ -114,7 +144,7 @@ namespace libtorrent
, std::string const& msg)
: torrent_alert(h, alert::info, msg)
, piece_index(index)
{ assert(index >= 0);}
{ TORRENT_ASSERT(index >= 0);}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new hash_failed_alert(*this)); }
@ -190,9 +220,9 @@ namespace libtorrent
const torrent_handle& h
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::warning, msg)
: torrent_alert(h, alert::debug, msg)
, piece_index(piece_num)
{ assert(piece_index >= 0);}
{ TORRENT_ASSERT(piece_index >= 0);}
int piece_index;
@ -207,10 +237,10 @@ namespace libtorrent
, int block_num
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::warning, msg)
: torrent_alert(h, alert::debug, msg)
, block_index(block_num)
, piece_index(piece_num)
{ assert(block_index >= 0 && piece_index >= 0);}
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);}
int block_index;
int piece_index;
@ -223,15 +253,15 @@ namespace libtorrent
{
block_downloading_alert(
const torrent_handle& h
, std::string& speedmsg
, char const* speedmsg
, int block_num
, int piece_num
, const std::string& msg)
: torrent_alert(h, alert::warning, msg)
: torrent_alert(h, alert::debug, msg)
, peer_speedmsg(speedmsg)
, block_index(block_num)
, piece_index(piece_num)
{ assert(block_index >= 0 && piece_index >= 0);}
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);}
std::string peer_speedmsg;
int block_index;
@ -251,6 +281,16 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new storage_moved_alert(*this)); }
};
struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert
{
torrent_deleted_alert(torrent_handle const& h, std::string const& msg)
: torrent_alert(h, alert::warning, msg)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new torrent_deleted_alert(*this)); }
};
struct TORRENT_EXPORT torrent_paused_alert: torrent_alert
{
torrent_paused_alert(torrent_handle const& h, std::string const& msg)
@ -327,14 +367,33 @@ namespace libtorrent
struct TORRENT_EXPORT listen_failed_alert: alert
{
listen_failed_alert(
const std::string& msg)
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_failed_alert(*this)); }
};
struct TORRENT_EXPORT listen_succeeded_alert: alert
{
listen_succeeded_alert(
tcp::endpoint const& ep
, std::string const& msg)
: alert(alert::fatal, msg)
, endpoint(ep)
{}
tcp::endpoint endpoint;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new listen_succeeded_alert(*this)); }
};
struct TORRENT_EXPORT portmap_error_alert: alert
{
portmap_error_alert(const std::string& msg)

View File

@ -0,0 +1,78 @@
/*
Copyright (c) 2003, Magnus Jonsson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_ALLOCATE_RESOURCES_HPP_INCLUDED
#define TORRENT_ALLOCATE_RESOURCES_HPP_INCLUDED
#include <map>
#include <utility>
#include <boost/shared_ptr.hpp>
#include "libtorrent/resource_request.hpp"
#include "libtorrent/peer_id.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/session.hpp"
namespace libtorrent
{
class peer_connection;
class torrent;
int saturated_add(int a, int b);
// Function to allocate a limited resource fairly among many consumers.
// It takes into account the current use, and the consumer's desired use.
// Should be invoked periodically to allow it adjust to the situation (make
// sure "used" is updated between calls!).
// If resources = std::numeric_limits<int>::max() it means there is an infinite
// supply of resources (so everyone can get what they want).
void allocate_resources(
int resources
, std::map<sha1_hash, boost::shared_ptr<torrent> >& torrents
, resource_request torrent::* res);
void allocate_resources(
int resources
, 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);
}
#endif

View File

@ -1,74 +0,0 @@
//
// asio.hpp
// ~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_HPP
#define ASIO_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/basic_datagram_socket.hpp"
#include "asio/basic_deadline_timer.hpp"
#include "asio/basic_io_object.hpp"
#include "asio/basic_socket_acceptor.hpp"
#include "asio/basic_socket_iostream.hpp"
#include "asio/basic_socket_streambuf.hpp"
#include "asio/basic_stream_socket.hpp"
#include "asio/basic_streambuf.hpp"
#include "asio/buffer.hpp"
#include "asio/buffered_read_stream_fwd.hpp"
#include "asio/buffered_read_stream.hpp"
#include "asio/buffered_stream_fwd.hpp"
#include "asio/buffered_stream.hpp"
#include "asio/buffered_write_stream_fwd.hpp"
#include "asio/buffered_write_stream.hpp"
#include "asio/completion_condition.hpp"
#include "asio/datagram_socket_service.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/deadline_timer.hpp"
#include "asio/error.hpp"
#include "asio/error_code.hpp"
#include "asio/handler_alloc_hook.hpp"
#include "asio/handler_invoke_hook.hpp"
#include "asio/io_service.hpp"
#include "asio/ip/address.hpp"
#include "asio/ip/address_v4.hpp"
#include "asio/ip/address_v6.hpp"
#include "asio/ip/basic_endpoint.hpp"
#include "asio/ip/basic_resolver.hpp"
#include "asio/ip/basic_resolver_entry.hpp"
#include "asio/ip/basic_resolver_iterator.hpp"
#include "asio/ip/basic_resolver_query.hpp"
#include "asio/ip/host_name.hpp"
#include "asio/ip/multicast.hpp"
#include "asio/ip/resolver_query_base.hpp"
#include "asio/ip/resolver_service.hpp"
#include "asio/ip/tcp.hpp"
#include "asio/ip/udp.hpp"
#include "asio/ip/unicast.hpp"
#include "asio/ip/v6_only.hpp"
#include "asio/is_read_buffered.hpp"
#include "asio/is_write_buffered.hpp"
#include "asio/placeholders.hpp"
#include "asio/read.hpp"
#include "asio/read_until.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_base.hpp"
#include "asio/strand.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/streambuf.hpp"
#include "asio/system_error.hpp"
#include "asio/thread.hpp"
#include "asio/time_traits.hpp"
#include "asio/version.hpp"
#include "asio/write.hpp"
#endif // ASIO_HPP

View File

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

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

View File

@ -732,8 +732,8 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::system_error& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation

View File

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

View File

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

View File

@ -27,7 +27,7 @@
#include "asio/detail/pop_options.hpp"
#if defined(BOOST_MSVC)
# if defined(_HAS_ITERATOR_DEBUGGING)
# 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)
@ -390,6 +390,11 @@ public:
{
}
~buffer_debug_check()
{
iter_ = Iterator();
}
void operator()()
{
*iter_;
@ -542,9 +547,10 @@ inline const_buffers_1 buffer(const PodType (&data)[N],
? N * sizeof(PodType) : max_size_in_bytes));
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
// Borland C++ thinks the overloads:
// Borland C++ and Sun Studio think the overloads:
//
// unspecified buffer(boost::array<PodType, N>& array ...);
//
@ -610,6 +616,7 @@ buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
}
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
/// Create a new modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>
@ -650,6 +657,7 @@ inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
}
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
/// Create a new non-modifiable buffer that represents the given POD array.
template <typename PodType, std::size_t N>

View File

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

View File

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

View File

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

View File

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

View File

@ -29,6 +29,7 @@
#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 {
@ -62,13 +63,16 @@ private:
// The type of the platform-specific implementation.
#if defined(ASIO_HAS_IOCP)
typedef detail::deadline_timer_service<
traits_type, detail::select_reactor<true> > service_impl_type;
traits_type, detail::win_iocp_io_service> 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;

View File

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

View File

@ -0,0 +1,647 @@
//
// 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

@ -0,0 +1,40 @@
//
// dev_poll_reactor_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP
#define ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
#if !defined(ASIO_DISABLE_DEV_POLL)
#if defined(__sun) // This service is only supported on Solaris.
// Define this to indicate that /dev/poll is supported on the target platform.
#define ASIO_HAS_DEV_POLL 1
namespace asio {
namespace detail {
template <bool Own_Thread>
class dev_poll_reactor;
} // namespace detail
} // namespace asio
#endif // defined(__sun)
#endif // !defined(ASIO_DISABLE_DEV_POLL)
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP

View File

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

View File

@ -0,0 +1,219 @@
//
// handler_queue.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_HANDLER_QUEUE_HPP
#define ASIO_DETAIL_HANDLER_QUEUE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/push_options.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/noncopyable.hpp"
namespace asio {
namespace detail {
class handler_queue
: private noncopyable
{
public:
// Base class for handlers in the queue.
class handler
: private noncopyable
{
public:
void invoke()
{
invoke_func_(this);
}
void destroy()
{
destroy_func_(this);
}
protected:
typedef void (*invoke_func_type)(handler*);
typedef void (*destroy_func_type)(handler*);
handler(invoke_func_type invoke_func,
destroy_func_type destroy_func)
: next_(0),
invoke_func_(invoke_func),
destroy_func_(destroy_func)
{
}
~handler()
{
}
private:
friend class handler_queue;
handler* next_;
invoke_func_type invoke_func_;
destroy_func_type destroy_func_;
};
// Smart point to manager handler lifetimes.
class scoped_ptr
: private noncopyable
{
public:
explicit scoped_ptr(handler* h)
: handler_(h)
{
}
~scoped_ptr()
{
if (handler_)
handler_->destroy();
}
handler* get() const
{
return handler_;
}
handler* release()
{
handler* tmp = handler_;
handler_ = 0;
return tmp;
}
private:
handler* handler_;
};
// Constructor.
handler_queue()
: front_(0),
back_(0)
{
}
// Wrap a handler to be pushed into the queue.
template <typename Handler>
static handler* wrap(Handler h)
{
// Allocate and construct an object to wrap the handler.
typedef handler_wrapper<Handler> value_type;
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(h);
handler_ptr<alloc_traits> ptr(raw_ptr, h);
return ptr.release();
}
// Get the handler at the front of the queue.
handler* front()
{
return front_;
}
// Pop a handler from the front of the queue.
void pop()
{
if (front_)
{
handler* tmp = front_;
front_ = front_->next_;
if (front_ == 0)
back_ = 0;
tmp->next_= 0;
}
}
// Push a handler on to the back of the queue.
void push(handler* h)
{
h->next_ = 0;
if (back_)
{
back_->next_ = h;
back_ = h;
}
else
{
front_ = back_ = h;
}
}
// Whether the queue is empty.
bool empty() const
{
return front_ == 0;
}
private:
// Template wrapper for handlers.
template <typename Handler>
class handler_wrapper
: public handler
{
public:
handler_wrapper(Handler h)
: handler(
&handler_wrapper<Handler>::do_call,
&handler_wrapper<Handler>::do_destroy),
handler_(h)
{
}
static void do_call(handler* base)
{
// Take ownership of the handler object.
typedef handler_wrapper<Handler> this_type;
this_type* h(static_cast<this_type*>(base));
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
handler_ptr<alloc_traits> ptr(h->handler_, h);
// Make a copy of the handler so that the memory can be deallocated before
// the upcall is made.
Handler handler(h->handler_);
// Free the memory associated with the handler.
ptr.reset();
// Make the upcall.
asio_handler_invoke_helpers::invoke(handler, &handler);
}
static void do_destroy(handler* base)
{
// Take ownership of the handler object.
typedef handler_wrapper<Handler> this_type;
this_type* h(static_cast<this_type*>(base));
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
handler_ptr<alloc_traits> ptr(h->handler_, h);
}
private:
Handler handler_;
};
// The front of the queue.
handler* front_;
// The back of the queue.
handler* back_;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_HANDLER_QUEUE_HPP

View File

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

View File

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

View File

@ -19,6 +19,7 @@
#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__)
@ -27,6 +28,8 @@
#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 {
@ -46,6 +49,13 @@ 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

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

View File

@ -35,11 +35,16 @@ public:
FD_ZERO(&fd_set_);
}
void set(socket_type descriptor)
bool set(socket_type descriptor)
{
if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_)
max_descriptor_ = descriptor;
FD_SET(descriptor, &fd_set_);
if (descriptor < (socket_type)FD_SETSIZE)
{
if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_)
max_descriptor_ = descriptor;
FD_SET(descriptor, &fd_set_);
return true;
}
return false;
}
bool is_set(socket_type descriptor) const
@ -58,7 +63,7 @@ public:
}
private:
fd_set fd_set_;
mutable fd_set fd_set_;
socket_type max_descriptor_;
};

View File

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

View File

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

View File

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

View File

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

View File

@ -173,8 +173,13 @@ public:
typename operation_map::iterator i = operations_.begin();
while (i != operations_.end())
{
descriptors.set(i->first);
Descriptor descriptor = i->first;
++i;
if (!descriptors.set(descriptor))
{
asio::error_code ec(error::fd_set_failure);
dispatch_all_operations(descriptor, ec);
}
}
}

View File

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

View File

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

View File

@ -166,7 +166,8 @@ private:
}
// Check if a service matches the given id.
bool service_id_matches(const asio::io_service::service& service,
static bool service_id_matches(
const asio::io_service::service& service,
const asio::io_service::id& id)
{
return service.id_ == &id;
@ -174,7 +175,8 @@ private:
// Check if a service matches the given id.
template <typename Service>
bool service_id_matches(const asio::io_service::service& service,
static bool service_id_matches(
const asio::io_service::service& service,
const asio::detail::service_id<Service>& /*id*/)
{
return service.type_info_ != 0 && *service.type_info_ == typeid(Service);

View File

@ -26,9 +26,6 @@
#include <cerrno>
#include <boost/detail/workaround.hpp>
#include <new>
#if defined(__MACH__) && defined(__APPLE__)
# include <AvailabilityMacros.h>
#endif // defined(__MACH__) && defined(__APPLE__)
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
@ -38,12 +35,24 @@ namespace asio {
namespace detail {
namespace socket_ops {
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
struct msghdr { int msg_namelen; };
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#if defined(__hpux)
// HP-UX doesn't declare these functions extern "C", so they are declared again
// here to avoid linker errors about undefined symbols.
extern "C" char* if_indextoname(unsigned int, char*);
extern "C" unsigned int if_nametoindex(const char*);
#endif // defined(__hpux)
inline void clear_error(asio::error_code& ec)
{
errno = 0;
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
WSASetLastError(0);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#else
errno = 0;
#endif
ec = asio::error_code();
}
@ -52,22 +61,37 @@ inline ReturnType error_wrapper(ReturnType return_value,
asio::error_code& ec)
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
ec = asio::error_code(WSAGetLastError(), asio::native_ecat);
ec = asio::error_code(WSAGetLastError(),
asio::error::get_system_category());
#else
ec = asio::error_code(errno, asio::native_ecat);
ec = asio::error_code(errno,
asio::error::get_system_category());
#endif
return return_value;
}
template <typename SockLenType>
inline socket_type call_accept(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
if (addrlen)
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
inline socket_type accept(socket_type s, socket_addr_type* addr,
socket_addr_len_type* addrlen, asio::error_code& ec)
std::size_t* addrlen, asio::error_code& ec)
{
clear_error(ec);
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
socket_type new_s = error_wrapper(::accept(s, addr, addrlen), ec);
socket_type new_s = error_wrapper(call_accept(
&msghdr::msg_namelen, s, addr, addrlen), ec);
if (new_s == invalid_socket)
return new_s;
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
int optval = 1;
int result = error_wrapper(::setsockopt(new_s,
SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
@ -76,25 +100,45 @@ inline socket_type accept(socket_type s, socket_addr_type* addr,
::close(new_s);
return invalid_socket;
}
#endif
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
clear_error(ec);
#endif
return new_s;
#else
return error_wrapper(::accept(s, addr, addrlen), ec);
#endif
}
template <typename SockLenType>
inline int call_bind(SockLenType msghdr::*,
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
{
return ::bind(s, addr, (SockLenType)addrlen);
}
inline int bind(socket_type s, const socket_addr_type* addr,
socket_addr_len_type addrlen, asio::error_code& ec)
std::size_t addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(::bind(s, addr, addrlen), ec);
int result = error_wrapper(call_bind(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
inline int close(socket_type s, asio::error_code& ec)
{
clear_error(ec);
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::closesocket(s), ec);
int result = error_wrapper(::closesocket(s), ec);
# if defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::close(s), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@ -103,20 +147,43 @@ inline int close(socket_type s, asio::error_code& ec)
inline int shutdown(socket_type s, int what, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(::shutdown(s, what), ec);
int result = error_wrapper(::shutdown(s, what), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
template <typename SockLenType>
inline int call_connect(SockLenType msghdr::*,
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
{
return ::connect(s, addr, (SockLenType)addrlen);
}
inline int connect(socket_type s, const socket_addr_type* addr,
socket_addr_len_type addrlen, asio::error_code& ec)
std::size_t addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(::connect(s, addr, addrlen), ec);
int result = error_wrapper(call_connect(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
inline int listen(socket_type s, int backlog, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(::listen(s, backlog), ec);
int result = error_wrapper(::listen(s, backlog), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@ -147,6 +214,28 @@ inline void init_buf(buf& b, const void* data, size_t size)
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
{
name = addr;
}
inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
{
name = const_cast<socket_addr_type*>(addr);
}
template <typename T>
inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
{
name = reinterpret_cast<T>(addr);
}
template <typename T>
inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
{
name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
}
inline int recv(socket_type s, buf* bufs, size_t count, int flags,
asio::error_code& ec)
{
@ -160,22 +249,20 @@ inline int recv(socket_type s, buf* bufs, size_t count, int flags,
recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg;
msg.msg_name = 0;
msg.msg_namelen = 0;
msghdr msg = msghdr();
msg.msg_iov = bufs;
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
return error_wrapper(::recvmsg(s, &msg, flags), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
socket_addr_type* addr, socket_addr_len_type* addrlen,
socket_addr_type* addr, std::size_t* addrlen,
asio::error_code& ec)
{
clear_error(ec);
@ -184,25 +271,22 @@ inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
DWORD recv_buf_count = static_cast<DWORD>(count);
DWORD bytes_transferred = 0;
DWORD recv_flags = flags;
int tmp_addrlen = (int)*addrlen;
int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
&bytes_transferred, &recv_flags, addr, addrlen, 0, 0), ec);
&bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);
*addrlen = (std::size_t)tmp_addrlen;
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg;
#if defined(__MACH__) && defined(__APPLE__) \
&& (MAC_OS_X_VERSION_MAX_ALLOWED < 1040)
msg.msg_name = reinterpret_cast<char*>(addr);
#else
msg.msg_name = addr;
#endif
msghdr msg = msghdr();
init_msghdr_msg_name(msg.msg_name, addr);
msg.msg_namelen = *addrlen;
msg.msg_iov = bufs;
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
*addrlen = msg.msg_namelen;
return result;
@ -222,16 +306,14 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg;
msg.msg_name = 0;
msg.msg_namelen = 0;
msghdr msg = msghdr();
msg.msg_iov = const_cast<buf*>(bufs);
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
#if defined(__linux__)
flags |= MSG_NOSIGNAL;
#endif // defined(__linux__)
@ -240,7 +322,7 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
}
inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
const socket_addr_type* addr, socket_addr_len_type addrlen,
const socket_addr_type* addr, std::size_t addrlen,
asio::error_code& ec)
{
clear_error(ec);
@ -249,24 +331,20 @@ inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
DWORD send_buf_count = static_cast<DWORD>(count);
DWORD bytes_transferred = 0;
int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
send_buf_count, &bytes_transferred, flags, addr, addrlen, 0, 0), ec);
send_buf_count, &bytes_transferred, flags, addr,
static_cast<int>(addrlen), 0, 0), ec);
if (result != 0)
return -1;
# if defined(UNDER_CE)
clear_error(ec);
# endif
return bytes_transferred;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
msghdr msg;
#if defined(__MACH__) && defined(__APPLE__) \
&& (MAC_OS_X_VERSION_MAX_ALLOWED < 1040)
msg.msg_name = reinterpret_cast<char*>(const_cast<socket_addr_type*>(addr));
#else
msg.msg_name = const_cast<socket_addr_type*>(addr);
#endif
msghdr msg = msghdr();
init_msghdr_msg_name(msg.msg_name, addr);
msg.msg_namelen = addrlen;
msg.msg_iov = const_cast<buf*>(bufs);
msg.msg_iovlen = count;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
#if defined(__linux__)
flags |= MSG_NOSIGNAL;
#endif // defined(__linux__)
@ -294,6 +372,10 @@ inline socket_type socket(int af, int type, int protocol,
reinterpret_cast<const char*>(&optval), sizeof(optval));
}
# if defined(UNDER_CE)
clear_error(ec);
# endif
return s;
#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
socket_type s = error_wrapper(::socket(af, type, protocol), ec);
@ -315,8 +397,17 @@ inline socket_type socket(int af, int type, int protocol,
#endif
}
template <typename SockLenType>
inline int call_setsockopt(SockLenType msghdr::*,
socket_type s, int level, int optname,
const void* optval, std::size_t optlen)
{
return ::setsockopt(s, level, optname,
(const char*)optval, (SockLenType)optlen);
}
inline int setsockopt(socket_type s, int level, int optname,
const void* optval, size_t optlen, asio::error_code& ec)
const void* optval, std::size_t optlen, asio::error_code& ec)
{
if (level == custom_socket_option_level && optname == always_fail_option)
{
@ -341,15 +432,27 @@ inline int setsockopt(socket_type s, int level, int optname,
}
ec = asio::error::fault;
return -1;
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#else // defined(__BORLANDC__)
clear_error(ec);
return error_wrapper(::setsockopt(s, level, optname,
reinterpret_cast<const char*>(optval), static_cast<int>(optlen)), ec);
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
return error_wrapper(::setsockopt(s, level, optname, optval,
static_cast<socklen_t>(optlen)), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen), ec);
# if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#endif // defined(__BORLANDC__)
}
template <typename SockLenType>
inline int call_getsockopt(SockLenType msghdr::*,
socket_type s, int level, int optname,
void* optval, std::size_t* optlen)
{
SockLenType tmp_optlen = (SockLenType)*optlen;
int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
*optlen = (std::size_t)tmp_optlen;
return result;
}
inline int getsockopt(socket_type s, int level, int optname, void* optval,
@ -393,10 +496,8 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
return -1;
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
int tmp_optlen = static_cast<int>(*optlen);
int result = error_wrapper(::getsockopt(s, level, optname,
reinterpret_cast<char*>(optval), &tmp_optlen), ec);
*optlen = static_cast<size_t>(tmp_optlen);
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen), ec);
if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
&& ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
{
@ -408,13 +509,15 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
*static_cast<DWORD*>(optval) = 1;
clear_error(ec);
}
# if defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
socklen_t tmp_optlen = static_cast<socklen_t>(*optlen);
int result = error_wrapper(::getsockopt(s, level, optname,
optval, &tmp_optlen), ec);
*optlen = static_cast<size_t>(tmp_optlen);
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen), ec);
#if defined(__linux__)
if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
&& (optname == SO_SNDBUF || optname == SO_RCVBUF))
@ -431,18 +534,50 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
}
template <typename SockLenType>
inline int call_getpeername(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = (SockLenType)*addrlen;
int result = ::getpeername(s, addr, &tmp_addrlen);
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
inline int getpeername(socket_type s, socket_addr_type* addr,
socket_addr_len_type* addrlen, asio::error_code& ec)
std::size_t* addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(::getpeername(s, addr, addrlen), ec);
int result = error_wrapper(call_getpeername(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
template <typename SockLenType>
inline int call_getsockname(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = (SockLenType)*addrlen;
int result = ::getsockname(s, addr, &tmp_addrlen);
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
inline int getsockname(socket_type s, socket_addr_type* addr,
socket_addr_len_type* addrlen, asio::error_code& ec)
std::size_t* addrlen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(::getsockname(s, addr, addrlen), ec);
int result = error_wrapper(call_getsockname(
&msghdr::msg_namelen, s, addr, addrlen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
@ -450,7 +585,12 @@ inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
{
clear_error(ec);
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::ioctlsocket(s, cmd, arg), ec);
int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);
# if defined(UNDER_CE)
if (result == 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::ioctl(s, cmd, arg), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@ -481,8 +621,22 @@ inline int select(int nfds, fd_set* readfds, fd_set* writefds,
&& timeout->tv_usec > 0 && timeout->tv_usec < 1000)
timeout->tv_usec = 1000;
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::select(nfds, readfds,
#if defined(__hpux) && defined(__HP_aCC)
timespec ts;
ts.tv_sec = timeout ? timeout->tv_sec : 0;
ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
return error_wrapper(::pselect(nfds, readfds,
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
#else
int result = error_wrapper(::select(nfds, readfds,
writefds, exceptfds, timeout), ec);
# if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result >= 0)
clear_error(ec);
# endif
return result;
#endif
}
inline int poll_read(socket_type s, asio::error_code& ec)
@ -492,7 +646,12 @@ inline int poll_read(socket_type s, asio::error_code& ec)
FD_ZERO(&fds);
FD_SET(s, &fds);
clear_error(ec);
return error_wrapper(::select(s, &fds, 0, 0, 0), ec);
int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec);
# if defined(UNDER_CE)
if (result >= 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
pollfd fds;
fds.fd = s;
@ -510,7 +669,12 @@ inline int poll_write(socket_type s, asio::error_code& ec)
FD_ZERO(&fds);
FD_SET(s, &fds);
clear_error(ec);
return error_wrapper(::select(s, 0, &fds, 0, 0), ec);
int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec);
# if defined(UNDER_CE)
if (result >= 0)
clear_error(ec);
# endif
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
pollfd fds;
fds.fd = s;
@ -558,9 +722,17 @@ inline const char* inet_ntop(int af, const void* src, char* dest, size_t length,
}
DWORD string_length = static_cast<DWORD>(length);
#if defined(BOOST_NO_ANSI_APIS)
LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));
int result = error_wrapper(::WSAAddressToStringW(
reinterpret_cast<sockaddr*>(&address),
address_length, 0, string_buffer, &string_length), ec);
::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0);
#else
int result = error_wrapper(::WSAAddressToStringA(
reinterpret_cast<sockaddr*>(&address),
address_length, 0, dest, &string_length), ec);
#endif
// Windows may set error code on success.
if (result != socket_error_retval)
@ -604,10 +776,20 @@ inline int inet_pton(int af, const char* src, void* dest,
sockaddr_storage_type address;
int address_length = sizeof(sockaddr_storage_type);
#if defined(BOOST_NO_ANSI_APIS)
int num_wide_chars = strlen(src) + 1;
LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR));
::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars);
int result = error_wrapper(::WSAStringToAddressW(
wide_buffer, af, 0,
reinterpret_cast<sockaddr*>(&address),
&address_length), ec);
#else
int result = error_wrapper(::WSAStringToAddressA(
const_cast<char*>(src), af, 0,
reinterpret_cast<sockaddr*>(&address),
&address_length), ec);
#endif
if (af == AF_INET)
{
@ -641,6 +823,11 @@ inline int inet_pton(int af, const char* src, void* dest,
if (result == socket_error_retval && !ec)
ec = asio::error::invalid_argument;
#if defined(UNDER_CE)
if (result != socket_error_retval)
clear_error(ec);
#endif
return result == socket_error_retval ? -1 : 1;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
int result = error_wrapper(::inet_pton(af, src, dest), ec);
@ -667,7 +854,12 @@ inline int inet_pton(int af, const char* src, void* dest,
inline int gethostname(char* name, int namelen, asio::error_code& ec)
{
clear_error(ec);
return error_wrapper(::gethostname(name, namelen), ec);
int result = error_wrapper(::gethostname(name, namelen), ec);
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
if (result == 0)
clear_error(ec);
#endif
return result;
}
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \
@ -706,6 +898,9 @@ inline hostent* gethostbyaddr(const char* addr, int length, int af,
hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
if (!retval)
return 0;
# if defined(UNDER_CE)
clear_error(ec);
# endif
*result = *retval;
return retval;
#elif defined(__sun) || defined(__QNX__)
@ -754,6 +949,9 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result,
hostent* retval = error_wrapper(::gethostbyname(name), ec);
if (!retval)
return 0;
# if defined(UNDER_CE)
clear_error(ec);
# endif
*result = *retval;
return result;
#elif defined(__sun) || defined(__QNX__)
@ -923,6 +1121,17 @@ inline void gai_free(void* p)
::operator delete(p);
}
inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
{
using namespace std;
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
strcpy_s(target, max_size, source);
#else
*target = 0;
strncat(target, source, max_size);
#endif
}
enum { gai_clone_flag = 1 << 30 };
inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
@ -1292,14 +1501,15 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
&& (hints.ai_flags & AI_CANONNAME) && canon == 0)
{
canon = gai_alloc<char>(strlen(hptr->h_name) + 1);
std::size_t canon_len = strlen(hptr->h_name) + 1;
canon = gai_alloc<char>(canon_len);
if (canon == 0)
{
freeaddrinfo_emulation(aihead);
socket_ops::freehostent(hptr);
return EAI_MEMORY;
}
strcpy(canon, hptr->h_name);
gai_strcpy(canon, hptr->h_name, canon_len);
}
// Create an addrinfo structure for each returned address.
@ -1335,13 +1545,14 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
}
else
{
aihead->ai_canonname = gai_alloc<char>(strlen(search[0].host) + 1);
std::size_t canonname_len = strlen(search[0].host) + 1;
aihead->ai_canonname = gai_alloc<char>(canonname_len);
if (aihead->ai_canonname == 0)
{
freeaddrinfo_emulation(aihead);
return EAI_MEMORY;
}
strcpy(aihead->ai_canonname, search[0].host);
gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
}
}
gai_free(canon);
@ -1363,7 +1574,7 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
}
inline asio::error_code getnameinfo_emulation(
const socket_addr_type* sa, socket_addr_len_type salen, char* host,
const socket_addr_type* sa, std::size_t salen, char* host,
std::size_t hostlen, char* serv, std::size_t servlen, int flags,
asio::error_code& ec)
{
@ -1424,8 +1635,7 @@ inline asio::error_code getnameinfo_emulation(
*dot = 0;
}
}
*host = '\0';
strncat(host, hptr->h_name, hostlen);
gai_strcpy(host, hptr->h_name, hostlen);
socket_ops::freehostent(hptr);
}
else
@ -1452,7 +1662,11 @@ inline asio::error_code getnameinfo_emulation(
{
return ec = asio::error::no_buffer_space;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
sprintf_s(serv, servlen, "%u", ntohs(port));
#else
sprintf(serv, "%u", ntohs(port));
#endif
}
else
{
@ -1463,8 +1677,7 @@ inline asio::error_code getnameinfo_emulation(
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
{
*serv = '\0';
strncat(serv, sptr->s_name, servlen);
gai_strcpy(serv, sptr->s_name, servlen);
}
else
{
@ -1472,7 +1685,11 @@ inline asio::error_code getnameinfo_emulation(
{
return ec = asio::error::no_buffer_space;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
sprintf_s(serv, servlen, "%u", ntohs(port));
#else
sprintf(serv, "%u", ntohs(port));
#endif
}
#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
::pthread_mutex_unlock(&mutex);
@ -1518,10 +1735,10 @@ inline asio::error_code translate_addrinfo_error(int error)
default: // Possibly the non-portable EAI_SYSTEM.
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return asio::error_code(
WSAGetLastError(), asio::native_ecat);
WSAGetLastError(), asio::error::get_system_category());
#else
return asio::error_code(
errno, asio::native_ecat);
errno, asio::error::get_system_category());
#endif
}
}
@ -1532,7 +1749,7 @@ inline asio::error_code getaddrinfo(const char* host,
{
clear_error(ec);
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
// Building for Windows XP, Windows Server 2003, or later.
int error = ::getaddrinfo(host, service, hints, result);
return ec = translate_addrinfo_error(error);
@ -1563,7 +1780,7 @@ inline asio::error_code getaddrinfo(const char* host,
inline void freeaddrinfo(addrinfo_type* ai)
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
// Building for Windows XP, Windows Server 2003, or later.
::freeaddrinfo(ai);
# else
@ -1587,11 +1804,11 @@ inline void freeaddrinfo(addrinfo_type* ai)
}
inline asio::error_code getnameinfo(const socket_addr_type* addr,
socket_addr_len_type addrlen, char* host, std::size_t hostlen,
std::size_t addrlen, char* host, std::size_t hostlen,
char* serv, std::size_t servlen, int flags, asio::error_code& ec)
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
// Building for Windows XP, Windows Server 2003, or later.
clear_error(ec);
int error = ::getnameinfo(addr, addrlen, host, static_cast<DWORD>(hostlen),
@ -1600,7 +1817,7 @@ inline asio::error_code getnameinfo(const socket_addr_type* addr,
# else
// Building for Windows 2000 or earlier.
typedef int (WSAAPI *gni_t)(const socket_addr_type*,
socket_addr_len_type, char*, std::size_t, char*, std::size_t, int);
int, char*, std::size_t, char*, std::size_t, int);
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
{
if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))

View File

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

View File

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

View File

@ -29,12 +29,12 @@
# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER) || defined(__BORLANDC__)
# pragma message("Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately")
# pragma message("Assuming _WIN32_WINNT=0x0500 (i.e. Windows 2000 target)")
# pragma message("Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target)")
# else // defined(_MSC_VER) || defined(__BORLANDC__)
# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately
# warning Assuming _WIN32_WINNT=0x0500 (i.e. Windows 2000 target)
# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target)
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
# define _WIN32_WINNT 0x0500
# define _WIN32_WINNT 0x0501
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER)
# if defined(_WIN32) && !defined(WIN32)
@ -80,7 +80,9 @@
# undef ASIO_WSPIAPI_H_DEFINED
# endif // defined(ASIO_WSPIAPI_H_DEFINED)
# if !defined(ASIO_NO_DEFAULT_LINKED_LIBS)
# if defined(_MSC_VER) || defined(__BORLANDC__)
# if defined(UNDER_CE)
# pragma comment(lib, "ws2.lib")
# elif defined(_MSC_VER) || defined(__BORLANDC__)
# pragma comment(lib, "ws2_32.lib")
# pragma comment(lib, "mswsock.lib")
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
@ -90,7 +92,11 @@
# include <sys/ioctl.h>
# include <sys/poll.h>
# include <sys/types.h>
# include <sys/select.h>
# if defined(__hpux)
# include <sys/time.h>
# else
# include <sys/select.h>
# endif
# include <sys/socket.h>
# include <sys/uio.h>
# include <netinet/in.h>
@ -98,6 +104,7 @@
# include <arpa/inet.h>
# include <netdb.h>
# include <net/if.h>
# include <limits.h>
# if defined(__sun)
# include <sys/filio.h>
# include <sys/sockio.h>
@ -115,7 +122,6 @@ const int socket_error_retval = SOCKET_ERROR;
const int max_addr_v4_str_len = 256;
const int max_addr_v6_str_len = 256;
typedef sockaddr socket_addr_type;
typedef int socket_addr_len_type;
typedef in_addr in4_addr_type;
typedef ip_mreq in4_mreq_type;
typedef sockaddr_in sockaddr_in4_type;
@ -141,6 +147,11 @@ const int shutdown_both = SD_BOTH;
const int message_peek = MSG_PEEK;
const int message_out_of_band = MSG_OOB;
const int message_do_not_route = MSG_DONTROUTE;
# if defined (_WIN32_WINNT)
const int max_iov_len = 64;
# else
const int max_iov_len = 16;
# endif
#else
typedef int socket_type;
const int invalid_socket = -1;
@ -148,9 +159,17 @@ const int socket_error_retval = -1;
const int max_addr_v4_str_len = INET_ADDRSTRLEN;
const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
typedef sockaddr socket_addr_type;
typedef socklen_t socket_addr_len_type;
typedef in_addr in4_addr_type;
# if defined(__hpux)
// HP-UX doesn't provide ip_mreq when _XOPEN_SOURCE_EXTENDED is defined.
struct in4_mreq_type
{
struct in_addr imr_multiaddr;
struct in_addr imr_interface;
};
# else
typedef ip_mreq in4_mreq_type;
# endif
typedef sockaddr_in sockaddr_in4_type;
typedef in6_addr in6_addr_type;
typedef ipv6_mreq in6_mreq_type;
@ -166,6 +185,7 @@ const int shutdown_both = SHUT_RDWR;
const int message_peek = MSG_PEEK;
const int message_out_of_band = MSG_OOB;
const int message_do_not_route = MSG_DONTROUTE;
const int max_iov_len = IOV_MAX;
#endif
const int custom_socket_option_level = 0xA5100000;
const int enable_connection_aborted_option = 1;

View File

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

View File

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

View File

@ -24,7 +24,11 @@
#if !defined(BOOST_HAS_THREADS)
# include "asio/detail/null_thread.hpp"
#elif defined(BOOST_WINDOWS)
# include "asio/detail/win_thread.hpp"
# if defined(UNDER_CE)
# include "asio/detail/wince_thread.hpp"
# else
# include "asio/detail/win_thread.hpp"
# endif
#elif defined(BOOST_HAS_PTHREADS)
# include "asio/detail/posix_thread.hpp"
#else
@ -37,7 +41,11 @@ namespace detail {
#if !defined(BOOST_HAS_THREADS)
typedef null_thread thread;
#elif defined(BOOST_WINDOWS)
# if defined(UNDER_CE)
typedef wince_thread thread;
# else
typedef win_thread thread;
# endif
#elif defined(BOOST_HAS_PTHREADS)
typedef posix_thread thread;
#endif

View File

@ -162,13 +162,7 @@ public:
// Destroy timers that are waiting to be cleaned up.
virtual void cleanup_timers()
{
while (cleanup_timers_)
{
timer_base* next_timer = cleanup_timers_->next_;
cleanup_timers_->next_ = 0;
cleanup_timers_->destroy();
cleanup_timers_ = next_timer;
}
destroy_timer_list(cleanup_timers_);
}
// Destroy all timers.
@ -181,11 +175,12 @@ public:
timer_base* t = i->second;
typename hash_map<void*, timer_base*>::iterator old_i = i++;
timers_.erase(old_i);
t->destroy();
destroy_timer_list(t);
}
heap_.clear();
timers_.clear();
cleanup_timers();
destroy_timer_list(cancelled_timers_);
destroy_timer_list(cleanup_timers_);
}
private:
@ -367,6 +362,18 @@ private:
}
}
// Destroy all timers in a linked list.
void destroy_timer_list(timer_base*& t)
{
while (t)
{
timer_base* next = t->next_;
t->next_ = 0;
t->destroy();
t = next;
}
}
// A hash of timer token to linked lists of timers.
hash_map<void*, timer_base*> timers_;

View File

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

View File

@ -36,13 +36,17 @@ public:
fd_set_.fd_count = 0;
}
void set(socket_type descriptor)
bool set(socket_type descriptor)
{
for (u_int i = 0; i < fd_set_.fd_count; ++i)
if (fd_set_.fd_array[i] == descriptor)
return;
return true;
if (fd_set_.fd_count < win_fd_set_size)
{
fd_set_.fd_array[fd_set_.fd_count++] = descriptor;
return true;
}
return false;
}
bool is_set(socket_type descriptor) const

View File

@ -33,7 +33,9 @@
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/service_base.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/timer_queue.hpp"
#include "asio/detail/win_iocp_operation.hpp"
#include "asio/detail/mutex.hpp"
namespace asio {
namespace detail {
@ -51,7 +53,9 @@ public:
iocp_(),
outstanding_work_(0),
stopped_(0),
shutdown_(0)
shutdown_(0),
timer_thread_(0),
timer_interrupt_issued_(false)
{
}
@ -63,7 +67,8 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
asio::error_code(last_error,
asio::error::get_system_category()),
"iocp");
boost::throw_exception(e);
}
@ -92,6 +97,10 @@ public:
if (overlapped)
static_cast<operation*>(overlapped)->destroy();
}
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
timer_queues_[i]->destroy_timers();
timer_queues_.clear();
}
// Register a handle with the IO completion port.
@ -173,7 +182,8 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
asio::error_code(last_error,
asio::error::get_system_category()),
"pqcs");
boost::throw_exception(e);
}
@ -228,7 +238,8 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
asio::error_code(last_error,
asio::error::get_system_category()),
"pqcs");
boost::throw_exception(e);
}
@ -247,20 +258,103 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
asio::error_code(last_error,
asio::error::get_system_category()),
"pqcs");
boost::throw_exception(e);
}
}
// Add a new timer queue to the service.
template <typename Time_Traits>
void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(timer_mutex_);
timer_queues_.push_back(&timer_queue);
}
// Remove a timer queue from the service.
template <typename Time_Traits>
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
{
asio::detail::mutex::scoped_lock lock(timer_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)
{
// If the service has been shut down we silently discard the timer.
if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
return;
asio::detail::mutex::scoped_lock lock(timer_mutex_);
if (timer_queue.enqueue_timer(time, handler, token))
{
if (!timer_interrupt_issued_)
{
timer_interrupt_issued_ = true;
lock.unlock();
::PostQueuedCompletionStatus(iocp_.handle,
0, steal_timer_dispatching, 0);
}
}
}
// 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)
{
// If the service has been shut down we silently ignore the cancellation.
if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
return 0;
asio::detail::mutex::scoped_lock lock(timer_mutex_);
std::size_t n = timer_queue.cancel_timer(token);
if (n > 0 && !timer_interrupt_issued_)
{
timer_interrupt_issued_ = true;
lock.unlock();
::PostQueuedCompletionStatus(iocp_.handle,
0, steal_timer_dispatching, 0);
}
return n;
}
private:
// Dequeues at most one operation from the I/O completion port, and then
// executes it. Returns the number of operations that were dequeued (i.e.
// either 0 or 1).
size_t do_one(bool block, asio::error_code& ec)
{
long this_thread_id = static_cast<long>(::GetCurrentThreadId());
for (;;)
{
// Try to acquire responsibility for dispatching timers.
bool dispatching_timers = (::InterlockedCompareExchange(
&timer_thread_, this_thread_id, 0) == 0);
// Calculate timeout for GetQueuedCompletionStatus call.
DWORD timeout = max_timeout;
if (dispatching_timers)
{
asio::detail::mutex::scoped_lock lock(timer_mutex_);
timer_interrupt_issued_ = false;
timeout = get_timeout();
}
// Get the next operation from the queue.
DWORD bytes_transferred = 0;
#if (WINVER < 0x0500)
@ -271,18 +365,47 @@ private:
LPOVERLAPPED overlapped = 0;
::SetLastError(0);
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
&completion_key, &overlapped, block ? 1000 : 0);
&completion_key, &overlapped, block ? timeout : 0);
DWORD last_error = ::GetLastError();
// Dispatch any pending timers.
if (dispatching_timers)
{
asio::detail::mutex::scoped_lock lock(timer_mutex_);
timer_queues_copy_ = timer_queues_;
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
timer_queues_[i]->dispatch_timers();
timer_queues_[i]->dispatch_cancellations();
timer_queues_[i]->cleanup_timers();
}
}
if (!ok && overlapped == 0)
{
if (block && last_error == WAIT_TIMEOUT)
{
// Relinquish responsibility for dispatching timers.
if (dispatching_timers)
{
::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
}
continue;
}
// Transfer responsibility for dispatching timers to another thread.
if (dispatching_timers && ::InterlockedCompareExchange(
&timer_thread_, 0, this_thread_id) == this_thread_id)
{
::PostQueuedCompletionStatus(iocp_.handle,
0, transfer_timer_dispatching, 0);
}
ec = asio::error_code();
return 0;
}
if (overlapped)
else if (overlapped)
{
// We may have been passed a last_error value in the completion_key.
if (last_error == 0)
@ -290,6 +413,14 @@ private:
last_error = completion_key;
}
// Transfer responsibility for dispatching timers to another thread.
if (dispatching_timers && ::InterlockedCompareExchange(
&timer_thread_, 0, this_thread_id) == this_thread_id)
{
::PostQueuedCompletionStatus(iocp_.handle,
0, transfer_timer_dispatching, 0);
}
// Ensure that the io_service does not exit due to running out of work
// while we make the upcall.
auto_work work(*this);
@ -301,18 +432,34 @@ private:
ec = asio::error_code();
return 1;
}
else if (completion_key == transfer_timer_dispatching)
{
// Woken up to try to acquire responsibility for dispatching timers.
::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
}
else if (completion_key == steal_timer_dispatching)
{
// Woken up to steal responsibility for dispatching timers.
::InterlockedExchange(&timer_thread_, 0);
}
else
{
// The stopped_ flag is always checked to ensure that any leftover
// interrupts from a previous run invocation are ignored.
if (::InterlockedExchangeAdd(&stopped_, 0) != 0)
{
// Relinquish responsibility for dispatching timers.
if (dispatching_timers)
{
::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
}
// Wake up next thread that is blocked on GetQueuedCompletionStatus.
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
{
DWORD last_error = ::GetLastError();
ec = asio::error_code(last_error,
asio::native_ecat);
asio::error::get_system_category());
return 0;
}
@ -323,6 +470,45 @@ private:
}
}
// 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 GetQueuedCompletionStatus call. The timeout
// value is returned as a number of milliseconds. We will wait no longer than
// 1000 milliseconds.
DWORD get_timeout()
{
if (all_timer_queues_are_empty())
return max_timeout;
boost::posix_time::time_duration minimum_wait_duration
= boost::posix_time::milliseconds(max_timeout);
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 static_cast<DWORD>(milliseconds > 0 ? milliseconds : 1);
}
else
{
return 0;
}
}
struct auto_work
{
auto_work(win_iocp_io_service& io_service)
@ -412,6 +598,37 @@ private:
// Flag to indicate whether the service has been shut down.
long shutdown_;
enum
{
// Maximum GetQueuedCompletionStatus timeout, in milliseconds.
max_timeout = 1000,
// Completion key value to indicate that responsibility for dispatching
// timers is being cooperatively transferred from one thread to another.
transfer_timer_dispatching = 1,
// Completion key value to indicate that responsibility for dispatching
// timers should be stolen from another thread.
steal_timer_dispatching = 2
};
// The thread that's currently in charge of dispatching timers.
long timer_thread_;
// Mutex for protecting access to the timer queues.
mutex timer_mutex_;
// Whether a thread has been interrupted to process a new timeout.
bool timer_interrupt_issued_;
// The timer queues.
std::vector<timer_queue_base*> timer_queues_;
// A copy of the timer queues, used when dispatching, cancelling and cleaning
// up timers. The copy is stored as a class data member to avoid unnecessary
// memory allocation.
std::vector<timer_queue_base*> timer_queues_copy_;
};
} // namespace detail

View File

@ -27,6 +27,7 @@
#if !defined(ASIO_DISABLE_IOCP)
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
#if !defined(UNDER_CE)
// Define this to indicate that IOCP is supported on the target platform.
#define ASIO_HAS_IOCP 1
@ -39,6 +40,7 @@ class win_iocp_io_service;
} // namespace detail
} // namespace asio
#endif // !defined(UNDER_CE)
#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#endif // !defined(ASIO_DISABLE_IOCP)

View File

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

View File

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

View File

@ -21,8 +21,9 @@
#include <boost/config.hpp>
#include "asio/detail/pop_options.hpp"
#if defined(BOOST_WINDOWS)
#if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
@ -54,7 +55,8 @@ public:
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
asio::error_code(last_error,
asio::error::get_system_category()),
"thread");
boost::throw_exception(e);
}
@ -116,7 +118,7 @@ inline unsigned int __stdcall win_thread_function(void* arg)
} // namespace detail
} // namespace asio
#endif // defined(BOOST_WINDOWS)
#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
#include "asio/detail/pop_options.hpp"

View File

@ -23,6 +23,7 @@
#if defined(BOOST_WINDOWS)
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
@ -39,15 +40,22 @@ class win_tss_ptr
: private noncopyable
{
public:
#if defined(UNDER_CE)
enum { out_of_indexes = 0xFFFFFFFF };
#else
enum { out_of_indexes = TLS_OUT_OF_INDEXES };
#endif
// Constructor.
win_tss_ptr()
{
tss_key_ = ::TlsAlloc();
if (tss_key_ == TLS_OUT_OF_INDEXES)
if (tss_key_ == out_of_indexes)
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error, asio::native_ecat),
asio::error_code(last_error,
asio::error::get_system_category()),
"tss");
boost::throw_exception(e);
}

View File

@ -0,0 +1,124 @@
//
// wince_thread.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_WINCE_THREAD_HPP
#define ASIO_DETAIL_WINCE_THREAD_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(UNDER_CE)
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/throw_exception.hpp>
#include <memory>
#include "asio/detail/pop_options.hpp"
namespace asio {
namespace detail {
DWORD WINAPI wince_thread_function(LPVOID arg);
class wince_thread
: private noncopyable
{
public:
// Constructor.
template <typename Function>
wince_thread(Function f)
{
std::auto_ptr<func_base> arg(new func<Function>(f));
DWORD thread_id = 0;
thread_ = ::CreateThread(0, 0, wince_thread_function,
arg.get(), 0, &thread_id);
if (!thread_)
{
DWORD last_error = ::GetLastError();
asio::system_error e(
asio::error_code(last_error,
asio::error::get_system_category()),
"thread");
boost::throw_exception(e);
}
arg.release();
}
// Destructor.
~wince_thread()
{
::CloseHandle(thread_);
}
// Wait for the thread to exit.
void join()
{
::WaitForSingleObject(thread_, INFINITE);
}
private:
friend DWORD WINAPI wince_thread_function(LPVOID arg);
class func_base
{
public:
virtual ~func_base() {}
virtual void run() = 0;
};
template <typename Function>
class func
: public func_base
{
public:
func(Function f)
: f_(f)
{
}
virtual void run()
{
f_();
}
private:
Function f_;
};
::HANDLE thread_;
};
inline DWORD WINAPI wince_thread_function(LPVOID arg)
{
std::auto_ptr<wince_thread::func_base> func(
static_cast<wince_thread::func_base*>(arg));
func->run();
return 0;
}
} // namespace detail
} // namespace asio
#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE)
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_WINCE_THREAD_HPP

View File

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

View File

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

View File

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

View File

@ -32,24 +32,38 @@
namespace asio {
/// Available error code categories.
enum error_category
namespace error
{
/// Native error codes.
native_ecat = ASIO_WIN_OR_POSIX(0, 0),
/// Available error code categories.
enum error_category
{
/// System error codes.
system_category = ASIO_WIN_OR_POSIX(0, 0),
/// Error codes from NetDB functions.
netdb_ecat = ASIO_WIN_OR_POSIX(native_ecat, 1),
/// Error codes from NetDB functions.
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1),
/// Error codes from getaddrinfo.
addrinfo_ecat = ASIO_WIN_OR_POSIX(native_ecat, 2),
/// Error codes from getaddrinfo.
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2),
/// Miscellaneous error codes.
misc_ecat = ASIO_WIN_OR_POSIX(3, 3),
/// Miscellaneous error codes.
misc_category = ASIO_WIN_OR_POSIX(3, 3),
/// SSL error codes.
ssl_ecat = ASIO_WIN_OR_POSIX(4, 4)
};
/// SSL error codes.
ssl_category = ASIO_WIN_OR_POSIX(4, 4)
};
// Category getters.
inline error_category get_system_category() { return system_category; }
inline error_category get_netdb_category() { return netdb_category; }
inline error_category get_addrinfo_category() { return addrinfo_category; }
inline error_category get_misc_category() { return misc_category; }
inline error_category get_ssl_category() { return ssl_category; }
} // namespace error
/// Bring error category type into the asio namespace.
typedef asio::error::error_category error_category;
/// Class to represent an error code value.
class error_code
@ -61,7 +75,7 @@ public:
/// Default constructor.
error_code()
: value_(0),
category_(native_ecat)
category_(error::system_category)
{
}
@ -72,6 +86,13 @@ public:
{
}
/// Construct from an error code enum.
template <typename ErrorEnum>
error_code(ErrorEnum e)
{
*this = make_error_code(e);
}
/// Get the error value.
value_type value() const
{
@ -91,7 +112,11 @@ public:
{
};
typedef unspecified_bool_type_t* unspecified_bool_type;
typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
static void unspecified_bool_true(unspecified_bool_type_t)
{
}
/// Operator returns non-null if there is a non-success error code.
operator unspecified_bool_type() const
@ -99,7 +124,7 @@ public:
if (value_ == 0)
return 0;
else
return reinterpret_cast<unspecified_bool_type>(1);
return &error_code::unspecified_bool_true;
}
/// Operator to test if the error represents success.

View File

@ -35,10 +35,14 @@ inline std::string error_code::message() const
return "Already open.";
if (*this == error::not_found)
return "Not found.";
if (category_ == ssl_ecat)
if (*this == error::fd_set_failure)
return "The descriptor does not fit into the select call's fd_set.";
if (category_ == error::get_ssl_category())
return "SSL error.";
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
value_type value = value_;
if (category() != error::get_system_category() && *this != error::eof)
return "asio error";
if (*this == error::eof)
value = ERROR_HANDLE_EOF;
char* msg = 0;
@ -76,11 +80,13 @@ inline std::string error_code::message() const
return "Service not found.";
if (*this == error::socket_type_not_supported)
return "Socket type not supported.";
if (category() != error::get_system_category())
return "asio error";
#if defined(__sun) || defined(__QNX__)
return strerror(value_);
#elif defined(__MACH__) && defined(__APPLE__) \
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
|| defined(_AIX)
|| defined(_AIX) || defined(__hpux) || defined(__osf__)
char buf[256] = "";
strerror_r(value_, buf, sizeof(buf));
return buf;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -100,6 +100,10 @@ public:
&openssl_operation::do_async_write,
this, boost::arg<1>(), boost::arg<2>()
);
read_ = boost::bind(
&openssl_operation::do_async_read,
this
);
handler_= boost::bind(
&openssl_operation::async_user_handler,
this, boost::arg<1>(), boost::arg<2>()
@ -122,6 +126,10 @@ public:
&openssl_operation::do_sync_write,
this, boost::arg<1>(), boost::arg<2>()
);
read_ = boost::bind(
&openssl_operation::do_sync_read,
this
);
handler_ = boost::bind(
&openssl_operation::sync_user_handler,
this, boost::arg<1>(), boost::arg<2>()
@ -134,7 +142,7 @@ public:
int start()
{
int rc = primitive_( session_ );
int sys_error_code = ERR_get_error();
bool is_operation_done = (rc > 0);
// For connect/accept/shutdown, the operation
// is done, when return code is 1
@ -144,6 +152,8 @@ public:
int error_code = !is_operation_done ?
::SSL_get_error( session_, rc ) :
0;
int sys_error_code = ERR_get_error();
bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
::BIO_ctrl_pending( ssl_bio_ ));
@ -174,12 +184,12 @@ public:
if (error_code == SSL_ERROR_SYSCALL)
{
return handler_(asio::error_code(
sys_error_code, asio::native_ecat), rc);
sys_error_code, asio::error::system_category), rc);
}
else
{
return handler_(asio::error_code(
error_code, asio::ssl_ecat), rc);
error_code, asio::error::get_ssl_category()), rc);
}
}
@ -211,6 +221,10 @@ public:
return start();
}
else if (is_read_needed)
{
return read_();
}
}
// Continue with operation, flush any SSL data out to network...
@ -222,10 +236,12 @@ private:
typedef boost::function<int (const asio::error_code&, int)>
int_handler_func;
typedef boost::function<int (bool, int)> write_func;
typedef boost::function<int ()> read_func;
ssl_primitive_func primitive_;
user_handler_func user_handler_;
write_func write_;
read_func read_;
int_handler_func handler_;
net_buffer send_buf_; // buffers for network IO
@ -249,8 +265,15 @@ private:
throw asio::system_error(error);
}
int async_user_handler(const asio::error_code& error, int rc)
int async_user_handler(asio::error_code error, int rc)
{
if (rc < 0)
{
if (!error)
error = asio::error::no_recovery;
rc = 0;
}
user_handler_(error, rc);
return 0;
}
@ -315,8 +338,8 @@ private:
}
// OPeration is not done and writing to net has been made...
// start reading...
do_async_read();
// start operation again
start();
return 0;
}
@ -339,7 +362,7 @@ private:
handler_(error, rc);
}
void do_async_read()
int do_async_read()
{
// Wait for new data
socket_.async_read_some
@ -354,6 +377,7 @@ private:
asio::placeholders::bytes_transferred
)
);
return 0;
}
void async_read_handler(const asio::error_code& error,
@ -432,8 +456,8 @@ private:
// Finish the operation, with success
return rc;
// Operation is not finished, read data from net...
return do_sync_read();
// Operation is not finished, start again.
return start();
}
int do_sync_read()

View File

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

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