Compare commits
661 Commits
deluge-0.5
...
deluge-0.5
Author | SHA1 | Date | |
---|---|---|---|
fb308d5dca | |||
3618b4bfe8 | |||
fe01d8c55f | |||
263387c6c9 | |||
379eac85c4 | |||
d2f6a99778 | |||
4a7e0a578b | |||
8fadfb8254 | |||
1c3c5b76b0 | |||
ac80dd4d59 | |||
d1eb4bc8d6 | |||
790eda0f2c | |||
cc81e1073d | |||
642663604f | |||
6b68ac9ad7 | |||
1de14a1ce0 | |||
0d793e7f89 | |||
2e0be83732 | |||
dc60e26c59 | |||
dbe41a3cd5 | |||
49c09bf297 | |||
8f675ebacf | |||
c7f3323d3e | |||
c763d82306 | |||
ee4d054582 | |||
cb64ecb282 | |||
fcfdcd6b06 | |||
77f542b925 | |||
068e4008c6 | |||
70497c074e | |||
7b39f7adf5 | |||
e0fc7f3d2e | |||
7d781568ea | |||
dcefa152c0 | |||
294e1f6b76 | |||
d76ed8cfba | |||
62b9a9170a | |||
8c67f97631 | |||
3997c235be | |||
c6eb180e66 | |||
b31fa3a6df | |||
22225963d5 | |||
9741cbbda0 | |||
65d007c681 | |||
d15a03bce1 | |||
0e82847ae0 | |||
d497a971db | |||
3baecc13d3 | |||
0ca8b5887b | |||
76e9cb3e76 | |||
c7fcbd40e3 | |||
9a3a96a31f | |||
72f49e3557 | |||
7e49e9acc4 | |||
ff0ade61b0 | |||
9972471231 | |||
42f4d55db2 | |||
2d27cede5f | |||
4d4b30700a | |||
736afd6a19 | |||
91fa4df798 | |||
150609e8c8 | |||
aeb1b9bac2 | |||
d1a5490e6b | |||
7ac3421e31 | |||
3b2d205866 | |||
c067cbe4bd | |||
fb222ce57f | |||
c21f650c45 | |||
ea7fdc3bc1 | |||
eeb2c26002 | |||
4156788296 | |||
2dec88e5c2 | |||
5eeabadc88 | |||
85fb85cf13 | |||
d3492be2c2 | |||
c6f69d47e2 | |||
ea953f54b1 | |||
eea8ff8e98 | |||
cd74538adf | |||
7e748a1306 | |||
ab8e6e6bde | |||
2465c5d214 | |||
5828ee03e9 | |||
a29c735acd | |||
dacebd2eec | |||
659c1c5f34 | |||
d647031bee | |||
02ad4098bc | |||
f7952eaa7f | |||
5a3527611d | |||
3c0d9279eb | |||
3d794b6983 | |||
9b52e63f5b | |||
214042af9a | |||
3fb919b99d | |||
653dcb046e | |||
445f3840b2 | |||
c748419fa9 | |||
431664fec4 | |||
77d4fefba9 | |||
3ba156632f | |||
4ee8fd8394 | |||
5b1a381389 | |||
b59de9aa8b | |||
4149e1d285 | |||
8d12fe6312 | |||
75684cde8d | |||
5ccca41ea6 | |||
23d13a2cfd | |||
b803d39d63 | |||
93d0ab797b | |||
9251a82259 | |||
53702b378e | |||
3e9eff9b16 | |||
3dd3d22fd0 | |||
c6ff9e43b7 | |||
c8507b4c28 | |||
8821113742 | |||
2317bb4d52 | |||
0ed3bda526 | |||
3fd1434b04 | |||
71cf5198d4 | |||
22ddf86a4d | |||
fa7a785aab | |||
202b3019a3 | |||
5eb2e95dd4 | |||
b800545ca1 | |||
bf037ab3d6 | |||
79b0f67760 | |||
657055cab1 | |||
9eaf2e602a | |||
c35a13b227 | |||
54155670b5 | |||
43c09af8b1 | |||
d355a42af8 | |||
91531deb6d | |||
f73e9be9c9 | |||
0f8199dbab | |||
04ad4ae7be | |||
68f9a3f265 | |||
2324fdca83 | |||
db80d433b6 | |||
b4795cc362 | |||
d849684e8b | |||
b079f1b755 | |||
c7067c93d2 | |||
d45b859705 | |||
856420c640 | |||
4f55d7dfc6 | |||
27bc2a72b0 | |||
4037479119 | |||
a0af136b81 | |||
f757efde4d | |||
cfe1bd241d | |||
2eb3868115 | |||
5b71f1f6d9 | |||
7d5e079336 | |||
039c5591ed | |||
e00fece477 | |||
fb5d4c8e55 | |||
36a5440858 | |||
b3ab64182e | |||
47acfd93ea | |||
9ec83822a0 | |||
d288e39a54 | |||
8c5355498c | |||
4dad638a41 | |||
1698c57f58 | |||
f96cc8e56a | |||
675a286f8a | |||
0d51bb250e | |||
8f6bb96df0 | |||
32fc9bbf07 | |||
b7983a5ab4 | |||
776ed5a9d8 | |||
6595fe0621 | |||
fd7d1ce675 | |||
e0367895b7 | |||
1e65e4e396 | |||
51bc2329c2 | |||
5c7031ab80 | |||
9c3929f15e | |||
ee409d71c5 | |||
9777d4e00c | |||
7e9576a947 | |||
1b0f7e89c1 | |||
fbf7564d42 | |||
0b2faf6ee1 | |||
cda1b3aa98 | |||
ced47db339 | |||
b221e7ac82 | |||
19f38da504 | |||
54aca23618 | |||
dde291d6dd | |||
adb7bcdf38 | |||
ceaec1897d | |||
e701fa28ba | |||
5701324e00 | |||
71bee41ff0 | |||
54bba4d74c | |||
063fe8fe2d | |||
2cb306ca86 | |||
e617c1d3b7 | |||
bb03e2ff6a | |||
4b7d40ed49 | |||
cc0d1502cc | |||
74f739a693 | |||
22317356c5 | |||
037be4d170 | |||
d918302e3e | |||
fde0c836aa | |||
d9a783118a | |||
3e6b577b1b | |||
19ee80cfab | |||
7b6ece4a2c | |||
a0b2638ffb | |||
8b4053dd2e | |||
9afc4ce936 | |||
1ae6dbf871 | |||
3d1cd9bf00 | |||
15983c8901 | |||
7bdf7e9d1e | |||
34e0a0e839 | |||
1c369bce31 | |||
9b88b8d61f | |||
423cce7c56 | |||
43ad15b3b2 | |||
5a01eec297 | |||
06e8a0c6b9 | |||
b0f991b43c | |||
61a4842bed | |||
06eaabc45f | |||
553bdcc3a6 | |||
3eab9473bf | |||
3a77185e1e | |||
63fa4601fb | |||
77f6be5aac | |||
f5f7f04e1e | |||
8e22078402 | |||
d0d2e59192 | |||
b793646437 | |||
51eceeae3a | |||
dba9a65749 | |||
bbbc8024e5 | |||
989abbc531 | |||
dc2f24344c | |||
732c3d8674 | |||
4ff0a04608 | |||
1163096a70 | |||
e47f0a756e | |||
709b2a04a3 | |||
94a159a66f | |||
de8b55c9ed | |||
85f9b8bf41 | |||
0c83ffc391 | |||
0c5c099097 | |||
e4ab021d20 | |||
e21da8636e | |||
f40e5522bd | |||
7e175dd4c0 | |||
b764486bff | |||
5a90e14794 | |||
2a8d36029e | |||
052894e805 | |||
0b582261ec | |||
b95e3c4988 | |||
abc9534f7f | |||
2b519730bc | |||
edfd988cf9 | |||
f7a1db3be7 | |||
de2f265c2a | |||
97f2f244ae | |||
c4c8539401 | |||
fced9a2c71 | |||
ebe0ac39d9 | |||
2e86ebc6ee | |||
fd817f5e76 | |||
70b7c120bc | |||
091b57d65f | |||
31b05cfaa9 | |||
d7c7222d4f | |||
efc8179261 | |||
3400c444a8 | |||
b6ff01e7c7 | |||
89533158e6 | |||
3eb3ab5b6b | |||
812eeb024e | |||
56e8db547c | |||
6a51a4b9ed | |||
d3fe619f11 | |||
8886ee9a59 | |||
5c75c5192f | |||
e7a789e453 | |||
6e58e5113f | |||
2c48226cdc | |||
d1f2aed58b | |||
6da46bc546 | |||
b645417689 | |||
da9bf950a7 | |||
4e8d9b6e6d | |||
576b81e910 | |||
24b6def6bd | |||
1f24972c9d | |||
14c34684dc | |||
1bc07d2d8e | |||
8bf1c1e60a | |||
8b13d85bdc | |||
4eb0e558a8 | |||
2dfb02e062 | |||
92c9d28d0c | |||
554ad73aa1 | |||
d94694fc73 | |||
e2e507b94b | |||
8d6b749a5d | |||
23c83e6bb1 | |||
6d70add980 | |||
6b3065d2cf | |||
047a32ef9f | |||
ab9a3f778f | |||
179b5f8c55 | |||
f9e5157d6e | |||
86732c72d0 | |||
09798cd394 | |||
0998506f9f | |||
5f21c9d276 | |||
8050c3f8a6 | |||
4b21cc6bf1 | |||
c244b29a03 | |||
9ac2b85068 | |||
5383d6d197 | |||
9b170fe759 | |||
a624ff5557 | |||
1d36020f9d | |||
cdb6450d48 | |||
ca51b3eeff | |||
b48956397f | |||
319bc25cd5 | |||
e202a79dc3 | |||
63ac691e64 | |||
a769af2262 | |||
0dcc01c942 | |||
580d2a2e84 | |||
91d8ad33ae | |||
67e79250d2 | |||
0898680adc | |||
b64bbf1e76 | |||
330b4c2115 | |||
8adff80407 | |||
a09c03dafd | |||
3610c30a25 | |||
9ecb8a388d | |||
3733b91d32 | |||
b144525cab | |||
2eec0a766d | |||
b3cdf1371c | |||
bd8329e971 | |||
3c94a2039d | |||
c446d60ecd | |||
3ab044409f | |||
5ad442341f | |||
a4373ef156 | |||
9604c3ff09 | |||
64aeb867a4 | |||
99065bf452 | |||
2a9455e50a | |||
15d39eeb54 | |||
cf2c4a50f4 | |||
054f7e5721 | |||
6520e618c2 | |||
c059d5162b | |||
9b59c0507e | |||
4cca79c764 | |||
2bac676de7 | |||
f21eb1c3f4 | |||
925416dded | |||
cd2f45da92 | |||
019ea1f601 | |||
2949ab545d | |||
3ed1de43c2 | |||
902e8a2526 | |||
dead0864ad | |||
9bd76e077a | |||
eec0be17f9 | |||
0a0183b0b9 | |||
d320f2aebe | |||
38471aa832 | |||
4bb1f06fd3 | |||
cbeb2c6e6c | |||
2b12b10f8c | |||
557d90987c | |||
dbbace5f23 | |||
a534f23661 | |||
a28e33b809 | |||
ac00fef1d4 | |||
f436cbff64 | |||
74e5e49ee1 | |||
1bf007907c | |||
0bec032638 | |||
d17f6ee274 | |||
571ecbdfac | |||
92c4adc4c1 | |||
80f941a249 | |||
c04ae40cf1 | |||
3eacd3e2d6 | |||
7d680bdd3a | |||
79e9e1de53 | |||
5d4a69d852 | |||
2e5eb2b885 | |||
f2c036650c | |||
0b4b409a53 | |||
58be40da1e | |||
589c007386 | |||
c70721aeac | |||
1ddbf05b92 | |||
cc77df8216 | |||
5fb1987b1b | |||
aef72f74a2 | |||
3dc0b25876 | |||
d07d25e189 | |||
664877a7e6 | |||
9d75b5f306 | |||
891a9955ad | |||
8444cb852c | |||
20f580014b | |||
382f4b0f1a | |||
8f030fb112 | |||
1690fd846b | |||
871d0d15c6 | |||
27d7e80658 | |||
dad79748fa | |||
3169b460f0 | |||
b403530fab | |||
7d98d49803 | |||
f20d0485c3 | |||
3fd9a0dc05 | |||
715874df58 | |||
87fe5fe4ad | |||
b6dd803a95 | |||
30b5967f12 | |||
f54f2a50ec | |||
3947a75336 | |||
71a5c79c15 | |||
dbe83d4ede | |||
375a7fdc64 | |||
528e8c7625 | |||
b612f3663f | |||
ce8e47fae3 | |||
e4f5d822de | |||
20ffbf122e | |||
7585642a98 | |||
fe67907a5d | |||
7fa861f83a | |||
0a6d638c59 | |||
c14d4dd23a | |||
0eb88197c7 | |||
a7868ed3fd | |||
a1d757dfbf | |||
1251a671bd | |||
6e4528875e | |||
734fa157b4 | |||
370578119e | |||
3a23ad301a | |||
8687aab7b6 | |||
81861afa64 | |||
30d357d797 | |||
106e98a15b | |||
991467790b | |||
5a813106ba | |||
daaa79360a | |||
dabe429108 | |||
ff2483af90 | |||
a45c49d037 | |||
a54432d0cf | |||
8464c9c0f6 | |||
94ca1789d5 | |||
7196070f59 | |||
bd02f837bb | |||
4ff8458b3f | |||
4de4fce8ec | |||
ad239210dd | |||
4892cf3df2 | |||
df158d88cb | |||
a0031240fb | |||
54f0e6b91f | |||
a21b852e07 | |||
fc12ade03a | |||
1addf2541a | |||
d8482a3fc9 | |||
bf8727f7bf | |||
278c6c9f3e | |||
cd175ebe9a | |||
5541700881 | |||
19621315c6 | |||
1489ef5bc0 | |||
a335153e0e | |||
a90069b5d0 | |||
24fbfccfb0 | |||
20d63448cb | |||
b8a8757076 | |||
c80a2e822b | |||
d6fb920382 | |||
4e5a6d61dc | |||
53f4a55711 | |||
3273dddb8a | |||
d55fff555c | |||
9ed93af6b2 | |||
b2ae9f1db1 | |||
3211dc9019 | |||
8fa2f73434 | |||
5cda3e71fa | |||
a101b4c1c9 | |||
13a0630875 | |||
7b5fb39d7f | |||
2e0d50407b | |||
e833a2d75e | |||
190a2de73e | |||
563c437675 | |||
5bb79f682c | |||
107b044fba | |||
fa9bf5afc8 | |||
fd7140b15e | |||
6445d1cc26 | |||
2e398cb212 | |||
47fe9bd11f | |||
b9f543682b | |||
3de1cb9938 | |||
c0d8bf2d7f | |||
999e18e4be | |||
45f5fef825 | |||
5d62060bd8 | |||
b16930ea4c | |||
1d8b9cb402 | |||
53e65e9554 | |||
9a050065a9 | |||
72d868ff79 | |||
d36ec723ac | |||
0858836a67 | |||
b02ef923ff | |||
918da976cb | |||
c4b5101189 | |||
e74c62d307 | |||
283f30f884 | |||
691cf5b34f | |||
e4effa22b1 | |||
ed33fa1eb6 | |||
c1d3fbc3f3 | |||
2738bb2835 | |||
71809e968c | |||
8b35caa3c8 | |||
2c1bed04ca | |||
6bcafc02e3 | |||
5d4931c94b | |||
9ac92ca982 | |||
8a723474ed | |||
4d05a9dfc9 | |||
c3e960aa86 | |||
33a99c140e | |||
44240b194e | |||
b209d268f2 | |||
f5868df3ad | |||
f62bf99941 | |||
ddc1ee6295 | |||
f673833fe9 | |||
cd10e9bbaa | |||
760acc8f30 | |||
25146891ff | |||
a93c236e0e | |||
4fbef5d94a | |||
2037ceba69 | |||
3e5ad3e60d | |||
a026f0472d | |||
9d85580029 | |||
e4e4ded874 | |||
dcfb14d7e5 | |||
3f89fd2753 | |||
2e461091dd | |||
82e7eb2e32 | |||
444ac9ec99 | |||
36cd2cda98 | |||
389f9d94a2 | |||
63e4724a8c | |||
dc71d16ac1 | |||
491e7ea0d6 | |||
da60769933 | |||
ccf5f91dc2 | |||
05b105276e | |||
eb7db72965 | |||
47cac3dc4a | |||
c1e4364c1d | |||
7ad2b9ec6a | |||
4bc18ed940 | |||
ff073dc4fb | |||
b7f0447228 | |||
b0fdc2fab8 | |||
c857b1fbbf | |||
08ea29aa4c | |||
0d356ff79a | |||
bd5cd655a1 | |||
116c79ba3f | |||
63501ebe5b | |||
f4bd67c320 | |||
d793835a7e | |||
120b3335b4 | |||
4c5a53b982 | |||
ca4305c0a9 | |||
c2b3109d0a | |||
f880a05e14 | |||
fd5f99630f | |||
5929d1ad53 | |||
c6cb4a20c8 | |||
c2b9a5eaaa | |||
dcf3cac453 | |||
aef7f31f5c | |||
6064706d6c | |||
f2e78f407c | |||
10a34b0951 | |||
f7039bdc0a | |||
aff7718e21 | |||
889a025396 | |||
1ef898ba37 | |||
9a18581b20 | |||
8b7419eb51 | |||
02720ddcd9 | |||
47e47ac9cc | |||
93f928baac | |||
af4c9c0ea8 | |||
8142c69e2a | |||
f164cfd2cb | |||
af177749ff | |||
1abb7c161d | |||
1b6a8925eb | |||
a91c00c247 | |||
cfe44a3ad9 | |||
eac5b42336 | |||
f5951ef7b7 | |||
83474930fd | |||
3aedc14399 | |||
de0f454879 | |||
20bbb09f4f | |||
e8e6f5bd4b | |||
58bcb2abb9 | |||
402bd70816 | |||
f8029692bf | |||
2ffbbe1eb8 | |||
5c072322e3 | |||
5b57463125 | |||
63621be3ee | |||
87d58cd0e1 | |||
1914cbea3e | |||
83042205ab | |||
899dd558c9 | |||
d7363ffb5f | |||
26dd7a83cf | |||
1ac7e0eaab | |||
692cd471f1 | |||
11f033db48 | |||
0e3f5672a5 | |||
f1fde2dcf0 | |||
9af94bda88 | |||
3f60aa4c73 |
127
ChangeLog
@ -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
|
||||
|
@ -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/ *
|
||||
|
2
Makefile
@ -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
@ -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):
|
||||
|
||||
|
5
createicons.sh
Executable 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
|
@ -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;
|
||||
|
@ -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">
|
||||
|
@ -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"><b>Downloaded:</b></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"><b>Uploaded:</b></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"><b>Seeders:</b></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"><b>Share Ratio:</b></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"><b>Speed:</b></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"><b>Speed:</b></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"><b>Peers:</b></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"><b>ETA:</b></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"><b>Pieces:</b></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"><b>Pieces:</b></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"><b>ETA:</b></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"><b>Peers:</b></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"><b>Speed:</b></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"><b>Speed:</b></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"><b>Share Ratio:</b></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"><b>Seeders:</b></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"><b>Uploaded:</b></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"><b>Downloaded:</b></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>
|
||||
|
@ -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">
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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"><b>Autoload</b></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"><b>Desktop File Manager</b></property>
|
||||
<property name="label" translatable="yes"><b>Desktop File Manager</b> - 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"><b>Performance</b></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"><b>Detailed Progress Bar</b></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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
BIN
icons/hicolor/128x128/apps/deluge.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
icons/hicolor/16x16/apps/deluge.png
Normal file
After Width: | Height: | Size: 722 B |
BIN
icons/hicolor/192x192/apps/deluge.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
icons/hicolor/22x22/apps/deluge.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/hicolor/24x24/apps/deluge.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
icons/hicolor/256x256/apps/deluge.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
icons/hicolor/32x32/apps/deluge.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
icons/hicolor/36x36/apps/deluge.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
icons/hicolor/48x48/apps/deluge.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
icons/hicolor/64x64/apps/deluge.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
icons/hicolor/72x72/apps/deluge.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
BIN
icons/hicolor/96x96/apps/deluge.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
402
icons/scalable/apps/deluge.svg
Normal 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
@ -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
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
78
libtorrent/include/libtorrent/allocate_resources.hpp
Normal 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
|
@ -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
|
4
libtorrent/include/libtorrent/asio/COPYING
Normal 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)
|
23
libtorrent/include/libtorrent/asio/LICENSE_1_0.txt
Normal 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.
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
647
libtorrent/include/libtorrent/asio/detail/dev_poll_reactor.hpp
Normal 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
|
@ -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
|
@ -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
|
||||
{
|
||||
|
219
libtorrent/include/libtorrent/asio/detail/handler_queue.hpp
Normal 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
|
@ -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;
|
||||
|
@ -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&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -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.
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
|
@ -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"))
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
124
libtorrent/include/libtorrent/asio/detail/wince_thread.hpp
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -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_);
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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.
|
||||
|