Compare commits
602 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16d6a0b49d | ||
|
|
436c04048e | ||
|
|
feddddb56b | ||
|
|
f61f9c29d8 | ||
|
|
843b64faf5 | ||
|
|
85b526f56a | ||
|
|
8a94b7b2ec | ||
|
|
b807450e98 | ||
|
|
82cdfb75ff | ||
|
|
dcace2a393 | ||
|
|
378edb28f4 | ||
|
|
7894072528 | ||
|
|
abe59d6319 | ||
|
|
e399e00e78 | ||
|
|
51477bc711 | ||
|
|
23632e9104 | ||
|
|
a6ddf41edf | ||
|
|
82351168b3 | ||
|
|
bc19beadbd | ||
|
|
f15c602bd0 | ||
|
|
0f31978c30 | ||
|
|
a2ba04f83f | ||
|
|
8fb9cb9194 | ||
|
|
be8eec8c5a | ||
|
|
e59e2a9e49 | ||
|
|
ec5a4b54f7 | ||
|
|
beebf02cf6 | ||
|
|
a94f2ad2b7 | ||
|
|
3d78d121f4 | ||
|
|
e8969bff6c | ||
|
|
7b4cf04a91 | ||
|
|
acebb97490 | ||
|
|
88201044ed | ||
|
|
72d9abccd7 | ||
|
|
16e6e84dcc | ||
|
|
7752218db2 | ||
|
|
88baee1a35 | ||
|
|
264bb335af | ||
|
|
6af08fb527 | ||
|
|
2494c088f0 | ||
|
|
467859c2ba | ||
|
|
69bad8201b | ||
|
|
c431bc39c3 | ||
|
|
14644080c8 | ||
|
|
3d0578e6eb | ||
|
|
61c966cf0b | ||
|
|
b7d07d78e9 | ||
|
|
556a0f1f0f | ||
|
|
b1d30f9489 | ||
|
|
c6d43bea09 | ||
|
|
31ea3411cc | ||
|
|
d05744e3ed | ||
|
|
1b084f7bbe | ||
|
|
5dcef22c62 | ||
|
|
15e3f84678 | ||
|
|
2907f6d69e | ||
|
|
c6b67af390 | ||
|
|
7b75935b00 | ||
|
|
2d8371a06e | ||
|
|
d4ab6fbba4 | ||
|
|
e129cd7fda | ||
|
|
a3abfbcb08 | ||
|
|
64f4502b9b | ||
|
|
0caf5bb876 | ||
|
|
94e467ad93 | ||
|
|
078180e13d | ||
|
|
e1095c7a43 | ||
|
|
058c49b7ba | ||
|
|
7e6590f31d | ||
|
|
9cf0710d71 | ||
|
|
52a9243317 | ||
|
|
18d48bc13c | ||
|
|
fbe2d85bd5 | ||
|
|
be0b00a80d | ||
|
|
bfbd6db0d6 | ||
|
|
8be336f4ee | ||
|
|
7c3abfbf1e | ||
|
|
1f36b01ed0 | ||
|
|
8d957c56b3 | ||
|
|
0be52c8251 | ||
|
|
1cbffcbd5d | ||
|
|
670e75ee7e | ||
|
|
f55efb2f38 | ||
|
|
88b874e63c | ||
|
|
473dafc593 | ||
|
|
65e3735320 | ||
|
|
f806be87d3 | ||
|
|
bcc6d1c1fc | ||
|
|
675a5a5396 | ||
|
|
5467ec969a | ||
|
|
511e202e13 | ||
|
|
d2e56a5e8d | ||
|
|
cc2e0aa3cf | ||
|
|
e1a5465255 | ||
|
|
32603fd5ff | ||
|
|
1c778bd001 | ||
|
|
5bb19f35ea | ||
|
|
88af4a87d2 | ||
|
|
9dddebab0d | ||
|
|
a49f264dff | ||
|
|
44e61dab7e | ||
|
|
0a00e80c36 | ||
|
|
5ff1fc724f | ||
|
|
f00d4b6775 | ||
|
|
5cbc82e369 | ||
|
|
58dfb6c89b | ||
|
|
b5eb41d882 | ||
|
|
c869cd1d8a | ||
|
|
5cc7175514 | ||
|
|
3e1733a053 | ||
|
|
8809d1df8d | ||
|
|
1790abb3b2 | ||
|
|
31d9165999 | ||
|
|
27134547ff | ||
|
|
1eac3310ad | ||
|
|
a53e7877e4 | ||
|
|
c84a2dbe03 | ||
|
|
88ab6e78da | ||
|
|
5537d6a689 | ||
|
|
e78e29c231 | ||
|
|
9b3b61f606 | ||
|
|
a6a987c0de | ||
|
|
727ee7237e | ||
|
|
4e310d0f90 | ||
|
|
f23037fe21 | ||
|
|
e5cb1d3d3d | ||
|
|
63b22be083 | ||
|
|
badecdca14 | ||
|
|
83306585ff | ||
|
|
18266a6969 | ||
|
|
0c36b16d1b | ||
|
|
e4d47c5357 | ||
|
|
593aa3b2f6 | ||
|
|
47c833675b | ||
|
|
372e4c645e | ||
|
|
6ab153cf8e | ||
|
|
9678211c24 | ||
|
|
5d1ccc12c4 | ||
|
|
f56f21d7da | ||
|
|
ecc11611d3 | ||
|
|
f279d9e6c6 | ||
|
|
ae6e146775 | ||
|
|
90648ea3e5 | ||
|
|
2780b87d56 | ||
|
|
e37539a46c | ||
|
|
7c491bde32 | ||
|
|
6621fe045a | ||
|
|
36f0789d83 | ||
|
|
fedfa9893e | ||
|
|
ba24986f8d | ||
|
|
eb5af8e3c0 | ||
|
|
1ee1063402 | ||
|
|
541329d51f | ||
|
|
d2d92b74a8 | ||
|
|
c8d4a87f49 | ||
|
|
ab3ecf6565 | ||
|
|
287987b37c | ||
|
|
10ccd08471 | ||
|
|
bf61390769 | ||
|
|
520eb622f0 | ||
|
|
497f3168d1 | ||
|
|
8083ab26e0 | ||
|
|
c0a61c3bb3 | ||
|
|
f50ae53c42 | ||
|
|
17219b8f39 | ||
|
|
46c0e1769b | ||
|
|
4fce06ec96 | ||
|
|
77e4cd5b18 | ||
|
|
d05ed869bb | ||
|
|
abc9767034 | ||
|
|
6adeeacee7 | ||
|
|
f55628eed0 | ||
|
|
3ecce91410 | ||
|
|
cc23e204d7 | ||
|
|
e0c5fc8714 | ||
|
|
91ba13054a | ||
|
|
b0816180e3 | ||
|
|
fa6745b4f2 | ||
|
|
6912038d72 | ||
|
|
2c15345016 | ||
|
|
ff9587991f | ||
|
|
625d3d275a | ||
|
|
a7c44d6748 | ||
|
|
e8458b2402 | ||
|
|
6b56200cc8 | ||
|
|
cc9e96147f | ||
|
|
507f3046d1 | ||
|
|
7b9e37c7da | ||
|
|
009d7414bc | ||
|
|
08a1e7fd23 | ||
|
|
99e576612d | ||
|
|
e9f29cb984 | ||
|
|
c858a14764 | ||
|
|
e0327e1d50 | ||
|
|
3530bcc303 | ||
|
|
0f2d7e784a | ||
|
|
bb6fbcf6e7 | ||
|
|
10f313631c | ||
|
|
129362f356 | ||
|
|
3f7191e5c2 | ||
|
|
535efdf319 | ||
|
|
f98516ddd5 | ||
|
|
3b6a1a14ca | ||
|
|
a7cbda92b6 | ||
|
|
a407b232f0 | ||
|
|
160cd5629e | ||
|
|
7d092913b3 | ||
|
|
a9381cdb03 | ||
|
|
e72a91e063 | ||
|
|
64bd28f5ba | ||
|
|
1dd0ab1315 | ||
|
|
8861a97efa | ||
|
|
51a22f60d6 | ||
|
|
8a499e1331 | ||
|
|
34db4c21b1 | ||
|
|
1479b76310 | ||
|
|
a7d5255122 | ||
|
|
12bd89bbc3 | ||
|
|
5e302730cd | ||
|
|
a5c01d4de3 | ||
|
|
de43f42735 | ||
|
|
fc70430b09 | ||
|
|
7ba94d3909 | ||
|
|
bfbe4e38d7 | ||
|
|
4785ad6337 | ||
|
|
6be130e1b8 | ||
|
|
f144429365 | ||
|
|
35da5ded3b | ||
|
|
b9421d7066 | ||
|
|
54d8364c24 | ||
|
|
d843b7cf7f | ||
|
|
e135dfe183 | ||
|
|
31e4b90c3c | ||
|
|
874363f652 | ||
|
|
f01219dfb7 | ||
|
|
f067f50ae4 | ||
|
|
4107b8d4db | ||
|
|
815693f715 | ||
|
|
97b7873cba | ||
|
|
be6b81a352 | ||
|
|
66160d6973 | ||
|
|
93efccf4ee | ||
|
|
77991a0761 | ||
|
|
f388908593 | ||
|
|
56fca44a4b | ||
|
|
a389393ffa | ||
|
|
7b34154cf2 | ||
|
|
da527d8d2a | ||
|
|
b8368a1441 | ||
|
|
c5f027d6be | ||
|
|
9956da1567 | ||
|
|
8ac649e2aa | ||
|
|
8d69f256d1 | ||
|
|
815dd8a25c | ||
|
|
dc1bb0088e | ||
|
|
197f453b76 | ||
|
|
d8669609d8 | ||
|
|
004dfd2d4b | ||
|
|
13148457a9 | ||
|
|
75f7de4010 | ||
|
|
fc4840ebc9 | ||
|
|
011a1ac1a3 | ||
|
|
56fada47f2 | ||
|
|
737f4f953f | ||
|
|
fef619608b | ||
|
|
663d88b677 | ||
|
|
c03569f0df | ||
|
|
2a4cab70ef | ||
|
|
d83fadaf09 | ||
|
|
d277f71333 | ||
|
|
c811169f91 | ||
|
|
4e416266f6 | ||
|
|
0d78f3c758 | ||
|
|
e2c8fed7b3 | ||
|
|
0a02887e62 | ||
|
|
65dc822d6c | ||
|
|
b3759772d2 | ||
|
|
65541f772f | ||
|
|
1b4bd9209e | ||
|
|
c97017dd1d | ||
|
|
2f82750098 | ||
|
|
e893cd6826 | ||
|
|
124d55c970 | ||
|
|
30c3ef9f6f | ||
|
|
55376b044b | ||
|
|
9c1de6e93f | ||
|
|
49d83c0301 | ||
|
|
d09441ca03 | ||
|
|
50b53cbd0d | ||
|
|
1230fad8f4 | ||
|
|
a939d643dd | ||
|
|
2f87d5c114 | ||
|
|
c5644368b5 | ||
|
|
ad523c20c7 | ||
|
|
f0bb7e40f0 | ||
|
|
7b43d70be4 | ||
|
|
c8fad2ac09 | ||
|
|
ca544ed6fc | ||
|
|
6df5a72151 | ||
|
|
3e0b846bdb | ||
|
|
4b0fe81758 | ||
|
|
1752791c9e | ||
|
|
2bf97f123f | ||
|
|
9179888c2b | ||
|
|
dde50f0e22 | ||
|
|
24d1d0802d | ||
|
|
6a9e4293d8 | ||
|
|
4002231bd9 | ||
|
|
7ada448d18 | ||
|
|
2f1614b128 | ||
|
|
b9b6db052b | ||
|
|
e8ec610f28 | ||
|
|
65c1402ee6 | ||
|
|
e7b9633170 | ||
|
|
1b01b786c0 | ||
|
|
8f32a14afa | ||
|
|
6d0d4a3e4d | ||
|
|
962b8e626c | ||
|
|
281e6185cc | ||
|
|
5bf18a6e88 | ||
|
|
4e766761d0 | ||
|
|
a4649f5078 | ||
|
|
d4f8a4ab5d | ||
|
|
b9789a452f | ||
|
|
07261493a7 | ||
|
|
03bb703741 | ||
|
|
ef6a9a624d | ||
|
|
d23a20f62c | ||
|
|
6f94701467 | ||
|
|
d1a2efc77b | ||
|
|
1a56f68451 | ||
|
|
e7ecd116e0 | ||
|
|
44b8153005 | ||
|
|
30fc896cc1 | ||
|
|
6ad347fae4 | ||
|
|
748d894e82 | ||
|
|
f70027cbdc | ||
|
|
8a5b0955de | ||
|
|
ff7dcd2654 | ||
|
|
3990fcad62 | ||
|
|
15e81386bf | ||
|
|
3f331e97da | ||
|
|
6e073ef5da | ||
|
|
f272082240 | ||
|
|
c51522c08f | ||
|
|
932092e95d | ||
|
|
c8a1e6132b | ||
|
|
e02642cf3b | ||
|
|
b60f08e782 | ||
|
|
4fc331f8e8 | ||
|
|
507f2f950d | ||
|
|
1c935a3445 | ||
|
|
dfae365f84 | ||
|
|
5ca5e475bb | ||
|
|
3ba75f1300 | ||
|
|
a7ff759ca1 | ||
|
|
d2c31f429b | ||
|
|
cb5da59226 | ||
|
|
2f33980a91 | ||
|
|
e189c31375 | ||
|
|
1eae55984d | ||
|
|
244df24bf4 | ||
|
|
28b9f1e68b | ||
|
|
0c8eccc3fc | ||
|
|
7b84d5b0ec | ||
|
|
6600954906 | ||
|
|
4a65e10f5e | ||
|
|
d4eb276eea | ||
|
|
91a7e49846 | ||
|
|
dfb206c8b0 | ||
|
|
9581e3df0c | ||
|
|
964f79f7c8 | ||
|
|
460accf9be | ||
|
|
780b40ea7b | ||
|
|
e613fdd83c | ||
|
|
62c2374a8c | ||
|
|
84525b26fe | ||
|
|
be2ddacb90 | ||
|
|
42cc412c4a | ||
|
|
f1b4c76648 | ||
|
|
ee206367d4 | ||
|
|
2638237e1f | ||
|
|
67063ead60 | ||
|
|
a3b7dfcfca | ||
|
|
bcbaf671a9 | ||
|
|
c58cd28279 | ||
|
|
f328457cb1 | ||
|
|
7b5a21deaa | ||
|
|
895a1c03be | ||
|
|
679d679f25 | ||
|
|
0235e150e2 | ||
|
|
17ea56ee73 | ||
|
|
b4440f5aa2 | ||
|
|
fe7ee4a624 | ||
|
|
a40058dbd1 | ||
|
|
c70cc5832b | ||
|
|
a4ba1bd73e | ||
|
|
61e0bbda6b | ||
|
|
a38c4dfa99 | ||
|
|
975f685d69 | ||
|
|
4155405e60 | ||
|
|
55b5d88b01 | ||
|
|
2f110a50df | ||
|
|
7fd7e8264f | ||
|
|
1279a20c03 | ||
|
|
39f9189f34 | ||
|
|
434eb4b0ac | ||
|
|
5ee455ffc2 | ||
|
|
e972c6705f | ||
|
|
12b8c116a4 | ||
|
|
e9d91fccfc | ||
|
|
d5cfb89959 | ||
|
|
a3de1384c3 | ||
|
|
abf77a9eda | ||
|
|
75d9411e80 | ||
|
|
cc000cfb5e | ||
|
|
e1143f1265 | ||
|
|
244e0e2059 | ||
|
|
1a91508857 | ||
|
|
a138041c59 | ||
|
|
c17bd99f1c | ||
|
|
5102b2c093 | ||
|
|
2c6858a018 | ||
|
|
8ddffeeea3 | ||
|
|
238ba3b625 | ||
|
|
988d225cf0 | ||
|
|
a737255791 | ||
|
|
64669fdd8d | ||
|
|
e141586053 | ||
|
|
6f69654294 | ||
|
|
3706c4f855 | ||
|
|
96637d032f | ||
|
|
3300502231 | ||
|
|
8975c05d19 | ||
|
|
07949ce2ae | ||
|
|
dff3f8ccab | ||
|
|
8a1f378f05 | ||
|
|
ec5130c3f9 | ||
|
|
a7b16bfb33 | ||
|
|
2b4b293ebb | ||
|
|
c880de3004 | ||
|
|
c83b9bd9c6 | ||
|
|
e900006642 | ||
|
|
357d28a256 | ||
|
|
1de43a1a17 | ||
|
|
821b0ba8cb | ||
|
|
acfe668ecb | ||
|
|
73b0c1f947 | ||
|
|
3e7d2a6492 | ||
|
|
cd1a510d16 | ||
|
|
9a5a5140e5 | ||
|
|
f610339f74 | ||
|
|
71a782b641 | ||
|
|
cdbba74d7a | ||
|
|
81264cfcaf | ||
|
|
c798dd7ae5 | ||
|
|
b00d1bd225 | ||
|
|
47effc4bd3 | ||
|
|
d651403b47 | ||
|
|
48c90d3781 | ||
|
|
d59b2905f9 | ||
|
|
0f478a7de7 | ||
|
|
9d898acc56 | ||
|
|
a855c74183 | ||
|
|
fb76f210eb | ||
|
|
97dcdb1926 | ||
|
|
7bccb562e4 | ||
|
|
4db0a9a6b7 | ||
|
|
850f002cb2 | ||
|
|
df0ac426f3 | ||
|
|
6c692ad1cb | ||
|
|
ac5180e29c | ||
|
|
fb85db1d3e | ||
|
|
06948c6ee5 | ||
|
|
495ffca2c2 | ||
|
|
e81cc74ca2 | ||
|
|
57a9a7196f | ||
|
|
0c1fa696aa | ||
|
|
ee970e38a6 | ||
|
|
f5e4d85cd2 | ||
|
|
47e95602c4 | ||
|
|
c4d73c306b | ||
|
|
6999994def | ||
|
|
f1635257cb | ||
|
|
7ca20a2679 | ||
|
|
3136561cd0 | ||
|
|
1a91b51976 | ||
|
|
2108309302 | ||
|
|
27eec099d6 | ||
|
|
e3aaff185f | ||
|
|
0b1c752b5c | ||
|
|
8bcd689c04 | ||
|
|
d938c104e1 | ||
|
|
524c5ed87d | ||
|
|
75ad046bfb | ||
|
|
77c8e993ec | ||
|
|
51dcac5da7 | ||
|
|
99ab53e998 | ||
|
|
730e07e2f7 | ||
|
|
1b8cc56194 | ||
|
|
ee3718dd71 | ||
|
|
ec67735412 | ||
|
|
7825bfb49d | ||
|
|
03a698b9c6 | ||
|
|
e0680d3061 | ||
|
|
4e63e48879 | ||
|
|
a302ad427d | ||
|
|
9e59aa1bc8 | ||
|
|
7c9b3938df | ||
|
|
6dfcdb9878 | ||
|
|
6d9275e412 | ||
|
|
571f898192 | ||
|
|
07c4cacb58 | ||
|
|
612c28b89f | ||
|
|
b51e940dfa | ||
|
|
a78671543b | ||
|
|
69ebb2d720 | ||
|
|
1fe609ea05 | ||
|
|
7233c428ec | ||
|
|
223e526f27 | ||
|
|
e6c67bf803 | ||
|
|
2a31fe8552 | ||
|
|
9f2ed35da0 | ||
|
|
264f16dcf6 | ||
|
|
abf201a894 | ||
|
|
e64ec13c13 | ||
|
|
8528c622b0 | ||
|
|
93309c6dbf | ||
|
|
a6ba1d709e | ||
|
|
4d8af0c945 | ||
|
|
0b23a1ee7e | ||
|
|
ff8290179c | ||
|
|
c1128f3db3 | ||
|
|
739e441d4d | ||
|
|
442e471cfc | ||
|
|
bc9cd56345 | ||
|
|
08fe5aabff | ||
|
|
5ec89b8c50 | ||
|
|
df63ee1a1d | ||
|
|
ee2668e586 | ||
|
|
e8b7eb6908 | ||
|
|
bae2992cb0 | ||
|
|
3c569c00df | ||
|
|
4296fec7f5 | ||
|
|
761de533b2 | ||
|
|
8367fc2aac | ||
|
|
d2bff50845 | ||
|
|
20a2b1c341 | ||
|
|
538d718ff4 | ||
|
|
c8583bbdf1 | ||
|
|
8e67d8b364 | ||
|
|
6ac063d10e | ||
|
|
fd34b17f90 | ||
|
|
60fbcad9ac | ||
|
|
f250c6c73e | ||
|
|
c40f8cb9f8 | ||
|
|
83efa3dd71 | ||
|
|
56e279021f | ||
|
|
993e9ebd07 | ||
|
|
7ae0c9543d | ||
|
|
f3e0bffcb1 | ||
|
|
c2a345fa67 | ||
|
|
e0a5f58d2c | ||
|
|
2bc22c40eb | ||
|
|
d54c92e3e6 | ||
|
|
d41a9a07e4 | ||
|
|
cc7dbaa3a1 | ||
|
|
3b2c25d223 | ||
|
|
0209466496 | ||
|
|
722d003076 | ||
|
|
df78de04e4 | ||
|
|
912bb8c577 | ||
|
|
8ec1732af0 | ||
|
|
636cb8633b | ||
|
|
04a35efe69 | ||
|
|
cf7f70c25d | ||
|
|
d0e500c876 | ||
|
|
939a05633f | ||
|
|
7a68f5ab4b | ||
|
|
50c1d00839 | ||
|
|
de24da8c11 | ||
|
|
038086dc08 | ||
|
|
953f901dd2 | ||
|
|
870828c8af | ||
|
|
930af43437 | ||
|
|
cdced3a3ad | ||
|
|
125da33f82 | ||
|
|
e89abc80ea | ||
|
|
d9e90857f0 | ||
|
|
bb0b4bb783 | ||
|
|
e43eb667b5 | ||
|
|
b5fa965bcb | ||
|
|
d5ed7f1256 | ||
|
|
e9cb18484e | ||
|
|
2fbfa0358b | ||
|
|
c8cbdbd2c4 | ||
|
|
3a7b95593a | ||
|
|
a3e02e5e4a | ||
|
|
2e42847f4e | ||
|
|
abb109f30f | ||
|
|
bb6248bca4 | ||
|
|
2c31ecb8fa |
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
23
.github/stale.yml
vendored
23
.github/stale.yml
vendored
@ -1,23 +0,0 @@
|
|||||||
# Number of days of inactivity before an issue becomes stale
|
|
||||||
daysUntilStale: 28
|
|
||||||
# Number of days of inactivity before a stale issue is closed
|
|
||||||
# Set to false to disable. If disabled, issues still need to be closed
|
|
||||||
# manually, but will remain marked as stale.
|
|
||||||
daysUntilClose: false
|
|
||||||
# Issues with these labels will never be considered stale
|
|
||||||
exemptLabels:
|
|
||||||
- v2
|
|
||||||
- enhancement
|
|
||||||
- good first issue
|
|
||||||
- feature-request
|
|
||||||
- doc
|
|
||||||
- bug
|
|
||||||
- not-stale
|
|
||||||
# Label to use when marking an issue as stale
|
|
||||||
staleLabel: stale
|
|
||||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
This issue has been automatically marked as stale because it has not had
|
|
||||||
recent activity. Thank you for your contributions.
|
|
||||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
|
||||||
closeComment: false
|
|
||||||
25
.github/workflows/CI-docs.yml
vendored
Normal file
25
.github/workflows/CI-docs.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
name: CI-docs
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'docs/**'
|
||||||
|
- '!docs/code/**'
|
||||||
|
- '.github/workflows/CI-docs.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docs-src:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
cache: 'pip' # caching pip dependencies
|
||||||
|
- run: pip install -r docs/requirements.txt
|
||||||
|
- name: html
|
||||||
|
run: |
|
||||||
|
make -C docs html
|
||||||
|
- name: linkcheck
|
||||||
|
run: |
|
||||||
|
make -C docs linkcheck
|
||||||
33
.github/workflows/CI-sample.yml
vendored
Normal file
33
.github/workflows/CI-sample.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
name: ci-sample
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '**'
|
||||||
|
- '!docs/**'
|
||||||
|
- '!.**'
|
||||||
|
- 'docs/code/**'
|
||||||
|
- '.github/workflows/CI-sample.yml'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- v[0-9].*
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: setup
|
||||||
|
run: cmake -E make_directory ${{runner.workspace}}/libuv/docs/code/build
|
||||||
|
- name: configure
|
||||||
|
# you may like use Ninja on unix-like OS, but for windows, the only easy way is to use Visual Studio if you want Ninja
|
||||||
|
run: cmake ..
|
||||||
|
working-directory: ${{runner.workspace}}/libuv/docs/code/build
|
||||||
|
- name: build
|
||||||
|
run: cmake --build .
|
||||||
|
working-directory: ${{runner.workspace}}/libuv/docs/code/build
|
||||||
182
.github/workflows/CI-unix.yml
vendored
Normal file
182
.github/workflows/CI-unix.yml
vendored
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
name: CI-unix
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '**'
|
||||||
|
- '!docs/**'
|
||||||
|
- '!src/win/**'
|
||||||
|
- '!.**'
|
||||||
|
- '.github/workflows/CI-unix.yml'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- v[0-9].*
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: configure
|
||||||
|
run: |
|
||||||
|
./autogen.sh
|
||||||
|
mkdir build
|
||||||
|
(cd build && ../configure)
|
||||||
|
- name: distcheck
|
||||||
|
run: |
|
||||||
|
make -C build distcheck
|
||||||
|
|
||||||
|
build-android:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ANDROID_AVD_HOME: /root/.android/avd
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Envinfo
|
||||||
|
run: npx envinfo
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
- name: Build and Test
|
||||||
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
|
with:
|
||||||
|
api-level: 30
|
||||||
|
arch: x86_64
|
||||||
|
target: google_apis
|
||||||
|
ram-size: 2048M
|
||||||
|
emulator-options: -no-audio -no-window -gpu off -no-boot-anim -netdelay none -netspeed full -writable-system -no-snapshot-save -no-snapshot-load -no-snapshot
|
||||||
|
disable-animations: true
|
||||||
|
script: |
|
||||||
|
echo "::group::Configure"
|
||||||
|
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="x86_64" -DANDROID_PLATFORM=android-30
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
## Correct some ld bugs that cause problems with libuv tests
|
||||||
|
wget "https://github.com/termux/termux-elf-cleaner/releases/download/v2.2.1/termux-elf-cleaner" -P build
|
||||||
|
chmod a+x build/termux-elf-cleaner
|
||||||
|
build/termux-elf-cleaner --api-level 30 ./build/uv_run_tests
|
||||||
|
build/termux-elf-cleaner --api-level 30 ./build/uv_run_tests_a
|
||||||
|
|
||||||
|
adb shell "su 0 setenforce 0" # to allow some syscalls like link, chmod, etc.
|
||||||
|
|
||||||
|
## Push the build and test fixtures to the device
|
||||||
|
adb push build /data/local/tmp
|
||||||
|
adb shell mkdir /data/local/tmp/build/test
|
||||||
|
adb push test/fixtures /data/local/tmp/build/test
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
## Run the tests
|
||||||
|
file build/uv_run_tests_a
|
||||||
|
adb shell "cd /data/local/tmp/build && env UV_TEST_TIMEOUT_MULTIPLIER=5 ./uv_run_tests_a"
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [macos-13, macos-14]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Envinfo
|
||||||
|
run: npx envinfo
|
||||||
|
- name: Disable Firewall
|
||||||
|
run: |
|
||||||
|
/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
|
||||||
|
sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 0
|
||||||
|
/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
|
||||||
|
- name: Setup
|
||||||
|
run: |
|
||||||
|
brew install ninja automake libtool
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -DBUILD_TESTING=ON -G Ninja
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake --build build
|
||||||
|
ls -lh
|
||||||
|
- name: platform_output
|
||||||
|
run: |
|
||||||
|
./build/uv_run_tests platform_output
|
||||||
|
- name: platform_output_a
|
||||||
|
run: |
|
||||||
|
./build/uv_run_tests_a platform_output
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
cd build && ctest -V
|
||||||
|
- name: Autotools configure
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
./autogen.sh
|
||||||
|
mkdir build-auto
|
||||||
|
(cd build-auto && ../configure)
|
||||||
|
make -C build-auto -j4
|
||||||
|
|
||||||
|
build-ios:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [macos-13, macos-14]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
mkdir build-ios
|
||||||
|
cd build-ios
|
||||||
|
cmake .. -GXcode -DCMAKE_SYSTEM_NAME:STRING=iOS -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED:BOOL=NO -DCMAKE_CONFIGURATION_TYPES:STRING=Release
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake --build build-ios
|
||||||
|
ls -lh build-ios
|
||||||
|
|
||||||
|
build-cross-qemu:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
name: build-cross-qemu-${{ matrix.config.target }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- {target: arm, toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm }
|
||||||
|
- {target: armhf, toolchain: gcc-arm-linux-gnueabihf, cc: arm-linux-gnueabihf-gcc, qemu: qemu-arm }
|
||||||
|
- {target: aarch64, toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64 }
|
||||||
|
- {target: riscv64, toolchain: gcc-riscv64-linux-gnu, cc: riscv64-linux-gnu-gcc, qemu: qemu-riscv64 }
|
||||||
|
- {target: ppc, toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc }
|
||||||
|
- {target: ppc64, toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64 }
|
||||||
|
- {target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le }
|
||||||
|
- {target: s390x, toolchain: gcc-s390x-linux-gnu, cc: s390x-linux-gnu-gcc, qemu: qemu-s390x }
|
||||||
|
- {target: mips, toolchain: gcc-mips-linux-gnu, cc: mips-linux-gnu-gcc, qemu: qemu-mips }
|
||||||
|
- {target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64 }
|
||||||
|
- {target: mipsel, toolchain: gcc-mipsel-linux-gnu, cc: mipsel-linux-gnu-gcc, qemu: qemu-mipsel }
|
||||||
|
- {target: mips64el, toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc,qemu: qemu-mips64el }
|
||||||
|
- {target: arm (u64 slots), toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm }
|
||||||
|
- {target: aarch64 (u64 slots), toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64 }
|
||||||
|
- {target: ppc (u64 slots), toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc }
|
||||||
|
- {target: ppc64 (u64 slots), toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64 }
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install qemu and ${{ matrix.config.toolchain }}
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install qemu-user qemu-user-binfmt ${{ matrix.config.toolchain }} -y
|
||||||
|
- name: Configure with ${{ matrix.config.cc }}
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -DBUILD_TESTING=ON -DQEMU=ON -DCMAKE_C_COMPILER=${{ matrix.config.cc }}
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake --build build
|
||||||
|
ls -lh build
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
${{ matrix.config.qemu }} build/uv_run_tests_a
|
||||||
129
.github/workflows/CI-win.yml
vendored
Normal file
129
.github/workflows/CI-win.yml
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
name: CI-win
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '**'
|
||||||
|
- '!docs/**'
|
||||||
|
- '!src/unix/**'
|
||||||
|
- '!.**'
|
||||||
|
- '.github/workflows/CI-win.yml'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- v[0-9].*
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-windows:
|
||||||
|
runs-on: windows-${{ matrix.config.server }}
|
||||||
|
name: build-${{ join(matrix.config.*, '-') }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- {toolchain: Visual Studio 16 2019, arch: Win32, server: 2019}
|
||||||
|
- {toolchain: Visual Studio 16 2019, arch: x64, server: 2019}
|
||||||
|
- {toolchain: Visual Studio 17 2022, arch: Win32, server: 2022}
|
||||||
|
- {toolchain: Visual Studio 17 2022, arch: x64, server: 2022}
|
||||||
|
- {toolchain: Visual Studio 17 2022, arch: x64, server: 2022, config: ASAN}
|
||||||
|
- {toolchain: Visual Studio 17 2022, arch: x64, server: 2022, config: UBSAN}
|
||||||
|
- {toolchain: Visual Studio 17 2022, arch: arm64, server: 2022}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Build
|
||||||
|
run:
|
||||||
|
cmake -S . -B build -DBUILD_TESTING=ON
|
||||||
|
-G "${{ matrix.config.toolchain }}" -A ${{ matrix.config.arch }}
|
||||||
|
${{ matrix.config.config == 'ASAN' && '-DASAN=on -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded' || '' }}
|
||||||
|
|
||||||
|
cmake --build build --config RelWithDebInfo
|
||||||
|
|
||||||
|
${{ matrix.config.config == 'ASAN' && 'Copy-Item -Path "build\\*.exe" -Destination "build\\RelWithDebInfo\\"' || '' }}
|
||||||
|
|
||||||
|
${{ matrix.config.config == 'ASAN' && 'Copy-Item -Path "build\\*.dll" -Destination "build\\RelWithDebInfo\\"' || '' }}
|
||||||
|
|
||||||
|
ls -l build
|
||||||
|
|
||||||
|
ls -l build\\RelWithDebInfo
|
||||||
|
- name: platform_output_a
|
||||||
|
if: ${{ matrix.config.arch != 'arm64' }}
|
||||||
|
shell: cmd
|
||||||
|
run:
|
||||||
|
build\\RelWithDebInfo\\uv_run_tests_a.exe platform_output
|
||||||
|
- name: platform_output
|
||||||
|
if: ${{ matrix.config.arch != 'arm64' }}
|
||||||
|
shell: cmd
|
||||||
|
run:
|
||||||
|
build\\RelWithDebInfo\\uv_run_tests.exe platform_output
|
||||||
|
- name: Test
|
||||||
|
# only valid with libuv-master with the fix for
|
||||||
|
# https://github.com/libuv/leps/blob/master/005-windows-handles-not-fd.md
|
||||||
|
if: ${{ matrix.config.config != 'ASAN' && matrix.config.arch != 'arm64' }}
|
||||||
|
shell: cmd
|
||||||
|
run:
|
||||||
|
cd build
|
||||||
|
|
||||||
|
ctest -C RelWithDebInfo -V
|
||||||
|
- name: Test only static
|
||||||
|
if: ${{ matrix.config.config == 'ASAN' && matrix.config.arch != 'arm64' }}
|
||||||
|
shell: cmd
|
||||||
|
run:
|
||||||
|
build\\RelWithDebInfo\\uv_run_tests_a.exe
|
||||||
|
|
||||||
|
build-mingw:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: build-mingw-${{ matrix.config.arch }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- {arch: i686, server: 2022, libgcc: dw2 }
|
||||||
|
- {arch: x86_64, server: 2022, libgcc: seh }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install mingw32 environment
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install mingw-w64 ninja-build -y
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build -G Ninja -DHOST_ARCH=${{ matrix.config.arch }} -DBUILD_TESTING=ON -DCMAKE_TOOLCHAIN_FILE=cmake-toolchains/cross-mingw32.cmake
|
||||||
|
cmake --build build
|
||||||
|
cmake --install build --prefix "`pwd`/build/usr"
|
||||||
|
mkdir -p build/usr/test build/usr/bin
|
||||||
|
cp -av test/fixtures build/usr/test
|
||||||
|
cp -av build/uv_run_tests_a.exe build/uv_run_tests.exe build/uv_run_tests_a_no_ext build/uv_run_tests_no_ext \
|
||||||
|
`${{ matrix.config.arch }}-w64-mingw32-gcc -print-file-name=libgcc_s_${{ matrix.config.libgcc }}-1.dll` \
|
||||||
|
`${{ matrix.config.arch }}-w64-mingw32-gcc -print-file-name=libwinpthread-1.dll` \
|
||||||
|
`${{ matrix.config.arch }}-w64-mingw32-gcc -print-file-name=libatomic-1.dll` \
|
||||||
|
build/usr/bin
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: mingw-${{ matrix.config.arch }}
|
||||||
|
path: build/usr/**/*
|
||||||
|
retention-days: 2
|
||||||
|
|
||||||
|
test-mingw:
|
||||||
|
runs-on: windows-${{ matrix.config.server }}
|
||||||
|
name: test-mingw-${{ matrix.config.arch }}
|
||||||
|
needs: build-mingw
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- {arch: i686, server: 2022}
|
||||||
|
- {arch: x86_64, server: 2022}
|
||||||
|
steps:
|
||||||
|
- name: Download build artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: mingw-${{ matrix.config.arch }}
|
||||||
|
- name: Test
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
bin\uv_run_tests_a.exe
|
||||||
|
- name: Test
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
bin\uv_run_tests.exe
|
||||||
118
.github/workflows/CI.yml
vendored
118
.github/workflows/CI.yml
vendored
@ -1,118 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-windows:
|
|
||||||
runs-on: windows-${{ matrix.config.server }}
|
|
||||||
name: build-${{ matrix.config.toolchain}}-${{ matrix.config.arch}}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
config:
|
|
||||||
- {toolchain: Visual Studio 15 2017, arch: Win32, server: 2016}
|
|
||||||
- {toolchain: Visual Studio 15 2017, arch: x64, server: 2016}
|
|
||||||
- {toolchain: Visual Studio 16 2019, arch: Win32, server: 2019}
|
|
||||||
- {toolchain: Visual Studio 16 2019, arch: x64, server: 2019}
|
|
||||||
- {toolchain: Visual Studio 17 2022, arch: Win32, server: 2022}
|
|
||||||
- {toolchain: Visual Studio 17 2022, arch: x64, server: 2022}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Envinfo
|
|
||||||
run: npx envinfo
|
|
||||||
- name: Build
|
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
mkdir -p build
|
|
||||||
cd build
|
|
||||||
cmake .. -DBUILD_TESTING=ON -G "${{ matrix.config.toolchain }}" -A ${{ matrix.config.arch }}
|
|
||||||
cmake --build .
|
|
||||||
- name: Test
|
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
ctest -C Debug --output-on-failure
|
|
||||||
|
|
||||||
build-android:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: reactnativecommunity/react-native-android:2020-5-20
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Envinfo
|
|
||||||
run: npx envinfo
|
|
||||||
- name: Build android arm64
|
|
||||||
# see build options you can use in https://developer.android.com/ndk/guides/cmake
|
|
||||||
run: |
|
|
||||||
mkdir build && cd build
|
|
||||||
$ANDROID_HOME/cmake/3.10.2.4988404/bin/cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/20.0.5594570/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-21 ..
|
|
||||||
$ANDROID_HOME/cmake/3.10.2.4988404/bin/cmake --build .
|
|
||||||
|
|
||||||
build-macos:
|
|
||||||
runs-on: macos-10.15
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Envinfo
|
|
||||||
run: npx envinfo
|
|
||||||
- name: Setup
|
|
||||||
run: |
|
|
||||||
brew install ninja
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
mkdir build
|
|
||||||
cd build && cmake .. -DBUILD_TESTING=ON -G Ninja
|
|
||||||
cmake --build .
|
|
||||||
ls -lh
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
cd build && ctest -V
|
|
||||||
|
|
||||||
build-cross-qemu:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: build-cross-qemu-${{ matrix.config.target }}
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
config:
|
|
||||||
- {target: arm, toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static }
|
|
||||||
- {target: armhf, toolchain: gcc-arm-linux-gnueabihf, cc: arm-linux-gnueabihf-gcc, qemu: qemu-arm-static }
|
|
||||||
- {target: aarch64, toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static }
|
|
||||||
- {target: riscv64, toolchain: gcc-riscv64-linux-gnu, cc: riscv64-linux-gnu-gcc, qemu: qemu-riscv64-static }
|
|
||||||
- {target: ppc, toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static }
|
|
||||||
- {target: ppc64, toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static }
|
|
||||||
- {target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le-static }
|
|
||||||
- {target: s390x, toolchain: gcc-s390x-linux-gnu, cc: s390x-linux-gnu-gcc, qemu: qemu-s390x-static }
|
|
||||||
- {target: mips, toolchain: gcc-mips-linux-gnu, cc: mips-linux-gnu-gcc, qemu: qemu-mips-static }
|
|
||||||
- {target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64-static }
|
|
||||||
- {target: mipsel, toolchain: gcc-mipsel-linux-gnu, cc: mipsel-linux-gnu-gcc, qemu: qemu-mipsel-static }
|
|
||||||
- {target: mips64el,toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc,qemu: qemu-mips64el-static }
|
|
||||||
- {target: alpha, toolchain: gcc-alpha-linux-gnu, cc: alpha-linux-gnu-gcc, qemu: qemu-alpha-static }
|
|
||||||
- {target: arm (u64 slots), toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static}
|
|
||||||
- {target: aarch64 (u64 slots), toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static}
|
|
||||||
- {target: ppc (u64 slots), toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static}
|
|
||||||
- {target: ppc64 (u64 slots), toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install QEMU
|
|
||||||
# this ensure install latest qemu on ubuntu, apt get version is old
|
|
||||||
env:
|
|
||||||
QEMU_SRC: "http://archive.ubuntu.com/ubuntu/pool/universe/q/qemu"
|
|
||||||
QEMU_VER: "qemu-user-static_4\\.2-.*_amd64.deb$"
|
|
||||||
run: |
|
|
||||||
DEB=`curl -s $QEMU_SRC/ | grep -o -E 'href="([^"#]+)"' | cut -d'"' -f2 | grep $QEMU_VER | tail -1`
|
|
||||||
wget $QEMU_SRC/$DEB
|
|
||||||
sudo dpkg -i $DEB
|
|
||||||
- name: Install ${{ matrix.config.toolchain }}
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install ${{ matrix.config.toolchain }} -y
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
mkdir build
|
|
||||||
cd build && cmake .. -DBUILD_TESTING=ON -DQEMU=ON -DCMAKE_C_COMPILER=${{ matrix.config.cc }}
|
|
||||||
cmake --build .
|
|
||||||
ls -lh
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
${{ matrix.config.qemu }} build/uv_run_tests_a
|
|
||||||
122
.github/workflows/sanitizer.yml
vendored
122
.github/workflows/sanitizer.yml
vendored
@ -1,26 +1,128 @@
|
|||||||
name: Sanitizer checks
|
name: Sanitizer checks
|
||||||
|
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '**'
|
||||||
|
- '!docs/**'
|
||||||
|
- '!.**'
|
||||||
|
- '.github/workflows/sanitizer.yml'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- v[0-9].*
|
||||||
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
sanitizers:
|
sanitizers-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Setup
|
- name: Setup
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install ninja-build
|
sudo apt-get install ninja-build
|
||||||
- name: Envinfo
|
- name: Envinfo
|
||||||
run: npx envinfo
|
run: npx envinfo
|
||||||
- name: TSAN
|
|
||||||
|
# [AM]SAN fail on newer kernels due to a bigger PIE slide
|
||||||
|
- name: Disable ASLR
|
||||||
run: |
|
run: |
|
||||||
mkdir build-tsan
|
sudo sysctl -w kernel.randomize_va_space=0
|
||||||
(cd build-tsan && cmake .. -G Ninja -DBUILD_TESTING=ON -DTSAN=ON -DCMAKE_BUILD_TYPE=Release)
|
|
||||||
cmake --build build-tsan
|
- name: ASAN Build
|
||||||
./build-tsan/uv_run_tests_a || true # currently permit failures
|
|
||||||
- name: ASAN
|
|
||||||
run: |
|
run: |
|
||||||
mkdir build-asan
|
mkdir build-asan
|
||||||
(cd build-asan && cmake .. -G Ninja -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug)
|
(cd build-asan && cmake .. -G Ninja -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug)
|
||||||
cmake --build build-asan
|
cmake --build build-asan
|
||||||
|
- name: ASAN Test
|
||||||
|
run: |
|
||||||
./build-asan/uv_run_tests_a
|
./build-asan/uv_run_tests_a
|
||||||
|
|
||||||
|
- name: MSAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-msan
|
||||||
|
(cd build-msan && cmake .. -G Ninja -DBUILD_TESTING=ON -DMSAN=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang)
|
||||||
|
cmake --build build-msan
|
||||||
|
- name: MSAN Test
|
||||||
|
run: |
|
||||||
|
./build-msan/uv_run_tests_a
|
||||||
|
|
||||||
|
- name: TSAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-tsan
|
||||||
|
(cd build-tsan && cmake .. -G Ninja -DBUILD_TESTING=ON -DTSAN=ON -DCMAKE_BUILD_TYPE=Release)
|
||||||
|
cmake --build build-tsan
|
||||||
|
- name: TSAN Test
|
||||||
|
# Note: path must be absolute because some tests chdir.
|
||||||
|
# TSan exits with an error when it can't find the file.
|
||||||
|
run: |
|
||||||
|
env TSAN_OPTIONS="suppressions=$PWD/tsansupp.txt" ./build-tsan/uv_run_tests_a
|
||||||
|
|
||||||
|
- name: UBSAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-ubsan
|
||||||
|
(cd build-ubsan && cmake .. -G Ninja -DBUILD_TESTING=ON -DUBSAN=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang)
|
||||||
|
cmake --build build-ubsan
|
||||||
|
- name: UBSAN Test
|
||||||
|
run: |
|
||||||
|
./build-ubsan/uv_run_tests_a
|
||||||
|
|
||||||
|
sanitizers-macos:
|
||||||
|
runs-on: macos-13
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Envinfo
|
||||||
|
run: npx envinfo
|
||||||
|
|
||||||
|
- name: ASAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-asan
|
||||||
|
(cd build-asan && cmake .. -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug)
|
||||||
|
cmake --build build-asan
|
||||||
|
- name: ASAN Test
|
||||||
|
run: |
|
||||||
|
./build-asan/uv_run_tests_a
|
||||||
|
|
||||||
|
- name: TSAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-tsan
|
||||||
|
(cd build-tsan && cmake .. -DBUILD_TESTING=ON -DTSAN=ON -DCMAKE_BUILD_TYPE=Release)
|
||||||
|
cmake --build build-tsan
|
||||||
|
- name: TSAN Test
|
||||||
|
run: |
|
||||||
|
./build-tsan/uv_run_tests_a
|
||||||
|
|
||||||
|
- name: UBSAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-ubsan
|
||||||
|
(cd build-ubsan && cmake .. -DBUILD_TESTING=ON -DUBSAN=ON -DCMAKE_BUILD_TYPE=Debug)
|
||||||
|
cmake --build build-ubsan
|
||||||
|
- name: UBSAN Test
|
||||||
|
run: |
|
||||||
|
./build-ubsan/uv_run_tests_a
|
||||||
|
|
||||||
|
sanitizers-windows:
|
||||||
|
runs-on: windows-2022
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup
|
||||||
|
run: |
|
||||||
|
choco install ninja
|
||||||
|
|
||||||
|
# Note: clang shipped with VS2022 has an issue where the UBSAN runtime doesn't link.
|
||||||
|
- name: Install LLVM and Clang
|
||||||
|
uses: KyleMayes/install-llvm-action@v2
|
||||||
|
with:
|
||||||
|
version: "17"
|
||||||
|
|
||||||
|
- name: Envinfo
|
||||||
|
run: npx envinfo
|
||||||
|
|
||||||
|
- name: UBSAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-ubsan
|
||||||
|
cmake -B build-ubsan -G Ninja -DBUILD_TESTING=ON -DUBSAN=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang
|
||||||
|
cmake --build build-ubsan
|
||||||
|
- name: UBSAN Test
|
||||||
|
run: |
|
||||||
|
./build-ubsan/uv_run_tests_a
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -7,9 +7,11 @@
|
|||||||
*.sdf
|
*.sdf
|
||||||
*.suo
|
*.suo
|
||||||
.vs/
|
.vs/
|
||||||
|
.vscode/
|
||||||
*.VC.db
|
*.VC.db
|
||||||
*.VC.opendb
|
*.VC.opendb
|
||||||
core
|
core
|
||||||
|
.cache
|
||||||
vgcore.*
|
vgcore.*
|
||||||
.buildstamp
|
.buildstamp
|
||||||
.dirstamp
|
.dirstamp
|
||||||
@ -74,3 +76,5 @@ cmake-build-debug/
|
|||||||
|
|
||||||
# make dist output
|
# make dist output
|
||||||
libuv-*.tar.*
|
libuv-*.tar.*
|
||||||
|
/dist.libuv.org/
|
||||||
|
/libuv-release-tool/
|
||||||
|
|||||||
9
.mailmap
9
.mailmap
@ -4,6 +4,7 @@ Aaron Bieber <qbit@deftly.net> <deftly@gmail.com>
|
|||||||
Alan Gutierrez <alan@prettyrobots.com> <alan@blogometer.com>
|
Alan Gutierrez <alan@prettyrobots.com> <alan@blogometer.com>
|
||||||
Andrius Bentkus <andrius.bentkus@gmail.com> <toxedvirus@gmail.com>
|
Andrius Bentkus <andrius.bentkus@gmail.com> <toxedvirus@gmail.com>
|
||||||
Andy Fiddaman <andy@omniosce.org> <omnios@citrus-it.co.uk>
|
Andy Fiddaman <andy@omniosce.org> <omnios@citrus-it.co.uk>
|
||||||
|
Andy Pan <panjf2000@gmail.com> <i@andypan.me>
|
||||||
Bert Belder <bertbelder@gmail.com> <i@bertbelder.com>
|
Bert Belder <bertbelder@gmail.com> <i@bertbelder.com>
|
||||||
Bert Belder <bertbelder@gmail.com> <info@2bs.nl>
|
Bert Belder <bertbelder@gmail.com> <info@2bs.nl>
|
||||||
Bert Belder <bertbelder@gmail.com> <user@ChrUbuntu.(none)>
|
Bert Belder <bertbelder@gmail.com> <user@ChrUbuntu.(none)>
|
||||||
@ -18,6 +19,7 @@ David Carlier <devnexen@gmail.com>
|
|||||||
Devchandra Meetei Leishangthem <dlmeetei@gmail.com>
|
Devchandra Meetei Leishangthem <dlmeetei@gmail.com>
|
||||||
Fedor Indutny <fedor.indutny@gmail.com> <fedor@indutny.com>
|
Fedor Indutny <fedor.indutny@gmail.com> <fedor@indutny.com>
|
||||||
Frank Denis <github@pureftpd.org>
|
Frank Denis <github@pureftpd.org>
|
||||||
|
Hüseyin Açacak <110401522+huseyinacacak-janea@users.noreply.github.com> <huseyin@janeasystems.com>
|
||||||
Imran Iqbal <imrani@ca.ibm.com> <imran@imraniqbal.org>
|
Imran Iqbal <imrani@ca.ibm.com> <imran@imraniqbal.org>
|
||||||
Isaac Z. Schlueter <i@izs.me>
|
Isaac Z. Schlueter <i@izs.me>
|
||||||
Jason Williams <necmon@yahoo.com>
|
Jason Williams <necmon@yahoo.com>
|
||||||
@ -29,6 +31,7 @@ Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
|
|||||||
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
|
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
|
||||||
Leith Bade <leith@leithalweapon.geek.nz> <leith@mapbox.com>
|
Leith Bade <leith@leithalweapon.geek.nz> <leith@mapbox.com>
|
||||||
Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
|
Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
|
||||||
|
Lewis Russell <me@lewisr.dev> <lewis6991@gmail.com>
|
||||||
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
|
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
|
||||||
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
|
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
|
||||||
Michael <michael_dawson@ca.ibm.com>
|
Michael <michael_dawson@ca.ibm.com>
|
||||||
@ -36,6 +39,7 @@ Michael Neumann <mneumann@think.localnet> <mneumann@ntecs.de>
|
|||||||
Michael Penick <michael.penick@datastax.com> <mpenick@users.noreply.github.com>
|
Michael Penick <michael.penick@datastax.com> <mpenick@users.noreply.github.com>
|
||||||
Nicholas Vavilov <vvnicholas@gmail.com>
|
Nicholas Vavilov <vvnicholas@gmail.com>
|
||||||
Nick Logan <ugexe@cpan.org> <nlogan@gmail.com>
|
Nick Logan <ugexe@cpan.org> <nlogan@gmail.com>
|
||||||
|
Olivier Valentin <ovalenti@redhat.com> <valentio@free.fr>
|
||||||
Rasmus Christian Pedersen <zerhacken@yahoo.com>
|
Rasmus Christian Pedersen <zerhacken@yahoo.com>
|
||||||
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
|
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
|
||||||
Richard Lau <rlau@redhat.com> <riclau@uk.ibm.com>
|
Richard Lau <rlau@redhat.com> <riclau@uk.ibm.com>
|
||||||
@ -46,7 +50,8 @@ Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
|
|||||||
Sam Roberts <vieuxtech@gmail.com> <sam@strongloop.com>
|
Sam Roberts <vieuxtech@gmail.com> <sam@strongloop.com>
|
||||||
San-Tai Hsu <vanilla@fatpipi.com>
|
San-Tai Hsu <vanilla@fatpipi.com>
|
||||||
Santiago Gimeno <santiago.gimeno@quantion.es> <santiago.gimeno@gmail.com>
|
Santiago Gimeno <santiago.gimeno@quantion.es> <santiago.gimeno@gmail.com>
|
||||||
Saúl Ibarra Corretgé <saghul@gmail.com>
|
Saúl Ibarra Corretgé <s@saghul.net>
|
||||||
|
Saúl Ibarra Corretgé <s@saghul.net> <saghul@gmail.com>
|
||||||
Saúl Ibarra Corretgé <saghul@gmail.com> <s@saghul.net>
|
Saúl Ibarra Corretgé <saghul@gmail.com> <s@saghul.net>
|
||||||
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
|
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
|
||||||
Shuowang (Wayne) Zhang <shuowang.zhang@ibm.com>
|
Shuowang (Wayne) Zhang <shuowang.zhang@ibm.com>
|
||||||
@ -60,5 +65,7 @@ gengjiawen <technicalcute@gmail.com>
|
|||||||
jBarz <jBarz@users.noreply.github.com> <jbarboza@ca.ibm.com>
|
jBarz <jBarz@users.noreply.github.com> <jbarboza@ca.ibm.com>
|
||||||
jBarz <jBarz@users.noreply.github.com> <jbarz@users.noreply.github.com>
|
jBarz <jBarz@users.noreply.github.com> <jbarz@users.noreply.github.com>
|
||||||
ptlomholt <pt@lomholt.com>
|
ptlomholt <pt@lomholt.com>
|
||||||
|
theanarkh <2923878201@qq.com> <theratliter@gmail.com>
|
||||||
tjarlama <59913901+tjarlama@users.noreply.github.com> <tjarlama@gmail.com>
|
tjarlama <59913901+tjarlama@users.noreply.github.com> <tjarlama@gmail.com>
|
||||||
|
ywave620 <rogertyang@tencent.com> <60539365+ywave620@users.noreply.github.com>
|
||||||
zlargon <zlargon1988@gmail.com>
|
zlargon <zlargon1988@gmail.com>
|
||||||
|
|||||||
@ -2,10 +2,14 @@ version: 2
|
|||||||
|
|
||||||
sphinx:
|
sphinx:
|
||||||
builder: html
|
builder: html
|
||||||
configuration: null
|
configuration: docs/src/conf.py
|
||||||
fail_on_warning: false
|
fail_on_warning: false
|
||||||
|
|
||||||
|
build:
|
||||||
|
os: "ubuntu-22.04"
|
||||||
|
tools:
|
||||||
|
python: "3.9"
|
||||||
|
|
||||||
python:
|
python:
|
||||||
version: 3.8
|
|
||||||
install:
|
install:
|
||||||
- requirements: docs/requirements.txt
|
- requirements: docs/requirements.txt
|
||||||
|
|||||||
96
AUTHORS
96
AUTHORS
@ -496,3 +496,99 @@ Jesper Storm Bache <jsbache@users.noreply.github.com>
|
|||||||
Campbell He <duskmoon314@users.noreply.github.com>
|
Campbell He <duskmoon314@users.noreply.github.com>
|
||||||
Andrey Hohutkin <andrey.hohutkin@gmail.com>
|
Andrey Hohutkin <andrey.hohutkin@gmail.com>
|
||||||
deal <halx99@live.com>
|
deal <halx99@live.com>
|
||||||
|
David Machaj <46852402+dmachaj@users.noreply.github.com>
|
||||||
|
Jessica Clarke <jrtc27@jrtc27.com>
|
||||||
|
Jeremy Rose <nornagon@nornagon.net>
|
||||||
|
woclass <git@wo-class.cn>
|
||||||
|
Luca Adrian L <info@lucalindhorst.de>
|
||||||
|
WenTao Ou <owt5008137@live.com>
|
||||||
|
jonilaitinen <joni.laitinen@iki.fi>
|
||||||
|
UMU <UMU618@users.noreply.github.com>
|
||||||
|
Paul Evans <leonerd@leonerd.org.uk>
|
||||||
|
wyckster <wyckster@hotmail.com>
|
||||||
|
Vittore F. Scolari <vittore.scolari@gmail.com>
|
||||||
|
roflcopter4 <15476346+roflcopter4@users.noreply.github.com>
|
||||||
|
V-for-Vasili <vasili.skurydzin@protonmail.com>
|
||||||
|
Denny C. Dai <dennycd@me.com>
|
||||||
|
Hannah Shi <hannahshisfb@gmail.com>
|
||||||
|
tuftedocelot <tuftedocelot@fastmail.fm>
|
||||||
|
blogdaren <blogdaren@163.com>
|
||||||
|
chucksilvers <chuq@chuq.com>
|
||||||
|
Sergey Fedorov <vital.had@gmail.com>
|
||||||
|
theanarkh <2923878201@qq.com>
|
||||||
|
Samuel Cabrero <samuelcabrero@gmail.com>
|
||||||
|
自发对称破缺 <429839446@qq.com>
|
||||||
|
Luan Devecchi <luan@engineer.com>
|
||||||
|
Steven Schveighoffer <schveiguy@gmail.com>
|
||||||
|
number201724 <number201724@me.com>
|
||||||
|
Daniel <reymond315qq@gmail.com>
|
||||||
|
Christian Clason <christian.clason@uni-due.de>
|
||||||
|
ywave620 <rogertyang@tencent.com>
|
||||||
|
jensbjorgensen <jbj1@ultraemail.net>
|
||||||
|
daomingq <daoming.qiu@intel.com>
|
||||||
|
Qix <Qix-@users.noreply.github.com>
|
||||||
|
Edward Humes <29870961+aurxenon@users.noreply.github.com>
|
||||||
|
Tim Besard <tim.besard@gmail.com>
|
||||||
|
Sergey Rubanov <chi187@gmail.com>
|
||||||
|
Stefan Stojanovic <StefanStojanovic@users.noreply.github.com>
|
||||||
|
Zvicii <zvicii@qq.com>
|
||||||
|
dundargoc <33953936+dundargoc@users.noreply.github.com>
|
||||||
|
Jack·Boos·Yu <47264268+JackBoosY@users.noreply.github.com>
|
||||||
|
panran <310762957@qq.com>
|
||||||
|
Tamás Bálint Misius <lbphacker@gmail.com>
|
||||||
|
Bruno Passeri <Varstahl@users.noreply.github.com>
|
||||||
|
Jason Zhang <xzha4350@gmail.com>
|
||||||
|
Lewis Russell <me@lewisr.dev>
|
||||||
|
sivadeilra <arlie.davis@gmail.com>
|
||||||
|
cui fliter <imcusg@gmail.com>
|
||||||
|
Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
|
||||||
|
Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
|
||||||
|
Stefan Karpinski <stefan@karpinski.org>
|
||||||
|
liuxiang88 <94350585+liuxiang88@users.noreply.github.com>
|
||||||
|
Jeffrey H. Johnson <trnsz@pobox.com>
|
||||||
|
Abdirahim Musse <33973272+abmusse@users.noreply.github.com>
|
||||||
|
小明 <7737673+caobug@users.noreply.github.com>
|
||||||
|
Shuduo Sang <sangshuduo@gmail.com>
|
||||||
|
Keith Winstein <keithw@cs.stanford.edu>
|
||||||
|
michalbiesek <michalbiesek@gmail.com>
|
||||||
|
Alois Klink <alois@aloisklink.com>
|
||||||
|
SmorkalovG <smorkalov.g@gmail.com>
|
||||||
|
Pleuvens <pleuvens.fervil@gmail.com>
|
||||||
|
jolai <58589285+laijonathan@users.noreply.github.com>
|
||||||
|
Julien Roncaglia <fox@vbfox.net>
|
||||||
|
prubel <paul@rubels.net>
|
||||||
|
Per Allansson <65364157+per-allansson@users.noreply.github.com>
|
||||||
|
Matheus Izvekov <mizvekov@gmail.com>
|
||||||
|
Christian Heimlich <chris@pcserenity.com>
|
||||||
|
Hao Hu <33607772+hhu8@users.noreply.github.com>
|
||||||
|
matoro <12038583+matoro@users.noreply.github.com>
|
||||||
|
Bo Anderson <mail@boanderson.me>
|
||||||
|
Ardi Nugraha <33378542+ardi-nugraha@users.noreply.github.com>
|
||||||
|
Anton Bachin <antonbachin@yahoo.com>
|
||||||
|
Trevor Flynn <trevorflynn@liquidcrystalstudios.com>
|
||||||
|
Andy Pan <panjf2000@gmail.com>
|
||||||
|
Viacheslav Muravyev <slavamuravey@mail.ru>
|
||||||
|
Anthony Alayo <anthony.alayo@gmail.com>
|
||||||
|
Thomas Walter <31201229+waltoss@users.noreply.github.com>
|
||||||
|
hiiizxf <385122613@qq.com>
|
||||||
|
Geddy <guandichao@163.com>
|
||||||
|
Farzin Monsef <monseffarzin@gmail.com>
|
||||||
|
tgolang <154592711+tgolang@users.noreply.github.com>
|
||||||
|
josedelinux <josedelinux@hotmail.com>
|
||||||
|
Hüseyin Açacak <110401522+huseyinacacak-janea@users.noreply.github.com>
|
||||||
|
Uilian Ries <uilianries@gmail.com>
|
||||||
|
Olivier Valentin <ovalenti@redhat.com>
|
||||||
|
郑苏波 (Super Zheng) <superzheng@tencent.com>
|
||||||
|
zeertzjq <zeertzjq@outlook.com>
|
||||||
|
Ian Butterworth <i.r.butterworth@gmail.com>
|
||||||
|
握猫猫 <164346864@qq.com>
|
||||||
|
Zuohui Yang <274048862@qq.com>
|
||||||
|
Edigleysson Silva (Edy) <edigleyssonsilva@gmail.com>
|
||||||
|
Raihaan Shouhell <raihaanhimself@gmail.com>
|
||||||
|
Rialbat <miha-wead@mail.ru>
|
||||||
|
Adam <adam@NetBSD.org>
|
||||||
|
Poul T Lomholt <ptlomholt@users.noreply.github.com>
|
||||||
|
Thad House <ThadHouse@users.noreply.github.com>
|
||||||
|
Julian A Avar C <28635807+julian-a-avar-c@users.noreply.github.com>
|
||||||
|
amcgoogan <105525867+amcgoogan@users.noreply.github.com>
|
||||||
|
Rafael Gonzaga <rafael.nunu@hotmail.com>
|
||||||
|
|||||||
255
CMakeLists.txt
255
CMakeLists.txt
@ -1,8 +1,13 @@
|
|||||||
cmake_minimum_required(VERSION 3.4)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(libuv LANGUAGES C)
|
|
||||||
|
|
||||||
cmake_policy(SET CMP0057 NEW) # Enable IN_LIST operator
|
if(POLICY CMP0091)
|
||||||
cmake_policy(SET CMP0064 NEW) # Support if (TEST) operator
|
cmake_policy(SET CMP0091 NEW) # Enable MSVC_RUNTIME_LIBRARY setting
|
||||||
|
endif()
|
||||||
|
if(POLICY CMP0092)
|
||||||
|
cmake_policy(SET CMP0092 NEW) # disable /W3 warning, if possible
|
||||||
|
endif()
|
||||||
|
|
||||||
|
project(libuv LANGUAGES C)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
@ -17,9 +22,13 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
|
|||||||
set(CMAKE_C_EXTENSIONS ON)
|
set(CMAKE_C_EXTENSIONS ON)
|
||||||
set(CMAKE_C_STANDARD 90)
|
set(CMAKE_C_STANDARD 90)
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
option(LIBUV_BUILD_SHARED "Build shared lib" ON)
|
||||||
|
|
||||||
cmake_dependent_option(LIBUV_BUILD_TESTS
|
cmake_dependent_option(LIBUV_BUILD_TESTS
|
||||||
"Build the unit tests when BUILD_TESTING is enabled and we are the root project" ON
|
"Build the unit tests when BUILD_TESTING is enabled and we are the root project" ON
|
||||||
"BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
"BUILD_TESTING;LIBUV_BUILD_SHARED;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||||
cmake_dependent_option(LIBUV_BUILD_BENCH
|
cmake_dependent_option(LIBUV_BUILD_BENCH
|
||||||
"Build the benchmarks when building unit tests and we are the root project" ON
|
"Build the benchmarks when building unit tests and we are the root project" ON
|
||||||
"LIBUV_BUILD_TESTS" OFF)
|
"LIBUV_BUILD_TESTS" OFF)
|
||||||
@ -27,28 +36,66 @@ cmake_dependent_option(LIBUV_BUILD_BENCH
|
|||||||
# Qemu Build
|
# Qemu Build
|
||||||
option(QEMU "build for qemu" OFF)
|
option(QEMU "build for qemu" OFF)
|
||||||
if(QEMU)
|
if(QEMU)
|
||||||
add_definitions(-D__QEMU__=1)
|
list(APPEND uv_defines __QEMU__=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Note: these are mutually exclusive.
|
||||||
option(ASAN "Enable AddressSanitizer (ASan)" OFF)
|
option(ASAN "Enable AddressSanitizer (ASan)" OFF)
|
||||||
|
option(MSAN "Enable MemorySanitizer (MSan)" OFF)
|
||||||
option(TSAN "Enable ThreadSanitizer (TSan)" OFF)
|
option(TSAN "Enable ThreadSanitizer (TSan)" OFF)
|
||||||
|
option(UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF)
|
||||||
|
|
||||||
if((ASAN OR TSAN) AND NOT (CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang"))
|
if(MSAN AND NOT CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang")
|
||||||
message(SEND_ERROR "Sanitizer support requires clang or gcc. Try again with -DCMAKE_C_COMPILER.")
|
message(SEND_ERROR "MemorySanitizer requires clang. Try again with -DCMAKE_C_COMPILER=clang")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ASAN)
|
if(ASAN)
|
||||||
add_definitions(-D__ASAN__=1)
|
list(APPEND uv_defines __ASAN__=1)
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang")
|
||||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
||||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
||||||
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
||||||
|
elseif(MSVC)
|
||||||
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address")
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "AddressSanitizer support requires clang, gcc, or msvc. Try again with -DCMAKE_C_COMPILER.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MSAN)
|
||||||
|
list(APPEND uv_defines __MSAN__=1)
|
||||||
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=memory")
|
||||||
|
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=memory")
|
||||||
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=memory")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(TSAN)
|
if(TSAN)
|
||||||
add_definitions(-D__TSAN__=1)
|
list(APPEND uv_defines __TSAN__=1)
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang")
|
||||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
||||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
||||||
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "ThreadSanitizer support requires clang or gcc. Try again with -DCMAKE_C_COMPILER.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UBSAN)
|
||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
list(APPEND uv_defines __UBSAN__=1)
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang")
|
||||||
|
add_compile_options("-fsanitize=undefined" "-fno-sanitize-recover=undefined")
|
||||||
|
if (NOT WIN32)
|
||||||
|
add_link_options("-fsanitize=undefined")
|
||||||
|
endif()
|
||||||
|
if(MSVC)
|
||||||
|
add_compile_options("/Oy-")
|
||||||
|
else()
|
||||||
|
add_compile_options("-fno-omit-frame-pointer")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "UndefinedBehaviorSanitizer support requires clang or gcc. Try again with -DCMAKE_C_COMPILER.")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Compiler check
|
# Compiler check
|
||||||
@ -119,12 +166,19 @@ list(APPEND uv_cflags ${lint-utf8-msvc} )
|
|||||||
check_c_compiler_flag(-fno-strict-aliasing UV_F_STRICT_ALIASING)
|
check_c_compiler_flag(-fno-strict-aliasing UV_F_STRICT_ALIASING)
|
||||||
list(APPEND uv_cflags $<$<BOOL:${UV_F_STRICT_ALIASING}>:-fno-strict-aliasing>)
|
list(APPEND uv_cflags $<$<BOOL:${UV_F_STRICT_ALIASING}>:-fno-strict-aliasing>)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# Error on calling undeclared functions.
|
||||||
|
list(APPEND uv_cflags "/we4013")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(uv_sources
|
set(uv_sources
|
||||||
src/fs-poll.c
|
src/fs-poll.c
|
||||||
src/idna.c
|
src/idna.c
|
||||||
src/inet.c
|
src/inet.c
|
||||||
src/random.c
|
src/random.c
|
||||||
src/strscpy.c
|
src/strscpy.c
|
||||||
|
src/strtok.c
|
||||||
|
src/thread-common.c
|
||||||
src/threadpool.c
|
src/threadpool.c
|
||||||
src/timer.c
|
src/timer.c
|
||||||
src/uv-common.c
|
src/uv-common.c
|
||||||
@ -132,14 +186,17 @@ set(uv_sources
|
|||||||
src/version.c)
|
src/version.c)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602)
|
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00 _CRT_DECLARE_NONSTDC_NAMES=0)
|
||||||
list(APPEND uv_libraries
|
list(APPEND uv_libraries
|
||||||
psapi
|
psapi
|
||||||
user32
|
user32
|
||||||
advapi32
|
advapi32
|
||||||
iphlpapi
|
iphlpapi
|
||||||
userenv
|
userenv
|
||||||
ws2_32)
|
ws2_32
|
||||||
|
dbghelp
|
||||||
|
ole32
|
||||||
|
shell32)
|
||||||
list(APPEND uv_sources
|
list(APPEND uv_sources
|
||||||
src/win/async.c
|
src/win/async.c
|
||||||
src/win/core.c
|
src/win/core.c
|
||||||
@ -215,16 +272,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
|||||||
list(APPEND uv_defines _GNU_SOURCE)
|
list(APPEND uv_defines _GNU_SOURCE)
|
||||||
list(APPEND uv_libraries dl)
|
list(APPEND uv_libraries dl)
|
||||||
list(APPEND uv_sources
|
list(APPEND uv_sources
|
||||||
src/unix/android-ifaddrs.c
|
src/unix/linux.c
|
||||||
src/unix/linux-core.c
|
|
||||||
src/unix/linux-inotify.c
|
|
||||||
src/unix/linux-syscalls.c
|
|
||||||
src/unix/procfs-exepath.c
|
src/unix/procfs-exepath.c
|
||||||
src/unix/pthread-fixes.c
|
|
||||||
src/unix/random-getentropy.c
|
src/unix/random-getentropy.c
|
||||||
src/unix/random-getrandom.c
|
src/unix/random-getrandom.c
|
||||||
src/unix/random-sysctl-linux.c
|
src/unix/random-sysctl-linux.c)
|
||||||
src/unix/epoll.c)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux")
|
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux")
|
||||||
@ -259,17 +311,26 @@ if(APPLE)
|
|||||||
src/unix/fsevents.c)
|
src/unix/fsevents.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "GNU")
|
||||||
|
list(APPEND uv_defines _GNU_SOURCE _POSIX_C_SOURCE=200112 _XOPEN_SOURCE=500)
|
||||||
|
list(APPEND uv_libraries dl)
|
||||||
|
list(APPEND uv_sources
|
||||||
|
src/unix/bsd-ifaddrs.c
|
||||||
|
src/unix/no-fsevents.c
|
||||||
|
src/unix/no-proctitle.c
|
||||||
|
src/unix/posix-hrtime.c
|
||||||
|
src/unix/posix-poll.c
|
||||||
|
src/unix/hurd.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
list(APPEND uv_defines _GNU_SOURCE _POSIX_C_SOURCE=200112)
|
list(APPEND uv_defines _GNU_SOURCE _POSIX_C_SOURCE=200112)
|
||||||
list(APPEND uv_libraries dl rt)
|
list(APPEND uv_libraries dl rt)
|
||||||
list(APPEND uv_sources
|
list(APPEND uv_sources
|
||||||
src/unix/linux-core.c
|
src/unix/linux.c
|
||||||
src/unix/linux-inotify.c
|
|
||||||
src/unix/linux-syscalls.c
|
|
||||||
src/unix/procfs-exepath.c
|
src/unix/procfs-exepath.c
|
||||||
src/unix/random-getrandom.c
|
src/unix/random-getrandom.c
|
||||||
src/unix/random-sysctl-linux.c
|
src/unix/random-sysctl-linux.c)
|
||||||
src/unix/epoll.c)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
||||||
@ -300,7 +361,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
|||||||
list(APPEND uv_defines _XOPEN_SOURCE=600)
|
list(APPEND uv_defines _XOPEN_SOURCE=600)
|
||||||
list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED)
|
list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED)
|
||||||
list(APPEND uv_sources
|
list(APPEND uv_sources
|
||||||
src/unix/pthread-fixes.c
|
|
||||||
src/unix/os390.c
|
src/unix/os390.c
|
||||||
src/unix/os390-syscalls.c
|
src/unix/os390-syscalls.c
|
||||||
src/unix/os390-proctitle.c)
|
src/unix/os390-proctitle.c)
|
||||||
@ -338,6 +398,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS400")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||||
|
if(CMAKE_SYSTEM_VERSION STREQUAL "5.10")
|
||||||
|
list(APPEND uv_defines SUNOS_NO_IFADDRS)
|
||||||
|
list(APPEND uv_libraries rt)
|
||||||
|
endif()
|
||||||
list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500 _REENTRANT)
|
list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500 _REENTRANT)
|
||||||
list(APPEND uv_libraries kstat nsl sendfile socket)
|
list(APPEND uv_libraries kstat nsl sendfile socket)
|
||||||
list(APPEND uv_sources
|
list(APPEND uv_sources
|
||||||
@ -372,25 +436,42 @@ if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|Linux|NetBSD|OpenBSD")
|
|||||||
list(APPEND uv_test_libraries util)
|
list(APPEND uv_test_libraries util)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(uv SHARED ${uv_sources})
|
if(CYGWIN OR MSYS)
|
||||||
target_compile_definitions(uv
|
list(APPEND uv_defines _GNU_SOURCE)
|
||||||
INTERFACE
|
list(APPEND uv_sources
|
||||||
USING_UV_SHARED=1
|
src/unix/cygwin.c
|
||||||
PRIVATE
|
src/unix/bsd-ifaddrs.c
|
||||||
BUILDING_UV_SHARED=1
|
src/unix/no-fsevents.c
|
||||||
${uv_defines})
|
src/unix/no-proctitle.c
|
||||||
target_compile_options(uv PRIVATE ${uv_cflags})
|
src/unix/posix-hrtime.c
|
||||||
target_include_directories(uv
|
src/unix/posix-poll.c
|
||||||
PUBLIC
|
src/unix/procfs-exepath.c
|
||||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
src/unix/sysinfo-loadavg.c
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
src/unix/sysinfo-memory.c)
|
||||||
PRIVATE
|
endif()
|
||||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
if(LIBUV_BUILD_SHARED)
|
||||||
target_include_directories(uv PUBLIC $<BUILD_INTERFACE:${ZOSLIB_DIR}/include>)
|
add_library(uv SHARED ${uv_sources})
|
||||||
set_target_properties(uv PROPERTIES LINKER_LANGUAGE CXX)
|
target_compile_definitions(uv
|
||||||
|
INTERFACE
|
||||||
|
USING_UV_SHARED=1
|
||||||
|
PRIVATE
|
||||||
|
BUILDING_UV_SHARED=1
|
||||||
|
${uv_defines})
|
||||||
|
target_compile_options(uv PRIVATE ${uv_cflags})
|
||||||
|
target_include_directories(uv
|
||||||
|
PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||||
|
PRIVATE
|
||||||
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||||
|
target_include_directories(uv PUBLIC $<BUILD_INTERFACE:${ZOSLIB_DIR}/include>)
|
||||||
|
set_target_properties(uv PROPERTIES LINKER_LANGUAGE CXX)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(uv ${uv_libraries})
|
||||||
|
set_target_properties(uv PROPERTIES OUTPUT_NAME "uv")
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(uv ${uv_libraries})
|
|
||||||
|
|
||||||
add_library(uv_a STATIC ${uv_sources})
|
add_library(uv_a STATIC ${uv_sources})
|
||||||
target_compile_definitions(uv_a PRIVATE ${uv_defines})
|
target_compile_definitions(uv_a PRIVATE ${uv_defines})
|
||||||
@ -406,6 +487,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
|||||||
set_target_properties(uv_a PROPERTIES LINKER_LANGUAGE CXX)
|
set_target_properties(uv_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(uv_a ${uv_libraries})
|
target_link_libraries(uv_a ${uv_libraries})
|
||||||
|
set_target_properties(uv_a PROPERTIES OUTPUT_NAME "uv")
|
||||||
|
if(WIN32)
|
||||||
|
set_target_properties(uv_a PROPERTIES PREFIX "lib")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(LIBUV_BUILD_TESTS)
|
if(LIBUV_BUILD_TESTS)
|
||||||
# Small hack: use ${uv_test_sources} now to get the runner skeleton,
|
# Small hack: use ${uv_test_sources} now to get the runner skeleton,
|
||||||
@ -418,6 +503,7 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/benchmark-fs-stat.c
|
test/benchmark-fs-stat.c
|
||||||
test/benchmark-getaddrinfo.c
|
test/benchmark-getaddrinfo.c
|
||||||
test/benchmark-loop-count.c
|
test/benchmark-loop-count.c
|
||||||
|
test/benchmark-queue-work.c
|
||||||
test/benchmark-million-async.c
|
test/benchmark-million-async.c
|
||||||
test/benchmark-million-timers.c
|
test/benchmark-million-timers.c
|
||||||
test/benchmark-multi-accept.c
|
test/benchmark-multi-accept.c
|
||||||
@ -447,7 +533,6 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/test-async-null-cb.c
|
test/test-async-null-cb.c
|
||||||
test/test-async.c
|
test/test-async.c
|
||||||
test/test-barrier.c
|
test/test-barrier.c
|
||||||
test/test-callback-order.c
|
|
||||||
test/test-callback-stack.c
|
test/test-callback-stack.c
|
||||||
test/test-close-fd.c
|
test/test-close-fd.c
|
||||||
test/test-close-order.c
|
test/test-close-order.c
|
||||||
@ -487,6 +572,7 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/test-hrtime.c
|
test/test-hrtime.c
|
||||||
test/test-idle.c
|
test/test-idle.c
|
||||||
test/test-idna.c
|
test/test-idna.c
|
||||||
|
test/test-iouring-pollhup.c
|
||||||
test/test-ip4-addr.c
|
test/test-ip4-addr.c
|
||||||
test/test-ip6-addr.c
|
test/test-ip6-addr.c
|
||||||
test/test-ip-name.c
|
test/test-ip-name.c
|
||||||
@ -546,10 +632,12 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/test-spawn.c
|
test/test-spawn.c
|
||||||
test/test-stdio-over-pipes.c
|
test/test-stdio-over-pipes.c
|
||||||
test/test-strscpy.c
|
test/test-strscpy.c
|
||||||
|
test/test-strtok.c
|
||||||
test/test-tcp-alloc-cb-fail.c
|
test/test-tcp-alloc-cb-fail.c
|
||||||
test/test-tcp-bind-error.c
|
test/test-tcp-bind-error.c
|
||||||
test/test-tcp-bind6-error.c
|
test/test-tcp-bind6-error.c
|
||||||
test/test-tcp-close-accept.c
|
test/test-tcp-close-accept.c
|
||||||
|
test/test-tcp-close-after-read-timeout.c
|
||||||
test/test-tcp-close-while-connecting.c
|
test/test-tcp-close-while-connecting.c
|
||||||
test/test-tcp-close.c
|
test/test-tcp-close.c
|
||||||
test/test-tcp-close-reset.c
|
test/test-tcp-close-reset.c
|
||||||
@ -562,9 +650,12 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/test-tcp-oob.c
|
test/test-tcp-oob.c
|
||||||
test/test-tcp-open.c
|
test/test-tcp-open.c
|
||||||
test/test-tcp-read-stop.c
|
test/test-tcp-read-stop.c
|
||||||
|
test/test-tcp-reuseport.c
|
||||||
test/test-tcp-read-stop-start.c
|
test/test-tcp-read-stop-start.c
|
||||||
|
test/test-tcp-rst.c
|
||||||
test/test-tcp-shutdown-after-write.c
|
test/test-tcp-shutdown-after-write.c
|
||||||
test/test-tcp-try-write.c
|
test/test-tcp-try-write.c
|
||||||
|
test/test-tcp-write-in-a-row.c
|
||||||
test/test-tcp-try-write-error.c
|
test/test-tcp-try-write-error.c
|
||||||
test/test-tcp-unexpected-read.c
|
test/test-tcp-unexpected-read.c
|
||||||
test/test-tcp-write-after-connect.c
|
test/test-tcp-write-after-connect.c
|
||||||
@ -573,8 +664,11 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/test-tcp-write-to-half-open-connection.c
|
test/test-tcp-write-to-half-open-connection.c
|
||||||
test/test-tcp-writealot.c
|
test/test-tcp-writealot.c
|
||||||
test/test-test-macros.c
|
test/test-test-macros.c
|
||||||
|
test/test-thread-affinity.c
|
||||||
test/test-thread-equal.c
|
test/test-thread-equal.c
|
||||||
test/test-thread.c
|
test/test-thread.c
|
||||||
|
test/test-thread-name.c
|
||||||
|
test/test-thread-priority.c
|
||||||
test/test-threadpool-cancel.c
|
test/test-threadpool-cancel.c
|
||||||
test/test-threadpool.c
|
test/test-threadpool.c
|
||||||
test/test-timer-again.c
|
test/test-timer-again.c
|
||||||
@ -605,6 +699,8 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/test-udp-sendmmsg-error.c
|
test/test-udp-sendmmsg-error.c
|
||||||
test/test-udp-send-unreachable.c
|
test/test-udp-send-unreachable.c
|
||||||
test/test-udp-try-send.c
|
test/test-udp-try-send.c
|
||||||
|
test/test-udp-recv-in-a-row.c
|
||||||
|
test/test-udp-reuseport.c
|
||||||
test/test-uname.c
|
test/test-uname.c
|
||||||
test/test-walk-handles.c
|
test/test-walk-handles.c
|
||||||
test/test-watcher-cross-stop.c)
|
test/test-watcher-cross-stop.c)
|
||||||
@ -621,6 +717,12 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
set_tests_properties(uv_test PROPERTIES ENVIRONMENT
|
set_tests_properties(uv_test PROPERTIES ENVIRONMENT
|
||||||
"LIBPATH=${CMAKE_BINARY_DIR}:$ENV{LIBPATH}")
|
"LIBPATH=${CMAKE_BINARY_DIR}:$ENV{LIBPATH}")
|
||||||
endif()
|
endif()
|
||||||
|
if(WIN32)
|
||||||
|
add_custom_command(TARGET uv_run_tests POST_BUILD
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||||
|
"$<TARGET_FILE:uv_run_tests>"
|
||||||
|
"$<TARGET_FILE_DIR:uv_run_tests>/uv_run_tests_no_ext")
|
||||||
|
endif()
|
||||||
add_executable(uv_run_tests_a ${uv_test_sources} uv_win_longpath.manifest)
|
add_executable(uv_run_tests_a ${uv_test_sources} uv_win_longpath.manifest)
|
||||||
target_compile_definitions(uv_run_tests_a PRIVATE ${uv_defines})
|
target_compile_definitions(uv_run_tests_a PRIVATE ${uv_defines})
|
||||||
target_compile_options(uv_run_tests_a PRIVATE ${uv_cflags})
|
target_compile_options(uv_run_tests_a PRIVATE ${uv_cflags})
|
||||||
@ -637,6 +739,12 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
set_target_properties(uv_run_tests PROPERTIES LINKER_LANGUAGE CXX)
|
set_target_properties(uv_run_tests PROPERTIES LINKER_LANGUAGE CXX)
|
||||||
set_target_properties(uv_run_tests_a PROPERTIES LINKER_LANGUAGE CXX)
|
set_target_properties(uv_run_tests_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||||
endif()
|
endif()
|
||||||
|
if(WIN32)
|
||||||
|
add_custom_command(TARGET uv_run_tests_a POST_BUILD
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||||
|
"$<TARGET_FILE:uv_run_tests_a>"
|
||||||
|
"$<TARGET_FILE_DIR:uv_run_tests_a>/uv_run_tests_a_no_ext")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Now for some gibbering horrors from beyond the stars...
|
# Now for some gibbering horrors from beyond the stars...
|
||||||
@ -648,30 +756,55 @@ string(REPLACE ";" " " LIBS "${LIBS}")
|
|||||||
file(STRINGS configure.ac configure_ac REGEX ^AC_INIT)
|
file(STRINGS configure.ac configure_ac REGEX ^AC_INIT)
|
||||||
string(REGEX MATCH "([0-9]+)[.][0-9]+[.][0-9]+" PACKAGE_VERSION "${configure_ac}")
|
string(REGEX MATCH "([0-9]+)[.][0-9]+[.][0-9]+" PACKAGE_VERSION "${configure_ac}")
|
||||||
set(UV_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
set(UV_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||||
# The version in the filename is mirroring the behaviour of autotools.
|
|
||||||
set_target_properties(uv PROPERTIES
|
|
||||||
VERSION ${UV_VERSION_MAJOR}.0.0
|
|
||||||
SOVERSION ${UV_VERSION_MAJOR})
|
|
||||||
set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
|
set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
|
set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
|
||||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||||
configure_file(libuv.pc.in libuv.pc @ONLY)
|
|
||||||
configure_file(libuv-static.pc.in libuv-static.pc @ONLY)
|
configure_file(libuv-static.pc.in libuv-static.pc @ONLY)
|
||||||
|
|
||||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||||
install(FILES ${PROJECT_BINARY_DIR}/libuv.pc ${PROJECT_BINARY_DIR}/libuv-static.pc
|
install(FILES LICENSE-extra DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||||
|
install(FILES ${PROJECT_BINARY_DIR}/libuv-static.pc
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
install(TARGETS uv EXPORT libuvConfig
|
install(TARGETS uv_a EXPORT libuvConfig
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
install(EXPORT libuvConfig
|
||||||
install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv
|
||||||
install(EXPORT libuvConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv)
|
NAMESPACE libuv::)
|
||||||
|
|
||||||
|
if(LIBUV_BUILD_SHARED)
|
||||||
|
# The version in the filename is mirroring the behaviour of autotools.
|
||||||
|
set_target_properties(uv PROPERTIES
|
||||||
|
VERSION ${UV_VERSION_MAJOR}.0.0
|
||||||
|
SOVERSION ${UV_VERSION_MAJOR})
|
||||||
|
configure_file(libuv.pc.in libuv.pc @ONLY)
|
||||||
|
install(FILES ${PROJECT_BINARY_DIR}/libuv.pc
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
|
install(TARGETS uv EXPORT libuvConfig
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
set(CMAKE_DEBUG_POSTFIX d)
|
set(CMAKE_DEBUG_POSTFIX d)
|
||||||
|
get_filename_component(CMAKE_C_COMPILER_DIR ${CMAKE_C_COMPILER} DIRECTORY)
|
||||||
|
if(ASAN)
|
||||||
|
file(INSTALL "${CMAKE_C_COMPILER_DIR}/llvm-symbolizer.exe" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
file(INSTALL "${CMAKE_C_COMPILER_DIR}/clang_rt.asan_dynamic-x86_64.dll" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
file(INSTALL "${CMAKE_C_COMPILER_DIR}/clang_rt.asan_dbg_dynamic-x86_64.dll" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
set(LIB_SELECTED uv)
|
||||||
|
else()
|
||||||
|
set(LIB_SELECTED uv_a)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(libuv::libuv ALIAS ${LIB_SELECTED})
|
||||||
|
|
||||||
message(STATUS "summary of build options:
|
message(STATUS "summary of build options:
|
||||||
Install prefix: ${CMAKE_INSTALL_PREFIX}
|
Install prefix: ${CMAKE_INSTALL_PREFIX}
|
||||||
Target system: ${CMAKE_SYSTEM_NAME}
|
Target system: ${CMAKE_SYSTEM_NAME}
|
||||||
|
|||||||
51
LICENSE
51
LICENSE
@ -1,6 +1,3 @@
|
|||||||
libuv is licensed for use as follows:
|
|
||||||
|
|
||||||
====
|
|
||||||
Copyright (c) 2015-present libuv project contributors.
|
Copyright (c) 2015-present libuv project contributors.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -20,51 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
IN THE SOFTWARE.
|
IN THE SOFTWARE.
|
||||||
====
|
|
||||||
|
|
||||||
This license applies to parts of libuv originating from the
|
|
||||||
https://github.com/joyent/libuv repository:
|
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to
|
|
||||||
deal in the Software without restriction, including without limitation the
|
|
||||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
IN THE SOFTWARE.
|
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
This license applies to all parts of libuv that are not externally
|
|
||||||
maintained libraries.
|
|
||||||
|
|
||||||
The externally maintained libraries used by libuv are:
|
|
||||||
|
|
||||||
- tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license.
|
|
||||||
|
|
||||||
- inet_pton and inet_ntop implementations, contained in src/inet.c, are
|
|
||||||
copyright the Internet Systems Consortium, Inc., and licensed under the ISC
|
|
||||||
license.
|
|
||||||
|
|
||||||
- stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three
|
|
||||||
clause BSD license.
|
|
||||||
|
|
||||||
- pthread-fixes.c, copyright Google Inc. and Sony Mobile Communications AB.
|
|
||||||
Three clause BSD license.
|
|
||||||
|
|
||||||
- android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design
|
|
||||||
Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement
|
|
||||||
n° 289016). Three clause BSD license.
|
|
||||||
|
|||||||
36
LICENSE-extra
Normal file
36
LICENSE-extra
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
This license applies to parts of libuv originating from the
|
||||||
|
https://github.com/joyent/libuv repository:
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
deal in the Software without restriction, including without limitation the
|
||||||
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
This license applies to all parts of libuv that are not externally
|
||||||
|
maintained libraries.
|
||||||
|
|
||||||
|
The externally maintained libraries used by libuv are:
|
||||||
|
|
||||||
|
- tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license.
|
||||||
|
|
||||||
|
- inet_pton and inet_ntop implementations, contained in src/inet.c, are
|
||||||
|
copyright the Internet Systems Consortium, Inc., and licensed under the ISC
|
||||||
|
license.
|
||||||
15
LINKS.md
15
LINKS.md
@ -1,16 +1,20 @@
|
|||||||
### Apps / VM
|
### Apps / VM
|
||||||
|
* [AliceO2](https://github.com/AliceO2Group/AliceO2): The framework and detector specific code for the reconstruction, calibration and simulation for the ALICE experiment at CERN.
|
||||||
|
* [Beam](https://github.com/BeamMW/beam): A scalable, confidential cryptocurrency based on the Mimblewimble protocol.
|
||||||
* [BIND 9](https://bind.isc.org/): DNS software system including an authoritative server, a recursive resolver and related utilities.
|
* [BIND 9](https://bind.isc.org/): DNS software system including an authoritative server, a recursive resolver and related utilities.
|
||||||
* [cjdns](https://github.com/cjdelisle/cjdns): Encrypted self-configuring network/VPN routing engine
|
* [cjdns](https://github.com/cjdelisle/cjdns): Encrypted self-configuring network/VPN routing engine
|
||||||
* [clearskies_core](https://github.com/larroy/clearskies_core): Clearskies file synchronization program. (C++11)
|
* [clearskies_core](https://github.com/larroy/clearskies_core): Clearskies file synchronization program. (C++11)
|
||||||
* [CMake](https://cmake.org) open-source, cross-platform family of tools designed to build, test and package software
|
* [CMake](https://cmake.org) open-source, cross-platform family of tools designed to build, test and package software
|
||||||
* [Coherence](https://github.com/liesware/coherence/): Cryptographic server for modern web apps.
|
* [Cocos-Engine](https://github.com/cocos/cocos-engine): The runtime framework for Cocos Creator editor.
|
||||||
|
* [Coherence](https://github.com/liesware/coherence/): Cryptographic server for modern web apps.
|
||||||
|
* [DPS8M](https://dps8m.gitlab.io): GE ∕ Honeywell ∕ Bull DPS‑8/M and 6180/L68 mainframe simulator.
|
||||||
* [DPS-For-IoT](https://github.com/intel/dps-for-iot/wiki): Fully distributed publish/subscribe protocol.
|
* [DPS-For-IoT](https://github.com/intel/dps-for-iot/wiki): Fully distributed publish/subscribe protocol.
|
||||||
* [HashLink](https://github.com/HaxeFoundation/hashlink): Haxe run-time with libuv support included.
|
* [HashLink](https://github.com/HaxeFoundation/hashlink): Haxe run-time with libuv support included.
|
||||||
* [Haywire](https://github.com/kellabyte/Haywire): Asynchronous HTTP server.
|
* [Haywire](https://github.com/kellabyte/Haywire): Asynchronous HTTP server.
|
||||||
* [H2O](https://github.com/h2o/h2o): An optimized HTTP server with support for HTTP/1.x and HTTP/2.
|
* [H2O](https://github.com/h2o/h2o): An optimized HTTP server with support for HTTP/1.x and HTTP/2.
|
||||||
* [Igropyr](https://github.com/guenchi/Igropyr): a async Scheme http server base on libuv.
|
* [Igropyr](https://github.com/guenchi/Igropyr): a async Scheme http server base on libuv.
|
||||||
* [Julia](http://julialang.org/): Scientific computing programming language
|
* [Julia](http://julialang.org/): Scientific computing programming language
|
||||||
* [Kestrel](https://github.com/aspnet/AspNetCore/tree/master/src/Servers/Kestrel): web server (C# + libuv + [ASP.NET Core](http://github.com/aspnet))
|
* [Kestrel](https://github.com/dotnet/aspnetcore/tree/main/src/Servers/Kestrel): web server (C# + libuv + [ASP.NET Core](http://github.com/aspnet))
|
||||||
* [Knot DNS Resolver](https://www.knot-resolver.cz/): A minimalistic DNS caching resolver
|
* [Knot DNS Resolver](https://www.knot-resolver.cz/): A minimalistic DNS caching resolver
|
||||||
* [Lever](http://leverlanguage.com): runtime, libuv at the 0.9.0 release
|
* [Lever](http://leverlanguage.com): runtime, libuv at the 0.9.0 release
|
||||||
* [libnode](https://github.com/plenluno/libnode): C++ implementation of Node.js
|
* [libnode](https://github.com/plenluno/libnode): C++ implementation of Node.js
|
||||||
@ -30,8 +34,11 @@
|
|||||||
* [phastlight](https://github.com/phastlight/phastlight): Command line tool and web server written in PHP 5.3+ inspired by Node.js
|
* [phastlight](https://github.com/phastlight/phastlight): Command line tool and web server written in PHP 5.3+ inspired by Node.js
|
||||||
* [pilight](https://www.pilight.org/): home automation ("domotica")
|
* [pilight](https://www.pilight.org/): home automation ("domotica")
|
||||||
* [pixie](https://github.com/pixie-lang/pixie): clojure-inspired lisp with a tracing JIT
|
* [pixie](https://github.com/pixie-lang/pixie): clojure-inspired lisp with a tracing JIT
|
||||||
|
* [Pixie-io](https://github.com/pixie-io/pixie): Open-source observability tool for Kubernetes applications.
|
||||||
* [potion](https://github.com/perl11/potion)/[p2](https://github.com/perl11/p2): runtime
|
* [potion](https://github.com/perl11/potion)/[p2](https://github.com/perl11/p2): runtime
|
||||||
* [racer](https://libraries.io/rubygems/racer): Ruby web server written as an C extension
|
* [racer](https://libraries.io/rubygems/racer): Ruby web server written as an C extension
|
||||||
|
* [scala-native-loop](https://github.com/scala-native/scala-native-loop): Extensible event loop and async-oriented IO for Scala Native; powered by libuv
|
||||||
|
* [Socket Runtime](https://sockets.sh): A runtime for creating native cross-platform software on mobile and desktop using HTML, CSS, and JavaScript
|
||||||
* [spider-gazelle](https://github.com/cotag/spider-gazelle): Ruby web server using libuv bindings
|
* [spider-gazelle](https://github.com/cotag/spider-gazelle): Ruby web server using libuv bindings
|
||||||
* [Suave](http://suave.io/): A simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition
|
* [Suave](http://suave.io/): A simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition
|
||||||
* [Swish](https://github.com/becls/swish/): Concurrency engine with Erlang-like concepts. Includes a web server.
|
* [Swish](https://github.com/becls/swish/): Concurrency engine with Erlang-like concepts. Includes a web server.
|
||||||
@ -39,6 +46,7 @@
|
|||||||
* [Urbit](http://urbit.org): runtime
|
* [Urbit](http://urbit.org): runtime
|
||||||
* [uv_callback](https://github.com/litesync/uv_callback) libuv thread communication
|
* [uv_callback](https://github.com/litesync/uv_callback) libuv thread communication
|
||||||
* [uvloop](https://github.com/MagicStack/uvloop): Ultra fast implementation of python's asyncio event loop on top of libuv
|
* [uvloop](https://github.com/MagicStack/uvloop): Ultra fast implementation of python's asyncio event loop on top of libuv
|
||||||
|
* [WPILib](https://github.com/wpilibsuite/allwpilib): Libraries for creating robot programs for the roboRIO.
|
||||||
* [Wren CLI](https://github.com/wren-lang/wren-cli): For io, process, scheduler and timer modules
|
* [Wren CLI](https://github.com/wren-lang/wren-cli): For io, process, scheduler and timer modules
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
@ -59,6 +67,7 @@
|
|||||||
* [lluv](https://github.com/moteus/lua-lluv)
|
* [lluv](https://github.com/moteus/lua-lluv)
|
||||||
* C++11
|
* C++11
|
||||||
* [uvpp](https://github.com/larroy/uvpp) - Not complete, exposes very few aspects of `libuv`
|
* [uvpp](https://github.com/larroy/uvpp) - Not complete, exposes very few aspects of `libuv`
|
||||||
|
* [nsuv](https://github.com/nodesource/nsuv) - Template wrapper focused on enforcing compile-time type safety when propagating data
|
||||||
* C++17
|
* C++17
|
||||||
* [uvw](https://github.com/skypjack/uvw) - Header-only, event based, tiny and easy to use *libuv* wrapper in modern C++.
|
* [uvw](https://github.com/skypjack/uvw) - Header-only, event based, tiny and easy to use *libuv* wrapper in modern C++.
|
||||||
* Python
|
* Python
|
||||||
@ -99,3 +108,5 @@
|
|||||||
* [node.pas](https://github.com/vovach777/node.pas) NodeJS-like ecosystem
|
* [node.pas](https://github.com/vovach777/node.pas) NodeJS-like ecosystem
|
||||||
* Haskell
|
* Haskell
|
||||||
* [Z.Haskell](https://z.haskell.world)
|
* [Z.Haskell](https://z.haskell.world)
|
||||||
|
* C3
|
||||||
|
* [libuv.c3l](https://github.com/velikoss/libuv.c3l)
|
||||||
|
|||||||
@ -1,23 +1,16 @@
|
|||||||
|
|
||||||
# Project Maintainers
|
# Project Maintainers
|
||||||
|
|
||||||
libuv is currently managed by the following individuals:
|
libuv is currently managed by the following individuals:
|
||||||
|
|
||||||
* **Anna Henningsen** ([@addaleax](https://github.com/addaleax))
|
|
||||||
* **Bartosz Sosnowski** ([@bzoz](https://github.com/bzoz))
|
|
||||||
* **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis))
|
* **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis))
|
||||||
- GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis)
|
- GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis)
|
||||||
* **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus))
|
|
||||||
* **Colin Ihrig** ([@cjihrig](https://github.com/cjihrig))
|
* **Colin Ihrig** ([@cjihrig](https://github.com/cjihrig))
|
||||||
- GPG key: 94AE 3667 5C46 4D64 BAFA 68DD 7434 390B DBE9 B9C5 (pubkey-cjihrig)
|
- GPG key: 94AE 3667 5C46 4D64 BAFA 68DD 7434 390B DBE9 B9C5 (pubkey-cjihrig)
|
||||||
- GPG key: 5735 3E0D BDAA A7E8 39B6 6A1A FF47 D5E4 AD8B 4FDC (pubkey-cjihrig-kb)
|
- GPG key: 5735 3E0D BDAA A7E8 39B6 6A1A FF47 D5E4 AD8B 4FDC (pubkey-cjihrig-kb)
|
||||||
* **Fedor Indutny** ([@indutny](https://github.com/indutny))
|
|
||||||
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
|
|
||||||
* **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq))
|
|
||||||
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
|
|
||||||
* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
|
* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
|
||||||
- GPG key: AEAD 0A4B 6867 6775 1A0E 4AEF 34A2 5FB1 2824 6514 (pubkey-vtjnash)
|
- GPG key: AEAD 0A4B 6867 6775 1A0E 4AEF 34A2 5FB1 2824 6514 (pubkey-vtjnash)
|
||||||
* **John Barboza** ([@jbarz](https://github.com/jbarz))
|
- GPG key: CFBB 9CA9 A5BE AFD7 0E2B 3C5A 79A6 7C55 A367 9C8B (pubkey2022-vtjnash)
|
||||||
|
* **Jiawen Geng** ([@gengjiawen](https://github.com/gengjiawen))
|
||||||
* **Kaoru Takanashi** ([@erw7](https://github.com/erw7))
|
* **Kaoru Takanashi** ([@erw7](https://github.com/erw7))
|
||||||
- GPG Key: 5804 F999 8A92 2AFB A398 47A0 7183 5090 6134 887F (pubkey-erw7)
|
- GPG Key: 5804 F999 8A92 2AFB A398 47A0 7183 5090 6134 887F (pubkey-erw7)
|
||||||
* **Richard Lau** ([@richardlau](https://github.com/richardlau))
|
* **Richard Lau** ([@richardlau](https://github.com/richardlau))
|
||||||
@ -26,6 +19,18 @@ libuv is currently managed by the following individuals:
|
|||||||
- GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
|
- GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
|
||||||
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
|
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
|
||||||
- GPG key: FDF5 1936 4458 319F A823 3DC9 410E 5553 AE9B C059 (pubkey-saghul)
|
- GPG key: FDF5 1936 4458 319F A823 3DC9 410E 5553 AE9B C059 (pubkey-saghul)
|
||||||
|
* **Trevor Norris** ([@trevnorris](https://github.com/trevnorris))
|
||||||
|
- GPG key: AEFC 279A 0C93 0676 7E58 29A1 251C A676 820D C7F3 (pubkey-trevnorris)
|
||||||
|
|
||||||
|
## Project Maintainers emeriti
|
||||||
|
|
||||||
|
* **Anna Henningsen** ([@addaleax](https://github.com/addaleax))
|
||||||
|
* **Bartosz Sosnowski** ([@bzoz](https://github.com/bzoz))
|
||||||
|
* **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus))
|
||||||
|
* **Fedor Indutny** ([@indutny](https://github.com/indutny))
|
||||||
|
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
|
||||||
|
* **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq))
|
||||||
|
* **John Barboza** ([@jbarz](https://github.com/jbarz))
|
||||||
|
|
||||||
## Storing a maintainer key in Git
|
## Storing a maintainer key in Git
|
||||||
|
|
||||||
|
|||||||
59
Makefile.am
59
Makefile.am
@ -27,8 +27,8 @@ uvinclude_HEADERS = include/uv/errno.h \
|
|||||||
CLEANFILES =
|
CLEANFILES =
|
||||||
|
|
||||||
lib_LTLIBRARIES = libuv.la
|
lib_LTLIBRARIES = libuv.la
|
||||||
libuv_la_CFLAGS = @CFLAGS@
|
libuv_la_CFLAGS = $(AM_CFLAGS)
|
||||||
libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0
|
libuv_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 1:0:0
|
||||||
libuv_la_SOURCES = src/fs-poll.c \
|
libuv_la_SOURCES = src/fs-poll.c \
|
||||||
src/heap-inl.h \
|
src/heap-inl.h \
|
||||||
src/idna.c \
|
src/idna.c \
|
||||||
@ -38,12 +38,15 @@ libuv_la_SOURCES = src/fs-poll.c \
|
|||||||
src/random.c \
|
src/random.c \
|
||||||
src/strscpy.c \
|
src/strscpy.c \
|
||||||
src/strscpy.h \
|
src/strscpy.h \
|
||||||
|
src/thread-common.c \
|
||||||
src/threadpool.c \
|
src/threadpool.c \
|
||||||
src/timer.c \
|
src/timer.c \
|
||||||
src/uv-data-getter-setters.c \
|
src/uv-data-getter-setters.c \
|
||||||
src/uv-common.c \
|
src/uv-common.c \
|
||||||
src/uv-common.h \
|
src/uv-common.h \
|
||||||
src/version.c
|
src/version.c \
|
||||||
|
src/strtok.c \
|
||||||
|
src/strtok.h
|
||||||
|
|
||||||
if SUNOS
|
if SUNOS
|
||||||
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
|
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
|
||||||
@ -56,7 +59,7 @@ if WINNT
|
|||||||
uvinclude_HEADERS += include/uv/win.h include/uv/tree.h
|
uvinclude_HEADERS += include/uv/win.h include/uv/tree.h
|
||||||
AM_CPPFLAGS += -I$(top_srcdir)/src/win \
|
AM_CPPFLAGS += -I$(top_srcdir)/src/win \
|
||||||
-DWIN32_LEAN_AND_MEAN \
|
-DWIN32_LEAN_AND_MEAN \
|
||||||
-D_WIN32_WINNT=0x0602
|
-D_WIN32_WINNT=0x0A00
|
||||||
libuv_la_SOURCES += src/win/async.c \
|
libuv_la_SOURCES += src/win/async.c \
|
||||||
src/win/atomicops-inl.h \
|
src/win/atomicops-inl.h \
|
||||||
src/win/core.c \
|
src/win/core.c \
|
||||||
@ -94,7 +97,6 @@ else # WINNT
|
|||||||
uvinclude_HEADERS += include/uv/unix.h
|
uvinclude_HEADERS += include/uv/unix.h
|
||||||
AM_CPPFLAGS += -I$(top_srcdir)/src/unix
|
AM_CPPFLAGS += -I$(top_srcdir)/src/unix
|
||||||
libuv_la_SOURCES += src/unix/async.c \
|
libuv_la_SOURCES += src/unix/async.c \
|
||||||
src/unix/atomic-ops.h \
|
|
||||||
src/unix/core.c \
|
src/unix/core.c \
|
||||||
src/unix/dl.c \
|
src/unix/dl.c \
|
||||||
src/unix/fs.c \
|
src/unix/fs.c \
|
||||||
@ -108,7 +110,6 @@ libuv_la_SOURCES += src/unix/async.c \
|
|||||||
src/unix/process.c \
|
src/unix/process.c \
|
||||||
src/unix/random-devurandom.c \
|
src/unix/random-devurandom.c \
|
||||||
src/unix/signal.c \
|
src/unix/signal.c \
|
||||||
src/unix/spinlock.h \
|
|
||||||
src/unix/stream.c \
|
src/unix/stream.c \
|
||||||
src/unix/tcp.c \
|
src/unix/tcp.c \
|
||||||
src/unix/thread.c \
|
src/unix/thread.c \
|
||||||
@ -120,18 +121,26 @@ endif # WINNT
|
|||||||
EXTRA_DIST = test/fixtures/empty_file \
|
EXTRA_DIST = test/fixtures/empty_file \
|
||||||
test/fixtures/load_error.node \
|
test/fixtures/load_error.node \
|
||||||
test/fixtures/lorem_ipsum.txt \
|
test/fixtures/lorem_ipsum.txt \
|
||||||
|
test/fixtures/one_file/one_file \
|
||||||
include \
|
include \
|
||||||
docs \
|
docs \
|
||||||
img \
|
img \
|
||||||
CONTRIBUTING.md \
|
CONTRIBUTING.md \
|
||||||
LICENSE \
|
LICENSE \
|
||||||
|
LICENSE-extra \
|
||||||
README.md
|
README.md
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TESTS = test/run-tests
|
TESTS = test/run-tests
|
||||||
check_PROGRAMS = test/run-tests
|
check_PROGRAMS = test/run-tests
|
||||||
test_run_tests_CFLAGS =
|
test_run_tests_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
|
if WINNT
|
||||||
|
check-am: test/run-tests_no_ext
|
||||||
|
test/run-tests_no_ext: test/run-tests$(EXEEXT)
|
||||||
|
cp test/run-tests$(EXEEXT) test/run-tests_no_ext
|
||||||
|
endif
|
||||||
|
|
||||||
if SUNOS
|
if SUNOS
|
||||||
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
|
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
|
||||||
@ -139,7 +148,7 @@ if SUNOS
|
|||||||
test_run_tests_CFLAGS += -pthreads
|
test_run_tests_CFLAGS += -pthreads
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test_run_tests_LDFLAGS =
|
test_run_tests_LDFLAGS = $(AM_LDFLAGS)
|
||||||
test_run_tests_SOURCES = test/blackhole-server.c \
|
test_run_tests_SOURCES = test/blackhole-server.c \
|
||||||
test/echo-server.c \
|
test/echo-server.c \
|
||||||
test/run-tests.c \
|
test/run-tests.c \
|
||||||
@ -150,7 +159,6 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-async.c \
|
test/test-async.c \
|
||||||
test/test-async-null-cb.c \
|
test/test-async-null-cb.c \
|
||||||
test/test-barrier.c \
|
test/test-barrier.c \
|
||||||
test/test-callback-order.c \
|
|
||||||
test/test-callback-stack.c \
|
test/test-callback-stack.c \
|
||||||
test/test-close-fd.c \
|
test/test-close-fd.c \
|
||||||
test/test-close-order.c \
|
test/test-close-order.c \
|
||||||
@ -190,6 +198,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-hrtime.c \
|
test/test-hrtime.c \
|
||||||
test/test-idle.c \
|
test/test-idle.c \
|
||||||
test/test-idna.c \
|
test/test-idna.c \
|
||||||
|
test/test-iouring-pollhup.c \
|
||||||
test/test-ip4-addr.c \
|
test/test-ip4-addr.c \
|
||||||
test/test-ip6-addr.c \
|
test/test-ip6-addr.c \
|
||||||
test/test-ip-name.c \
|
test/test-ip-name.c \
|
||||||
@ -250,11 +259,13 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-spawn.c \
|
test/test-spawn.c \
|
||||||
test/test-stdio-over-pipes.c \
|
test/test-stdio-over-pipes.c \
|
||||||
test/test-strscpy.c \
|
test/test-strscpy.c \
|
||||||
|
test/test-strtok.c \
|
||||||
test/test-tcp-alloc-cb-fail.c \
|
test/test-tcp-alloc-cb-fail.c \
|
||||||
test/test-tcp-bind-error.c \
|
test/test-tcp-bind-error.c \
|
||||||
test/test-tcp-bind6-error.c \
|
test/test-tcp-bind6-error.c \
|
||||||
test/test-tcp-close-accept.c \
|
test/test-tcp-close-accept.c \
|
||||||
test/test-tcp-close-while-connecting.c \
|
test/test-tcp-close-while-connecting.c \
|
||||||
|
test/test-tcp-close-after-read-timeout.c \
|
||||||
test/test-tcp-close.c \
|
test/test-tcp-close.c \
|
||||||
test/test-tcp-close-reset.c \
|
test/test-tcp-close-reset.c \
|
||||||
test/test-tcp-create-socket-early.c \
|
test/test-tcp-create-socket-early.c \
|
||||||
@ -265,7 +276,9 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-tcp-flags.c \
|
test/test-tcp-flags.c \
|
||||||
test/test-tcp-open.c \
|
test/test-tcp-open.c \
|
||||||
test/test-tcp-read-stop.c \
|
test/test-tcp-read-stop.c \
|
||||||
|
test/test-tcp-reuseport.c \
|
||||||
test/test-tcp-read-stop-start.c \
|
test/test-tcp-read-stop-start.c \
|
||||||
|
test/test-tcp-rst.c \
|
||||||
test/test-tcp-shutdown-after-write.c \
|
test/test-tcp-shutdown-after-write.c \
|
||||||
test/test-tcp-unexpected-read.c \
|
test/test-tcp-unexpected-read.c \
|
||||||
test/test-tcp-oob.c \
|
test/test-tcp-oob.c \
|
||||||
@ -274,11 +287,15 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-tcp-writealot.c \
|
test/test-tcp-writealot.c \
|
||||||
test/test-tcp-write-fail.c \
|
test/test-tcp-write-fail.c \
|
||||||
test/test-tcp-try-write.c \
|
test/test-tcp-try-write.c \
|
||||||
|
test/test-tcp-write-in-a-row.c \
|
||||||
test/test-tcp-try-write-error.c \
|
test/test-tcp-try-write-error.c \
|
||||||
test/test-tcp-write-queue-order.c \
|
test/test-tcp-write-queue-order.c \
|
||||||
test/test-test-macros.c \
|
test/test-test-macros.c \
|
||||||
test/test-thread-equal.c \
|
test/test-thread-equal.c \
|
||||||
test/test-thread.c \
|
test/test-thread.c \
|
||||||
|
test/test-thread-affinity.c \
|
||||||
|
test/test-thread-name.c \
|
||||||
|
test/test-thread-priority.c \
|
||||||
test/test-threadpool-cancel.c \
|
test/test-threadpool-cancel.c \
|
||||||
test/test-threadpool.c \
|
test/test-threadpool.c \
|
||||||
test/test-timer-again.c \
|
test/test-timer-again.c \
|
||||||
@ -309,6 +326,8 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-udp-sendmmsg-error.c \
|
test/test-udp-sendmmsg-error.c \
|
||||||
test/test-udp-send-unreachable.c \
|
test/test-udp-send-unreachable.c \
|
||||||
test/test-udp-try-send.c \
|
test/test-udp-try-send.c \
|
||||||
|
test/test-udp-recv-in-a-row.c \
|
||||||
|
test/test-udp-reuseport.c \
|
||||||
test/test-uname.c \
|
test/test-uname.c \
|
||||||
test/test-walk-handles.c \
|
test/test-walk-handles.c \
|
||||||
test/test-watcher-cross-stop.c
|
test/test-watcher-cross-stop.c
|
||||||
@ -388,10 +407,7 @@ libuv_la_SOURCES += src/unix/aix-common.c \
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if ANDROID
|
if ANDROID
|
||||||
uvinclude_HEADERS += include/uv/android-ifaddrs.h
|
|
||||||
libuv_la_CFLAGS += -D_GNU_SOURCE
|
libuv_la_CFLAGS += -D_GNU_SOURCE
|
||||||
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
|
|
||||||
src/unix/pthread-fixes.c
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if CYGWIN
|
if CYGWIN
|
||||||
@ -415,6 +431,7 @@ libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
|
|||||||
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||||
src/unix/darwin-proctitle.c \
|
src/unix/darwin-proctitle.c \
|
||||||
src/unix/darwin-stub.h \
|
src/unix/darwin-stub.h \
|
||||||
|
src/unix/darwin-syscalls.h \
|
||||||
src/unix/darwin.c \
|
src/unix/darwin.c \
|
||||||
src/unix/fsevents.c \
|
src/unix/fsevents.c \
|
||||||
src/unix/kqueue.c \
|
src/unix/kqueue.c \
|
||||||
@ -457,23 +474,22 @@ endif
|
|||||||
|
|
||||||
if HURD
|
if HURD
|
||||||
uvinclude_HEADERS += include/uv/posix.h
|
uvinclude_HEADERS += include/uv/posix.h
|
||||||
libuv_la_SOURCES += src/unix/no-fsevents.c \
|
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||||
|
src/unix/no-fsevents.c \
|
||||||
|
src/unix/no-proctitle.c \
|
||||||
src/unix/posix-hrtime.c \
|
src/unix/posix-hrtime.c \
|
||||||
src/unix/posix-poll.c
|
src/unix/posix-poll.c \
|
||||||
|
src/unix/hurd.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if LINUX
|
if LINUX
|
||||||
uvinclude_HEADERS += include/uv/linux.h
|
uvinclude_HEADERS += include/uv/linux.h
|
||||||
libuv_la_CFLAGS += -D_GNU_SOURCE
|
libuv_la_CFLAGS += -D_GNU_SOURCE
|
||||||
libuv_la_SOURCES += src/unix/linux-core.c \
|
libuv_la_SOURCES += src/unix/linux.c \
|
||||||
src/unix/linux-inotify.c \
|
|
||||||
src/unix/linux-syscalls.c \
|
|
||||||
src/unix/linux-syscalls.h \
|
|
||||||
src/unix/procfs-exepath.c \
|
src/unix/procfs-exepath.c \
|
||||||
src/unix/proctitle.c \
|
src/unix/proctitle.c \
|
||||||
src/unix/random-getrandom.c \
|
src/unix/random-getrandom.c \
|
||||||
src/unix/random-sysctl-linux.c \
|
src/unix/random-sysctl-linux.c
|
||||||
src/unix/epoll.c
|
|
||||||
test_run_tests_LDFLAGS += -lutil
|
test_run_tests_LDFLAGS += -lutil
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -537,8 +553,7 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \
|
|||||||
-qXPLINK \
|
-qXPLINK \
|
||||||
-qFLOAT=IEEE
|
-qFLOAT=IEEE
|
||||||
libuv_la_LDFLAGS += -qXPLINK
|
libuv_la_LDFLAGS += -qXPLINK
|
||||||
libuv_la_SOURCES += src/unix/pthread-fixes.c \
|
libuv_la_SOURCES += src/unix/os390.c \
|
||||||
src/unix/os390.c \
|
|
||||||
src/unix/os390-syscalls.c \
|
src/unix/os390-syscalls.c \
|
||||||
src/unix/proctitle.c
|
src/unix/proctitle.c
|
||||||
endif
|
endif
|
||||||
|
|||||||
28
README.md
28
README.md
@ -43,8 +43,11 @@ The ABI/API changes can be tracked [here](http://abi-laboratory.pro/tracker/time
|
|||||||
|
|
||||||
## Licensing
|
## Licensing
|
||||||
|
|
||||||
libuv is licensed under the MIT license. Check the [LICENSE file](LICENSE).
|
libuv is licensed under the MIT license. Check the [LICENSE](LICENSE) and
|
||||||
The documentation is licensed under the CC BY 4.0 license. Check the [LICENSE-docs file](LICENSE-docs).
|
[LICENSE-extra](LICENSE-extra) files.
|
||||||
|
|
||||||
|
The documentation is licensed under the CC BY 4.0 license. Check the
|
||||||
|
[LICENSE-docs file](LICENSE-docs).
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
@ -220,6 +223,27 @@ Make sure that you specify the architecture you wish to build for in the
|
|||||||
"ARCHS" flag. You can specify more than one by delimiting with a space
|
"ARCHS" flag. You can specify more than one by delimiting with a space
|
||||||
(e.g. "x86_64 i386").
|
(e.g. "x86_64 i386").
|
||||||
|
|
||||||
|
### Install with vcpkg
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git clone https://github.com/microsoft/vcpkg.git
|
||||||
|
$ ./bootstrap-vcpkg.bat # for powershell
|
||||||
|
$ ./bootstrap-vcpkg.sh # for bash
|
||||||
|
$ ./vcpkg install libuv
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install with Conan
|
||||||
|
|
||||||
|
You can install pre-built binaries for libuv or build it from source using [Conan](https://conan.io/). Use the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
conan install --requires="libuv/[*]" --build=missing
|
||||||
|
```
|
||||||
|
|
||||||
|
The libuv Conan recipe is kept up to date by Conan maintainers and community contributors.
|
||||||
|
If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the ConanCenterIndex repository.
|
||||||
|
|
||||||
|
|
||||||
### Running tests
|
### Running tests
|
||||||
|
|
||||||
Some tests are timing sensitive. Relaxing test timeouts may be necessary
|
Some tests are timing sensitive. Relaxing test timeouts may be necessary
|
||||||
|
|||||||
27
SECURITY.md
Normal file
27
SECURITY.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
Currently, we are providing security updates for the latest release in the v1.x series:
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| Latest v1.x | :white_check_mark: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
If you believe you have found a security vulnerability in `libuv`, please use the [GitHub's private vulnerability reporting feature](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability) in the [libuv repository](https://github.com/libuv/libuv) to report it to us.
|
||||||
|
|
||||||
|
This will allow us to assess the risk, and make a fix available before we add a bug report to the GitHub repository.
|
||||||
|
|
||||||
|
Please do:
|
||||||
|
|
||||||
|
* Provide as much information as you can about the vulnerability.
|
||||||
|
* Provide details about your configuration and environment, if applicable.
|
||||||
|
|
||||||
|
Please do not:
|
||||||
|
|
||||||
|
* Post any information about the vulnerability in public places.
|
||||||
|
* Attempt to exploit the vulnerability yourself.
|
||||||
|
|
||||||
|
We take all security bugs seriously. Thank you for improving the security of `libuv`. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.
|
||||||
@ -2,17 +2,16 @@
|
|||||||
|
|
||||||
| System | Support type | Supported versions | Notes |
|
| System | Support type | Supported versions | Notes |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | |
|
| GNU/Linux | Tier 1 | Linux >= 3.10 with glibc >= 2.17 | |
|
||||||
| macOS | Tier 1 | macOS >= 10.7 | |
|
| macOS | Tier 1 | macOS >= 11 | Currently supported macOS releases |
|
||||||
| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported |
|
| Windows | Tier 1 | >= Windows 10 | VS 2015 and later are supported |
|
||||||
| FreeBSD | Tier 1 | >= 10 | |
|
| FreeBSD | Tier 2 | >= 12 | |
|
||||||
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
||||||
| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |
|
| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |
|
||||||
| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
|
| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
|
||||||
| Linux with musl | Tier 2 | musl >= 1.0 | |
|
| Linux with musl | Tier 2 | musl >= 1.0 | |
|
||||||
| SmartOS | Tier 3 | >= 14.4 | |
|
| Android | Tier 3 | NDK >= r15b | Android 7.0, `-DANDROID_PLATFORM=android-24` |
|
||||||
| Android | Tier 3 | NDK >= r15b | |
|
| MinGW | Tier 3 | MinGW-w64 | |
|
||||||
| MinGW | Tier 3 | MinGW32 and MinGW-w64 | |
|
|
||||||
| SunOS | Tier 3 | Solaris 121 and later | |
|
| SunOS | Tier 3 | Solaris 121 and later | |
|
||||||
| Other | Tier 3 | N/A | |
|
| Other | Tier 3 | N/A | |
|
||||||
|
|
||||||
|
|||||||
35
autogen.sh
35
autogen.sh
@ -14,9 +14,16 @@
|
|||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
set -eu
|
||||||
cd `dirname "$0"`
|
cd `dirname "$0"`
|
||||||
|
|
||||||
if [ "$LIBTOOLIZE" = "" ] && [ "`uname`" = "Darwin" ]; then
|
if [ "${1:-dev}" = "release" ]; then
|
||||||
|
export LIBUV_RELEASE=true
|
||||||
|
else
|
||||||
|
export LIBUV_RELEASE=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${LIBTOOLIZE:-}" = "" ] && [ "`uname`" = "Darwin" ]; then
|
||||||
LIBTOOLIZE=glibtoolize
|
LIBTOOLIZE=glibtoolize
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -25,9 +32,17 @@ AUTOCONF=${AUTOCONF:-autoconf}
|
|||||||
AUTOMAKE=${AUTOMAKE:-automake}
|
AUTOMAKE=${AUTOMAKE:-automake}
|
||||||
LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}
|
LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}
|
||||||
|
|
||||||
|
aclocal_version=`"$ACLOCAL" --version | head -n 1 | sed 's/[^.0-9]//g'`
|
||||||
|
autoconf_version=`"$AUTOCONF" --version | head -n 1 | sed 's/[^.0-9]//g'`
|
||||||
automake_version=`"$AUTOMAKE" --version | head -n 1 | sed 's/[^.0-9]//g'`
|
automake_version=`"$AUTOMAKE" --version | head -n 1 | sed 's/[^.0-9]//g'`
|
||||||
automake_version_major=`echo "$automake_version" | cut -d. -f1`
|
automake_version_major=`echo "$automake_version" | cut -d. -f1`
|
||||||
automake_version_minor=`echo "$automake_version" | cut -d. -f2`
|
automake_version_minor=`echo "$automake_version" | cut -d. -f2`
|
||||||
|
libtoolize_version=`"$LIBTOOLIZE" --version | head -n 1 | sed 's/[^.0-9]//g'`
|
||||||
|
|
||||||
|
if [ $aclocal_version != $automake_version ]; then
|
||||||
|
echo "FATAL: aclocal version appears not to be from the same as automake"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
UV_EXTRA_AUTOMAKE_FLAGS=
|
UV_EXTRA_AUTOMAKE_FLAGS=
|
||||||
if test "$automake_version_major" -gt 1 || \
|
if test "$automake_version_major" -gt 1 || \
|
||||||
@ -39,8 +54,22 @@ fi
|
|||||||
echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \
|
echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \
|
||||||
> m4/libuv-extra-automake-flags.m4
|
> m4/libuv-extra-automake-flags.m4
|
||||||
|
|
||||||
set -ex
|
(set -x
|
||||||
"$LIBTOOLIZE" --copy
|
"$LIBTOOLIZE" --copy --force
|
||||||
"$ACLOCAL" -I m4
|
"$ACLOCAL" -I m4
|
||||||
|
)
|
||||||
|
if $LIBUV_RELEASE; then
|
||||||
|
"$AUTOCONF" -o /dev/null m4/libuv-check-versions.m4
|
||||||
|
echo "
|
||||||
|
AC_PREREQ($autoconf_version)
|
||||||
|
AC_INIT([libuv-release-check], [0.0])
|
||||||
|
AM_INIT_AUTOMAKE([$automake_version])
|
||||||
|
LT_PREREQ($libtoolize_version)
|
||||||
|
AC_OUTPUT
|
||||||
|
" > m4/libuv-check-versions.m4
|
||||||
|
fi
|
||||||
|
(
|
||||||
|
set -x
|
||||||
"$AUTOCONF"
|
"$AUTOCONF"
|
||||||
"$AUTOMAKE" --add-missing --copy
|
"$AUTOMAKE" --add-missing --copy
|
||||||
|
)
|
||||||
|
|||||||
17
cmake-toolchains/cross-mingw32.cmake
Normal file
17
cmake-toolchains/cross-mingw32.cmake
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
if(NOT HOST_ARCH)
|
||||||
|
message(SEND_ERROR "-DHOST_ARCH required to be specified")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
|
||||||
|
HOST_ARCH
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(CMAKE_SYSTEM_NAME Windows)
|
||||||
|
set(COMPILER_PREFIX "${HOST_ARCH}-w64-mingw32")
|
||||||
|
find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
|
||||||
|
find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc)
|
||||||
|
find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
18
configure.ac
18
configure.ac
@ -13,12 +13,13 @@
|
|||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
AC_INIT([libuv], [1.43.0], [https://github.com/libuv/libuv/issues])
|
AC_INIT([libuv], [1.50.1-dev], [https://github.com/libuv/libuv/issues])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||||
m4_include([m4/as_case.m4])
|
m4_include([m4/as_case.m4])
|
||||||
m4_include([m4/libuv-check-flags.m4])
|
m4_include([m4/libuv-check-flags.m4])
|
||||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
|
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
|
||||||
|
AM_MAINTAINER_MODE([enable]) # pass --disable-maintainer-mode if autotools may be unavailable
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_ENABLE_SHARED
|
AC_ENABLE_SHARED
|
||||||
AC_ENABLE_STATIC
|
AC_ENABLE_STATIC
|
||||||
@ -28,7 +29,9 @@ AM_PROG_CC_C_O
|
|||||||
CC_ATTRIBUTE_VISIBILITY([default], [
|
CC_ATTRIBUTE_VISIBILITY([default], [
|
||||||
CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"])
|
CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"])
|
||||||
])
|
])
|
||||||
CC_CHECK_CFLAGS_APPEND([-fno-strict-aliasing])
|
# Xlc has a flag "-f<filename>". Need to use CC_CHECK_FLAG_SUPPORTED_APPEND so
|
||||||
|
# we exclude -fno-strict-aliasing for xlc
|
||||||
|
CC_CHECK_FLAG_SUPPORTED_APPEND([-fno-strict-aliasing])
|
||||||
CC_CHECK_CFLAGS_APPEND([-g])
|
CC_CHECK_CFLAGS_APPEND([-g])
|
||||||
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
|
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
|
||||||
CC_CHECK_CFLAGS_APPEND([-Wall])
|
CC_CHECK_CFLAGS_APPEND([-Wall])
|
||||||
@ -59,7 +62,7 @@ AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])
|
|||||||
AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])])
|
AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])])
|
||||||
AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])])
|
AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])])
|
||||||
AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])])
|
AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])])
|
||||||
AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[*freebsd*], [true], [false])])
|
AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[freebsd*], [true], [false])])
|
||||||
AM_CONDITIONAL([HAIKU], [AS_CASE([$host_os],[haiku], [true], [false])])
|
AM_CONDITIONAL([HAIKU], [AS_CASE([$host_os],[haiku], [true], [false])])
|
||||||
AM_CONDITIONAL([HURD], [AS_CASE([$host_os],[gnu*], [true], [false])])
|
AM_CONDITIONAL([HURD], [AS_CASE([$host_os],[gnu*], [true], [false])])
|
||||||
AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])])
|
AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])])
|
||||||
@ -71,12 +74,12 @@ AM_CONDITIONAL([OS400], [AS_CASE([$host_os],[os400], [true], [false])
|
|||||||
AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])])
|
AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])])
|
||||||
AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])])
|
AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])])
|
||||||
AS_CASE([$host_os],[mingw*], [
|
AS_CASE([$host_os],[mingw*], [
|
||||||
LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -luser32"
|
LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -luserenv -luser32 -ldbghelp -lole32 -lshell32"
|
||||||
|
])
|
||||||
|
AS_CASE([$host_os], [solaris2.10], [
|
||||||
|
CFLAGS="$CFLAGS -DSUNOS_NO_IFADDRS"
|
||||||
])
|
])
|
||||||
AS_CASE([$host_os], [netbsd*], [AC_CHECK_LIB([kvm], [kvm_open])])
|
AS_CASE([$host_os], [netbsd*], [AC_CHECK_LIB([kvm], [kvm_open])])
|
||||||
AS_CASE([$host_os], [kfreebsd*], [
|
|
||||||
LIBS="$LIBS -lfreebsd-glue"
|
|
||||||
])
|
|
||||||
AS_CASE([$host_os], [haiku], [
|
AS_CASE([$host_os], [haiku], [
|
||||||
LIBS="$LIBS -lnetwork"
|
LIBS="$LIBS -lnetwork"
|
||||||
])
|
])
|
||||||
@ -85,4 +88,5 @@ AC_CONFIG_FILES([Makefile libuv.pc])
|
|||||||
AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file])
|
AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file])
|
||||||
AC_CONFIG_LINKS([test/fixtures/load_error.node:test/fixtures/load_error.node])
|
AC_CONFIG_LINKS([test/fixtures/load_error.node:test/fixtures/load_error.node])
|
||||||
AC_CONFIG_LINKS([test/fixtures/lorem_ipsum.txt:test/fixtures/lorem_ipsum.txt])
|
AC_CONFIG_LINKS([test/fixtures/lorem_ipsum.txt:test/fixtures/lorem_ipsum.txt])
|
||||||
|
AC_CONFIG_LINKS([test/fixtures/one_file/one_file:test/fixtures/one_file/one_file])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|||||||
3
docs/code/.gitignore
vendored
Normal file
3
docs/code/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*/*
|
||||||
|
!*.c
|
||||||
|
!*.h
|
||||||
51
docs/code/CMakeLists.txt
Normal file
51
docs/code/CMakeLists.txt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(libuv_sample)
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
add_subdirectory("../../" build)
|
||||||
|
|
||||||
|
set(SIMPLE_SAMPLES
|
||||||
|
cgi
|
||||||
|
helloworld
|
||||||
|
dns
|
||||||
|
detach
|
||||||
|
default-loop
|
||||||
|
idle-basic
|
||||||
|
idle-compute
|
||||||
|
interfaces
|
||||||
|
locks
|
||||||
|
onchange
|
||||||
|
pipe-echo-server
|
||||||
|
ref-timer
|
||||||
|
spawn
|
||||||
|
tcp-echo-server
|
||||||
|
thread-create
|
||||||
|
udp-dhcp
|
||||||
|
uvcat
|
||||||
|
uvstop
|
||||||
|
uvtee
|
||||||
|
)
|
||||||
|
IF (NOT WIN32)
|
||||||
|
list(APPEND SIMPLE_SAMPLES
|
||||||
|
signal
|
||||||
|
progress
|
||||||
|
queue-cancel
|
||||||
|
queue-work
|
||||||
|
tty
|
||||||
|
tty-gravity
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
foreach (X IN LISTS SIMPLE_SAMPLES)
|
||||||
|
add_executable(${X} ${X}/main.c)
|
||||||
|
target_link_libraries(${X} uv_a)
|
||||||
|
endforeach ()
|
||||||
|
|
||||||
|
|
||||||
|
FIND_PACKAGE(CURL)
|
||||||
|
IF(CURL_FOUND)
|
||||||
|
add_executable(uvwget uvwget/main.c)
|
||||||
|
target_link_libraries(uvwget uv_a ${CURL_LIBRARIES})
|
||||||
|
ENDIF(CURL_FOUND)
|
||||||
@ -15,8 +15,8 @@ void cleanup_handles(uv_process_t *req, int64_t exit_status, int term_signal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void invoke_cgi_script(uv_tcp_t *client) {
|
void invoke_cgi_script(uv_tcp_t *client) {
|
||||||
size_t size = 500;
|
char path[500];
|
||||||
char path[size];
|
size_t size = sizeof(path);
|
||||||
uv_exepath(path, &size);
|
uv_exepath(path, &size);
|
||||||
strcpy(path + (strlen(path) - strlen("cgi")), "tick");
|
strcpy(path + (strlen(path) - strlen("cgi")), "tick");
|
||||||
|
|
||||||
|
|||||||
12
docs/code/default-loop/main.c
Normal file
12
docs/code/default-loop/main.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
uv_loop_t *loop = uv_default_loop();
|
||||||
|
|
||||||
|
printf("Default loop.\n");
|
||||||
|
uv_run(loop, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
uv_loop_close(loop);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -11,17 +11,17 @@ int main() {
|
|||||||
|
|
||||||
printf("Number of interfaces: %d\n", count);
|
printf("Number of interfaces: %d\n", count);
|
||||||
while (i--) {
|
while (i--) {
|
||||||
uv_interface_address_t interface = info[i];
|
uv_interface_address_t interface_a = info[i];
|
||||||
|
|
||||||
printf("Name: %s\n", interface.name);
|
printf("Name: %s\n", interface_a.name);
|
||||||
printf("Internal? %s\n", interface.is_internal ? "Yes" : "No");
|
printf("Internal? %s\n", interface_a.is_internal ? "Yes" : "No");
|
||||||
|
|
||||||
if (interface.address.address4.sin_family == AF_INET) {
|
if (interface_a.address.address4.sin_family == AF_INET) {
|
||||||
uv_ip4_name(&interface.address.address4, buf, sizeof(buf));
|
uv_ip4_name(&interface_a.address.address4, buf, sizeof(buf));
|
||||||
printf("IPv4 address: %s\n", buf);
|
printf("IPv4 address: %s\n", buf);
|
||||||
}
|
}
|
||||||
else if (interface.address.address4.sin_family == AF_INET6) {
|
else if (interface_a.address.address4.sin_family == AF_INET6) {
|
||||||
uv_ip6_name(&interface.address.address6, buf, sizeof(buf));
|
uv_ip6_name(&interface_a.address.address6, buf, sizeof(buf));
|
||||||
printf("IPv6 address: %s\n", buf);
|
printf("IPv6 address: %s\n", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
@ -7,7 +6,7 @@ void hare(void *arg) {
|
|||||||
int tracklen = *((int *) arg);
|
int tracklen = *((int *) arg);
|
||||||
while (tracklen) {
|
while (tracklen) {
|
||||||
tracklen--;
|
tracklen--;
|
||||||
sleep(1);
|
uv_sleep(1000);
|
||||||
fprintf(stderr, "Hare ran another step\n");
|
fprintf(stderr, "Hare ran another step\n");
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Hare done running!\n");
|
fprintf(stderr, "Hare done running!\n");
|
||||||
@ -18,7 +17,7 @@ void tortoise(void *arg) {
|
|||||||
while (tracklen) {
|
while (tracklen) {
|
||||||
tracklen--;
|
tracklen--;
|
||||||
fprintf(stderr, "Tortoise ran another step\n");
|
fprintf(stderr, "Tortoise ran another step\n");
|
||||||
sleep(3);
|
uv_sleep(3000);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Tortoise done running!\n");
|
fprintf(stderr, "Tortoise done running!\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,25 +5,27 @@
|
|||||||
|
|
||||||
uv_loop_t *loop;
|
uv_loop_t *loop;
|
||||||
uv_tty_t tty;
|
uv_tty_t tty;
|
||||||
int main() {
|
|
||||||
loop = uv_default_loop();
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
uv_write_t req;
|
||||||
|
uv_buf_t buf;
|
||||||
|
uv_write_t req1;
|
||||||
|
uv_buf_t buf1;
|
||||||
|
|
||||||
|
loop = uv_default_loop();
|
||||||
uv_tty_init(loop, &tty, STDOUT_FILENO, 0);
|
uv_tty_init(loop, &tty, STDOUT_FILENO, 0);
|
||||||
uv_tty_set_mode(&tty, UV_TTY_MODE_NORMAL);
|
uv_tty_set_mode(&tty, UV_TTY_MODE_NORMAL);
|
||||||
|
|
||||||
if (uv_guess_handle(1) == UV_TTY) {
|
if (uv_guess_handle(1) == UV_TTY) {
|
||||||
uv_write_t req;
|
buf1.base = "\033[41;37m";
|
||||||
uv_buf_t buf;
|
buf1.len = strlen(buf1.base);
|
||||||
buf.base = "\033[41;37m";
|
uv_write(&req1, (uv_stream_t*) &tty, &buf1, 1, NULL);
|
||||||
buf.len = strlen(buf.base);
|
|
||||||
uv_write(&req, (uv_stream_t*) &tty, &buf, 1, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_write_t req;
|
|
||||||
uv_buf_t buf;
|
|
||||||
buf.base = "Hello TTY\n";
|
buf.base = "Hello TTY\n";
|
||||||
buf.len = strlen(buf.base);
|
buf.len = strlen(buf.base);
|
||||||
uv_write(&req, (uv_stream_t*) &tty, &buf, 1, NULL);
|
uv_write(&req, (uv_stream_t*) &tty, &buf, 1, NULL);
|
||||||
|
|
||||||
uv_tty_reset_mode();
|
uv_tty_reset_mode();
|
||||||
return uv_run(loop, UV_RUN_DEFAULT);
|
return uv_run(loop, UV_RUN_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,8 @@ uv_buf_t make_discover_msg() {
|
|||||||
// HOPS
|
// HOPS
|
||||||
buffer.base[3] = 0x0;
|
buffer.base[3] = 0x0;
|
||||||
// XID 4 bytes
|
// XID 4 bytes
|
||||||
buffer.base[4] = (unsigned int) random();
|
if (uv_random(NULL, NULL, &buffer.base[4], 4, 0, NULL))
|
||||||
|
abort();
|
||||||
// SECS
|
// SECS
|
||||||
buffer.base[8] = 0x0;
|
buffer.base[8] = 0x0;
|
||||||
// FLAGS
|
// FLAGS
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
void on_read(uv_fs_t *req);
|
void on_read(uv_fs_t *req);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|||||||
@ -1,42 +1,36 @@
|
|||||||
# primary
|
# primary
|
||||||
Sphinx==3.5.4
|
furo==2023.5.20
|
||||||
|
Sphinx==6.1.3
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
alabaster==0.7.12
|
alabaster==0.7.13
|
||||||
appdirs==1.4.3
|
Babel==2.11.0
|
||||||
Babel==2.9.0
|
beautifulsoup4==4.12.2
|
||||||
CacheControl==0.12.6
|
certifi==2022.12.7
|
||||||
certifi==2019.11.28
|
charset-normalizer==3.0.1
|
||||||
chardet==3.0.4
|
colorama==0.4.6
|
||||||
colorama==0.4.3
|
docutils==0.19
|
||||||
contextlib2==0.6.0
|
idna==3.4
|
||||||
distlib==0.3.0
|
imagesize==1.4.1
|
||||||
distro==1.4.0
|
importlib-metadata==6.0.0
|
||||||
docutils==0.16
|
Jinja2==3.1.2
|
||||||
html5lib==1.0.1
|
livereload==2.6.3
|
||||||
idna==2.8
|
MarkupSafe==2.1.2
|
||||||
imagesize==1.2.0
|
packaging==23.0
|
||||||
ipaddr==2.2.0
|
Pygments==2.14.0
|
||||||
Jinja2==2.11.3
|
pytz==2022.7.1
|
||||||
lockfile==0.12.2
|
requests==2.28.2
|
||||||
MarkupSafe==1.1.1
|
six==1.16.0
|
||||||
msgpack==0.6.2
|
snowballstemmer==2.2.0
|
||||||
packaging==20.3
|
soupsieve==2.4.1
|
||||||
pep517==0.8.2
|
sphinx-autobuild==2021.3.14
|
||||||
progress==1.5
|
sphinx-basic-ng==1.0.0b2
|
||||||
Pygments==2.8.1
|
|
||||||
pyparsing==2.4.6
|
|
||||||
pytoml==0.1.21
|
|
||||||
pytz==2021.1
|
|
||||||
requests==2.22.0
|
|
||||||
retrying==1.3.3
|
|
||||||
six==1.14.0
|
|
||||||
snowballstemmer==2.1.0
|
|
||||||
sphinxcontrib-applehelp==1.0.2
|
|
||||||
sphinxcontrib-devhelp==1.0.2
|
sphinxcontrib-devhelp==1.0.2
|
||||||
sphinxcontrib-htmlhelp==1.0.3
|
sphinxcontrib-htmlhelp==2.0.0
|
||||||
sphinxcontrib-jsmath==1.0.1
|
sphinxcontrib-jsmath==1.0.1
|
||||||
sphinxcontrib-qthelp==1.0.3
|
sphinxcontrib-qthelp==1.0.3
|
||||||
sphinxcontrib-serializinghtml==1.1.4
|
sphinxcontrib-serializinghtml==1.1.5
|
||||||
urllib3==1.25.8
|
sphinxcontrib.applehelp==1.0.3
|
||||||
webencodings==0.5.1
|
tornado==6.3.2
|
||||||
|
urllib3==1.26.14
|
||||||
|
zipp==3.11.0
|
||||||
|
|||||||
@ -118,7 +118,7 @@ pygments_style = 'sphinx'
|
|||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
html_theme = 'nature'
|
html_theme = 'furo'
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
|
|||||||
@ -60,16 +60,15 @@ stages of a loop iteration:
|
|||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
|
|
||||||
#. The loop concept of 'now' is updated. The event loop caches the current time at the start of
|
#. The loop concept of 'now' is initially set.
|
||||||
the event loop tick in order to reduce the number of time-related system calls.
|
|
||||||
|
#. Due timers are run if the loop was run with ``UV_RUN_DEFAULT``. All active timers scheduled
|
||||||
|
for a time before the loop's concept of *now* get their callbacks called.
|
||||||
|
|
||||||
#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So,
|
#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So,
|
||||||
when is a loop considered to be *alive*? If a loop has active and ref'd handles, active
|
when is a loop considered to be *alive*? If a loop has active and ref'd handles, active
|
||||||
requests or closing handles it's considered to be *alive*.
|
requests or closing handles it's considered to be *alive*.
|
||||||
|
|
||||||
#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now*
|
|
||||||
get their callbacks called.
|
|
||||||
|
|
||||||
#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the
|
#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the
|
||||||
most part. There are cases, however, in which calling such a callback is deferred for the next
|
most part. There are cases, however, in which calling such a callback is deferred for the next
|
||||||
loop iteration. If the previous iteration deferred any I/O callback it will be run at this point.
|
loop iteration. If the previous iteration deferred any I/O callback it will be run at this point.
|
||||||
@ -101,9 +100,11 @@ stages of a loop iteration:
|
|||||||
#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will
|
#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will
|
||||||
get the close callback called.
|
get the close callback called.
|
||||||
|
|
||||||
#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress.
|
#. The loop concept of 'now' is updated.
|
||||||
It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed
|
|
||||||
so there might be timers which are due, those timers get their callbacks called.
|
#. Due timers are run. Note that 'now' is not updated again until the next loop iteration.
|
||||||
|
So if a timer became due while other timers were being processed, it won't be run until
|
||||||
|
the following event loop iteration.
|
||||||
|
|
||||||
#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the
|
#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the
|
||||||
iteration ends and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT``
|
iteration ends and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT``
|
||||||
@ -125,7 +126,7 @@ File I/O
|
|||||||
Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on,
|
Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on,
|
||||||
so the current approach is to run blocking file I/O operations in a thread pool.
|
so the current approach is to run blocking file I/O operations in a thread pool.
|
||||||
|
|
||||||
For a thorough explanation of the cross-platform file I/O landscape, checkout
|
For a thorough explanation of the cross-platform file I/O landscape, check out
|
||||||
`this post <https://blog.libtorrent.org/2012/10/asynchronous-disk-io/>`_.
|
`this post <https://blog.libtorrent.org/2012/10/asynchronous-disk-io/>`_.
|
||||||
|
|
||||||
libuv currently uses a global thread pool on which all loops can queue work. 3 types of
|
libuv currently uses a global thread pool on which all loops can queue work. 3 types of
|
||||||
|
|||||||
@ -339,6 +339,9 @@ Error constants
|
|||||||
|
|
||||||
socket type not supported
|
socket type not supported
|
||||||
|
|
||||||
|
.. c:macro:: UV_EUNATCH
|
||||||
|
|
||||||
|
protocol driver not attached
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
---
|
||||||
|
|||||||
@ -12,6 +12,15 @@ otherwise it will be performed asynchronously.
|
|||||||
All file operations are run on the threadpool. See :ref:`threadpool` for information
|
All file operations are run on the threadpool. See :ref:`threadpool` for information
|
||||||
on the threadpool size.
|
on the threadpool size.
|
||||||
|
|
||||||
|
Starting with libuv v1.45.0, some file operations on Linux are handed off to
|
||||||
|
`io_uring <https://en.wikipedia.org/wiki/Io_uring>` when possible. Apart from
|
||||||
|
a (sometimes significant) increase in throughput there should be no change in
|
||||||
|
observable behavior. Libuv reverts to using its threadpool when the necessary
|
||||||
|
kernel features are unavailable or unsuitable. Starting with libuv v1.49.0 this
|
||||||
|
behavior was reverted and Libuv on Linux by default will be using the threadpool
|
||||||
|
again. In order to enable io_uring the :c:type:`uv_loop_t` instance must be
|
||||||
|
configured with the :c:type:`UV_LOOP_ENABLE_IO_URING_SQPOLL` option.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
On Windows `uv_fs_*` functions use utf-8 encoding.
|
On Windows `uv_fs_*` functions use utf-8 encoding.
|
||||||
|
|
||||||
@ -24,7 +33,8 @@ Data types
|
|||||||
|
|
||||||
.. c:type:: uv_timespec_t
|
.. c:type:: uv_timespec_t
|
||||||
|
|
||||||
Portable equivalent of ``struct timespec``.
|
Y2K38-unsafe data type for storing times with nanosecond resolution.
|
||||||
|
Will be replaced with :c:type:`uv_timespec64_t` in libuv v2.0.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -122,10 +132,9 @@ Data types
|
|||||||
uint64_t f_spare[4];
|
uint64_t f_spare[4];
|
||||||
} uv_statfs_t;
|
} uv_statfs_t;
|
||||||
|
|
||||||
.. c:enum:: uv_dirent_t
|
.. c:enum:: uv_dirent_type_t
|
||||||
|
|
||||||
Cross platform (reduced) equivalent of ``struct dirent``.
|
Type of dirent.
|
||||||
Used in :c:func:`uv_fs_scandir_next`.
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -140,6 +149,14 @@ Data types
|
|||||||
UV_DIRENT_BLOCK
|
UV_DIRENT_BLOCK
|
||||||
} uv_dirent_type_t;
|
} uv_dirent_type_t;
|
||||||
|
|
||||||
|
|
||||||
|
.. c:type:: uv_dirent_t
|
||||||
|
|
||||||
|
Cross platform (reduced) equivalent of ``struct dirent``.
|
||||||
|
Used in :c:func:`uv_fs_scandir_next`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
typedef struct uv_dirent_s {
|
typedef struct uv_dirent_s {
|
||||||
const char* name;
|
const char* name;
|
||||||
uv_dirent_type_t type;
|
uv_dirent_type_t type;
|
||||||
@ -160,6 +177,10 @@ Data types
|
|||||||
size_t nentries;
|
size_t nentries;
|
||||||
} uv_dir_t;
|
} uv_dir_t;
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_fs_cb)(uv_fs_t* req)
|
||||||
|
|
||||||
|
Callback called when a request is completed asynchronously.
|
||||||
|
|
||||||
|
|
||||||
Public members
|
Public members
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
@ -218,7 +239,8 @@ API
|
|||||||
|
|
||||||
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
||||||
|
|
||||||
Equivalent to :man:`preadv(2)`.
|
Equivalent to :man:`preadv(2)`. If the `offset` argument is `-1`, then
|
||||||
|
the current file offset is used and updated.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
On Windows, under non-MSVC environments (e.g. when GCC or Clang is used
|
On Windows, under non-MSVC environments (e.g. when GCC or Clang is used
|
||||||
@ -231,7 +253,8 @@ API
|
|||||||
|
|
||||||
.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
||||||
|
|
||||||
Equivalent to :man:`pwritev(2)`.
|
Equivalent to :man:`pwritev(2)`. If the `offset` argument is `-1`, then
|
||||||
|
the current file offset is used and updated.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
On Windows, under non-MSVC environments (e.g. when GCC or Clang is used
|
On Windows, under non-MSVC environments (e.g. when GCC or Clang is used
|
||||||
@ -407,6 +430,12 @@ API
|
|||||||
|
|
||||||
Equivalent to :man:`utime(2)`, :man:`futimes(3)` and :man:`lutimes(3)` respectively.
|
Equivalent to :man:`utime(2)`, :man:`futimes(3)` and :man:`lutimes(3)` respectively.
|
||||||
|
|
||||||
|
Passing `UV_FS_UTIME_NOW` as the atime or mtime sets the timestamp to the
|
||||||
|
current time.
|
||||||
|
|
||||||
|
Passing `UV_FS_UTIME_OMIT` as the atime or mtime leaves the timestamp
|
||||||
|
untouched.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
z/OS: `uv_fs_lutime()` is not implemented for z/OS. It can still be called but will return
|
z/OS: `uv_fs_lutime()` is not implemented for z/OS. It can still be called but will return
|
||||||
``UV_ENOSYS``.
|
``UV_ENOSYS``.
|
||||||
@ -441,7 +470,7 @@ API
|
|||||||
|
|
||||||
.. c:function:: int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
.. c:function:: int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||||
|
|
||||||
Equivalent to :man:`realpath(3)` on Unix. Windows uses `GetFinalPathNameByHandle <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlea>`_.
|
Equivalent to :man:`realpath(3)` on Unix. Windows uses `GetFinalPathNameByHandleW <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew>`_.
|
||||||
The resulting string is stored in `req->ptr`.
|
The resulting string is stored in `req->ptr`.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
@ -463,10 +492,6 @@ API
|
|||||||
The background story and some more details on these issues can be checked
|
The background story and some more details on these issues can be checked
|
||||||
`here <https://github.com/nodejs/node/issues/7726>`_.
|
`here <https://github.com/nodejs/node/issues/7726>`_.
|
||||||
|
|
||||||
.. note::
|
|
||||||
This function is not implemented on Windows XP and Windows Server 2003.
|
|
||||||
On these systems, UV_ENOSYS is returned.
|
|
||||||
|
|
||||||
.. versionadded:: 1.8.0
|
.. versionadded:: 1.8.0
|
||||||
|
|
||||||
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
|
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
|
||||||
@ -644,7 +669,7 @@ File open constants
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
`UV_FS_O_RANDOM` is only supported on Windows via
|
`UV_FS_O_RANDOM` is only supported on Windows via
|
||||||
`FILE_FLAG_RANDOM_ACCESS <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea>`_.
|
`FILE_FLAG_RANDOM_ACCESS <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew>`_.
|
||||||
|
|
||||||
.. c:macro:: UV_FS_O_RDONLY
|
.. c:macro:: UV_FS_O_RDONLY
|
||||||
|
|
||||||
@ -661,7 +686,7 @@ File open constants
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
`UV_FS_O_SEQUENTIAL` is only supported on Windows via
|
`UV_FS_O_SEQUENTIAL` is only supported on Windows via
|
||||||
`FILE_FLAG_SEQUENTIAL_SCAN <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea>`_.
|
`FILE_FLAG_SEQUENTIAL_SCAN <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew>`_.
|
||||||
|
|
||||||
.. c:macro:: UV_FS_O_SHORT_LIVED
|
.. c:macro:: UV_FS_O_SHORT_LIVED
|
||||||
|
|
||||||
@ -669,7 +694,7 @@ File open constants
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
`UV_FS_O_SHORT_LIVED` is only supported on Windows via
|
`UV_FS_O_SHORT_LIVED` is only supported on Windows via
|
||||||
`FILE_ATTRIBUTE_TEMPORARY <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea>`_.
|
`FILE_ATTRIBUTE_TEMPORARY <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew>`_.
|
||||||
|
|
||||||
.. c:macro:: UV_FS_O_SYMLINK
|
.. c:macro:: UV_FS_O_SYMLINK
|
||||||
|
|
||||||
@ -690,7 +715,7 @@ File open constants
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
`UV_FS_O_TEMPORARY` is only supported on Windows via
|
`UV_FS_O_TEMPORARY` is only supported on Windows via
|
||||||
`FILE_ATTRIBUTE_TEMPORARY <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea>`_.
|
`FILE_ATTRIBUTE_TEMPORARY <https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew>`_.
|
||||||
|
|
||||||
.. c:macro:: UV_FS_O_TRUNC
|
.. c:macro:: UV_FS_O_TRUNC
|
||||||
|
|
||||||
|
|||||||
@ -39,11 +39,20 @@ Data types
|
|||||||
.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status)
|
.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status)
|
||||||
|
|
||||||
Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly
|
Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly
|
||||||
after the handle is started. If the handle was started with a directory the
|
after the handle is started.
|
||||||
`filename` parameter will be a relative path to a file contained in the directory.
|
|
||||||
The `events` parameter is an ORed mask of :c:type:`uv_fs_event` elements.
|
|
||||||
|
|
||||||
.. c:type:: uv_fs_event
|
If the handle was started with a directory the `filename` parameter will
|
||||||
|
be a relative path to a file contained in the directory, or `NULL` if the
|
||||||
|
file name cannot be determined.
|
||||||
|
|
||||||
|
The `events` parameter is an ORed mask of :c:enum:`uv_fs_event` elements.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
For FreeBSD path could sometimes be `NULL` due to a kernel bug.
|
||||||
|
|
||||||
|
.. _Reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197695
|
||||||
|
|
||||||
|
.. c:enum:: uv_fs_event
|
||||||
|
|
||||||
Event types that :c:type:`uv_fs_event_t` handles monitor.
|
Event types that :c:type:`uv_fs_event_t` handles monitor.
|
||||||
|
|
||||||
@ -54,7 +63,7 @@ Data types
|
|||||||
UV_CHANGE = 2
|
UV_CHANGE = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
.. c:type:: uv_fs_event_flags
|
.. c:enum:: uv_fs_event_flags
|
||||||
|
|
||||||
Flags that can be passed to :c:func:`uv_fs_event_start` to control its
|
Flags that can be passed to :c:func:`uv_fs_event_start` to control its
|
||||||
behavior.
|
behavior.
|
||||||
@ -105,10 +114,13 @@ API
|
|||||||
.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags)
|
.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags)
|
||||||
|
|
||||||
Start the handle with the given callback, which will watch the specified
|
Start the handle with the given callback, which will watch the specified
|
||||||
`path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`.
|
`path` for changes. `flags` can be an ORed mask of :c:enum:`uv_fs_event_flags`.
|
||||||
|
|
||||||
.. note:: Currently the only supported flag is ``UV_FS_EVENT_RECURSIVE`` and
|
.. note:: Currently the only supported flag is ``UV_FS_EVENT_RECURSIVE`` and
|
||||||
only on OSX and Windows.
|
only on OSX and Windows.
|
||||||
|
.. note:: On macOS, events collected by the OS immediately before calling
|
||||||
|
``uv_fs_event_start`` might be reported to the `uv_fs_event_cb`
|
||||||
|
callback.
|
||||||
|
|
||||||
.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle)
|
.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle)
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,7 @@ architecture of libuv and its background. If you have no prior experience with
|
|||||||
either libuv or libev, it is a quick, useful watch.
|
either libuv or libev, it is a quick, useful watch.
|
||||||
|
|
||||||
libuv's event loop is explained in more detail in the `documentation
|
libuv's event loop is explained in more detail in the `documentation
|
||||||
<http://docs.libuv.org/en/v1.x/design.html#the-i-o-loop>`_.
|
<https://docs.libuv.org/en/v1.x/design.html#the-i-o-loop>`_.
|
||||||
|
|
||||||
.. raw:: html
|
.. raw:: html
|
||||||
|
|
||||||
@ -109,6 +109,11 @@ A default loop is provided by libuv and can be accessed using
|
|||||||
``uv_default_loop()``. You should use this loop if you only want a single
|
``uv_default_loop()``. You should use this loop if you only want a single
|
||||||
loop.
|
loop.
|
||||||
|
|
||||||
|
.. rubric:: default-loop/main.c
|
||||||
|
.. literalinclude:: ../../code/default-loop/main.c
|
||||||
|
:language: c
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
node.js uses the default loop as its main loop. If you are writing bindings
|
node.js uses the default loop as its main loop. If you are writing bindings
|
||||||
@ -119,9 +124,9 @@ loop.
|
|||||||
Error handling
|
Error handling
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Initialization functions or synchronous functions which may fail return a negative number on error. Async functions that may fail will pass a status parameter to their callbacks. The error messages are defined as ``UV_E*`` `constants`_.
|
Initialization functions or synchronous functions which may fail return a negative number on error. Async functions that may fail will pass a status parameter to their callbacks. The error messages are defined as ``UV_E*`` `constants`_.
|
||||||
|
|
||||||
.. _constants: http://docs.libuv.org/en/v1.x/errors.html#error-constants
|
.. _constants: https://docs.libuv.org/en/v1.x/errors.html#error-constants
|
||||||
|
|
||||||
You can use the ``uv_strerror(int)`` and ``uv_err_name(int)`` functions
|
You can use the ``uv_strerror(int)`` and ``uv_err_name(int)`` functions
|
||||||
to get a ``const char *`` describing the error or the error name respectively.
|
to get a ``const char *`` describing the error or the error name respectively.
|
||||||
@ -134,7 +139,7 @@ Handles and Requests
|
|||||||
libuv works by the user expressing interest in particular events. This is
|
libuv works by the user expressing interest in particular events. This is
|
||||||
usually done by creating a **handle** to an I/O device, timer or process.
|
usually done by creating a **handle** to an I/O device, timer or process.
|
||||||
Handles are opaque structs named as ``uv_TYPE_t`` where type signifies what the
|
Handles are opaque structs named as ``uv_TYPE_t`` where type signifies what the
|
||||||
handle is used for.
|
handle is used for.
|
||||||
|
|
||||||
.. rubric:: libuv watchers
|
.. rubric:: libuv watchers
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
@ -169,6 +174,16 @@ handle is used for.
|
|||||||
typedef struct uv_udp_send_s uv_udp_send_t;
|
typedef struct uv_udp_send_s uv_udp_send_t;
|
||||||
typedef struct uv_fs_s uv_fs_t;
|
typedef struct uv_fs_s uv_fs_t;
|
||||||
typedef struct uv_work_s uv_work_t;
|
typedef struct uv_work_s uv_work_t;
|
||||||
|
typedef struct uv_random_s uv_random_t;
|
||||||
|
|
||||||
|
/* None of the above. */
|
||||||
|
typedef struct uv_env_item_s uv_env_item_t;
|
||||||
|
typedef struct uv_cpu_info_s uv_cpu_info_t;
|
||||||
|
typedef struct uv_interface_address_s uv_interface_address_t;
|
||||||
|
typedef struct uv_dirent_s uv_dirent_t;
|
||||||
|
typedef struct uv_passwd_s uv_passwd_t;
|
||||||
|
typedef struct uv_utsname_s uv_utsname_t;
|
||||||
|
typedef struct uv_statfs_s uv_statfs_t;
|
||||||
|
|
||||||
|
|
||||||
Handles represent long-lived objects. Async operations on such handles are
|
Handles represent long-lived objects. Async operations on such handles are
|
||||||
|
|||||||
@ -13,7 +13,7 @@ Simple filesystem read/write is achieved using the ``uv_fs_*`` functions and the
|
|||||||
watchers registered with the event loop when application interaction is
|
watchers registered with the event loop when application interaction is
|
||||||
required.
|
required.
|
||||||
|
|
||||||
.. _thread pool: http://docs.libuv.org/en/v1.x/threadpool.html#thread-pool-work-scheduling
|
.. _thread pool: https://docs.libuv.org/en/v1.x/threadpool.html#thread-pool-work-scheduling
|
||||||
|
|
||||||
All filesystem functions have two forms - *synchronous* and *asynchronous*.
|
All filesystem functions have two forms - *synchronous* and *asynchronous*.
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ The ``result`` field of a ``uv_fs_t`` is the file descriptor in case of the
|
|||||||
.. literalinclude:: ../../code/uvcat/main.c
|
.. literalinclude:: ../../code/uvcat/main.c
|
||||||
:language: c
|
:language: c
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 26-40
|
:lines: 26-39
|
||||||
:emphasize-lines: 2,8,12
|
:emphasize-lines: 2,8,12
|
||||||
|
|
||||||
In the case of a read call, you should pass an *initialized* buffer which will
|
In the case of a read call, you should pass an *initialized* buffer which will
|
||||||
@ -91,7 +91,7 @@ callbacks.
|
|||||||
.. literalinclude:: ../../code/uvcat/main.c
|
.. literalinclude:: ../../code/uvcat/main.c
|
||||||
:language: c
|
:language: c
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 16-24
|
:lines: 17-24
|
||||||
:emphasize-lines: 6
|
:emphasize-lines: 6
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
@ -132,6 +132,7 @@ same patterns as the read/write/open calls, returning the result in the
|
|||||||
int uv_fs_copyfile(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb);
|
int uv_fs_copyfile(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb);
|
||||||
int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb);
|
int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb);
|
||||||
int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb);
|
int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb);
|
||||||
|
int uv_fs_mkstemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb);
|
||||||
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
|
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
|
||||||
int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb);
|
int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb);
|
||||||
int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent);
|
int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent);
|
||||||
@ -149,6 +150,7 @@ same patterns as the read/write/open calls, returning the result in the
|
|||||||
int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb);
|
int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb);
|
||||||
int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb);
|
int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb);
|
||||||
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb);
|
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb);
|
||||||
|
int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb);
|
||||||
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
|
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
|
||||||
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb);
|
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb);
|
||||||
int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb);
|
int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb);
|
||||||
@ -158,6 +160,7 @@ same patterns as the read/write/open calls, returning the result in the
|
|||||||
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
|
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
|
||||||
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
|
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
|
||||||
int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
|
int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
|
||||||
|
int uv_fs_statfs(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
|
||||||
|
|
||||||
|
|
||||||
.. _buffers-and-streams:
|
.. _buffers-and-streams:
|
||||||
@ -190,7 +193,7 @@ and freed by the application.
|
|||||||
|
|
||||||
.. ERROR::
|
.. ERROR::
|
||||||
|
|
||||||
THIS PROGRAM DOES NOT ALWAYS WORK, NEED SOMETHING BETTER**
|
**THIS PROGRAM DOES NOT ALWAYS WORK, NEED SOMETHING BETTER**
|
||||||
|
|
||||||
To demonstrate streams we will need to use ``uv_pipe_t``. This allows streaming
|
To demonstrate streams we will need to use ``uv_pipe_t``. This allows streaming
|
||||||
local files [#]_. Here is a simple tee utility using libuv. Doing all operations
|
local files [#]_. Here is a simple tee utility using libuv. Doing all operations
|
||||||
@ -209,7 +212,7 @@ opened as bidirectional by default.
|
|||||||
.. literalinclude:: ../../code/uvtee/main.c
|
.. literalinclude:: ../../code/uvtee/main.c
|
||||||
:language: c
|
:language: c
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 61-80
|
:lines: 62-80
|
||||||
:emphasize-lines: 4,5,15
|
:emphasize-lines: 4,5,15
|
||||||
|
|
||||||
The third argument of ``uv_pipe_init()`` should be set to 1 for IPC using named
|
The third argument of ``uv_pipe_init()`` should be set to 1 for IPC using named
|
||||||
@ -285,6 +288,13 @@ a command whenever any of the watched files change::
|
|||||||
|
|
||||||
./onchange <command> <file1> [file2] ...
|
./onchange <command> <file1> [file2] ...
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Currently this example only works on OSX and Windows.
|
||||||
|
Refer to the `notes of uv_fs_event_start`_ function.
|
||||||
|
|
||||||
|
.. _notes of uv_fs_event_start: https://docs.libuv.org/en/v1.x/fs_event.html#c.uv_fs_event_start
|
||||||
|
|
||||||
The file change notification is started using ``uv_fs_event_init()``:
|
The file change notification is started using ``uv_fs_event_init()``:
|
||||||
|
|
||||||
.. rubric:: onchange/main.c - The setup
|
.. rubric:: onchange/main.c - The setup
|
||||||
@ -300,8 +310,8 @@ argument, ``flags``, can be:
|
|||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags to be passed to uv_fs_event_start().
|
* Flags to be passed to uv_fs_event_start().
|
||||||
*/
|
*/
|
||||||
enum uv_fs_event_flags {
|
enum uv_fs_event_flags {
|
||||||
UV_FS_EVENT_WATCH_ENTRY = 1,
|
UV_FS_EVENT_WATCH_ENTRY = 1,
|
||||||
UV_FS_EVENT_STAT = 2,
|
UV_FS_EVENT_STAT = 2,
|
||||||
@ -319,9 +329,9 @@ The callback will receive the following arguments:
|
|||||||
#. ``const char *filename`` - If a directory is being monitored, this is the
|
#. ``const char *filename`` - If a directory is being monitored, this is the
|
||||||
file which was changed. Only non-``null`` on Linux and Windows. May be ``null``
|
file which was changed. Only non-``null`` on Linux and Windows. May be ``null``
|
||||||
even on those platforms.
|
even on those platforms.
|
||||||
#. ``int flags`` - one of ``UV_RENAME`` or ``UV_CHANGE``, or a bitwise OR of
|
#. ``int events`` - one of ``UV_RENAME`` or ``UV_CHANGE``, or a bitwise OR of
|
||||||
both.
|
both.
|
||||||
#. ``int status`` - Currently 0.
|
#. ``int status`` - If ``status < 0``, there is an :ref:`libuv error<libuv-error-handling>`.
|
||||||
|
|
||||||
In our example we simply print the arguments and run the command using
|
In our example we simply print the arguments and run the command using
|
||||||
``system()``.
|
``system()``.
|
||||||
|
|||||||
@ -8,7 +8,7 @@ It is meant to cover the main areas of libuv, but is not a comprehensive
|
|||||||
reference discussing every function and data structure. The `official libuv
|
reference discussing every function and data structure. The `official libuv
|
||||||
documentation`_ may be consulted for full details.
|
documentation`_ may be consulted for full details.
|
||||||
|
|
||||||
.. _official libuv documentation: http://docs.libuv.org/en/v1.x/
|
.. _official libuv documentation: https://docs.libuv.org/en/v1.x/
|
||||||
|
|
||||||
This book is still a work in progress, so sections may be incomplete, but
|
This book is still a work in progress, so sections may be incomplete, but
|
||||||
I hope you will enjoy it as it grows.
|
I hope you will enjoy it as it grows.
|
||||||
@ -47,25 +47,23 @@ Since then libuv has continued to mature and become a high quality standalone
|
|||||||
library for system programming. Users outside of node.js include Mozilla's
|
library for system programming. Users outside of node.js include Mozilla's
|
||||||
Rust_ programming language, and a variety_ of language bindings.
|
Rust_ programming language, and a variety_ of language bindings.
|
||||||
|
|
||||||
This book and the code is based on libuv version `v1.3.0`_.
|
This book and the code is based on libuv version `v1.42.0`_.
|
||||||
|
|
||||||
Code
|
Code
|
||||||
----
|
----
|
||||||
|
|
||||||
All the code from this book is included as part of the source of the book on
|
All the example code and the source of the book is included as part of
|
||||||
Github. `Clone`_/`Download`_ the book, then build libuv::
|
the libuv_ project on GitHub.
|
||||||
|
Clone or Download libuv_, then build it::
|
||||||
|
|
||||||
cd libuv
|
sh autogen.sh
|
||||||
./autogen.sh
|
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
|
|
||||||
There is no need to ``make install``. To build the examples run ``make`` in the
|
There is no need to ``make install``. To build the examples run ``make`` in the
|
||||||
``code/`` directory.
|
``docs/code/`` directory.
|
||||||
|
|
||||||
.. _Clone: https://github.com/nikhilm/uvbook
|
.. _v1.42.0: https://github.com/libuv/libuv/releases/tag/v1.42.0
|
||||||
.. _Download: https://github.com/nikhilm/uvbook/downloads
|
|
||||||
.. _v1.3.0: https://github.com/libuv/libuv/tags
|
|
||||||
.. _V8: https://v8.dev
|
.. _V8: https://v8.dev
|
||||||
.. _libev: http://software.schmorp.de/pkg/libev.html
|
.. _libev: http://software.schmorp.de/pkg/libev.html
|
||||||
.. _libuv: https://github.com/libuv/libuv
|
.. _libuv: https://github.com/libuv/libuv
|
||||||
|
|||||||
@ -164,7 +164,7 @@ IPv6 stack only
|
|||||||
|
|
||||||
IPv6 sockets can be used for both IPv4 and IPv6 communication. If you want to
|
IPv6 sockets can be used for both IPv4 and IPv6 communication. If you want to
|
||||||
restrict the socket to IPv6 only, pass the ``UV_UDP_IPV6ONLY`` flag to
|
restrict the socket to IPv6 only, pass the ``UV_UDP_IPV6ONLY`` flag to
|
||||||
``uv_udp_bind`` [#]_.
|
``uv_udp_bind``.
|
||||||
|
|
||||||
Multicast
|
Multicast
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
@ -250,7 +250,6 @@ times, with each address being reported once.
|
|||||||
----
|
----
|
||||||
|
|
||||||
.. [#] https://beej.us/guide/bgnet/html/#broadcast-packetshello-world
|
.. [#] https://beej.us/guide/bgnet/html/#broadcast-packetshello-world
|
||||||
.. [#] on Windows only supported on Windows Vista and later.
|
|
||||||
.. [#] https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html#ss6.1
|
.. [#] https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html#ss6.1
|
||||||
.. [#] libuv use the system ``getaddrinfo`` in the libuv threadpool. libuv
|
.. [#] libuv use the system ``getaddrinfo`` in the libuv threadpool. libuv
|
||||||
v0.8.0 and earlier also included c-ares_ as an alternative, but this has been
|
v0.8.0 and earlier also included c-ares_ as an alternative, but this has been
|
||||||
|
|||||||
@ -53,6 +53,8 @@ ID of the child process.
|
|||||||
The exit callback will be invoked with the *exit status* and the type of *signal*
|
The exit callback will be invoked with the *exit status* and the type of *signal*
|
||||||
which caused the exit.
|
which caused the exit.
|
||||||
|
|
||||||
|
Note that it is important **not** to call ``uv_close`` before the exit callback.
|
||||||
|
|
||||||
.. rubric:: spawn/main.c
|
.. rubric:: spawn/main.c
|
||||||
.. literalinclude:: ../../code/spawn/main.c
|
.. literalinclude:: ../../code/spawn/main.c
|
||||||
:language: c
|
:language: c
|
||||||
@ -126,7 +128,8 @@ of ``uv_kill`` is::
|
|||||||
|
|
||||||
For processes started using libuv, you may use ``uv_process_kill`` instead,
|
For processes started using libuv, you may use ``uv_process_kill`` instead,
|
||||||
which accepts the ``uv_process_t`` watcher as the first argument, rather than
|
which accepts the ``uv_process_t`` watcher as the first argument, rather than
|
||||||
the pid. In this case, **remember to call** ``uv_close`` on the watcher.
|
the pid. In this case, **remember to call** ``uv_close`` on the watcher _after_
|
||||||
|
the exit callback has been called.
|
||||||
|
|
||||||
Signals
|
Signals
|
||||||
-------
|
-------
|
||||||
@ -330,7 +333,7 @@ to hand off their I/O to other processes. Applications include load-balancing
|
|||||||
servers, worker processes and other ways to make optimum use of CPU. libuv only
|
servers, worker processes and other ways to make optimum use of CPU. libuv only
|
||||||
supports sending **TCP sockets or other pipes** over pipes for now.
|
supports sending **TCP sockets or other pipes** over pipes for now.
|
||||||
|
|
||||||
To demonstrate, we will look at a echo server implementation that hands of
|
To demonstrate, we will look at an echo server implementation that hands off
|
||||||
clients to worker processes in a round-robin fashion. This program is a bit
|
clients to worker processes in a round-robin fashion. This program is a bit
|
||||||
involved, and while only snippets are included in the book, it is recommended
|
involved, and while only snippets are included in the book, it is recommended
|
||||||
to read the full code to really understand it.
|
to read the full code to really understand it.
|
||||||
|
|||||||
@ -220,7 +220,7 @@ progress with the download whenever libuv notifies of I/O readiness.
|
|||||||
.. literalinclude:: ../../code/uvwget/main.c
|
.. literalinclude:: ../../code/uvwget/main.c
|
||||||
:language: c
|
:language: c
|
||||||
:linenos:
|
:linenos:
|
||||||
:lines: 1-9,140-
|
:lines: 1-9,142-
|
||||||
:emphasize-lines: 7,21,24-25
|
:emphasize-lines: 7,21,24-25
|
||||||
|
|
||||||
The way each library is integrated with libuv will vary. In the case of
|
The way each library is integrated with libuv will vary. In the case of
|
||||||
@ -235,7 +235,7 @@ Our downloader is to be invoked as::
|
|||||||
|
|
||||||
$ ./uvwget [url1] [url2] ...
|
$ ./uvwget [url1] [url2] ...
|
||||||
|
|
||||||
So we add each argument as an URL
|
So we add each argument as a URL
|
||||||
|
|
||||||
.. rubric:: uvwget/main.c - Adding urls
|
.. rubric:: uvwget/main.c - Adding urls
|
||||||
.. literalinclude:: ../../code/uvwget/main.c
|
.. literalinclude:: ../../code/uvwget/main.c
|
||||||
@ -363,7 +363,7 @@ to get the error message.
|
|||||||
argument. ``init_plugin_function`` is a function pointer to the sort of
|
argument. ``init_plugin_function`` is a function pointer to the sort of
|
||||||
function we are looking for in the application's plugins.
|
function we are looking for in the application's plugins.
|
||||||
|
|
||||||
.. _shared libraries: https://en.wikipedia.org/wiki/Shared_library#Shared_libraries
|
.. _shared libraries: https://en.wikipedia.org/wiki/Shared_library
|
||||||
|
|
||||||
TTY
|
TTY
|
||||||
---
|
---
|
||||||
|
|||||||
@ -94,7 +94,7 @@ Public members
|
|||||||
|
|
||||||
.. c:member:: uv_handle_type uv_handle_t.type
|
.. c:member:: uv_handle_type uv_handle_t.type
|
||||||
|
|
||||||
The :c:type:`uv_handle_type`, indicating the type of the underlying handle. Readonly.
|
The :c:enum:`uv_handle_type`, indicating the type of the underlying handle. Readonly.
|
||||||
|
|
||||||
.. c:member:: void* uv_handle_t.data
|
.. c:member:: void* uv_handle_t.data
|
||||||
|
|
||||||
@ -153,6 +153,9 @@ API
|
|||||||
In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
|
In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
|
||||||
have their callbacks called asynchronously with status=UV_ECANCELED.
|
have their callbacks called asynchronously with status=UV_ECANCELED.
|
||||||
|
|
||||||
|
`close_cb` can be `NULL` in cases where no cleanup or deallocation is
|
||||||
|
necessary.
|
||||||
|
|
||||||
.. c:function:: void uv_ref(uv_handle_t* handle)
|
.. c:function:: void uv_ref(uv_handle_t* handle)
|
||||||
|
|
||||||
Reference the given handle. References are idempotent, that is, if a handle
|
Reference the given handle. References are idempotent, that is, if a handle
|
||||||
@ -245,7 +248,7 @@ just for some handle types.
|
|||||||
|
|
||||||
.. versionadded:: 1.19.0
|
.. versionadded:: 1.19.0
|
||||||
|
|
||||||
.. c:function:: void* uv_handle_set_data(uv_handle_t* handle, void* data)
|
.. c:function:: void uv_handle_set_data(uv_handle_t* handle, void* data)
|
||||||
|
|
||||||
Sets `handle->data` to `data`.
|
Sets `handle->data` to `data`.
|
||||||
|
|
||||||
|
|||||||
@ -58,5 +58,5 @@ libuv can be downloaded from `here <https://dist.libuv.org/dist/>`_.
|
|||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Installation instructions can be found in `the README <https://github.com/libuv/libuv/blob/master/README.md>`_.
|
Installation instructions can be found in the `README <https://github.com/libuv/libuv/blob/master/README.md>`_.
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,19 @@ Data types
|
|||||||
|
|
||||||
Loop data type.
|
Loop data type.
|
||||||
|
|
||||||
|
.. c:enum:: uv_loop_option
|
||||||
|
|
||||||
|
Additional loop options.
|
||||||
|
See :c:func:`uv_loop_configure`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_LOOP_BLOCK_SIGNAL = 0,
|
||||||
|
UV_METRICS_IDLE_TIME,
|
||||||
|
UV_LOOP_USE_IO_URING_SQPOLL
|
||||||
|
} uv_loop_option;
|
||||||
|
|
||||||
.. c:enum:: uv_run_mode
|
.. c:enum:: uv_run_mode
|
||||||
|
|
||||||
Mode used to run the loop with :c:func:`uv_run`.
|
Mode used to run the loop with :c:func:`uv_run`.
|
||||||
@ -73,8 +86,13 @@ API
|
|||||||
|
|
||||||
This option is necessary to use :c:func:`uv_metrics_idle_time`.
|
This option is necessary to use :c:func:`uv_metrics_idle_time`.
|
||||||
|
|
||||||
|
- UV_LOOP_ENABLE_IO_URING_SQPOLL: Enable SQPOLL io_uring instance to handle
|
||||||
|
asynchronous file system operations.
|
||||||
|
|
||||||
.. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option.
|
.. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.49.0 added the UV_LOOP_ENABLE_IO_URING_SQPOLL option.
|
||||||
|
|
||||||
.. c:function:: int uv_loop_close(uv_loop_t* loop)
|
.. c:function:: int uv_loop_close(uv_loop_t* loop)
|
||||||
|
|
||||||
Releases all internal loop resources. Call this function only when the loop
|
Releases all internal loop resources. Call this function only when the loop
|
||||||
@ -238,7 +256,7 @@ API
|
|||||||
|
|
||||||
.. versionadded:: 1.19.0
|
.. versionadded:: 1.19.0
|
||||||
|
|
||||||
.. c:function:: void* uv_loop_set_data(uv_loop_t* loop, void* data)
|
.. c:function:: void uv_loop_set_data(uv_loop_t* loop, void* data)
|
||||||
|
|
||||||
Sets `loop->data` to `data`.
|
Sets `loop->data` to `data`.
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,46 @@
|
|||||||
Metrics operations
|
Metrics operations
|
||||||
======================
|
======================
|
||||||
|
|
||||||
libuv provides a metrics API to track the amount of time the event loop has
|
libuv provides a metrics API to track various internal operations of the event
|
||||||
spent idle in the kernel's event provider.
|
loop.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_metrics_t
|
||||||
|
|
||||||
|
The struct that contains event loop metrics. It is recommended to retrieve
|
||||||
|
these metrics in a :c:type:`uv_prepare_cb` in order to make sure there are
|
||||||
|
no inconsistencies with the metrics counters.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t loop_count;
|
||||||
|
uint64_t events;
|
||||||
|
uint64_t events_waiting;
|
||||||
|
/* private */
|
||||||
|
uint64_t* reserved[13];
|
||||||
|
} uv_metrics_t;
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: uint64_t uv_metrics_t.loop_count
|
||||||
|
|
||||||
|
Number of event loop iterations.
|
||||||
|
|
||||||
|
.. c:member:: uint64_t uv_metrics_t.events
|
||||||
|
|
||||||
|
Number of events that have been processed by the event handler.
|
||||||
|
|
||||||
|
.. c:member:: uint64_t uv_metrics_t.events_waiting
|
||||||
|
|
||||||
|
Number of events that were waiting to be processed when the event provider
|
||||||
|
was called.
|
||||||
|
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
---
|
||||||
@ -25,3 +63,9 @@ API
|
|||||||
:c:type:`UV_METRICS_IDLE_TIME`.
|
:c:type:`UV_METRICS_IDLE_TIME`.
|
||||||
|
|
||||||
.. versionadded:: 1.39.0
|
.. versionadded:: 1.39.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_metrics_info(uv_loop_t* loop, uv_metrics_t* metrics)
|
||||||
|
|
||||||
|
Copy the current set of event loop metrics to the ``metrics`` pointer.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|||||||
@ -73,7 +73,8 @@ Data types
|
|||||||
|
|
||||||
.. c:type:: uv_timeval_t
|
.. c:type:: uv_timeval_t
|
||||||
|
|
||||||
Data type for storing times.
|
Y2K38-unsafe data type for storing times with microsecond resolution.
|
||||||
|
Will be replaced with :c:type:`uv_timeval64_t` in libuv v2.0.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ Data types
|
|||||||
|
|
||||||
.. c:type:: uv_timeval64_t
|
.. c:type:: uv_timeval64_t
|
||||||
|
|
||||||
Alternative data type for storing times.
|
Y2K38-safe data type for storing times with microsecond resolution.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -93,6 +94,28 @@ Data types
|
|||||||
int32_t tv_usec;
|
int32_t tv_usec;
|
||||||
} uv_timeval64_t;
|
} uv_timeval64_t;
|
||||||
|
|
||||||
|
.. c:type:: uv_timespec64_t
|
||||||
|
|
||||||
|
Y2K38-safe data type for storing times with nanosecond resolution.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t tv_sec;
|
||||||
|
int32_t tv_nsec;
|
||||||
|
} uv_timespec64_t;
|
||||||
|
|
||||||
|
.. c:enum:: uv_clock_id
|
||||||
|
|
||||||
|
Clock source for :c:func:`uv_clock_gettime`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_CLOCK_MONOTONIC,
|
||||||
|
UV_CLOCK_REALTIME
|
||||||
|
} uv_clock_id;
|
||||||
|
|
||||||
.. c:type:: uv_rusage_t
|
.. c:type:: uv_rusage_t
|
||||||
|
|
||||||
Data type for resource usage results.
|
Data type for resource usage results.
|
||||||
@ -119,7 +142,10 @@ Data types
|
|||||||
} uv_rusage_t;
|
} uv_rusage_t;
|
||||||
|
|
||||||
Members marked with `(X)` are unsupported on Windows.
|
Members marked with `(X)` are unsupported on Windows.
|
||||||
See :man:`getrusage(2)` for supported fields on Unix
|
See :man:`getrusage(2)` for supported fields on UNIX-like platforms.
|
||||||
|
|
||||||
|
The maximum resident set size is reported in kilobytes, the unit most
|
||||||
|
platforms use natively.
|
||||||
|
|
||||||
.. c:type:: uv_cpu_info_t
|
.. c:type:: uv_cpu_info_t
|
||||||
|
|
||||||
@ -173,6 +199,18 @@ Data types
|
|||||||
char* homedir;
|
char* homedir;
|
||||||
} uv_passwd_t;
|
} uv_passwd_t;
|
||||||
|
|
||||||
|
.. c:type:: uv_group_t
|
||||||
|
|
||||||
|
Data type for group file information.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct uv_group_s {
|
||||||
|
char* groupname;
|
||||||
|
unsigned long gid;
|
||||||
|
char** members;
|
||||||
|
} uv_group_t;
|
||||||
|
|
||||||
.. c:type:: uv_utsname_t
|
.. c:type:: uv_utsname_t
|
||||||
|
|
||||||
Data type for operating system name and version information.
|
Data type for operating system name and version information.
|
||||||
@ -211,7 +249,7 @@ API
|
|||||||
type of the stdio streams.
|
type of the stdio streams.
|
||||||
|
|
||||||
For :man:`isatty(3)` equivalent functionality use this function and test
|
For :man:`isatty(3)` equivalent functionality use this function and test
|
||||||
for ``UV_TTY``.
|
for `UV_TTY`.
|
||||||
|
|
||||||
.. c:function:: int uv_replace_allocator(uv_malloc_func malloc_func, uv_realloc_func realloc_func, uv_calloc_func calloc_func, uv_free_func free_func)
|
.. c:function:: int uv_replace_allocator(uv_malloc_func malloc_func, uv_realloc_func realloc_func, uv_calloc_func calloc_func, uv_free_func free_func)
|
||||||
|
|
||||||
@ -225,8 +263,8 @@ API
|
|||||||
after all resources have been freed and thus libuv doesn't reference
|
after all resources have been freed and thus libuv doesn't reference
|
||||||
any allocated memory chunk.
|
any allocated memory chunk.
|
||||||
|
|
||||||
On success, it returns 0, if any of the function pointers is NULL it
|
On success, it returns 0, if any of the function pointers is `NULL` it
|
||||||
returns UV_EINVAL.
|
returns `UV_EINVAL`.
|
||||||
|
|
||||||
.. warning:: There is no protection against changing the allocator multiple
|
.. warning:: There is no protection against changing the allocator multiple
|
||||||
times. If the user changes it they are responsible for making
|
times. If the user changes it they are responsible for making
|
||||||
@ -312,7 +350,7 @@ API
|
|||||||
|
|
||||||
.. c:function:: int uv_uptime(double* uptime)
|
.. c:function:: int uv_uptime(double* uptime)
|
||||||
|
|
||||||
Gets the current system uptime.
|
Gets the current system uptime. Depending on the system full or fractional seconds are returned.
|
||||||
|
|
||||||
.. c:function:: int uv_getrusage(uv_rusage_t* rusage)
|
.. c:function:: int uv_getrusage(uv_rusage_t* rusage)
|
||||||
|
|
||||||
@ -322,6 +360,17 @@ API
|
|||||||
On Windows not all fields are set, the unsupported fields are filled with zeroes.
|
On Windows not all fields are set, the unsupported fields are filled with zeroes.
|
||||||
See :c:type:`uv_rusage_t` for more details.
|
See :c:type:`uv_rusage_t` for more details.
|
||||||
|
|
||||||
|
.. c:function:: int uv_getrusage_thread(uv_rusage_t* rusage)
|
||||||
|
|
||||||
|
Gets the resource usage measures for the calling thread.
|
||||||
|
|
||||||
|
.. versionadded:: 1.50.0
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Not supported on all platforms. May return `UV_ENOTSUP`.
|
||||||
|
On macOS and Windows not all fields are set, the unsupported fields are filled with zeroes.
|
||||||
|
See :c:type:`uv_rusage_t` for more details.
|
||||||
|
|
||||||
.. c:function:: uv_pid_t uv_os_getpid(void)
|
.. c:function:: uv_pid_t uv_os_getpid(void)
|
||||||
|
|
||||||
Returns the current process ID.
|
Returns the current process ID.
|
||||||
@ -334,15 +383,41 @@ API
|
|||||||
|
|
||||||
.. versionadded:: 1.16.0
|
.. versionadded:: 1.16.0
|
||||||
|
|
||||||
|
.. c:function:: unsigned int uv_available_parallelism(void)
|
||||||
|
|
||||||
|
Returns an estimate of the default amount of parallelism a program should
|
||||||
|
use. Always returns a non-zero value.
|
||||||
|
|
||||||
|
On Linux, inspects the calling thread's CPU affinity mask to determine if
|
||||||
|
it has been pinned to specific CPUs.
|
||||||
|
|
||||||
|
On Windows, the available parallelism may be underreported on systems with
|
||||||
|
more than 64 logical CPUs.
|
||||||
|
|
||||||
|
On other platforms, reports the number of CPUs that the operating system
|
||||||
|
considers to be online.
|
||||||
|
|
||||||
|
.. versionadded:: 1.44.0
|
||||||
|
|
||||||
.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count)
|
.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count)
|
||||||
|
|
||||||
Gets information about the CPUs on the system. The `cpu_infos` array will
|
Gets information about the CPUs on the system. The `cpu_infos` array will
|
||||||
have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`.
|
have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`.
|
||||||
|
|
||||||
|
Use :c:func:`uv_available_parallelism` if you need to know how many CPUs
|
||||||
|
are available for threads or child processes.
|
||||||
|
|
||||||
.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count)
|
.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count)
|
||||||
|
|
||||||
Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`.
|
Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`.
|
||||||
|
|
||||||
|
.. c:function:: int uv_cpumask_size(void)
|
||||||
|
|
||||||
|
Returns the maximum size of the mask used for process/thread affinities,
|
||||||
|
or `UV_ENOTSUP` if affinities are not supported on the current platform.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count)
|
.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count)
|
||||||
|
|
||||||
Gets address information about the network interfaces on the system. An
|
Gets address information about the network interfaces on the system. An
|
||||||
@ -514,6 +589,35 @@ API
|
|||||||
|
|
||||||
.. versionadded:: 1.9.0
|
.. versionadded:: 1.9.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_os_get_passwd2(uv_passwd_t* pwd, uv_uid_t uid)
|
||||||
|
|
||||||
|
Gets a subset of the password file entry for the provided uid.
|
||||||
|
The populated data includes the username, euid, gid, shell,
|
||||||
|
and home directory. On non-Windows systems, all data comes from
|
||||||
|
:man:`getpwuid_r(3)`. On Windows, uid and gid are set to -1 and have no
|
||||||
|
meaning, and shell is `NULL`. After successfully calling this function, the
|
||||||
|
memory allocated to `pwd` needs to be freed with
|
||||||
|
:c:func:`uv_os_free_passwd`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_os_get_group(uv_group_t* group, uv_uid_t gid)
|
||||||
|
|
||||||
|
Gets a subset of the group file entry for the provided uid.
|
||||||
|
The populated data includes the group name, gid, and members. On non-Windows
|
||||||
|
systems, all data comes from :man:`getgrgid_r(3)`. On Windows, uid and gid
|
||||||
|
are set to -1 and have no meaning. After successfully calling this function,
|
||||||
|
the memory allocated to `group` needs to be freed with
|
||||||
|
:c:func:`uv_os_free_group`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
|
.. c:function:: void uv_os_free_group(uv_passwd_t* pwd)
|
||||||
|
|
||||||
|
Frees the memory previously allocated with :c:func:`uv_os_get_group`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
.. c:function:: void uv_os_free_passwd(uv_passwd_t* pwd)
|
.. c:function:: void uv_os_free_passwd(uv_passwd_t* pwd)
|
||||||
|
|
||||||
Frees the `pwd` memory previously allocated with :c:func:`uv_os_get_passwd`.
|
Frees the `pwd` memory previously allocated with :c:func:`uv_os_get_passwd`.
|
||||||
@ -522,18 +626,21 @@ API
|
|||||||
|
|
||||||
.. c:function:: uint64_t uv_get_free_memory(void)
|
.. c:function:: uint64_t uv_get_free_memory(void)
|
||||||
|
|
||||||
Gets the amount of free memory available in the system, as reported by the kernel (in bytes).
|
Gets the amount of free memory available in the system, as reported by
|
||||||
|
the kernel (in bytes). Returns 0 when unknown.
|
||||||
|
|
||||||
.. c:function:: uint64_t uv_get_total_memory(void)
|
.. c:function:: uint64_t uv_get_total_memory(void)
|
||||||
|
|
||||||
Gets the total amount of physical memory in the system (in bytes).
|
Gets the total amount of physical memory in the system (in bytes).
|
||||||
|
Returns 0 when unknown.
|
||||||
|
|
||||||
.. c:function:: uint64_t uv_get_constrained_memory(void)
|
.. c:function:: uint64_t uv_get_constrained_memory(void)
|
||||||
|
|
||||||
Gets the amount of memory available to the process (in bytes) based on
|
Gets the total amount of memory available to the process (in bytes) based on
|
||||||
limits imposed by the OS. If there is no such constraint, or the constraint
|
limits imposed by the OS. If there is no such constraint, or the constraint
|
||||||
is unknown, `0` is returned. Note that it is not unusual for this value to
|
is unknown, `0` is returned. If there is a constraining mechanism, but there
|
||||||
be less than or greater than :c:func:`uv_get_total_memory`.
|
is no constraint set, `UINT64_MAX` is returned. Note that it is not unusual
|
||||||
|
for this value to be less than or greater than :c:func:`uv_get_total_memory`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
This function currently only returns a non-zero value on Linux, based
|
This function currently only returns a non-zero value on Linux, based
|
||||||
@ -541,9 +648,23 @@ API
|
|||||||
|
|
||||||
.. versionadded:: 1.29.0
|
.. versionadded:: 1.29.0
|
||||||
|
|
||||||
|
.. c:function:: uint64_t uv_get_available_memory(void)
|
||||||
|
|
||||||
|
Gets the amount of free memory that is still available to the process (in bytes).
|
||||||
|
This differs from :c:func:`uv_get_free_memory` in that it takes into account any
|
||||||
|
limits imposed by the OS. If there is no such constraint, or the constraint
|
||||||
|
is unknown, the amount returned will be identical to :c:func:`uv_get_free_memory`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This function currently only returns a value that is different from
|
||||||
|
what :c:func:`uv_get_free_memory` reports on Linux, based
|
||||||
|
on cgroups if it is present.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
.. c:function:: uint64_t uv_hrtime(void)
|
.. c:function:: uint64_t uv_hrtime(void)
|
||||||
|
|
||||||
Returns the current high-resolution real time. This is expressed in
|
Returns the current high-resolution timestamp. This is expressed in
|
||||||
nanoseconds. It is relative to an arbitrary time in the past. It is not
|
nanoseconds. It is relative to an arbitrary time in the past. It is not
|
||||||
related to the time of day and therefore not subject to clock drift. The
|
related to the time of day and therefore not subject to clock drift. The
|
||||||
primary use is for measuring performance between intervals.
|
primary use is for measuring performance between intervals.
|
||||||
@ -552,6 +673,19 @@ API
|
|||||||
Not every platform can support nanosecond resolution; however, this value will always
|
Not every platform can support nanosecond resolution; however, this value will always
|
||||||
be in nanoseconds.
|
be in nanoseconds.
|
||||||
|
|
||||||
|
.. c:function:: int uv_clock_gettime(uv_clock_id clock_id, uv_timespec64_t* ts)
|
||||||
|
|
||||||
|
Obtain the current system time from a high-resolution real-time or monotonic
|
||||||
|
clock source.
|
||||||
|
|
||||||
|
The real-time clock counts from the UNIX epoch (1970-01-01) and is subject
|
||||||
|
to time adjustments; it can jump back in time.
|
||||||
|
|
||||||
|
The monotonic clock counts from an arbitrary point in the past and never
|
||||||
|
jumps back in time.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
.. c:function:: void uv_print_all_handles(uv_loop_t* loop, FILE* stream)
|
.. c:function:: void uv_print_all_handles(uv_loop_t* loop, FILE* stream)
|
||||||
|
|
||||||
Prints all handles associated with the given `loop` to the given `stream`.
|
Prints all handles associated with the given `loop` to the given `stream`.
|
||||||
@ -757,3 +891,50 @@ API
|
|||||||
Causes the calling thread to sleep for `msec` milliseconds.
|
Causes the calling thread to sleep for `msec` milliseconds.
|
||||||
|
|
||||||
.. versionadded:: 1.34.0
|
.. versionadded:: 1.34.0
|
||||||
|
|
||||||
|
String manipulation functions
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
These string utilities are needed internally for dealing with Windows, and are
|
||||||
|
exported to allow clients to work uniformly with this data when the libuv API
|
||||||
|
is not complete.
|
||||||
|
|
||||||
|
.. c:function:: size_t uv_utf16_length_as_wtf8(const uint16_t* utf16, ssize_t utf16_len)
|
||||||
|
|
||||||
|
Get the length of a UTF-16 (or UCS-2) `utf16` value after converting it to
|
||||||
|
WTF-8. If `utf16` is NUL terminated, `utf16_len` can be set to -1,
|
||||||
|
otherwise it must be specified.
|
||||||
|
|
||||||
|
.. versionadded:: 1.47.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_utf16_to_wtf8(const uint16_t* utf16, ssize_t utf16_len, char** wtf8_ptr, size_t* wtf8_len_ptr)
|
||||||
|
|
||||||
|
Convert UTF-16 (or UCS-2) data in `utf16` to WTF-8 data in `*wtf8_ptr`. The
|
||||||
|
`utf16_len` count (in characters) gives the length of `utf16`. If `utf16`
|
||||||
|
is NUL terminated, `utf16_len` can be set to -1, otherwise it must be
|
||||||
|
specified. If `wtf8_ptr` is `NULL`, no result will be computed, but the
|
||||||
|
length (equal to `uv_utf16_length_as_wtf8`) will be stored in `wtf8_ptr`.
|
||||||
|
If `*wtf8_ptr` is `NULL`, space for the conversion will be allocated and
|
||||||
|
returned in `wtf8_ptr` and the length will be returned in `wtf8_len_ptr`.
|
||||||
|
Otherwise, the length of `*wtf8_ptr` must be passed in `wtf8_len_ptr`. The
|
||||||
|
`wtf8_ptr` must contain an extra space for an extra NUL after the result.
|
||||||
|
If the result is truncated, `UV_ENOBUFS` will be returned and
|
||||||
|
`wtf8_len_ptr` will be the length of the required `wtf8_ptr` to contain the
|
||||||
|
whole result.
|
||||||
|
|
||||||
|
.. versionadded:: 1.47.0
|
||||||
|
|
||||||
|
.. c:function:: ssize_t uv_wtf8_length_as_utf16(const char* wtf8)
|
||||||
|
|
||||||
|
Get the length in characters of a NUL-terminated WTF-8 `wtf8` value
|
||||||
|
after converting it to UTF-16 (or UCS-2), including NUL terminator.
|
||||||
|
|
||||||
|
.. versionadded:: 1.47.0
|
||||||
|
|
||||||
|
.. c:function:: void uv_wtf8_to_utf16(const char* utf8, uint16_t* utf16, size_t utf16_len)
|
||||||
|
|
||||||
|
Convert NUL-terminated WTF-8 data in `wtf8` to UTF-16 (or UCS-2) data
|
||||||
|
in `utf16`. The `utf16_len` count (in characters) must include space
|
||||||
|
for the NUL terminator.
|
||||||
|
|
||||||
|
.. versionadded:: 1.47.0
|
||||||
|
|||||||
@ -55,17 +55,61 @@ API
|
|||||||
|
|
||||||
Bind the pipe to a file path (Unix) or a name (Windows).
|
Bind the pipe to a file path (Unix) or a name (Windows).
|
||||||
|
|
||||||
|
Does not support Linux abstract namespace sockets,
|
||||||
|
unlike :c:func:`uv_pipe_bind2`.
|
||||||
|
|
||||||
|
Alias for ``uv_pipe_bind2(handle, name, strlen(name), 0)``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
||||||
92 and 108 bytes.
|
typically between 92 and 108 bytes.
|
||||||
|
|
||||||
|
.. c:function:: int uv_pipe_bind2(uv_pipe_t* handle, const char* name, size_t namelen, unsigned int flags)
|
||||||
|
|
||||||
|
Bind the pipe to a file path (Unix) or a name (Windows).
|
||||||
|
|
||||||
|
``flags`` must be zero or ``UV_PIPE_NO_TRUNCATE``. Returns ``UV_EINVAL``
|
||||||
|
for unsupported flags without performing the bind operation.
|
||||||
|
|
||||||
|
Supports Linux abstract namespace sockets. ``namelen`` must include
|
||||||
|
the leading nul byte but not the trailing nul byte.
|
||||||
|
|
||||||
|
.. versionadded:: 1.46.0
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
||||||
|
typically between 92 and 108 bytes, unless the ``UV_PIPE_NO_TRUNCATE``
|
||||||
|
flag is specified, in which case an ``UV_EINVAL`` error is returned.
|
||||||
|
|
||||||
.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb)
|
.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb)
|
||||||
|
|
||||||
Connect to the Unix domain socket or the named pipe.
|
Connect to the Unix domain socket or the Windows named pipe.
|
||||||
|
|
||||||
|
Does not support Linux abstract namespace sockets,
|
||||||
|
unlike :c:func:`uv_pipe_connect2`.
|
||||||
|
|
||||||
|
Alias for ``uv_pipe_connect2(req, handle, name, strlen(name), 0, cb)``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
||||||
92 and 108 bytes.
|
typically between 92 and 108 bytes.
|
||||||
|
|
||||||
|
.. c:function:: void uv_pipe_connect2(uv_connect_t* req, uv_pipe_t* handle, const char* name, size_t namelen, unsigned int flags, uv_connect_cb cb)
|
||||||
|
|
||||||
|
Connect to the Unix domain socket or the Windows named pipe.
|
||||||
|
|
||||||
|
``flags`` must be zero or ``UV_PIPE_NO_TRUNCATE``. Returns ``UV_EINVAL``
|
||||||
|
for unsupported flags without performing the connect operation.
|
||||||
|
|
||||||
|
Supports Linux abstract namespace sockets. ``namelen`` must include
|
||||||
|
the leading nul byte but not the trailing nul byte.
|
||||||
|
|
||||||
|
.. versionadded:: 1.46.0
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
||||||
|
typically between 92 and 108 bytes, unless the ``UV_PIPE_NO_TRUNCATE``
|
||||||
|
flag is specified, in which case an ``UV_EINVAL`` error is returned.
|
||||||
|
|
||||||
.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@ Data types
|
|||||||
|
|
||||||
Type definition for callback passed to :c:func:`uv_poll_start`.
|
Type definition for callback passed to :c:func:`uv_poll_start`.
|
||||||
|
|
||||||
.. c:type:: uv_poll_event
|
.. c:enum:: uv_poll_event
|
||||||
|
|
||||||
Poll event types
|
Poll event types
|
||||||
|
|
||||||
@ -101,7 +101,9 @@ API
|
|||||||
with one of the `UV_E*` error codes (see :ref:`errors`). The user should
|
with one of the `UV_E*` error codes (see :ref:`errors`). The user should
|
||||||
not close the socket while the handle is active. If the user does that
|
not close the socket while the handle is active. If the user does that
|
||||||
anyway, the callback *may* be called reporting an error status, but this is
|
anyway, the callback *may* be called reporting an error status, but this is
|
||||||
**not** guaranteed.
|
**not** guaranteed. If `status == UV_EBADF` polling is discontinued for the
|
||||||
|
file handle and no further events will be reported. The user should
|
||||||
|
then call :c:func:`uv_close` on the handle.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Calling :c:func:`uv_poll_start` on a handle that is already active is
|
Calling :c:func:`uv_poll_start` on a handle that is already active is
|
||||||
|
|||||||
@ -40,7 +40,7 @@ Data types
|
|||||||
will indicate the exit status and the signal that caused the process to
|
will indicate the exit status and the signal that caused the process to
|
||||||
terminate, if any.
|
terminate, if any.
|
||||||
|
|
||||||
.. c:type:: uv_process_flags
|
.. c:enum:: uv_process_flags
|
||||||
|
|
||||||
Flags to be set on the flags field of :c:type:`uv_process_options_t`.
|
Flags to be set on the flags field of :c:type:`uv_process_options_t`.
|
||||||
|
|
||||||
@ -85,7 +85,14 @@ Data types
|
|||||||
* option is only meaningful on Windows systems. On Unix it is silently
|
* option is only meaningful on Windows systems. On Unix it is silently
|
||||||
* ignored.
|
* ignored.
|
||||||
*/
|
*/
|
||||||
UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6)
|
UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6),
|
||||||
|
/*
|
||||||
|
* On Windows, if the path to the program to execute, specified in
|
||||||
|
* uv_process_options_t's file field, has a directory component,
|
||||||
|
* search for the exact file name before trying variants with
|
||||||
|
* extensions like '.exe' or '.cmd'.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7)
|
||||||
};
|
};
|
||||||
|
|
||||||
.. c:type:: uv_stdio_container_t
|
.. c:type:: uv_stdio_container_t
|
||||||
@ -109,10 +116,39 @@ Data types
|
|||||||
::
|
::
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
/*
|
||||||
|
* The following four options are mutually-exclusive, and define
|
||||||
|
* the operation to perform for the corresponding file descriptor
|
||||||
|
* in the child process:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No file descriptor will be provided (or redirected to
|
||||||
|
* `/dev/null` if it is fd 0, 1 or 2).
|
||||||
|
*/
|
||||||
UV_IGNORE = 0x00,
|
UV_IGNORE = 0x00,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a new pipe into `data.stream`, per the flags below. The
|
||||||
|
* `data.stream` field must point to a uv_pipe_t object that has
|
||||||
|
* been initialized with `uv_pipe_init(loop, data.stream, ipc);`,
|
||||||
|
* but not yet opened or connected.
|
||||||
|
/*
|
||||||
UV_CREATE_PIPE = 0x01,
|
UV_CREATE_PIPE = 0x01,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The child process will be given a duplicate of the parent's
|
||||||
|
* file descriptor given by `data.fd`.
|
||||||
|
*/
|
||||||
UV_INHERIT_FD = 0x02,
|
UV_INHERIT_FD = 0x02,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The child process will be given a duplicate of the parent's
|
||||||
|
* file descriptor being used by the stream handle given by
|
||||||
|
* `data.stream`.
|
||||||
|
*/
|
||||||
UV_INHERIT_STREAM = 0x04,
|
UV_INHERIT_STREAM = 0x04,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
|
* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
|
||||||
* determine the direction of flow, from the child process' perspective. Both
|
* determine the direction of flow, from the child process' perspective. Both
|
||||||
@ -120,6 +156,7 @@ Data types
|
|||||||
*/
|
*/
|
||||||
UV_READABLE_PIPE = 0x10,
|
UV_READABLE_PIPE = 0x10,
|
||||||
UV_WRITABLE_PIPE = 0x20,
|
UV_WRITABLE_PIPE = 0x20,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the
|
* When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the
|
||||||
* handle in non-blocking mode in the child. This may cause loss of data,
|
* handle in non-blocking mode in the child. This may cause loss of data,
|
||||||
@ -153,7 +190,7 @@ Public members
|
|||||||
Command line arguments. args[0] should be the path to the program. On
|
Command line arguments. args[0] should be the path to the program. On
|
||||||
Windows this uses `CreateProcess` which concatenates the arguments into a
|
Windows this uses `CreateProcess` which concatenates the arguments into a
|
||||||
string this can cause some strange errors. See the
|
string this can cause some strange errors. See the
|
||||||
``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:type:`uv_process_flags`.
|
``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:enum:`uv_process_flags`.
|
||||||
|
|
||||||
.. c:member:: char** uv_process_options_t.env
|
.. c:member:: char** uv_process_options_t.env
|
||||||
|
|
||||||
@ -166,7 +203,7 @@ Public members
|
|||||||
.. c:member:: unsigned int uv_process_options_t.flags
|
.. c:member:: unsigned int uv_process_options_t.flags
|
||||||
|
|
||||||
Various flags that control how :c:func:`uv_spawn` behaves. See
|
Various flags that control how :c:func:`uv_spawn` behaves. See
|
||||||
:c:type:`uv_process_flags`.
|
:c:enum:`uv_process_flags`.
|
||||||
|
|
||||||
.. c:member:: int uv_process_options_t.stdio_count
|
.. c:member:: int uv_process_options_t.stdio_count
|
||||||
.. c:member:: uv_stdio_container_t* uv_process_options_t.stdio
|
.. c:member:: uv_stdio_container_t* uv_process_options_t.stdio
|
||||||
@ -232,6 +269,9 @@ API
|
|||||||
.. versionchanged:: 1.24.0 Added `UV_PROCESS_WINDOWS_HIDE_CONSOLE` and
|
.. versionchanged:: 1.24.0 Added `UV_PROCESS_WINDOWS_HIDE_CONSOLE` and
|
||||||
`UV_PROCESS_WINDOWS_HIDE_GUI` flags.
|
`UV_PROCESS_WINDOWS_HIDE_GUI` flags.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.48.0 Added the
|
||||||
|
`UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME` flag.
|
||||||
|
|
||||||
.. c:function:: int uv_process_kill(uv_process_t* handle, int signum)
|
.. c:function:: int uv_process_kill(uv_process_t* handle, int signum)
|
||||||
|
|
||||||
Sends the specified signal to the given process handle. Check the documentation
|
Sends the specified signal to the given process handle. Check the documentation
|
||||||
|
|||||||
@ -21,17 +21,9 @@ Data types
|
|||||||
|
|
||||||
Union of all request types.
|
Union of all request types.
|
||||||
|
|
||||||
|
.. c:enum:: uv_req_type
|
||||||
|
|
||||||
Public members
|
The kind of the libuv request.
|
||||||
^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
.. c:member:: void* uv_req_t.data
|
|
||||||
|
|
||||||
Space for user-defined arbitrary data. libuv does not use this field.
|
|
||||||
|
|
||||||
.. c:member:: uv_req_type uv_req_t.type
|
|
||||||
|
|
||||||
Indicated the type of request. Readonly.
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -50,6 +42,18 @@ Public members
|
|||||||
} uv_req_type;
|
} uv_req_type;
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: void* uv_req_t.data
|
||||||
|
|
||||||
|
Space for user-defined arbitrary data. libuv does not use this field.
|
||||||
|
|
||||||
|
.. c:member:: uv_req_type uv_req_t.type
|
||||||
|
|
||||||
|
The :c:enum:`uv_req_type`, indicating the type of the request. Readonly.
|
||||||
|
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -95,7 +99,7 @@ API
|
|||||||
|
|
||||||
.. versionadded:: 1.19.0
|
.. versionadded:: 1.19.0
|
||||||
|
|
||||||
.. c:function:: void* uv_req_set_data(uv_req_t* req, void* data)
|
.. c:function:: void uv_req_set_data(uv_req_t* req, void* data)
|
||||||
|
|
||||||
Sets `req->data` to `data`.
|
Sets `req->data` to `data`.
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 64 KiB |
@ -16,6 +16,28 @@ Data types
|
|||||||
|
|
||||||
TCP handle type.
|
TCP handle type.
|
||||||
|
|
||||||
|
.. c:enum:: uv_tcp_flags
|
||||||
|
|
||||||
|
Flags used in :c:func:`uv_tcp_bind`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
enum uv_tcp_flags {
|
||||||
|
/* Used with uv_tcp_bind, when an IPv6 address is used. */
|
||||||
|
UV_TCP_IPV6ONLY = 1,
|
||||||
|
|
||||||
|
/* Enable SO_REUSEPORT socket option when binding the handle.
|
||||||
|
* This allows completely duplicate bindings by multiple processes
|
||||||
|
* or threads if they all set SO_REUSEPORT before binding the port.
|
||||||
|
* Incoming connections are distributed across the participating
|
||||||
|
* listener sockets.
|
||||||
|
*
|
||||||
|
* This flag is available only on Linux 3.9+, DragonFlyBSD 3.6+,
|
||||||
|
* FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ for now.
|
||||||
|
*/
|
||||||
|
UV_TCP_REUSEPORT = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Public members
|
Public members
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
@ -65,6 +87,10 @@ API
|
|||||||
at the end of this procedure, then the handle is destroyed with a
|
at the end of this procedure, then the handle is destroyed with a
|
||||||
``UV_ETIMEDOUT`` error passed to the corresponding callback.
|
``UV_ETIMEDOUT`` error passed to the corresponding callback.
|
||||||
|
|
||||||
|
If `delay` is less than 1 then ``UV_EINVAL`` is returned.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.49.0 If `delay` is less than 1 then ``UV_EINVAL``` is returned.
|
||||||
|
|
||||||
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
|
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
|
||||||
|
|
||||||
Enable / disable simultaneous asynchronous accept requests that are
|
Enable / disable simultaneous asynchronous accept requests that are
|
||||||
@ -77,16 +103,34 @@ API
|
|||||||
|
|
||||||
.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags)
|
.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags)
|
||||||
|
|
||||||
Bind the handle to an address and port. `addr` should point to an
|
Bind the handle to an address and port.
|
||||||
initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``.
|
|
||||||
|
|
||||||
When the port is already taken, you can expect to see an ``UV_EADDRINUSE``
|
When the port is already taken, you can expect to see an ``UV_EADDRINUSE``
|
||||||
error from :c:func:`uv_listen` or :c:func:`uv_tcp_connect`. That is,
|
error from :c:func:`uv_listen` or :c:func:`uv_tcp_connect` unless you specify
|
||||||
a successful call to this function does not guarantee that the call
|
``UV_TCP_REUSEPORT`` in `flags` for all the binding sockets. That is, a successful
|
||||||
to :c:func:`uv_listen` or :c:func:`uv_tcp_connect` will succeed as well.
|
call to this function does not guarantee that the call to :c:func:`uv_listen` or
|
||||||
|
:c:func:`uv_tcp_connect` will succeed as well.
|
||||||
|
|
||||||
`flags` can contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support
|
:param handle: TCP handle. It should have been initialized with :c:func:`uv_tcp_init`.
|
||||||
is disabled and only IPv6 is used.
|
|
||||||
|
:param addr: Address to bind to. It should point to an initialized ``struct sockaddr_in``
|
||||||
|
or ``struct sockaddr_in6``.
|
||||||
|
|
||||||
|
:param flags: Flags that control the behavior of binding the socket.
|
||||||
|
``UV_TCP_IPV6ONLY`` can be contained in `flags` to disable dual-stack
|
||||||
|
support and only use IPv6.
|
||||||
|
``UV_TCP_REUSEPORT`` can be contained in `flags` to enable the socket option
|
||||||
|
`SO_REUSEPORT` with the capability of load balancing that distribute incoming
|
||||||
|
connections across all listening sockets in multiple processes or threads.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.49.0 added the ``UV_TCP_REUSEPORT`` flag.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
``UV_TCP_REUSEPORT`` flag is available only on Linux 3.9+, DragonFlyBSD 3.6+,
|
||||||
|
FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ at the moment. On other platforms
|
||||||
|
this function will return an UV_ENOTSUP error.
|
||||||
|
|
||||||
.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
|
.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
|
||||||
|
|
||||||
|
|||||||
@ -78,6 +78,14 @@ Threads
|
|||||||
|
|
||||||
.. versionchanged:: 1.4.1 returns a UV_E* error code on failure
|
.. versionchanged:: 1.4.1 returns a UV_E* error code on failure
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_detach(uv_thread_t* tid)
|
||||||
|
|
||||||
|
Detaches a thread. Detached threads automatically release their
|
||||||
|
resources upon termination, eliminating the need for the application to
|
||||||
|
call `uv_thread_join`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.50.0
|
||||||
|
|
||||||
.. c:function:: int uv_thread_create_ex(uv_thread_t* tid, const uv_thread_options_t* params, uv_thread_cb entry, void* arg)
|
.. c:function:: int uv_thread_create_ex(uv_thread_t* tid, const uv_thread_options_t* params, uv_thread_cb entry, void* arg)
|
||||||
|
|
||||||
Like :c:func:`uv_thread_create`, but additionally specifies options for creating a new thread.
|
Like :c:func:`uv_thread_create`, but additionally specifies options for creating a new thread.
|
||||||
@ -88,10 +96,89 @@ Threads
|
|||||||
|
|
||||||
.. versionadded:: 1.26.0
|
.. versionadded:: 1.26.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_setaffinity(uv_thread_t* tid, char* cpumask, char* oldmask, size_t mask_size)
|
||||||
|
|
||||||
|
Sets the specified thread's affinity to cpumask, which is specified in
|
||||||
|
bytes. Optionally returning the previous affinity setting in oldmask.
|
||||||
|
On Unix, uses :man:`pthread_getaffinity_np(3)` to get the affinity setting
|
||||||
|
and maps the cpu_set_t to bytes in oldmask. Then maps the bytes in cpumask
|
||||||
|
to a cpu_set_t and uses :man:`pthread_setaffinity_np(3)`. On Windows, maps
|
||||||
|
the bytes in cpumask to a bitmask and uses SetThreadAffinityMask() which
|
||||||
|
returns the previous affinity setting.
|
||||||
|
|
||||||
|
The mask_size specifies the number of entries (bytes) in cpumask / oldmask,
|
||||||
|
and must be greater-than-or-equal-to :c:func:`uv_cpumask_size`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Thread affinity setting is not atomic on Windows. Unsupported on macOS.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_getaffinity(uv_thread_t* tid, char* cpumask, size_t mask_size)
|
||||||
|
|
||||||
|
Gets the specified thread's affinity setting. On Unix, this maps the
|
||||||
|
cpu_set_t returned by :man:`pthread_getaffinity_np(3)` to bytes in cpumask.
|
||||||
|
|
||||||
|
The mask_size specifies the number of entries (bytes) in cpumask,
|
||||||
|
and must be greater-than-or-equal-to :c:func:`uv_cpumask_size`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Thread affinity getting is not atomic on Windows. Unsupported on macOS.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_getcpu(void)
|
||||||
|
|
||||||
|
Gets the CPU number on which the calling thread is running.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Currently only implemented on Windows, Linux and FreeBSD.
|
||||||
|
|
||||||
|
.. versionadded:: 1.45.0
|
||||||
|
|
||||||
.. c:function:: uv_thread_t uv_thread_self(void)
|
.. c:function:: uv_thread_t uv_thread_self(void)
|
||||||
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
||||||
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
|
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_setname(const char* name)
|
||||||
|
|
||||||
|
Sets the name of the current thread. Different platforms define different limits on the max number of characters
|
||||||
|
a thread name can be: Linux, IBM i (16), macOS (64), Windows (32767), and NetBSD (32), etc. `uv_thread_setname()`
|
||||||
|
will truncate it in case `name` is larger than the limit of the platform.
|
||||||
|
|
||||||
|
Not supported on Windows Server 2016, returns `UV_ENOSYS`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.50.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_getname(uv_thread_t* tid, char* name, size_t* size)
|
||||||
|
|
||||||
|
Gets the name of the thread specified by `tid`. The thread name is copied, with the trailing NUL, into the buffer
|
||||||
|
pointed to by `name`. The `size` parameter specifies the size of the buffer pointed to by `name`.
|
||||||
|
The buffer should be large enough to hold the name of the thread plus the trailing NUL, or it will be truncated to fit
|
||||||
|
with the trailing NUL.
|
||||||
|
|
||||||
|
Not supported on Windows Server 2016, returns `UV_ENOSYS`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.50.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_setpriority(uv_thread_t tid, int priority)
|
||||||
|
|
||||||
|
If the function succeeds, the return value is 0.
|
||||||
|
If the function fails, the return value is less than zero.
|
||||||
|
Sets the scheduling priority of the thread specified by tid. It requires elevated
|
||||||
|
privilege to set specific priorities on some platforms.
|
||||||
|
The priority can be set to the following constants. UV_THREAD_PRIORITY_HIGHEST,
|
||||||
|
UV_THREAD_PRIORITY_ABOVE_NORMAL, UV_THREAD_PRIORITY_NORMAL,
|
||||||
|
UV_THREAD_PRIORITY_BELOW_NORMAL, UV_THREAD_PRIORITY_LOWEST.
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_getpriority(uv_thread_t tid, int* priority)
|
||||||
|
|
||||||
|
If the function succeeds, the return value is 0.
|
||||||
|
If the function fails, the return value is less than zero.
|
||||||
|
Retrieves the scheduling priority of the thread specified by tid. The value in the
|
||||||
|
output parameter priority is platform dependent.
|
||||||
|
For Linux, when schedule policy is SCHED_OTHER (default), priority is 0.
|
||||||
|
|
||||||
Thread-local storage
|
Thread-local storage
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,11 @@ is 1024).
|
|||||||
|
|
||||||
.. versionchanged:: 1.30.0 the maximum UV_THREADPOOL_SIZE allowed was increased from 128 to 1024.
|
.. versionchanged:: 1.30.0 the maximum UV_THREADPOOL_SIZE allowed was increased from 128 to 1024.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.45.0 threads now have an 8 MB stack instead of the
|
||||||
|
(sometimes too low) platform default.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.50.0 threads now have a default name of libuv-worker.
|
||||||
|
|
||||||
The threadpool is global and shared across all event loops. When a particular
|
The threadpool is global and shared across all event loops. When a particular
|
||||||
function makes use of the threadpool (i.e. when using :c:func:`uv_queue_work`)
|
function makes use of the threadpool (i.e. when using :c:func:`uv_queue_work`)
|
||||||
libuv preallocates and initializes the maximum number of threads allowed by
|
libuv preallocates and initializes the maximum number of threads allowed by
|
||||||
|
|||||||
@ -6,6 +6,15 @@
|
|||||||
|
|
||||||
Timer handles are used to schedule callbacks to be called in the future.
|
Timer handles are used to schedule callbacks to be called in the future.
|
||||||
|
|
||||||
|
Timers are either single-shot or repeating. Repeating timers do not adjust
|
||||||
|
for overhead but are rearmed relative to the event loop's idea of "now".
|
||||||
|
|
||||||
|
Libuv updates its idea of "now" right before executing timer callbacks, and
|
||||||
|
right after waking up from waiting for I/O. See also :c:func:`uv_update_time`.
|
||||||
|
|
||||||
|
Example: a repeating timer with a 50 ms interval whose callback takes 17 ms
|
||||||
|
to complete, runs again 33 ms later. If other tasks take longer than 33 ms,
|
||||||
|
the timer callback runs as soon as possible.
|
||||||
|
|
||||||
Data types
|
Data types
|
||||||
----------
|
----------
|
||||||
@ -64,11 +73,6 @@ API
|
|||||||
duration, and will follow normal timer semantics in the case of a
|
duration, and will follow normal timer semantics in the case of a
|
||||||
time-slice overrun.
|
time-slice overrun.
|
||||||
|
|
||||||
For example, if a 50ms repeating timer first runs for 17ms, it will be
|
|
||||||
scheduled to run again 33ms later. If other tasks consume more than the
|
|
||||||
33ms following the first timer callback, then the callback will run as soon
|
|
||||||
as possible.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
If the repeat value is set from a timer callback it does not immediately take effect.
|
If the repeat value is set from a timer callback it does not immediately take effect.
|
||||||
If the timer was non-repeating before, it will have been stopped. If it was repeating,
|
If the timer was non-repeating before, it will have been stopped. If it was repeating,
|
||||||
|
|||||||
@ -27,10 +27,15 @@ Data types
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
/* Initial/normal terminal mode */
|
/* Initial/normal terminal mode */
|
||||||
UV_TTY_MODE_NORMAL,
|
UV_TTY_MODE_NORMAL,
|
||||||
/* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
|
/*
|
||||||
|
* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled).
|
||||||
|
* May become equivalent to UV_TTY_MODE_RAW_VT in future libuv versions.
|
||||||
|
*/
|
||||||
UV_TTY_MODE_RAW,
|
UV_TTY_MODE_RAW,
|
||||||
/* Binary-safe I/O mode for IPC (Unix-only) */
|
/* Binary-safe I/O mode for IPC (Unix-only) */
|
||||||
UV_TTY_MODE_IO
|
UV_TTY_MODE_IO,
|
||||||
|
/* Raw input mode. On Windows ENABLE_VIRTUAL_TERMINAL_INPUT is also set. */
|
||||||
|
UV_TTY_MODE_RAW_VT
|
||||||
} uv_tty_mode_t;
|
} uv_tty_mode_t;
|
||||||
|
|
||||||
.. c:enum:: uv_tty_vtermstate_t
|
.. c:enum:: uv_tty_vtermstate_t
|
||||||
@ -98,7 +103,7 @@ API
|
|||||||
.. c:function:: int uv_tty_set_mode(uv_tty_t* handle, uv_tty_mode_t mode)
|
.. c:function:: int uv_tty_set_mode(uv_tty_t* handle, uv_tty_mode_t mode)
|
||||||
|
|
||||||
.. versionchanged:: 1.2.0: the mode is specified as a
|
.. versionchanged:: 1.2.0: the mode is specified as a
|
||||||
:c:type:`uv_tty_mode_t` value.
|
:c:enum:`uv_tty_mode_t` value.
|
||||||
|
|
||||||
Set the TTY using the specified terminal mode.
|
Set the TTY using the specified terminal mode.
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ Data types
|
|||||||
|
|
||||||
UDP send request type.
|
UDP send request type.
|
||||||
|
|
||||||
.. c:type:: uv_udp_flags
|
.. c:enum:: uv_udp_flags
|
||||||
|
|
||||||
Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`..
|
Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`..
|
||||||
|
|
||||||
@ -28,19 +28,21 @@ Data types
|
|||||||
/* Disables dual stack mode. */
|
/* Disables dual stack mode. */
|
||||||
UV_UDP_IPV6ONLY = 1,
|
UV_UDP_IPV6ONLY = 1,
|
||||||
/*
|
/*
|
||||||
* Indicates message was truncated because read buffer was too small. The
|
* Indicates message was truncated because read buffer was too small. The
|
||||||
* remainder was discarded by the OS. Used in uv_udp_recv_cb.
|
* remainder was discarded by the OS. Used in uv_udp_recv_cb.
|
||||||
*/
|
*/
|
||||||
UV_UDP_PARTIAL = 2,
|
UV_UDP_PARTIAL = 2,
|
||||||
/*
|
/*
|
||||||
* Indicates if SO_REUSEADDR will be set when binding the handle in
|
* Indicates if SO_REUSEADDR will be set when binding the handle.
|
||||||
* uv_udp_bind.
|
* This sets the SO_REUSEPORT socket flag on the BSDs (except for
|
||||||
* This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
|
* DragonFlyBSD), OS X, and other platforms where SO_REUSEPORTs don't
|
||||||
* Unix platforms, it sets the SO_REUSEADDR flag. What that means is that
|
* have the capability of load balancing, as the opposite of what
|
||||||
* multiple threads or processes can bind to the same address without error
|
* UV_UDP_REUSEPORT would do. On other Unix platforms, it sets the
|
||||||
* (provided they all set the flag) but only the last one to bind will receive
|
* SO_REUSEADDR flag. What that means is that multiple threads or
|
||||||
* any traffic, in effect "stealing" the port from the previous listener.
|
* processes can bind to the same address without error (provided
|
||||||
*/
|
* they all set the flag) but only the last one to bind will receive
|
||||||
|
* any traffic, in effect "stealing" the port from the previous listener.
|
||||||
|
*/
|
||||||
UV_UDP_REUSEADDR = 4,
|
UV_UDP_REUSEADDR = 4,
|
||||||
/*
|
/*
|
||||||
* Indicates that the message was received by recvmmsg, so the buffer provided
|
* Indicates that the message was received by recvmmsg, so the buffer provided
|
||||||
@ -56,14 +58,26 @@ Data types
|
|||||||
/*
|
/*
|
||||||
* Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle.
|
* Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle.
|
||||||
* This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on
|
* This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on
|
||||||
* Linux. This stops the Linux kernel from supressing some ICMP error messages
|
* Linux. This stops the Linux kernel from suppressing some ICMP error messages
|
||||||
* and enables full ICMP error reporting for faster failover.
|
* and enables full ICMP error reporting for faster failover.
|
||||||
* This flag is no-op on platforms other than Linux.
|
* This flag is no-op on platforms other than Linux.
|
||||||
*/
|
*/
|
||||||
UV_UDP_LINUX_RECVERR = 32,
|
UV_UDP_LINUX_RECVERR = 32,
|
||||||
/*
|
/*
|
||||||
* Indicates that recvmmsg should be used, if available.
|
* Indicates if SO_REUSEPORT will be set when binding the handle.
|
||||||
*/
|
* This sets the SO_REUSEPORT socket option on supported platforms.
|
||||||
|
* Unlike UV_UDP_REUSEADDR, this flag will make multiple threads or
|
||||||
|
* processes that are binding to the same address and port "share"
|
||||||
|
* the port, which means incoming datagrams are distributed across
|
||||||
|
* the receiving sockets among threads or processes.
|
||||||
|
*
|
||||||
|
* This flag is available only on Linux 3.9+, DragonFlyBSD 3.6+,
|
||||||
|
* FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ for now.
|
||||||
|
*/
|
||||||
|
UV_UDP_REUSEPORT = 64,
|
||||||
|
/*
|
||||||
|
* Indicates that recvmmsg should be used, if available.
|
||||||
|
*/
|
||||||
UV_UDP_RECVMMSG = 256
|
UV_UDP_RECVMMSG = 256
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -186,11 +200,24 @@ API
|
|||||||
with the address and port to bind to.
|
with the address and port to bind to.
|
||||||
|
|
||||||
:param flags: Indicate how the socket will be bound,
|
:param flags: Indicate how the socket will be bound,
|
||||||
``UV_UDP_IPV6ONLY``, ``UV_UDP_REUSEADDR``, and ``UV_UDP_RECVERR``
|
``UV_UDP_IPV6ONLY``, ``UV_UDP_REUSEADDR``, ``UV_UDP_REUSEPORT``,
|
||||||
are supported.
|
and ``UV_UDP_RECVERR`` are supported.
|
||||||
|
|
||||||
:returns: 0 on success, or an error code < 0 on failure.
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.49.0 added the ``UV_UDP_REUSEPORT`` flag.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
``UV_UDP_REUSEPORT`` flag is available only on Linux 3.9+, DragonFlyBSD 3.6+,
|
||||||
|
FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ at the moment. On other platforms
|
||||||
|
this function will return an UV_ENOTSUP error.
|
||||||
|
For platforms where `SO_REUSEPORT`s have the capability of load balancing,
|
||||||
|
specifying both ``UV_UDP_REUSEADDR`` and ``UV_UDP_REUSEPORT`` in flags is allowed
|
||||||
|
and `SO_REUSEPORT` will always override the behavior of `SO_REUSEADDR`.
|
||||||
|
For platforms where `SO_REUSEPORT`s don't have the capability of load balancing,
|
||||||
|
specifying both ``UV_UDP_REUSEADDR`` and ``UV_UDP_REUSEPORT`` in flags will fail,
|
||||||
|
returning an UV_ENOTSUP error.
|
||||||
|
|
||||||
.. c:function:: int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr)
|
.. c:function:: int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr)
|
||||||
|
|
||||||
Associate the UDP handle to a remote address and port, so every
|
Associate the UDP handle to a remote address and port, so every
|
||||||
@ -285,7 +312,9 @@ API
|
|||||||
local sockets.
|
local sockets.
|
||||||
|
|
||||||
:param handle: UDP handle. Should have been initialized with
|
:param handle: UDP handle. Should have been initialized with
|
||||||
:c:func:`uv_udp_init`.
|
:c:func:`uv_udp_init_ex` as either ``AF_INET`` or ``AF_INET6``, or have
|
||||||
|
been bound to an address explicitly with :c:func:`uv_udp_bind`, or
|
||||||
|
implicitly with :c:func:`uv_udp_send()` or :c:func:`uv_udp_recv_start`.
|
||||||
|
|
||||||
:param on: 1 for on, 0 for off.
|
:param on: 1 for on, 0 for off.
|
||||||
|
|
||||||
@ -296,7 +325,9 @@ API
|
|||||||
Set the multicast ttl.
|
Set the multicast ttl.
|
||||||
|
|
||||||
:param handle: UDP handle. Should have been initialized with
|
:param handle: UDP handle. Should have been initialized with
|
||||||
:c:func:`uv_udp_init`.
|
:c:func:`uv_udp_init_ex` as either ``AF_INET`` or ``AF_INET6``, or have
|
||||||
|
been bound to an address explicitly with :c:func:`uv_udp_bind`, or
|
||||||
|
implicitly with :c:func:`uv_udp_send()` or :c:func:`uv_udp_recv_start`.
|
||||||
|
|
||||||
:param ttl: 1 through 255.
|
:param ttl: 1 through 255.
|
||||||
|
|
||||||
@ -307,7 +338,9 @@ API
|
|||||||
Set the multicast interface to send or receive data on.
|
Set the multicast interface to send or receive data on.
|
||||||
|
|
||||||
:param handle: UDP handle. Should have been initialized with
|
:param handle: UDP handle. Should have been initialized with
|
||||||
:c:func:`uv_udp_init`.
|
:c:func:`uv_udp_init_ex` as either ``AF_INET`` or ``AF_INET6``, or have
|
||||||
|
been bound to an address explicitly with :c:func:`uv_udp_bind`, or
|
||||||
|
implicitly with :c:func:`uv_udp_send()` or :c:func:`uv_udp_recv_start`.
|
||||||
|
|
||||||
:param interface_addr: interface address.
|
:param interface_addr: interface address.
|
||||||
|
|
||||||
@ -318,7 +351,9 @@ API
|
|||||||
Set broadcast on or off.
|
Set broadcast on or off.
|
||||||
|
|
||||||
:param handle: UDP handle. Should have been initialized with
|
:param handle: UDP handle. Should have been initialized with
|
||||||
:c:func:`uv_udp_init`.
|
:c:func:`uv_udp_init_ex` as either ``AF_INET`` or ``AF_INET6``, or have
|
||||||
|
been bound to an address explicitly with :c:func:`uv_udp_bind`, or
|
||||||
|
implicitly with :c:func:`uv_udp_send()` or :c:func:`uv_udp_recv_start`.
|
||||||
|
|
||||||
:param on: 1 for on, 0 for off.
|
:param on: 1 for on, 0 for off.
|
||||||
|
|
||||||
@ -329,7 +364,9 @@ API
|
|||||||
Set the time to live.
|
Set the time to live.
|
||||||
|
|
||||||
:param handle: UDP handle. Should have been initialized with
|
:param handle: UDP handle. Should have been initialized with
|
||||||
:c:func:`uv_udp_init`.
|
:c:func:`uv_udp_init_ex` as either ``AF_INET`` or ``AF_INET6``, or have
|
||||||
|
been bound to an address explicitly with :c:func:`uv_udp_bind`, or
|
||||||
|
implicitly with :c:func:`uv_udp_send()` or :c:func:`uv_udp_recv_start`.
|
||||||
|
|
||||||
:param ttl: 1 through 255.
|
:param ttl: 1 through 255.
|
||||||
|
|
||||||
@ -389,6 +426,20 @@ API
|
|||||||
|
|
||||||
.. versionchanged:: 1.27.0 added support for connected sockets
|
.. versionchanged:: 1.27.0 added support for connected sockets
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_try_send2(uv_udp_t* handle, unsigned int count, uv_buf_t* bufs[/*count*/], unsigned int nbufs[/*count*/], struct sockaddr* addrs[/*count*/], unsigned int flags)
|
||||||
|
|
||||||
|
Like :c:func:`uv_udp_try_send`, but can send multiple datagrams.
|
||||||
|
Lightweight abstraction around :man:`sendmmsg(2)`, with a :man:`sendmsg(2)`
|
||||||
|
fallback loop for platforms that do not support the former. The handle must
|
||||||
|
be fully initialized; call c:func:`uv_udp_bind` first.
|
||||||
|
|
||||||
|
:returns: >= 0: number of datagrams sent. Zero only if `count` was zero.
|
||||||
|
< 0: negative error code. Only if sending the first datagram fails,
|
||||||
|
otherwise returns a positive send count. ``UV_EAGAIN`` when datagrams
|
||||||
|
cannot be sent right now; fall back to :c:func:`uv_udp_send`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.50.0
|
||||||
|
|
||||||
.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
|
.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
|
||||||
|
|
||||||
Prepare for receiving data. If the socket has not previously been bound
|
Prepare for receiving data. If the socket has not previously been bound
|
||||||
|
|||||||
201
include/uv.h
201
include/uv.h
@ -31,6 +31,7 @@ extern "C" {
|
|||||||
#error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both."
|
#error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef UV_EXTERN
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* Windows - set up dll import/export decorators. */
|
/* Windows - set up dll import/export decorators. */
|
||||||
# if defined(BUILDING_UV_SHARED)
|
# if defined(BUILDING_UV_SHARED)
|
||||||
@ -50,17 +51,20 @@ extern "C" {
|
|||||||
#else
|
#else
|
||||||
# define UV_EXTERN /* nothing */
|
# define UV_EXTERN /* nothing */
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* UV_EXTERN */
|
||||||
|
|
||||||
#include "uv/errno.h"
|
#include "uv/errno.h"
|
||||||
#include "uv/version.h"
|
#include "uv/version.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
/* Internal type, do not use. */
|
||||||
# include "uv/stdint-msvc2008.h"
|
struct uv__queue {
|
||||||
#else
|
struct uv__queue* next;
|
||||||
# include <stdint.h>
|
struct uv__queue* prev;
|
||||||
#endif
|
};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include "uv/win.h"
|
# include "uv/win.h"
|
||||||
@ -152,6 +156,9 @@ extern "C" {
|
|||||||
XX(EFTYPE, "inappropriate file type or format") \
|
XX(EFTYPE, "inappropriate file type or format") \
|
||||||
XX(EILSEQ, "illegal byte sequence") \
|
XX(EILSEQ, "illegal byte sequence") \
|
||||||
XX(ESOCKTNOSUPPORT, "socket type not supported") \
|
XX(ESOCKTNOSUPPORT, "socket type not supported") \
|
||||||
|
XX(ENODATA, "no data available") \
|
||||||
|
XX(EUNATCH, "protocol driver not attached") \
|
||||||
|
XX(ENOEXEC, "exec format error") \
|
||||||
|
|
||||||
#define UV_HANDLE_TYPE_MAP(XX) \
|
#define UV_HANDLE_TYPE_MAP(XX) \
|
||||||
XX(ASYNC, async) \
|
XX(ASYNC, async) \
|
||||||
@ -247,12 +254,17 @@ typedef struct uv_cpu_info_s uv_cpu_info_t;
|
|||||||
typedef struct uv_interface_address_s uv_interface_address_t;
|
typedef struct uv_interface_address_s uv_interface_address_t;
|
||||||
typedef struct uv_dirent_s uv_dirent_t;
|
typedef struct uv_dirent_s uv_dirent_t;
|
||||||
typedef struct uv_passwd_s uv_passwd_t;
|
typedef struct uv_passwd_s uv_passwd_t;
|
||||||
|
typedef struct uv_group_s uv_group_t;
|
||||||
typedef struct uv_utsname_s uv_utsname_t;
|
typedef struct uv_utsname_s uv_utsname_t;
|
||||||
typedef struct uv_statfs_s uv_statfs_t;
|
typedef struct uv_statfs_s uv_statfs_t;
|
||||||
|
|
||||||
|
typedef struct uv_metrics_s uv_metrics_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UV_LOOP_BLOCK_SIGNAL = 0,
|
UV_LOOP_BLOCK_SIGNAL = 0,
|
||||||
UV_METRICS_IDLE_TIME
|
UV_METRICS_IDLE_TIME,
|
||||||
|
UV_LOOP_USE_IO_URING_SQPOLL
|
||||||
|
#define UV_LOOP_USE_IO_URING_SQPOLL UV_LOOP_USE_IO_URING_SQPOLL
|
||||||
} uv_loop_option;
|
} uv_loop_option;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -282,13 +294,13 @@ UV_EXTERN int uv_loop_init(uv_loop_t* loop);
|
|||||||
UV_EXTERN int uv_loop_close(uv_loop_t* loop);
|
UV_EXTERN int uv_loop_close(uv_loop_t* loop);
|
||||||
/*
|
/*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* This function is DEPRECATED (to be removed after 0.12), users should
|
* This function is DEPRECATED, users should
|
||||||
* allocate the loop manually and use uv_loop_init instead.
|
* allocate the loop manually and use uv_loop_init instead.
|
||||||
*/
|
*/
|
||||||
UV_EXTERN uv_loop_t* uv_loop_new(void);
|
UV_EXTERN uv_loop_t* uv_loop_new(void);
|
||||||
/*
|
/*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* This function is DEPRECATED (to be removed after 0.12). Users should use
|
* This function is DEPRECATED. Users should use
|
||||||
* uv_loop_close and free the memory manually instead.
|
* uv_loop_close and free the memory manually instead.
|
||||||
*/
|
*/
|
||||||
UV_EXTERN void uv_loop_delete(uv_loop_t*);
|
UV_EXTERN void uv_loop_delete(uv_loop_t*);
|
||||||
@ -344,11 +356,32 @@ typedef void (*uv_random_cb)(uv_random_t* req,
|
|||||||
void* buf,
|
void* buf,
|
||||||
size_t buflen);
|
size_t buflen);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_CLOCK_MONOTONIC,
|
||||||
|
UV_CLOCK_REALTIME
|
||||||
|
} uv_clock_id;
|
||||||
|
|
||||||
|
/* XXX(bnoordhuis) not 2038-proof, https://github.com/libuv/libuv/issues/3864 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
long tv_sec;
|
long tv_sec;
|
||||||
long tv_nsec;
|
long tv_nsec;
|
||||||
} uv_timespec_t;
|
} uv_timespec_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t tv_sec;
|
||||||
|
int32_t tv_nsec;
|
||||||
|
} uv_timespec64_t;
|
||||||
|
|
||||||
|
/* XXX(bnoordhuis) not 2038-proof, https://github.com/libuv/libuv/issues/3864 */
|
||||||
|
typedef struct {
|
||||||
|
long tv_sec;
|
||||||
|
long tv_usec;
|
||||||
|
} uv_timeval_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t tv_sec;
|
||||||
|
int32_t tv_usec;
|
||||||
|
} uv_timeval64_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t st_dev;
|
uint64_t st_dev;
|
||||||
@ -437,7 +470,7 @@ struct uv_shutdown_s {
|
|||||||
uv_handle_type type; \
|
uv_handle_type type; \
|
||||||
/* private */ \
|
/* private */ \
|
||||||
uv_close_cb close_cb; \
|
uv_close_cb close_cb; \
|
||||||
void* handle_queue[2]; \
|
struct uv__queue handle_queue; \
|
||||||
union { \
|
union { \
|
||||||
int fd; \
|
int fd; \
|
||||||
void* reserved[4]; \
|
void* reserved[4]; \
|
||||||
@ -575,7 +608,18 @@ UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
|
|||||||
|
|
||||||
enum uv_tcp_flags {
|
enum uv_tcp_flags {
|
||||||
/* Used with uv_tcp_bind, when an IPv6 address is used. */
|
/* Used with uv_tcp_bind, when an IPv6 address is used. */
|
||||||
UV_TCP_IPV6ONLY = 1
|
UV_TCP_IPV6ONLY = 1,
|
||||||
|
|
||||||
|
/* Enable SO_REUSEPORT socket option when binding the handle.
|
||||||
|
* This allows completely duplicate bindings by multiple processes
|
||||||
|
* or threads if they all set SO_REUSEPORT before binding the port.
|
||||||
|
* Incoming connections are distributed across the participating
|
||||||
|
* listener sockets.
|
||||||
|
*
|
||||||
|
* This flag is available only on Linux 3.9+, DragonFlyBSD 3.6+,
|
||||||
|
* FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ for now.
|
||||||
|
*/
|
||||||
|
UV_TCP_REUSEPORT = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle,
|
UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle,
|
||||||
@ -616,10 +660,13 @@ enum uv_udp_flags {
|
|||||||
UV_UDP_PARTIAL = 2,
|
UV_UDP_PARTIAL = 2,
|
||||||
/*
|
/*
|
||||||
* Indicates if SO_REUSEADDR will be set when binding the handle.
|
* Indicates if SO_REUSEADDR will be set when binding the handle.
|
||||||
* This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
|
* This sets the SO_REUSEPORT socket flag on the BSDs (except for
|
||||||
* Unix platforms, it sets the SO_REUSEADDR flag. What that means is that
|
* DragonFlyBSD), OS X, and other platforms where SO_REUSEPORTs don't
|
||||||
* multiple threads or processes can bind to the same address without error
|
* have the capability of load balancing, as the opposite of what
|
||||||
* (provided they all set the flag) but only the last one to bind will receive
|
* UV_UDP_REUSEPORT would do. On other Unix platforms, it sets the
|
||||||
|
* SO_REUSEADDR flag. What that means is that multiple threads or
|
||||||
|
* processes can bind to the same address without error (provided
|
||||||
|
* they all set the flag) but only the last one to bind will receive
|
||||||
* any traffic, in effect "stealing" the port from the previous listener.
|
* any traffic, in effect "stealing" the port from the previous listener.
|
||||||
*/
|
*/
|
||||||
UV_UDP_REUSEADDR = 4,
|
UV_UDP_REUSEADDR = 4,
|
||||||
@ -642,6 +689,18 @@ enum uv_udp_flags {
|
|||||||
* This flag is no-op on platforms other than Linux.
|
* This flag is no-op on platforms other than Linux.
|
||||||
*/
|
*/
|
||||||
UV_UDP_LINUX_RECVERR = 32,
|
UV_UDP_LINUX_RECVERR = 32,
|
||||||
|
/*
|
||||||
|
* Indicates if SO_REUSEPORT will be set when binding the handle.
|
||||||
|
* This sets the SO_REUSEPORT socket option on supported platforms.
|
||||||
|
* Unlike UV_UDP_REUSEADDR, this flag will make multiple threads or
|
||||||
|
* processes that are binding to the same address and port "share"
|
||||||
|
* the port, which means incoming datagrams are distributed across
|
||||||
|
* the receiving sockets among threads or processes.
|
||||||
|
*
|
||||||
|
* This flag is available only on Linux 3.9+, DragonFlyBSD 3.6+,
|
||||||
|
* FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ for now.
|
||||||
|
*/
|
||||||
|
UV_UDP_REUSEPORT = 64,
|
||||||
/*
|
/*
|
||||||
* Indicates that recvmmsg should be used, if available.
|
* Indicates that recvmmsg should be used, if available.
|
||||||
*/
|
*/
|
||||||
@ -718,6 +777,12 @@ UV_EXTERN int uv_udp_try_send(uv_udp_t* handle,
|
|||||||
const uv_buf_t bufs[],
|
const uv_buf_t bufs[],
|
||||||
unsigned int nbufs,
|
unsigned int nbufs,
|
||||||
const struct sockaddr* addr);
|
const struct sockaddr* addr);
|
||||||
|
UV_EXTERN int uv_udp_try_send2(uv_udp_t* handle,
|
||||||
|
unsigned int count,
|
||||||
|
uv_buf_t* bufs[/*count*/],
|
||||||
|
unsigned int nbufs[/*count*/],
|
||||||
|
struct sockaddr* addrs[/*count*/],
|
||||||
|
unsigned int flags);
|
||||||
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
|
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
|
||||||
uv_alloc_cb alloc_cb,
|
uv_alloc_cb alloc_cb,
|
||||||
uv_udp_recv_cb recv_cb);
|
uv_udp_recv_cb recv_cb);
|
||||||
@ -741,10 +806,15 @@ struct uv_tty_s {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
/* Initial/normal terminal mode */
|
/* Initial/normal terminal mode */
|
||||||
UV_TTY_MODE_NORMAL,
|
UV_TTY_MODE_NORMAL,
|
||||||
/* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
|
/*
|
||||||
|
* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled).
|
||||||
|
* May become equivalent to UV_TTY_MODE_RAW_VT in future libuv versions.
|
||||||
|
*/
|
||||||
UV_TTY_MODE_RAW,
|
UV_TTY_MODE_RAW,
|
||||||
/* Binary-safe I/O mode for IPC (Unix-only) */
|
/* Binary-safe I/O mode for IPC (Unix-only) */
|
||||||
UV_TTY_MODE_IO
|
UV_TTY_MODE_IO,
|
||||||
|
/* Raw input mode. On Windows ENABLE_VIRTUAL_TERMINAL_INPUT is also set. */
|
||||||
|
UV_TTY_MODE_RAW_VT
|
||||||
} uv_tty_mode_t;
|
} uv_tty_mode_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -779,6 +849,10 @@ inline int uv_tty_set_mode(uv_tty_t* handle, int mode) {
|
|||||||
|
|
||||||
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
|
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UV_PIPE_NO_TRUNCATE = 1u << 0
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uv_pipe_t is a subclass of uv_stream_t.
|
* uv_pipe_t is a subclass of uv_stream_t.
|
||||||
*
|
*
|
||||||
@ -795,10 +869,20 @@ struct uv_pipe_s {
|
|||||||
UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
|
UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
|
||||||
UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file);
|
UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file);
|
||||||
UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
|
UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
|
||||||
|
UV_EXTERN int uv_pipe_bind2(uv_pipe_t* handle,
|
||||||
|
const char* name,
|
||||||
|
size_t namelen,
|
||||||
|
unsigned int flags);
|
||||||
UV_EXTERN void uv_pipe_connect(uv_connect_t* req,
|
UV_EXTERN void uv_pipe_connect(uv_connect_t* req,
|
||||||
uv_pipe_t* handle,
|
uv_pipe_t* handle,
|
||||||
const char* name,
|
const char* name,
|
||||||
uv_connect_cb cb);
|
uv_connect_cb cb);
|
||||||
|
UV_EXTERN int uv_pipe_connect2(uv_connect_t* req,
|
||||||
|
uv_pipe_t* handle,
|
||||||
|
const char* name,
|
||||||
|
size_t namelen,
|
||||||
|
unsigned int flags,
|
||||||
|
uv_connect_cb cb);
|
||||||
UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle,
|
UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle,
|
||||||
char* buffer,
|
char* buffer,
|
||||||
size_t* size);
|
size_t* size);
|
||||||
@ -1063,7 +1147,14 @@ enum uv_process_flags {
|
|||||||
* option is only meaningful on Windows systems. On Unix it is silently
|
* option is only meaningful on Windows systems. On Unix it is silently
|
||||||
* ignored.
|
* ignored.
|
||||||
*/
|
*/
|
||||||
UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6)
|
UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6),
|
||||||
|
/*
|
||||||
|
* On Windows, if the path to the program to execute, specified in
|
||||||
|
* uv_process_options_t's file field, has a directory component,
|
||||||
|
* search for the exact file name before trying variants with
|
||||||
|
* extensions like '.exe' or '.cmd'.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7)
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1133,12 +1224,18 @@ struct uv_interface_address_s {
|
|||||||
|
|
||||||
struct uv_passwd_s {
|
struct uv_passwd_s {
|
||||||
char* username;
|
char* username;
|
||||||
long uid;
|
unsigned long uid;
|
||||||
long gid;
|
unsigned long gid;
|
||||||
char* shell;
|
char* shell;
|
||||||
char* homedir;
|
char* homedir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct uv_group_s {
|
||||||
|
char* groupname;
|
||||||
|
unsigned long gid;
|
||||||
|
char** members;
|
||||||
|
};
|
||||||
|
|
||||||
struct uv_utsname_s {
|
struct uv_utsname_s {
|
||||||
char sysname[256];
|
char sysname[256];
|
||||||
char release[256];
|
char release[256];
|
||||||
@ -1184,16 +1281,6 @@ UV_EXTERN int uv_uptime(double* uptime);
|
|||||||
UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd);
|
UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd);
|
||||||
UV_EXTERN int uv_open_osfhandle(uv_os_fd_t os_fd);
|
UV_EXTERN int uv_open_osfhandle(uv_os_fd_t os_fd);
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
long tv_sec;
|
|
||||||
long tv_usec;
|
|
||||||
} uv_timeval_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int64_t tv_sec;
|
|
||||||
int32_t tv_usec;
|
|
||||||
} uv_timeval64_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uv_timeval_t ru_utime; /* user CPU time used */
|
uv_timeval_t ru_utime; /* user CPU time used */
|
||||||
uv_timeval_t ru_stime; /* system CPU time used */
|
uv_timeval_t ru_stime; /* system CPU time used */
|
||||||
@ -1214,11 +1301,15 @@ typedef struct {
|
|||||||
} uv_rusage_t;
|
} uv_rusage_t;
|
||||||
|
|
||||||
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
|
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
|
||||||
|
UV_EXTERN int uv_getrusage_thread(uv_rusage_t* rusage);
|
||||||
|
|
||||||
UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
|
UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
|
||||||
UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size);
|
UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size);
|
||||||
UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd);
|
UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd);
|
||||||
UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
|
UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
|
||||||
|
UV_EXTERN int uv_os_get_passwd2(uv_passwd_t* pwd, uv_uid_t uid);
|
||||||
|
UV_EXTERN int uv_os_get_group(uv_group_t* grp, uv_uid_t gid);
|
||||||
|
UV_EXTERN void uv_os_free_group(uv_group_t* grp);
|
||||||
UV_EXTERN uv_pid_t uv_os_getpid(void);
|
UV_EXTERN uv_pid_t uv_os_getpid(void);
|
||||||
UV_EXTERN uv_pid_t uv_os_getppid(void);
|
UV_EXTERN uv_pid_t uv_os_getppid(void);
|
||||||
|
|
||||||
@ -1242,8 +1333,21 @@ UV_EXTERN uv_pid_t uv_os_getppid(void);
|
|||||||
UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority);
|
UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority);
|
||||||
UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority);
|
UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UV_THREAD_PRIORITY_HIGHEST = 2,
|
||||||
|
UV_THREAD_PRIORITY_ABOVE_NORMAL = 1,
|
||||||
|
UV_THREAD_PRIORITY_NORMAL = 0,
|
||||||
|
UV_THREAD_PRIORITY_BELOW_NORMAL = -1,
|
||||||
|
UV_THREAD_PRIORITY_LOWEST = -2,
|
||||||
|
};
|
||||||
|
|
||||||
|
UV_EXTERN int uv_thread_getpriority(uv_thread_t tid, int* priority);
|
||||||
|
UV_EXTERN int uv_thread_setpriority(uv_thread_t tid, int priority);
|
||||||
|
|
||||||
|
UV_EXTERN unsigned int uv_available_parallelism(void);
|
||||||
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
|
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
|
||||||
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
|
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
|
||||||
|
UV_EXTERN int uv_cpumask_size(void);
|
||||||
|
|
||||||
UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
|
UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||||
int* count);
|
int* count);
|
||||||
@ -1276,6 +1380,15 @@ UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);
|
|||||||
|
|
||||||
UV_EXTERN int uv_os_uname(uv_utsname_t* buffer);
|
UV_EXTERN int uv_os_uname(uv_utsname_t* buffer);
|
||||||
|
|
||||||
|
struct uv_metrics_s {
|
||||||
|
uint64_t loop_count;
|
||||||
|
uint64_t events;
|
||||||
|
uint64_t events_waiting;
|
||||||
|
/* private */
|
||||||
|
uint64_t* reserved[13];
|
||||||
|
};
|
||||||
|
|
||||||
|
UV_EXTERN int uv_metrics_info(uv_loop_t* loop, uv_metrics_t* metrics);
|
||||||
UV_EXTERN uint64_t uv_metrics_idle_time(uv_loop_t* loop);
|
UV_EXTERN uint64_t uv_metrics_idle_time(uv_loop_t* loop);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -1478,6 +1591,8 @@ UV_EXTERN int uv_fs_chmod(uv_loop_t* loop,
|
|||||||
const char* path,
|
const char* path,
|
||||||
int mode,
|
int mode,
|
||||||
uv_fs_cb cb);
|
uv_fs_cb cb);
|
||||||
|
#define UV_FS_UTIME_NOW (INFINITY)
|
||||||
|
#define UV_FS_UTIME_OMIT (NAN)
|
||||||
UV_EXTERN int uv_fs_utime(uv_loop_t* loop,
|
UV_EXTERN int uv_fs_utime(uv_loop_t* loop,
|
||||||
uv_fs_t* req,
|
uv_fs_t* req,
|
||||||
const char* path,
|
const char* path,
|
||||||
@ -1709,7 +1824,9 @@ UV_EXTERN int uv_chdir(const char* dir);
|
|||||||
UV_EXTERN uint64_t uv_get_free_memory(void);
|
UV_EXTERN uint64_t uv_get_free_memory(void);
|
||||||
UV_EXTERN uint64_t uv_get_total_memory(void);
|
UV_EXTERN uint64_t uv_get_total_memory(void);
|
||||||
UV_EXTERN uint64_t uv_get_constrained_memory(void);
|
UV_EXTERN uint64_t uv_get_constrained_memory(void);
|
||||||
|
UV_EXTERN uint64_t uv_get_available_memory(void);
|
||||||
|
|
||||||
|
UV_EXTERN int uv_clock_gettime(uv_clock_id clock_id, uv_timespec64_t* ts);
|
||||||
UV_EXTERN uint64_t uv_hrtime(void);
|
UV_EXTERN uint64_t uv_hrtime(void);
|
||||||
UV_EXTERN void uv_sleep(unsigned int msec);
|
UV_EXTERN void uv_sleep(unsigned int msec);
|
||||||
|
|
||||||
@ -1768,6 +1885,7 @@ UV_EXTERN int uv_gettimeofday(uv_timeval64_t* tv);
|
|||||||
typedef void (*uv_thread_cb)(void* arg);
|
typedef void (*uv_thread_cb)(void* arg);
|
||||||
|
|
||||||
UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
|
UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
|
||||||
|
UV_EXTERN int uv_thread_detach(uv_thread_t* tid);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UV_THREAD_NO_FLAGS = 0x00,
|
UV_THREAD_NO_FLAGS = 0x00,
|
||||||
@ -1786,9 +1904,20 @@ UV_EXTERN int uv_thread_create_ex(uv_thread_t* tid,
|
|||||||
const uv_thread_options_t* params,
|
const uv_thread_options_t* params,
|
||||||
uv_thread_cb entry,
|
uv_thread_cb entry,
|
||||||
void* arg);
|
void* arg);
|
||||||
|
UV_EXTERN int uv_thread_setaffinity(uv_thread_t* tid,
|
||||||
|
char* cpumask,
|
||||||
|
char* oldmask,
|
||||||
|
size_t mask_size);
|
||||||
|
UV_EXTERN int uv_thread_getaffinity(uv_thread_t* tid,
|
||||||
|
char* cpumask,
|
||||||
|
size_t mask_size);
|
||||||
|
UV_EXTERN int uv_thread_getcpu(void);
|
||||||
UV_EXTERN uv_thread_t uv_thread_self(void);
|
UV_EXTERN uv_thread_t uv_thread_self(void);
|
||||||
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
|
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
|
||||||
UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2);
|
UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2);
|
||||||
|
UV_EXTERN int uv_thread_setname(const char* name);
|
||||||
|
UV_EXTERN int uv_thread_getname(uv_thread_t* tid, char* name, size_t size);
|
||||||
|
|
||||||
|
|
||||||
/* The presence of these unions force similar struct layout. */
|
/* The presence of these unions force similar struct layout. */
|
||||||
#define XX(_, name) uv_ ## name ## _t name;
|
#define XX(_, name) uv_ ## name ## _t name;
|
||||||
@ -1807,7 +1936,7 @@ struct uv_loop_s {
|
|||||||
void* data;
|
void* data;
|
||||||
/* Loop reference counting. */
|
/* Loop reference counting. */
|
||||||
unsigned int active_handles;
|
unsigned int active_handles;
|
||||||
void* handle_queue[2];
|
struct uv__queue handle_queue;
|
||||||
union {
|
union {
|
||||||
void* unused;
|
void* unused;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
@ -1822,6 +1951,18 @@ struct uv_loop_s {
|
|||||||
UV_EXTERN void* uv_loop_get_data(const uv_loop_t*);
|
UV_EXTERN void* uv_loop_get_data(const uv_loop_t*);
|
||||||
UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data);
|
UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data);
|
||||||
|
|
||||||
|
/* Unicode utilities needed for dealing with Windows. */
|
||||||
|
UV_EXTERN size_t uv_utf16_length_as_wtf8(const uint16_t* utf16,
|
||||||
|
ssize_t utf16_len);
|
||||||
|
UV_EXTERN int uv_utf16_to_wtf8(const uint16_t* utf16,
|
||||||
|
ssize_t utf16_len,
|
||||||
|
char** wtf8_ptr,
|
||||||
|
size_t* wtf8_len_ptr);
|
||||||
|
UV_EXTERN ssize_t uv_wtf8_length_as_utf16(const char* wtf8);
|
||||||
|
UV_EXTERN void uv_wtf8_to_utf16(const char* wtf8,
|
||||||
|
uint16_t* utf16,
|
||||||
|
size_t utf16_len);
|
||||||
|
|
||||||
/* Don't export the private CPP symbols. */
|
/* Don't export the private CPP symbols. */
|
||||||
#undef UV_HANDLE_TYPE_PRIVATE
|
#undef UV_HANDLE_TYPE_PRIVATE
|
||||||
#undef UV_REQ_TYPE_PRIVATE
|
#undef UV_REQ_TYPE_PRIVATE
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995, 1999
|
|
||||||
* Berkeley Software Design, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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.
|
|
||||||
*
|
|
||||||
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _IFADDRS_H_
|
|
||||||
#define _IFADDRS_H_
|
|
||||||
|
|
||||||
struct ifaddrs {
|
|
||||||
struct ifaddrs *ifa_next;
|
|
||||||
char *ifa_name;
|
|
||||||
unsigned int ifa_flags;
|
|
||||||
struct sockaddr *ifa_addr;
|
|
||||||
struct sockaddr *ifa_netmask;
|
|
||||||
struct sockaddr *ifa_dstaddr;
|
|
||||||
void *ifa_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
|
|
||||||
* to be included it must be included before this header file.
|
|
||||||
*/
|
|
||||||
#ifndef ifa_broadaddr
|
|
||||||
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
extern int getifaddrs(struct ifaddrs **ifap);
|
|
||||||
extern void freeifaddrs(struct ifaddrs *ifa);
|
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -40,7 +40,7 @@
|
|||||||
void* cf_state; \
|
void* cf_state; \
|
||||||
uv_mutex_t cf_mutex; \
|
uv_mutex_t cf_mutex; \
|
||||||
uv_sem_t cf_sem; \
|
uv_sem_t cf_sem; \
|
||||||
void* cf_signals[2]; \
|
struct uv__queue cf_signals; \
|
||||||
|
|
||||||
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
||||||
uv__io_t event_watcher; \
|
uv__io_t event_watcher; \
|
||||||
@ -48,8 +48,8 @@
|
|||||||
int realpath_len; \
|
int realpath_len; \
|
||||||
int cf_flags; \
|
int cf_flags; \
|
||||||
uv_async_t* cf_cb; \
|
uv_async_t* cf_cb; \
|
||||||
void* cf_events[2]; \
|
struct uv__queue cf_events; \
|
||||||
void* cf_member[2]; \
|
struct uv__queue cf_member; \
|
||||||
int cf_error; \
|
int cf_error; \
|
||||||
uv_mutex_t cf_mutex; \
|
uv_mutex_t cf_mutex; \
|
||||||
|
|
||||||
|
|||||||
@ -413,7 +413,6 @@
|
|||||||
#elif defined(__APPLE__) || \
|
#elif defined(__APPLE__) || \
|
||||||
defined(__DragonFly__) || \
|
defined(__DragonFly__) || \
|
||||||
defined(__FreeBSD__) || \
|
defined(__FreeBSD__) || \
|
||||||
defined(__FreeBSD_kernel__) || \
|
|
||||||
defined(__NetBSD__) || \
|
defined(__NetBSD__) || \
|
||||||
defined(__OpenBSD__)
|
defined(__OpenBSD__)
|
||||||
# define UV__EHOSTDOWN (-64)
|
# define UV__EHOSTDOWN (-64)
|
||||||
@ -457,4 +456,28 @@
|
|||||||
# define UV__ESOCKTNOSUPPORT (-4025)
|
# define UV__ESOCKTNOSUPPORT (-4025)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* FreeBSD defines ENODATA in /usr/include/c++/v1/errno.h which is only visible
|
||||||
|
* if C++ is being used. Define it directly to avoid problems when integrating
|
||||||
|
* libuv in a C++ project.
|
||||||
|
*/
|
||||||
|
#if defined(ENODATA) && !defined(_WIN32)
|
||||||
|
# define UV__ENODATA UV__ERR(ENODATA)
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
# define UV__ENODATA (-9919)
|
||||||
|
#else
|
||||||
|
# define UV__ENODATA (-4024)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(EUNATCH) && !defined(_WIN32)
|
||||||
|
# define UV__EUNATCH UV__ERR(EUNATCH)
|
||||||
|
#else
|
||||||
|
# define UV__EUNATCH (-4023)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENOEXEC) && !defined(_WIN32)
|
||||||
|
# define UV__ENOEXEC UV__ERR(ENOEXEC)
|
||||||
|
#else
|
||||||
|
# define UV__ENOEXEC (-4022)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* UV_ERRNO_H_ */
|
#endif /* UV_ERRNO_H_ */
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
int inotify_fd; \
|
int inotify_fd; \
|
||||||
|
|
||||||
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
||||||
void* watchers[2]; \
|
struct uv__queue watchers; \
|
||||||
int wd; \
|
int wd; \
|
||||||
|
|
||||||
#endif /* UV_LINUX_H */
|
#endif /* UV_LINUX_H */
|
||||||
|
|||||||
@ -1,247 +0,0 @@
|
|||||||
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
|
||||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
|
||||||
//
|
|
||||||
// Copyright (c) 2006-2008 Alexander Chemeris
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. 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.
|
|
||||||
//
|
|
||||||
// 3. The name of the author may be used to endorse or promote products
|
|
||||||
// derived from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [
|
|
||||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
|
||||||
#endif // _MSC_VER ]
|
|
||||||
|
|
||||||
#ifndef _MSC_STDINT_H_ // [
|
|
||||||
#define _MSC_STDINT_H_
|
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
|
||||||
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
|
||||||
// or compiler give many errors like this:
|
|
||||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
# include <wchar.h>
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Define _W64 macros to mark types changing their size, like intptr_t.
|
|
||||||
#ifndef _W64
|
|
||||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
|
||||||
# define _W64 __w64
|
|
||||||
# else
|
|
||||||
# define _W64
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.1 Integer types
|
|
||||||
|
|
||||||
// 7.18.1.1 Exact-width integer types
|
|
||||||
|
|
||||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
|
||||||
// realize that, e.g. char has the same size as __int8
|
|
||||||
// so we give up on __intX for them.
|
|
||||||
#if (_MSC_VER < 1300)
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef signed int int32_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#else
|
|
||||||
typedef signed __int8 int8_t;
|
|
||||||
typedef signed __int16 int16_t;
|
|
||||||
typedef signed __int32 int32_t;
|
|
||||||
typedef unsigned __int8 uint8_t;
|
|
||||||
typedef unsigned __int16 uint16_t;
|
|
||||||
typedef unsigned __int32 uint32_t;
|
|
||||||
#endif
|
|
||||||
typedef signed __int64 int64_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.1.2 Minimum-width integer types
|
|
||||||
typedef int8_t int_least8_t;
|
|
||||||
typedef int16_t int_least16_t;
|
|
||||||
typedef int32_t int_least32_t;
|
|
||||||
typedef int64_t int_least64_t;
|
|
||||||
typedef uint8_t uint_least8_t;
|
|
||||||
typedef uint16_t uint_least16_t;
|
|
||||||
typedef uint32_t uint_least32_t;
|
|
||||||
typedef uint64_t uint_least64_t;
|
|
||||||
|
|
||||||
// 7.18.1.3 Fastest minimum-width integer types
|
|
||||||
typedef int8_t int_fast8_t;
|
|
||||||
typedef int16_t int_fast16_t;
|
|
||||||
typedef int32_t int_fast32_t;
|
|
||||||
typedef int64_t int_fast64_t;
|
|
||||||
typedef uint8_t uint_fast8_t;
|
|
||||||
typedef uint16_t uint_fast16_t;
|
|
||||||
typedef uint32_t uint_fast32_t;
|
|
||||||
typedef uint64_t uint_fast64_t;
|
|
||||||
|
|
||||||
// 7.18.1.4 Integer types capable of holding object pointers
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
typedef signed __int64 intptr_t;
|
|
||||||
typedef unsigned __int64 uintptr_t;
|
|
||||||
#else // _WIN64 ][
|
|
||||||
typedef _W64 signed int intptr_t;
|
|
||||||
typedef _W64 unsigned int uintptr_t;
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
// 7.18.1.5 Greatest-width integer types
|
|
||||||
typedef int64_t intmax_t;
|
|
||||||
typedef uint64_t uintmax_t;
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.2 Limits of specified-width integer types
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
|
||||||
|
|
||||||
// 7.18.2.1 Limits of exact-width integer types
|
|
||||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
|
||||||
#define INT8_MAX _I8_MAX
|
|
||||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
|
||||||
#define INT16_MAX _I16_MAX
|
|
||||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
|
||||||
#define INT32_MAX _I32_MAX
|
|
||||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
|
||||||
#define INT64_MAX _I64_MAX
|
|
||||||
#define UINT8_MAX _UI8_MAX
|
|
||||||
#define UINT16_MAX _UI16_MAX
|
|
||||||
#define UINT32_MAX _UI32_MAX
|
|
||||||
#define UINT64_MAX _UI64_MAX
|
|
||||||
|
|
||||||
// 7.18.2.2 Limits of minimum-width integer types
|
|
||||||
#define INT_LEAST8_MIN INT8_MIN
|
|
||||||
#define INT_LEAST8_MAX INT8_MAX
|
|
||||||
#define INT_LEAST16_MIN INT16_MIN
|
|
||||||
#define INT_LEAST16_MAX INT16_MAX
|
|
||||||
#define INT_LEAST32_MIN INT32_MIN
|
|
||||||
#define INT_LEAST32_MAX INT32_MAX
|
|
||||||
#define INT_LEAST64_MIN INT64_MIN
|
|
||||||
#define INT_LEAST64_MAX INT64_MAX
|
|
||||||
#define UINT_LEAST8_MAX UINT8_MAX
|
|
||||||
#define UINT_LEAST16_MAX UINT16_MAX
|
|
||||||
#define UINT_LEAST32_MAX UINT32_MAX
|
|
||||||
#define UINT_LEAST64_MAX UINT64_MAX
|
|
||||||
|
|
||||||
// 7.18.2.3 Limits of fastest minimum-width integer types
|
|
||||||
#define INT_FAST8_MIN INT8_MIN
|
|
||||||
#define INT_FAST8_MAX INT8_MAX
|
|
||||||
#define INT_FAST16_MIN INT16_MIN
|
|
||||||
#define INT_FAST16_MAX INT16_MAX
|
|
||||||
#define INT_FAST32_MIN INT32_MIN
|
|
||||||
#define INT_FAST32_MAX INT32_MAX
|
|
||||||
#define INT_FAST64_MIN INT64_MIN
|
|
||||||
#define INT_FAST64_MAX INT64_MAX
|
|
||||||
#define UINT_FAST8_MAX UINT8_MAX
|
|
||||||
#define UINT_FAST16_MAX UINT16_MAX
|
|
||||||
#define UINT_FAST32_MAX UINT32_MAX
|
|
||||||
#define UINT_FAST64_MAX UINT64_MAX
|
|
||||||
|
|
||||||
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
# define INTPTR_MIN INT64_MIN
|
|
||||||
# define INTPTR_MAX INT64_MAX
|
|
||||||
# define UINTPTR_MAX UINT64_MAX
|
|
||||||
#else // _WIN64 ][
|
|
||||||
# define INTPTR_MIN INT32_MIN
|
|
||||||
# define INTPTR_MAX INT32_MAX
|
|
||||||
# define UINTPTR_MAX UINT32_MAX
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
// 7.18.2.5 Limits of greatest-width integer types
|
|
||||||
#define INTMAX_MIN INT64_MIN
|
|
||||||
#define INTMAX_MAX INT64_MAX
|
|
||||||
#define UINTMAX_MAX UINT64_MAX
|
|
||||||
|
|
||||||
// 7.18.3 Limits of other integer types
|
|
||||||
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
# define PTRDIFF_MIN _I64_MIN
|
|
||||||
# define PTRDIFF_MAX _I64_MAX
|
|
||||||
#else // _WIN64 ][
|
|
||||||
# define PTRDIFF_MIN _I32_MIN
|
|
||||||
# define PTRDIFF_MAX _I32_MAX
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
#define SIG_ATOMIC_MIN INT_MIN
|
|
||||||
#define SIG_ATOMIC_MAX INT_MAX
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX // [
|
|
||||||
# ifdef _WIN64 // [
|
|
||||||
# define SIZE_MAX _UI64_MAX
|
|
||||||
# else // _WIN64 ][
|
|
||||||
# define SIZE_MAX _UI32_MAX
|
|
||||||
# endif // _WIN64 ]
|
|
||||||
#endif // SIZE_MAX ]
|
|
||||||
|
|
||||||
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
|
||||||
#ifndef WCHAR_MIN // [
|
|
||||||
# define WCHAR_MIN 0
|
|
||||||
#endif // WCHAR_MIN ]
|
|
||||||
#ifndef WCHAR_MAX // [
|
|
||||||
# define WCHAR_MAX _UI16_MAX
|
|
||||||
#endif // WCHAR_MAX ]
|
|
||||||
|
|
||||||
#define WINT_MIN 0
|
|
||||||
#define WINT_MAX _UI16_MAX
|
|
||||||
|
|
||||||
#endif // __STDC_LIMIT_MACROS ]
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.4 Limits of other integer types
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
|
||||||
|
|
||||||
// 7.18.4.1 Macros for minimum-width integer constants
|
|
||||||
|
|
||||||
#define INT8_C(val) val##i8
|
|
||||||
#define INT16_C(val) val##i16
|
|
||||||
#define INT32_C(val) val##i32
|
|
||||||
#define INT64_C(val) val##i64
|
|
||||||
|
|
||||||
#define UINT8_C(val) val##ui8
|
|
||||||
#define UINT16_C(val) val##ui16
|
|
||||||
#define UINT32_C(val) val##ui32
|
|
||||||
#define UINT64_C(val) val##ui64
|
|
||||||
|
|
||||||
// 7.18.4.2 Macros for greatest-width integer constants
|
|
||||||
#define INTMAX_C INT64_C
|
|
||||||
#define UINTMAX_C UINT64_C
|
|
||||||
|
|
||||||
#endif // __STDC_CONSTANT_MACROS ]
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _MSC_STDINT_H_ ]
|
|
||||||
@ -31,7 +31,7 @@ struct uv__work {
|
|||||||
void (*work)(struct uv__work *w);
|
void (*work)(struct uv__work *w);
|
||||||
void (*done)(struct uv__work *w, int status);
|
void (*done)(struct uv__work *w, int status);
|
||||||
struct uv_loop_s* loop;
|
struct uv_loop_s* loop;
|
||||||
void* wq[2];
|
struct uv__queue wq;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* UV_THREADPOOL_H_ */
|
#endif /* UV_THREADPOOL_H_ */
|
||||||
|
|||||||
@ -35,21 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file defines data structures for different types of trees:
|
* This file defines data structures for red-black trees.
|
||||||
* splay trees and red-black trees.
|
|
||||||
*
|
|
||||||
* A splay tree is a self-organizing data structure. Every operation
|
|
||||||
* on the tree causes a splay to happen. The splay moves the requested
|
|
||||||
* node to the root of the tree and partly rebalances it.
|
|
||||||
*
|
|
||||||
* This has the benefit that request locality causes faster lookups as
|
|
||||||
* the requested nodes move to the top of the tree. On the other hand,
|
|
||||||
* every lookup causes memory writes.
|
|
||||||
*
|
|
||||||
* The Balance Theorem bounds the total access time for m operations
|
|
||||||
* and n inserts on an initially empty tree as O((m + n)lg n). The
|
|
||||||
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
|
|
||||||
*
|
|
||||||
* A red-black tree is a binary search tree with the node color as an
|
* A red-black tree is a binary search tree with the node color as an
|
||||||
* extra attribute. It fulfills a set of conditions:
|
* extra attribute. It fulfills a set of conditions:
|
||||||
* - every search path from the root to a leaf consists of the
|
* - every search path from the root to a leaf consists of the
|
||||||
@ -61,239 +47,6 @@
|
|||||||
* The maximum height of a red-black tree is 2lg (n+1).
|
* The maximum height of a red-black tree is 2lg (n+1).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SPLAY_HEAD(name, type) \
|
|
||||||
struct name { \
|
|
||||||
struct type *sph_root; /* root of the tree */ \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SPLAY_INITIALIZER(root) \
|
|
||||||
{ NULL }
|
|
||||||
|
|
||||||
#define SPLAY_INIT(root) do { \
|
|
||||||
(root)->sph_root = NULL; \
|
|
||||||
} while (/*CONSTCOND*/ 0)
|
|
||||||
|
|
||||||
#define SPLAY_ENTRY(type) \
|
|
||||||
struct { \
|
|
||||||
struct type *spe_left; /* left element */ \
|
|
||||||
struct type *spe_right; /* right element */ \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
|
|
||||||
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
|
|
||||||
#define SPLAY_ROOT(head) (head)->sph_root
|
|
||||||
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
|
|
||||||
|
|
||||||
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
|
|
||||||
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
|
|
||||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
|
|
||||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
|
||||||
(head)->sph_root = tmp; \
|
|
||||||
} while (/*CONSTCOND*/ 0)
|
|
||||||
|
|
||||||
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
|
|
||||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
|
|
||||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
|
||||||
(head)->sph_root = tmp; \
|
|
||||||
} while (/*CONSTCOND*/ 0)
|
|
||||||
|
|
||||||
#define SPLAY_LINKLEFT(head, tmp, field) do { \
|
|
||||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
|
||||||
tmp = (head)->sph_root; \
|
|
||||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
|
||||||
} while (/*CONSTCOND*/ 0)
|
|
||||||
|
|
||||||
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
|
|
||||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
|
||||||
tmp = (head)->sph_root; \
|
|
||||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
|
||||||
} while (/*CONSTCOND*/ 0)
|
|
||||||
|
|
||||||
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
|
|
||||||
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
|
|
||||||
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \
|
|
||||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
|
|
||||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
|
|
||||||
} while (/*CONSTCOND*/ 0)
|
|
||||||
|
|
||||||
/* Generates prototypes and inline functions */
|
|
||||||
|
|
||||||
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
|
|
||||||
void name##_SPLAY(struct name *, struct type *); \
|
|
||||||
void name##_SPLAY_MINMAX(struct name *, int); \
|
|
||||||
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
|
|
||||||
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
|
|
||||||
\
|
|
||||||
/* Finds the node with the same key as elm */ \
|
|
||||||
static __inline struct type * \
|
|
||||||
name##_SPLAY_FIND(struct name *head, struct type *elm) \
|
|
||||||
{ \
|
|
||||||
if (SPLAY_EMPTY(head)) \
|
|
||||||
return(NULL); \
|
|
||||||
name##_SPLAY(head, elm); \
|
|
||||||
if ((cmp)(elm, (head)->sph_root) == 0) \
|
|
||||||
return (head->sph_root); \
|
|
||||||
return (NULL); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static __inline struct type * \
|
|
||||||
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
|
|
||||||
{ \
|
|
||||||
name##_SPLAY(head, elm); \
|
|
||||||
if (SPLAY_RIGHT(elm, field) != NULL) { \
|
|
||||||
elm = SPLAY_RIGHT(elm, field); \
|
|
||||||
while (SPLAY_LEFT(elm, field) != NULL) { \
|
|
||||||
elm = SPLAY_LEFT(elm, field); \
|
|
||||||
} \
|
|
||||||
} else \
|
|
||||||
elm = NULL; \
|
|
||||||
return (elm); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static __inline struct type * \
|
|
||||||
name##_SPLAY_MIN_MAX(struct name *head, int val) \
|
|
||||||
{ \
|
|
||||||
name##_SPLAY_MINMAX(head, val); \
|
|
||||||
return (SPLAY_ROOT(head)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main splay operation.
|
|
||||||
* Moves node close to the key of elm to top
|
|
||||||
*/
|
|
||||||
#define SPLAY_GENERATE(name, type, field, cmp) \
|
|
||||||
struct type * \
|
|
||||||
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
|
|
||||||
{ \
|
|
||||||
if (SPLAY_EMPTY(head)) { \
|
|
||||||
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
|
|
||||||
} else { \
|
|
||||||
int __comp; \
|
|
||||||
name##_SPLAY(head, elm); \
|
|
||||||
__comp = (cmp)(elm, (head)->sph_root); \
|
|
||||||
if(__comp < 0) { \
|
|
||||||
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \
|
|
||||||
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
|
|
||||||
SPLAY_LEFT((head)->sph_root, field) = NULL; \
|
|
||||||
} else if (__comp > 0) { \
|
|
||||||
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \
|
|
||||||
SPLAY_LEFT(elm, field) = (head)->sph_root; \
|
|
||||||
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
|
|
||||||
} else \
|
|
||||||
return ((head)->sph_root); \
|
|
||||||
} \
|
|
||||||
(head)->sph_root = (elm); \
|
|
||||||
return (NULL); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
struct type * \
|
|
||||||
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
|
|
||||||
{ \
|
|
||||||
struct type *__tmp; \
|
|
||||||
if (SPLAY_EMPTY(head)) \
|
|
||||||
return (NULL); \
|
|
||||||
name##_SPLAY(head, elm); \
|
|
||||||
if ((cmp)(elm, (head)->sph_root) == 0) { \
|
|
||||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
|
|
||||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
|
||||||
} else { \
|
|
||||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
|
||||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
|
||||||
name##_SPLAY(head, elm); \
|
|
||||||
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
|
|
||||||
} \
|
|
||||||
return (elm); \
|
|
||||||
} \
|
|
||||||
return (NULL); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
void \
|
|
||||||
name##_SPLAY(struct name *head, struct type *elm) \
|
|
||||||
{ \
|
|
||||||
struct type __node, *__left, *__right, *__tmp; \
|
|
||||||
int __comp; \
|
|
||||||
\
|
|
||||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
|
|
||||||
__left = __right = &__node; \
|
|
||||||
\
|
|
||||||
while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \
|
|
||||||
if (__comp < 0) { \
|
|
||||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
|
||||||
if (__tmp == NULL) \
|
|
||||||
break; \
|
|
||||||
if ((cmp)(elm, __tmp) < 0){ \
|
|
||||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
|
||||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
SPLAY_LINKLEFT(head, __right, field); \
|
|
||||||
} else if (__comp > 0) { \
|
|
||||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
|
||||||
if (__tmp == NULL) \
|
|
||||||
break; \
|
|
||||||
if ((cmp)(elm, __tmp) > 0){ \
|
|
||||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
|
||||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
SPLAY_LINKRIGHT(head, __left, field); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
/* Splay with either the minimum or the maximum element \
|
|
||||||
* Used to find minimum or maximum element in tree. \
|
|
||||||
*/ \
|
|
||||||
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
|
||||||
{ \
|
|
||||||
struct type __node, *__left, *__right, *__tmp; \
|
|
||||||
\
|
|
||||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
|
|
||||||
__left = __right = &__node; \
|
|
||||||
\
|
|
||||||
for (;;) { \
|
|
||||||
if (__comp < 0) { \
|
|
||||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
|
||||||
if (__tmp == NULL) \
|
|
||||||
break; \
|
|
||||||
if (__comp < 0){ \
|
|
||||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
|
||||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
SPLAY_LINKLEFT(head, __right, field); \
|
|
||||||
} else if (__comp > 0) { \
|
|
||||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
|
||||||
if (__tmp == NULL) \
|
|
||||||
break; \
|
|
||||||
if (__comp > 0) { \
|
|
||||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
|
||||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
SPLAY_LINKRIGHT(head, __left, field); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SPLAY_NEGINF -1
|
|
||||||
#define SPLAY_INF 1
|
|
||||||
|
|
||||||
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
|
|
||||||
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
|
|
||||||
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
|
|
||||||
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
|
|
||||||
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
|
|
||||||
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
|
|
||||||
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
|
|
||||||
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
|
|
||||||
|
|
||||||
#define SPLAY_FOREACH(x, name, head) \
|
|
||||||
for ((x) = SPLAY_MIN(name, head); \
|
|
||||||
(x) != NULL; \
|
|
||||||
(x) = SPLAY_NEXT(name, head, x))
|
|
||||||
|
|
||||||
/* Macros that define a red-black tree */
|
/* Macros that define a red-black tree */
|
||||||
#define RB_HEAD(name, type) \
|
#define RB_HEAD(name, type) \
|
||||||
struct name { \
|
struct name { \
|
||||||
@ -730,8 +483,8 @@ name##_RB_MINMAX(struct name *head, int val) \
|
|||||||
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
|
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
|
||||||
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
|
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
|
||||||
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
|
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
|
||||||
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
|
#define RB_NEXT(name, x) name##_RB_NEXT(x)
|
||||||
#define RB_PREV(name, x, y) name##_RB_PREV(y)
|
#define RB_PREV(name, x) name##_RB_PREV(x)
|
||||||
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
|
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
|
||||||
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
|
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,6 @@
|
|||||||
# include "uv/darwin.h"
|
# include "uv/darwin.h"
|
||||||
#elif defined(__DragonFly__) || \
|
#elif defined(__DragonFly__) || \
|
||||||
defined(__FreeBSD__) || \
|
defined(__FreeBSD__) || \
|
||||||
defined(__FreeBSD_kernel__) || \
|
|
||||||
defined(__OpenBSD__) || \
|
defined(__OpenBSD__) || \
|
||||||
defined(__NetBSD__)
|
defined(__NetBSD__)
|
||||||
# include "uv/bsd.h"
|
# include "uv/bsd.h"
|
||||||
@ -93,8 +92,8 @@ typedef struct uv__io_s uv__io_t;
|
|||||||
|
|
||||||
struct uv__io_s {
|
struct uv__io_s {
|
||||||
uv__io_cb cb;
|
uv__io_cb cb;
|
||||||
void* pending_queue[2];
|
struct uv__queue pending_queue;
|
||||||
void* watcher_queue[2];
|
struct uv__queue watcher_queue;
|
||||||
unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
|
unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
|
||||||
unsigned int events; /* Current event mask. */
|
unsigned int events; /* Current event mask. */
|
||||||
int fd;
|
int fd;
|
||||||
@ -221,21 +220,21 @@ typedef struct {
|
|||||||
#define UV_LOOP_PRIVATE_FIELDS \
|
#define UV_LOOP_PRIVATE_FIELDS \
|
||||||
unsigned long flags; \
|
unsigned long flags; \
|
||||||
int backend_fd; \
|
int backend_fd; \
|
||||||
void* pending_queue[2]; \
|
struct uv__queue pending_queue; \
|
||||||
void* watcher_queue[2]; \
|
struct uv__queue watcher_queue; \
|
||||||
uv__io_t** watchers; \
|
uv__io_t** watchers; \
|
||||||
unsigned int nwatchers; \
|
unsigned int nwatchers; \
|
||||||
unsigned int nfds; \
|
unsigned int nfds; \
|
||||||
void* wq[2]; \
|
struct uv__queue wq; \
|
||||||
uv_mutex_t wq_mutex; \
|
uv_mutex_t wq_mutex; \
|
||||||
uv_async_t wq_async; \
|
uv_async_t wq_async; \
|
||||||
uv_rwlock_t cloexec_lock; \
|
uv_rwlock_t cloexec_lock; \
|
||||||
uv_handle_t* closing_handles; \
|
uv_handle_t* closing_handles; \
|
||||||
void* process_handles[2]; \
|
struct uv__queue process_handles; \
|
||||||
void* prepare_handles[2]; \
|
struct uv__queue prepare_handles; \
|
||||||
void* check_handles[2]; \
|
struct uv__queue check_handles; \
|
||||||
void* idle_handles[2]; \
|
struct uv__queue idle_handles; \
|
||||||
void* async_handles[2]; \
|
struct uv__queue async_handles; \
|
||||||
void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \
|
void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \
|
||||||
uv__io_t async_io_watcher; \
|
uv__io_t async_io_watcher; \
|
||||||
int async_wfd; \
|
int async_wfd; \
|
||||||
@ -258,7 +257,7 @@ typedef struct {
|
|||||||
#define UV_PRIVATE_REQ_TYPES /* empty */
|
#define UV_PRIVATE_REQ_TYPES /* empty */
|
||||||
|
|
||||||
#define UV_WRITE_PRIVATE_FIELDS \
|
#define UV_WRITE_PRIVATE_FIELDS \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
unsigned int write_index; \
|
unsigned int write_index; \
|
||||||
uv_buf_t* bufs; \
|
uv_buf_t* bufs; \
|
||||||
unsigned int nbufs; \
|
unsigned int nbufs; \
|
||||||
@ -266,13 +265,16 @@ typedef struct {
|
|||||||
uv_buf_t bufsml[4]; \
|
uv_buf_t bufsml[4]; \
|
||||||
|
|
||||||
#define UV_CONNECT_PRIVATE_FIELDS \
|
#define UV_CONNECT_PRIVATE_FIELDS \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
|
|
||||||
#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
|
#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
|
||||||
|
|
||||||
#define UV_UDP_SEND_PRIVATE_FIELDS \
|
#define UV_UDP_SEND_PRIVATE_FIELDS \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
struct sockaddr_storage addr; \
|
union { \
|
||||||
|
struct sockaddr addr; \
|
||||||
|
struct sockaddr_storage storage; \
|
||||||
|
} u; \
|
||||||
unsigned int nbufs; \
|
unsigned int nbufs; \
|
||||||
uv_buf_t* bufs; \
|
uv_buf_t* bufs; \
|
||||||
ssize_t status; \
|
ssize_t status; \
|
||||||
@ -287,8 +289,8 @@ typedef struct {
|
|||||||
uv_connect_t *connect_req; \
|
uv_connect_t *connect_req; \
|
||||||
uv_shutdown_t *shutdown_req; \
|
uv_shutdown_t *shutdown_req; \
|
||||||
uv__io_t io_watcher; \
|
uv__io_t io_watcher; \
|
||||||
void* write_queue[2]; \
|
struct uv__queue write_queue; \
|
||||||
void* write_completed_queue[2]; \
|
struct uv__queue write_completed_queue; \
|
||||||
uv_connection_cb connection_cb; \
|
uv_connection_cb connection_cb; \
|
||||||
int delayed_error; \
|
int delayed_error; \
|
||||||
int accepted_fd; \
|
int accepted_fd; \
|
||||||
@ -301,35 +303,38 @@ typedef struct {
|
|||||||
uv_alloc_cb alloc_cb; \
|
uv_alloc_cb alloc_cb; \
|
||||||
uv_udp_recv_cb recv_cb; \
|
uv_udp_recv_cb recv_cb; \
|
||||||
uv__io_t io_watcher; \
|
uv__io_t io_watcher; \
|
||||||
void* write_queue[2]; \
|
struct uv__queue write_queue; \
|
||||||
void* write_completed_queue[2]; \
|
struct uv__queue write_completed_queue; \
|
||||||
|
|
||||||
#define UV_PIPE_PRIVATE_FIELDS \
|
#define UV_PIPE_PRIVATE_FIELDS \
|
||||||
const char* pipe_fname; /* strdup'ed */
|
const char* pipe_fname; /* NULL or strdup'ed */
|
||||||
|
|
||||||
#define UV_POLL_PRIVATE_FIELDS \
|
#define UV_POLL_PRIVATE_FIELDS \
|
||||||
uv__io_t io_watcher;
|
uv__io_t io_watcher;
|
||||||
|
|
||||||
#define UV_PREPARE_PRIVATE_FIELDS \
|
#define UV_PREPARE_PRIVATE_FIELDS \
|
||||||
uv_prepare_cb prepare_cb; \
|
uv_prepare_cb prepare_cb; \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
|
|
||||||
#define UV_CHECK_PRIVATE_FIELDS \
|
#define UV_CHECK_PRIVATE_FIELDS \
|
||||||
uv_check_cb check_cb; \
|
uv_check_cb check_cb; \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
|
|
||||||
#define UV_IDLE_PRIVATE_FIELDS \
|
#define UV_IDLE_PRIVATE_FIELDS \
|
||||||
uv_idle_cb idle_cb; \
|
uv_idle_cb idle_cb; \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
|
|
||||||
#define UV_ASYNC_PRIVATE_FIELDS \
|
#define UV_ASYNC_PRIVATE_FIELDS \
|
||||||
uv_async_cb async_cb; \
|
uv_async_cb async_cb; \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
int pending; \
|
int pending; \
|
||||||
|
|
||||||
#define UV_TIMER_PRIVATE_FIELDS \
|
#define UV_TIMER_PRIVATE_FIELDS \
|
||||||
uv_timer_cb timer_cb; \
|
uv_timer_cb timer_cb; \
|
||||||
void* heap_node[3]; \
|
union { \
|
||||||
|
void* heap[3]; \
|
||||||
|
struct uv__queue queue; \
|
||||||
|
} node; \
|
||||||
uint64_t timeout; \
|
uint64_t timeout; \
|
||||||
uint64_t repeat; \
|
uint64_t repeat; \
|
||||||
uint64_t start_id;
|
uint64_t start_id;
|
||||||
@ -353,7 +358,7 @@ typedef struct {
|
|||||||
int retcode;
|
int retcode;
|
||||||
|
|
||||||
#define UV_PROCESS_PRIVATE_FIELDS \
|
#define UV_PROCESS_PRIVATE_FIELDS \
|
||||||
void* queue[2]; \
|
struct uv__queue queue; \
|
||||||
int status; \
|
int status; \
|
||||||
|
|
||||||
#define UV_FS_PRIVATE_FIELDS \
|
#define UV_FS_PRIVATE_FIELDS \
|
||||||
@ -418,6 +423,8 @@ typedef struct {
|
|||||||
# define UV_FS_O_DIRECT 0x04000
|
# define UV_FS_O_DIRECT 0x04000
|
||||||
#elif defined(__linux__) && defined(__x86_64__)
|
#elif defined(__linux__) && defined(__x86_64__)
|
||||||
# define UV_FS_O_DIRECT 0x04000
|
# define UV_FS_O_DIRECT 0x04000
|
||||||
|
#elif defined(__linux__) && defined(__loongarch__)
|
||||||
|
# define UV_FS_O_DIRECT 0x04000
|
||||||
#elif defined(O_DIRECT)
|
#elif defined(O_DIRECT)
|
||||||
# define UV_FS_O_DIRECT O_DIRECT
|
# define UV_FS_O_DIRECT O_DIRECT
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -31,10 +31,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define UV_VERSION_MAJOR 1
|
#define UV_VERSION_MAJOR 1
|
||||||
#define UV_VERSION_MINOR 43
|
#define UV_VERSION_MINOR 50
|
||||||
#define UV_VERSION_PATCH 0
|
#define UV_VERSION_PATCH 1
|
||||||
#define UV_VERSION_IS_RELEASE 1
|
#define UV_VERSION_IS_RELEASE 0
|
||||||
#define UV_VERSION_SUFFIX ""
|
#define UV_VERSION_SUFFIX "dev"
|
||||||
|
|
||||||
#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \
|
#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \
|
||||||
(UV_VERSION_MINOR << 8) | \
|
(UV_VERSION_MINOR << 8) | \
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT
|
#ifndef _WIN32_WINNT
|
||||||
# define _WIN32_WINNT 0x0600
|
# define _WIN32_WINNT 0x0A00
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
|
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
|
||||||
@ -32,20 +32,12 @@ typedef intptr_t ssize_t;
|
|||||||
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
|
||||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
|
||||||
typedef struct pollfd {
|
|
||||||
SOCKET fd;
|
|
||||||
short events;
|
|
||||||
short revents;
|
|
||||||
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LOCALE_INVARIANT
|
#ifndef LOCALE_INVARIANT
|
||||||
# define LOCALE_INVARIANT 0x007f
|
# define LOCALE_INVARIANT 0x007f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <mswsock.h>
|
#include <mswsock.h>
|
||||||
// Disable the typedef in mstcpip.h of MinGW.
|
/* Disable the typedef in mstcpip.h of MinGW. */
|
||||||
#define _TCP_INITIAL_RTO_PARAMETERS _TCP_INITIAL_RTO_PARAMETERS__AVOID
|
#define _TCP_INITIAL_RTO_PARAMETERS _TCP_INITIAL_RTO_PARAMETERS__AVOID
|
||||||
#define TCP_INITIAL_RTO_PARAMETERS TCP_INITIAL_RTO_PARAMETERS__AVOID
|
#define TCP_INITIAL_RTO_PARAMETERS TCP_INITIAL_RTO_PARAMETERS__AVOID
|
||||||
#define PTCP_INITIAL_RTO_PARAMETERS PTCP_INITIAL_RTO_PARAMETERS__AVOID
|
#define PTCP_INITIAL_RTO_PARAMETERS PTCP_INITIAL_RTO_PARAMETERS__AVOID
|
||||||
@ -59,12 +51,7 @@ typedef struct pollfd {
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <stdint.h>
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
|
||||||
# include "uv/stdint-msvc2008.h"
|
|
||||||
#else
|
|
||||||
# include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "uv/tree.h"
|
#include "uv/tree.h"
|
||||||
#include "uv/threadpool.h"
|
#include "uv/threadpool.h"
|
||||||
@ -75,6 +62,11 @@ typedef struct pollfd {
|
|||||||
# define S_IFLNK 0xA000
|
# define S_IFLNK 0xA000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Define missing in Windows Kit Include\{VERSION}\ucrt\sys\stat.h */
|
||||||
|
#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined(S_IFIFO)
|
||||||
|
# define S_IFIFO _S_IFIFO
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Additional signals supported by uv_signal and or uv_kill. The CRT defines
|
/* Additional signals supported by uv_signal and or uv_kill. The CRT defines
|
||||||
* the following signals already:
|
* the following signals already:
|
||||||
*
|
*
|
||||||
@ -91,6 +83,7 @@ typedef struct pollfd {
|
|||||||
* variants (Linux and Darwin)
|
* variants (Linux and Darwin)
|
||||||
*/
|
*/
|
||||||
#define SIGHUP 1
|
#define SIGHUP 1
|
||||||
|
#define SIGQUIT 3
|
||||||
#define SIGKILL 9
|
#define SIGKILL 9
|
||||||
#define SIGWINCH 28
|
#define SIGWINCH 28
|
||||||
|
|
||||||
@ -223,7 +216,7 @@ typedef struct _AFD_POLL_INFO {
|
|||||||
AFD_POLL_HANDLE_INFO Handles[1];
|
AFD_POLL_HANDLE_INFO Handles[1];
|
||||||
} AFD_POLL_INFO, *PAFD_POLL_INFO;
|
} AFD_POLL_INFO, *PAFD_POLL_INFO;
|
||||||
|
|
||||||
#define UV_MSAFD_PROVIDER_COUNT 3
|
#define UV_MSAFD_PROVIDER_COUNT 4
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -263,29 +256,23 @@ typedef union {
|
|||||||
} unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */
|
} unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */
|
||||||
} uv_cond_t;
|
} uv_cond_t;
|
||||||
|
|
||||||
typedef union {
|
typedef struct {
|
||||||
struct {
|
SRWLOCK read_write_lock_;
|
||||||
unsigned int num_readers_;
|
/* TODO: retained for ABI compatibility; remove me in v2.x */
|
||||||
CRITICAL_SECTION num_readers_lock_;
|
#ifdef _WIN64
|
||||||
HANDLE write_semaphore_;
|
unsigned char padding_[72];
|
||||||
} state_;
|
#else
|
||||||
/* TODO: remove me in v2.x. */
|
unsigned char padding_[44];
|
||||||
struct {
|
#endif
|
||||||
SRWLOCK unused_;
|
|
||||||
} unused1_;
|
|
||||||
/* TODO: remove me in v2.x. */
|
|
||||||
struct {
|
|
||||||
uv_mutex_t unused1_;
|
|
||||||
uv_mutex_t unused2_;
|
|
||||||
} unused2_;
|
|
||||||
} uv_rwlock_t;
|
} uv_rwlock_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int n;
|
unsigned threshold;
|
||||||
unsigned int count;
|
unsigned in;
|
||||||
uv_mutex_t mutex;
|
uv_mutex_t mutex;
|
||||||
uv_sem_t turnstile1;
|
/* TODO: in v2 make this a uv_cond_t, without unused_ */
|
||||||
uv_sem_t turnstile2;
|
CONDITION_VARIABLE cond;
|
||||||
|
unsigned out;
|
||||||
} uv_barrier_t;
|
} uv_barrier_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -295,8 +282,8 @@ typedef struct {
|
|||||||
#define UV_ONCE_INIT { 0, NULL }
|
#define UV_ONCE_INIT { 0, NULL }
|
||||||
|
|
||||||
typedef struct uv_once_s {
|
typedef struct uv_once_s {
|
||||||
unsigned char ran;
|
unsigned char unused;
|
||||||
HANDLE event;
|
INIT_ONCE init_once;
|
||||||
} uv_once_t;
|
} uv_once_t;
|
||||||
|
|
||||||
/* Platform-specific definitions for uv_spawn support. */
|
/* Platform-specific definitions for uv_spawn support. */
|
||||||
@ -355,14 +342,14 @@ typedef struct {
|
|||||||
uv_idle_t* next_idle_handle; \
|
uv_idle_t* next_idle_handle; \
|
||||||
/* This handle holds the peer sockets for the fast variant of uv_poll_t */ \
|
/* This handle holds the peer sockets for the fast variant of uv_poll_t */ \
|
||||||
SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT]; \
|
SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT]; \
|
||||||
/* Counter to keep track of active tcp streams */ \
|
/* No longer used. */ \
|
||||||
unsigned int active_tcp_streams; \
|
unsigned int active_tcp_streams; \
|
||||||
/* Counter to keep track of active udp streams */ \
|
/* No longer used. */ \
|
||||||
unsigned int active_udp_streams; \
|
unsigned int active_udp_streams; \
|
||||||
/* Counter to started timer */ \
|
/* Counter to started timer */ \
|
||||||
uint64_t timer_counter; \
|
uint64_t timer_counter; \
|
||||||
/* Threadpool */ \
|
/* Threadpool */ \
|
||||||
void* wq[2]; \
|
struct uv__queue wq; \
|
||||||
uv_mutex_t wq_mutex; \
|
uv_mutex_t wq_mutex; \
|
||||||
uv_async_t wq_async;
|
uv_async_t wq_async;
|
||||||
|
|
||||||
@ -384,6 +371,13 @@ typedef struct {
|
|||||||
OVERLAPPED overlapped; \
|
OVERLAPPED overlapped; \
|
||||||
size_t queued_bytes; \
|
size_t queued_bytes; \
|
||||||
} io; \
|
} io; \
|
||||||
|
/* in v2, we can move these to the UV_CONNECT_PRIVATE_FIELDS */ \
|
||||||
|
struct { \
|
||||||
|
ULONG_PTR result; /* overlapped.Internal is reused to hold the result */\
|
||||||
|
HANDLE pipeHandle; \
|
||||||
|
DWORD duplex_flags; \
|
||||||
|
WCHAR* name; \
|
||||||
|
} connect; \
|
||||||
} u; \
|
} u; \
|
||||||
struct uv_req_s* next_req;
|
struct uv_req_s* next_req;
|
||||||
|
|
||||||
@ -484,7 +478,7 @@ typedef struct {
|
|||||||
uint32_t payload_remaining; \
|
uint32_t payload_remaining; \
|
||||||
uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
|
uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
|
||||||
} ipc_data_frame; \
|
} ipc_data_frame; \
|
||||||
void* ipc_xfer_queue[2]; \
|
struct uv__queue ipc_xfer_queue; \
|
||||||
int ipc_xfer_queue_length; \
|
int ipc_xfer_queue_length; \
|
||||||
uv_write_t* non_overlapped_writes_tail; \
|
uv_write_t* non_overlapped_writes_tail; \
|
||||||
CRITICAL_SECTION readfile_thread_lock; \
|
CRITICAL_SECTION readfile_thread_lock; \
|
||||||
@ -498,15 +492,18 @@ typedef struct {
|
|||||||
struct { uv_pipe_connection_fields } conn; \
|
struct { uv_pipe_connection_fields } conn; \
|
||||||
} pipe;
|
} pipe;
|
||||||
|
|
||||||
/* TODO: put the parser states in an union - TTY handles are always half-duplex
|
/* TODO: put the parser states in a union - TTY handles are always half-duplex
|
||||||
* so read-state can safely overlap write-state. */
|
* so read-state can safely overlap write-state. */
|
||||||
#define UV_TTY_PRIVATE_FIELDS \
|
#define UV_TTY_PRIVATE_FIELDS \
|
||||||
HANDLE handle; \
|
HANDLE handle; \
|
||||||
union { \
|
union { \
|
||||||
struct { \
|
struct { \
|
||||||
/* Used for readable TTY handles */ \
|
/* Used for readable TTY handles */ \
|
||||||
/* TODO: remove me in v2.x. */ \
|
union { \
|
||||||
HANDLE unused_; \
|
/* TODO: remove me in v2.x. */ \
|
||||||
|
HANDLE unused_; \
|
||||||
|
int mode; \
|
||||||
|
} mode; \
|
||||||
uv_buf_t read_line_buffer; \
|
uv_buf_t read_line_buffer; \
|
||||||
HANDLE read_raw_wait; \
|
HANDLE read_raw_wait; \
|
||||||
/* Fields used for translating win keystrokes into vt100 characters */ \
|
/* Fields used for translating win keystrokes into vt100 characters */ \
|
||||||
@ -548,7 +545,10 @@ typedef struct {
|
|||||||
unsigned char events;
|
unsigned char events;
|
||||||
|
|
||||||
#define UV_TIMER_PRIVATE_FIELDS \
|
#define UV_TIMER_PRIVATE_FIELDS \
|
||||||
void* heap_node[3]; \
|
union { \
|
||||||
|
void* heap[3]; \
|
||||||
|
struct uv__queue queue; \
|
||||||
|
} node; \
|
||||||
int unused; \
|
int unused; \
|
||||||
uint64_t timeout; \
|
uint64_t timeout; \
|
||||||
uint64_t repeat; \
|
uint64_t repeat; \
|
||||||
@ -606,7 +606,7 @@ typedef struct {
|
|||||||
struct uv_process_exit_s { \
|
struct uv_process_exit_s { \
|
||||||
UV_REQ_FIELDS \
|
UV_REQ_FIELDS \
|
||||||
} exit_req; \
|
} exit_req; \
|
||||||
BYTE* child_stdio_buffer; \
|
void* unused; /* TODO: retained for ABI compat; remove this in v2.x. */ \
|
||||||
int exit_signal; \
|
int exit_signal; \
|
||||||
HANDLE wait_handle; \
|
HANDLE wait_handle; \
|
||||||
HANDLE process_handle; \
|
HANDLE process_handle; \
|
||||||
|
|||||||
@ -8,5 +8,5 @@ Version: @PACKAGE_VERSION@
|
|||||||
Description: multi-platform support library with a focus on asynchronous I/O.
|
Description: multi-platform support library with a focus on asynchronous I/O.
|
||||||
URL: http://libuv.org/
|
URL: http://libuv.org/
|
||||||
|
|
||||||
Libs: -L${libdir} -luv_a @LIBS@
|
Libs: -L${libdir} -l:libuv.a @LIBS@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ prefix=@prefix@
|
|||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
libdir=@libdir@
|
libdir=@libdir@
|
||||||
includedir=@includedir@
|
includedir=@includedir@
|
||||||
|
LIBUV_STATIC=-L${libdir} -l:libuv.a @LIBS@
|
||||||
|
|
||||||
Name: libuv
|
Name: libuv
|
||||||
Version: @PACKAGE_VERSION@
|
Version: @PACKAGE_VERSION@
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
dnl Macros to check the presence of generic (non-typed) symbols.
|
dnl Macros to check the presence of generic (non-typed) symbols.
|
||||||
dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes gmail com>
|
dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes gmail com>
|
||||||
dnl Copyright (c) 2006-2008 xine project
|
dnl Copyright (c) 2006-2008 xine project
|
||||||
|
dnl Copyright (c) 2021 libuv project
|
||||||
dnl
|
dnl
|
||||||
dnl This program is free software; you can redistribute it and/or modify
|
dnl This program is free software; you can redistribute it and/or modify
|
||||||
dnl it under the terms of the GNU General Public License as published by
|
dnl it under the terms of the GNU General Public License as published by
|
||||||
@ -63,7 +64,7 @@ AC_DEFUN([CC_CHECK_CFLAGS], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
|
dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
|
||||||
dnl Check for CFLAG and appends them to CFLAGS if supported
|
dnl Check for CFLAG and appends them to AM_CFLAGS if supported
|
||||||
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
|
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
|
||||||
AC_CACHE_CHECK([if $CC supports $1 flag],
|
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||||
AS_TR_SH([cc_cv_cflags_$1]),
|
AS_TR_SH([cc_cv_cflags_$1]),
|
||||||
@ -71,7 +72,9 @@ AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
|
|||||||
)
|
)
|
||||||
|
|
||||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||||
[CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
|
[AM_CFLAGS="$AM_CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
|
||||||
|
|
||||||
|
AC_SUBST([AM_CFLAGS])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
|
dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
|
||||||
@ -101,6 +104,20 @@ AC_DEFUN([CC_CHECK_LDFLAGS], [
|
|||||||
[$2], [$3])
|
[$2], [$3])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl Check if flag is supported by both compiler and linker
|
||||||
|
dnl If so, append it to AM_CFLAGS
|
||||||
|
dnl CC_CHECK_FLAG_SUPPORTED_APPEND([FLAG])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_FLAG_SUPPORTED_APPEND], [
|
||||||
|
CC_CHECK_CFLAGS([$1],
|
||||||
|
[CC_CHECK_LDFLAGS([$1],
|
||||||
|
[AM_CFLAGS="$AM_CFLAGS $1";
|
||||||
|
DEBUG_CFLAGS="$DEBUG_CFLAGS $1";
|
||||||
|
AC_SUBST([AM_CFLAGS])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
|
dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
|
||||||
dnl the current linker to avoid undefined references in a shared object.
|
dnl the current linker to avoid undefined references in a shared object.
|
||||||
AC_DEFUN([CC_NOUNDEFINED], [
|
AC_DEFUN([CC_NOUNDEFINED], [
|
||||||
|
|||||||
7
m4/libuv-check-versions.m4
Normal file
7
m4/libuv-check-versions.m4
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
AC_PREREQ(2.71)
|
||||||
|
AC_INIT([libuv-release-check], [0.0])
|
||||||
|
AM_INIT_AUTOMAKE([1.16.5])
|
||||||
|
LT_PREREQ(2.4.7)
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
@ -25,7 +25,7 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "win/internal.h"
|
#include "win/internal.h"
|
||||||
#include "win/handle-inl.h"
|
#include "win/handle-inl.h"
|
||||||
#define uv__make_close_pending(h) uv_want_endgame((h)->loop, (h))
|
#define uv__make_close_pending(h) uv__want_endgame((h)->loop, (h))
|
||||||
#else
|
#else
|
||||||
#include "unix/internal.h"
|
#include "unix/internal.h"
|
||||||
#endif
|
#endif
|
||||||
@ -139,6 +139,9 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
|
|||||||
struct poll_ctx* ctx;
|
struct poll_ctx* ctx;
|
||||||
size_t required_len;
|
size_t required_len;
|
||||||
|
|
||||||
|
if (buffer == NULL || size == NULL || *size == 0)
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (!uv_is_active((uv_handle_t*)handle)) {
|
if (!uv_is_active((uv_handle_t*)handle)) {
|
||||||
*size = 0;
|
*size = 0;
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|||||||
264
src/idna.c
264
src/idna.c
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2011, 2018 Ben Noordhuis <info@bnoordhuis.nl>
|
/* Copyright libuv contributors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -18,9 +18,55 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
|
#include "uv-common.h"
|
||||||
#include "idna.h"
|
#include "idna.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h> /* UINT_MAX */
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t uv__wtf8_decode1(const char** input) {
|
||||||
|
uint32_t code_point;
|
||||||
|
uint8_t b1;
|
||||||
|
uint8_t b2;
|
||||||
|
uint8_t b3;
|
||||||
|
uint8_t b4;
|
||||||
|
|
||||||
|
b1 = **input;
|
||||||
|
if (b1 <= 0x7F)
|
||||||
|
return b1; /* ASCII code point */
|
||||||
|
if (b1 < 0xC2)
|
||||||
|
return -1; /* invalid: continuation byte */
|
||||||
|
code_point = b1;
|
||||||
|
|
||||||
|
b2 = *++*input;
|
||||||
|
if ((b2 & 0xC0) != 0x80)
|
||||||
|
return -1; /* invalid: not a continuation byte */
|
||||||
|
code_point = (code_point << 6) | (b2 & 0x3F);
|
||||||
|
if (b1 <= 0xDF)
|
||||||
|
return 0x7FF & code_point; /* two-byte character */
|
||||||
|
|
||||||
|
b3 = *++*input;
|
||||||
|
if ((b3 & 0xC0) != 0x80)
|
||||||
|
return -1; /* invalid: not a continuation byte */
|
||||||
|
code_point = (code_point << 6) | (b3 & 0x3F);
|
||||||
|
if (b1 <= 0xEF)
|
||||||
|
return 0xFFFF & code_point; /* three-byte character */
|
||||||
|
|
||||||
|
b4 = *++*input;
|
||||||
|
if ((b4 & 0xC0) != 0x80)
|
||||||
|
return -1; /* invalid: not a continuation byte */
|
||||||
|
code_point = (code_point << 6) | (b4 & 0x3F);
|
||||||
|
if (b1 <= 0xF4) {
|
||||||
|
code_point &= 0x1FFFFF;
|
||||||
|
if (code_point <= 0x10FFFF)
|
||||||
|
return code_point; /* four-byte character */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* code point too large */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned uv__utf8_decode1_slow(const char** p,
|
static unsigned uv__utf8_decode1_slow(const char** p,
|
||||||
const char* pe,
|
const char* pe,
|
||||||
@ -88,6 +134,7 @@ static unsigned uv__utf8_decode1_slow(const char** p,
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned uv__utf8_decode1(const char** p, const char* pe) {
|
unsigned uv__utf8_decode1(const char** p, const char* pe) {
|
||||||
unsigned a;
|
unsigned a;
|
||||||
|
|
||||||
@ -101,6 +148,7 @@ unsigned uv__utf8_decode1(const char** p, const char* pe) {
|
|||||||
return uv__utf8_decode1_slow(p, pe, a);
|
return uv__utf8_decode1_slow(p, pe, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int uv__idna_toascii_label(const char* s, const char* se,
|
static int uv__idna_toascii_label(const char* s, const char* se,
|
||||||
char** d, char* de) {
|
char** d, char* de) {
|
||||||
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
@ -129,7 +177,7 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
|||||||
while (s < se) {
|
while (s < se) {
|
||||||
c = uv__utf8_decode1(&s, se);
|
c = uv__utf8_decode1(&s, se);
|
||||||
|
|
||||||
if (c == -1u)
|
if (c == UINT_MAX)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (c < 128)
|
if (c < 128)
|
||||||
@ -151,7 +199,7 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
|||||||
s = ss;
|
s = ss;
|
||||||
while (s < se) {
|
while (s < se) {
|
||||||
c = uv__utf8_decode1(&s, se);
|
c = uv__utf8_decode1(&s, se);
|
||||||
assert(c != -1u);
|
assert(c != UINT_MAX);
|
||||||
|
|
||||||
if (c > 127)
|
if (c > 127)
|
||||||
continue;
|
continue;
|
||||||
@ -182,7 +230,7 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
|||||||
|
|
||||||
while (s < se) {
|
while (s < se) {
|
||||||
c = uv__utf8_decode1(&s, se);
|
c = uv__utf8_decode1(&s, se);
|
||||||
assert(c != -1u);
|
assert(c != UINT_MAX);
|
||||||
|
|
||||||
if (c >= n)
|
if (c >= n)
|
||||||
if (c < m)
|
if (c < m)
|
||||||
@ -201,7 +249,7 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
|||||||
s = ss;
|
s = ss;
|
||||||
while (s < se) {
|
while (s < se) {
|
||||||
c = uv__utf8_decode1(&s, se);
|
c = uv__utf8_decode1(&s, se);
|
||||||
assert(c != -1u);
|
assert(c != UINT_MAX);
|
||||||
|
|
||||||
if (c < n)
|
if (c < n)
|
||||||
if (++delta == 0)
|
if (++delta == 0)
|
||||||
@ -266,13 +314,17 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
|
||||||
|
ssize_t uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
||||||
const char* si;
|
const char* si;
|
||||||
const char* st;
|
const char* st;
|
||||||
unsigned c;
|
unsigned c;
|
||||||
char* ds;
|
char* ds;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (s == se)
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
ds = d;
|
ds = d;
|
||||||
|
|
||||||
si = s;
|
si = s;
|
||||||
@ -280,7 +332,7 @@ long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
|||||||
st = si;
|
st = si;
|
||||||
c = uv__utf8_decode1(&si, se);
|
c = uv__utf8_decode1(&si, se);
|
||||||
|
|
||||||
if (c == -1u)
|
if (c == UINT_MAX)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (c != '.')
|
if (c != '.')
|
||||||
@ -307,8 +359,202 @@ long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d < de)
|
if (d >= de)
|
||||||
*d++ = '\0';
|
return UV_EINVAL;
|
||||||
|
|
||||||
|
*d++ = '\0';
|
||||||
return d - ds; /* Number of bytes written. */
|
return d - ds; /* Number of bytes written. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t uv_wtf8_length_as_utf16(const char* source_ptr) {
|
||||||
|
size_t w_target_len = 0;
|
||||||
|
int32_t code_point;
|
||||||
|
|
||||||
|
do {
|
||||||
|
code_point = uv__wtf8_decode1(&source_ptr);
|
||||||
|
if (code_point < 0)
|
||||||
|
return -1;
|
||||||
|
if (code_point > 0xFFFF)
|
||||||
|
w_target_len++;
|
||||||
|
w_target_len++;
|
||||||
|
} while (*source_ptr++);
|
||||||
|
|
||||||
|
return w_target_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_wtf8_to_utf16(const char* source_ptr,
|
||||||
|
uint16_t* w_target,
|
||||||
|
size_t w_target_len) {
|
||||||
|
int32_t code_point;
|
||||||
|
|
||||||
|
do {
|
||||||
|
code_point = uv__wtf8_decode1(&source_ptr);
|
||||||
|
/* uv_wtf8_length_as_utf16 should have been called and checked first. */
|
||||||
|
assert(code_point >= 0);
|
||||||
|
if (code_point > 0xFFFF) {
|
||||||
|
assert(code_point < 0x10FFFF);
|
||||||
|
*w_target++ = (((code_point - 0x10000) >> 10) + 0xD800);
|
||||||
|
*w_target++ = ((code_point - 0x10000) & 0x3FF) + 0xDC00;
|
||||||
|
w_target_len -= 2;
|
||||||
|
} else {
|
||||||
|
*w_target++ = code_point;
|
||||||
|
w_target_len -= 1;
|
||||||
|
}
|
||||||
|
} while (*source_ptr++);
|
||||||
|
|
||||||
|
(void)w_target_len;
|
||||||
|
assert(w_target_len == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t uv__get_surrogate_value(const uint16_t* w_source_ptr,
|
||||||
|
ssize_t w_source_len) {
|
||||||
|
uint16_t u;
|
||||||
|
uint16_t next;
|
||||||
|
|
||||||
|
u = w_source_ptr[0];
|
||||||
|
if (u >= 0xD800 && u <= 0xDBFF && w_source_len != 1) {
|
||||||
|
next = w_source_ptr[1];
|
||||||
|
if (next >= 0xDC00 && next <= 0xDFFF)
|
||||||
|
return 0x10000 + ((u - 0xD800) << 10) + (next - 0xDC00);
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t uv_utf16_length_as_wtf8(const uint16_t* w_source_ptr,
|
||||||
|
ssize_t w_source_len) {
|
||||||
|
size_t target_len;
|
||||||
|
int32_t code_point;
|
||||||
|
|
||||||
|
target_len = 0;
|
||||||
|
while (w_source_len) {
|
||||||
|
code_point = uv__get_surrogate_value(w_source_ptr, w_source_len);
|
||||||
|
/* Can be invalid UTF-8 but must be valid WTF-8. */
|
||||||
|
assert(code_point >= 0);
|
||||||
|
if (w_source_len < 0 && code_point == 0)
|
||||||
|
break;
|
||||||
|
if (code_point < 0x80)
|
||||||
|
target_len += 1;
|
||||||
|
else if (code_point < 0x800)
|
||||||
|
target_len += 2;
|
||||||
|
else if (code_point < 0x10000)
|
||||||
|
target_len += 3;
|
||||||
|
else {
|
||||||
|
target_len += 4;
|
||||||
|
w_source_ptr++;
|
||||||
|
if (w_source_len > 0)
|
||||||
|
w_source_len--;
|
||||||
|
}
|
||||||
|
w_source_ptr++;
|
||||||
|
if (w_source_len > 0)
|
||||||
|
w_source_len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_utf16_to_wtf8(const uint16_t* w_source_ptr,
|
||||||
|
ssize_t w_source_len,
|
||||||
|
char** target_ptr,
|
||||||
|
size_t* target_len_ptr) {
|
||||||
|
size_t target_len;
|
||||||
|
char* target;
|
||||||
|
char* target_end;
|
||||||
|
int32_t code_point;
|
||||||
|
|
||||||
|
/* If *target_ptr is provided, then *target_len_ptr must be its length
|
||||||
|
* (excluding space for NUL), otherwise we will compute the target_len_ptr
|
||||||
|
* length and may return a new allocation in *target_ptr if target_ptr is
|
||||||
|
* provided. */
|
||||||
|
if (target_ptr == NULL || *target_ptr == NULL) {
|
||||||
|
target_len = uv_utf16_length_as_wtf8(w_source_ptr, w_source_len);
|
||||||
|
if (target_len_ptr != NULL)
|
||||||
|
*target_len_ptr = target_len;
|
||||||
|
} else {
|
||||||
|
target_len = *target_len_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_ptr == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (*target_ptr == NULL) {
|
||||||
|
target = uv__malloc(target_len + 1);
|
||||||
|
if (target == NULL) {
|
||||||
|
return UV_ENOMEM;
|
||||||
|
}
|
||||||
|
*target_ptr = target;
|
||||||
|
} else {
|
||||||
|
target = *target_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_end = target + target_len;
|
||||||
|
|
||||||
|
while (target != target_end && w_source_len) {
|
||||||
|
code_point = uv__get_surrogate_value(w_source_ptr, w_source_len);
|
||||||
|
/* Can be invalid UTF-8 but must be valid WTF-8. */
|
||||||
|
assert(code_point >= 0);
|
||||||
|
if (w_source_len < 0 && code_point == 0) {
|
||||||
|
w_source_len = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (code_point < 0x80) {
|
||||||
|
*target++ = code_point;
|
||||||
|
} else if (code_point < 0x800) {
|
||||||
|
*target++ = 0xC0 | (code_point >> 6);
|
||||||
|
if (target == target_end)
|
||||||
|
break;
|
||||||
|
*target++ = 0x80 | (code_point & 0x3F);
|
||||||
|
} else if (code_point < 0x10000) {
|
||||||
|
*target++ = 0xE0 | (code_point >> 12);
|
||||||
|
if (target == target_end)
|
||||||
|
break;
|
||||||
|
*target++ = 0x80 | ((code_point >> 6) & 0x3F);
|
||||||
|
if (target == target_end)
|
||||||
|
break;
|
||||||
|
*target++ = 0x80 | (code_point & 0x3F);
|
||||||
|
} else {
|
||||||
|
*target++ = 0xF0 | (code_point >> 18);
|
||||||
|
if (target == target_end)
|
||||||
|
break;
|
||||||
|
*target++ = 0x80 | ((code_point >> 12) & 0x3F);
|
||||||
|
if (target == target_end)
|
||||||
|
break;
|
||||||
|
*target++ = 0x80 | ((code_point >> 6) & 0x3F);
|
||||||
|
if (target == target_end)
|
||||||
|
break;
|
||||||
|
*target++ = 0x80 | (code_point & 0x3F);
|
||||||
|
/* uv__get_surrogate_value consumed 2 input characters */
|
||||||
|
w_source_ptr++;
|
||||||
|
if (w_source_len > 0)
|
||||||
|
w_source_len--;
|
||||||
|
}
|
||||||
|
target_len = target - *target_ptr;
|
||||||
|
w_source_ptr++;
|
||||||
|
if (w_source_len > 0)
|
||||||
|
w_source_len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target != target_end && target_len_ptr != NULL)
|
||||||
|
/* Did not fill all of the provided buffer, so update the target_len_ptr
|
||||||
|
* output with the space used. */
|
||||||
|
*target_len_ptr = target - *target_ptr;
|
||||||
|
|
||||||
|
/* Check if input fit into target exactly. */
|
||||||
|
if (w_source_len < 0 && target == target_end && w_source_ptr[0] == 0)
|
||||||
|
w_source_len = 0;
|
||||||
|
|
||||||
|
*target++ = '\0';
|
||||||
|
|
||||||
|
/* Characters remained after filling the buffer, compute the remaining length now. */
|
||||||
|
if (w_source_len) {
|
||||||
|
if (target_len_ptr != NULL)
|
||||||
|
*target_len_ptr = target_len + uv_utf16_length_as_wtf8(w_source_ptr, w_source_len);
|
||||||
|
return UV_ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2011, 2018 Ben Noordhuis <info@bnoordhuis.nl>
|
/* Copyright libuv contributors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -26,6 +26,6 @@ unsigned uv__utf8_decode1(const char** p, const char* pe);
|
|||||||
* is the number of bytes written to |d|, including the trailing nul byte.
|
* is the number of bytes written to |d|, including the trailing nul byte.
|
||||||
* A return value < 0 is a libuv error code. |s| and |d| can not overlap.
|
* A return value < 0 is a libuv error code. |s| and |d| can not overlap.
|
||||||
*/
|
*/
|
||||||
long uv__idna_toascii(const char* s, const char* se, char* d, char* de);
|
ssize_t uv__idna_toascii(const char* s, const char* se, char* d, char* de);
|
||||||
|
|
||||||
#endif /* UV_SRC_IDNA_H_ */
|
#endif /* UV_SRC_IDNA_H_ */
|
||||||
|
|||||||
@ -17,12 +17,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
|
||||||
# include "uv/stdint-msvc2008.h"
|
|
||||||
#else
|
|
||||||
# include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "uv-common.h"
|
#include "uv-common.h"
|
||||||
@ -135,7 +130,7 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
|
|||||||
tp += strlen(tp);
|
tp += strlen(tp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tp += sprintf(tp, "%x", words[i]);
|
tp += snprintf(tp, sizeof tmp - (tp - tmp), "%x", words[i]);
|
||||||
}
|
}
|
||||||
/* Was it a trailing run of 0x00's? */
|
/* Was it a trailing run of 0x00's? */
|
||||||
if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
|
if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
|
||||||
|
|||||||
132
src/queue.h
132
src/queue.h
@ -18,91 +18,73 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef void *QUEUE[2];
|
#define uv__queue_data(pointer, type, field) \
|
||||||
|
((type*) ((char*) (pointer) - offsetof(type, field)))
|
||||||
|
|
||||||
/* Private macros. */
|
#define uv__queue_foreach(q, h) \
|
||||||
#define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0]))
|
for ((q) = (h)->next; (q) != (h); (q) = (q)->next)
|
||||||
#define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1]))
|
|
||||||
#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q)))
|
|
||||||
#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q)))
|
|
||||||
|
|
||||||
/* Public macros. */
|
static inline void uv__queue_init(struct uv__queue* q) {
|
||||||
#define QUEUE_DATA(ptr, type, field) \
|
q->next = q;
|
||||||
((type *) ((char *) (ptr) - offsetof(type, field)))
|
q->prev = q;
|
||||||
|
}
|
||||||
|
|
||||||
/* Important note: mutating the list while QUEUE_FOREACH is
|
static inline int uv__queue_empty(const struct uv__queue* q) {
|
||||||
* iterating over its elements results in undefined behavior.
|
return q == q->next;
|
||||||
*/
|
}
|
||||||
#define QUEUE_FOREACH(q, h) \
|
|
||||||
for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))
|
|
||||||
|
|
||||||
#define QUEUE_EMPTY(q) \
|
static inline struct uv__queue* uv__queue_head(const struct uv__queue* q) {
|
||||||
((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q))
|
return q->next;
|
||||||
|
}
|
||||||
|
|
||||||
#define QUEUE_HEAD(q) \
|
static inline struct uv__queue* uv__queue_next(const struct uv__queue* q) {
|
||||||
(QUEUE_NEXT(q))
|
return q->next;
|
||||||
|
}
|
||||||
|
|
||||||
#define QUEUE_INIT(q) \
|
static inline void uv__queue_add(struct uv__queue* h, struct uv__queue* n) {
|
||||||
do { \
|
h->prev->next = n->next;
|
||||||
QUEUE_NEXT(q) = (q); \
|
n->next->prev = h->prev;
|
||||||
QUEUE_PREV(q) = (q); \
|
h->prev = n->prev;
|
||||||
} \
|
h->prev->next = h;
|
||||||
while (0)
|
}
|
||||||
|
|
||||||
#define QUEUE_ADD(h, n) \
|
static inline void uv__queue_split(struct uv__queue* h,
|
||||||
do { \
|
struct uv__queue* q,
|
||||||
QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \
|
struct uv__queue* n) {
|
||||||
QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \
|
n->prev = h->prev;
|
||||||
QUEUE_PREV(h) = QUEUE_PREV(n); \
|
n->prev->next = n;
|
||||||
QUEUE_PREV_NEXT(h) = (h); \
|
n->next = q;
|
||||||
} \
|
h->prev = q->prev;
|
||||||
while (0)
|
h->prev->next = h;
|
||||||
|
q->prev = n;
|
||||||
|
}
|
||||||
|
|
||||||
#define QUEUE_SPLIT(h, q, n) \
|
static inline void uv__queue_move(struct uv__queue* h, struct uv__queue* n) {
|
||||||
do { \
|
if (uv__queue_empty(h))
|
||||||
QUEUE_PREV(n) = QUEUE_PREV(h); \
|
uv__queue_init(n);
|
||||||
QUEUE_PREV_NEXT(n) = (n); \
|
else
|
||||||
QUEUE_NEXT(n) = (q); \
|
uv__queue_split(h, h->next, n);
|
||||||
QUEUE_PREV(h) = QUEUE_PREV(q); \
|
}
|
||||||
QUEUE_PREV_NEXT(h) = (h); \
|
|
||||||
QUEUE_PREV(q) = (n); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#define QUEUE_MOVE(h, n) \
|
static inline void uv__queue_insert_head(struct uv__queue* h,
|
||||||
do { \
|
struct uv__queue* q) {
|
||||||
if (QUEUE_EMPTY(h)) \
|
q->next = h->next;
|
||||||
QUEUE_INIT(n); \
|
q->prev = h;
|
||||||
else { \
|
q->next->prev = q;
|
||||||
QUEUE* q = QUEUE_HEAD(h); \
|
h->next = q;
|
||||||
QUEUE_SPLIT(h, q, n); \
|
}
|
||||||
} \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#define QUEUE_INSERT_HEAD(h, q) \
|
static inline void uv__queue_insert_tail(struct uv__queue* h,
|
||||||
do { \
|
struct uv__queue* q) {
|
||||||
QUEUE_NEXT(q) = QUEUE_NEXT(h); \
|
q->next = h;
|
||||||
QUEUE_PREV(q) = (h); \
|
q->prev = h->prev;
|
||||||
QUEUE_NEXT_PREV(q) = (q); \
|
q->prev->next = q;
|
||||||
QUEUE_NEXT(h) = (q); \
|
h->prev = q;
|
||||||
} \
|
}
|
||||||
while (0)
|
|
||||||
|
|
||||||
#define QUEUE_INSERT_TAIL(h, q) \
|
static inline void uv__queue_remove(struct uv__queue* q) {
|
||||||
do { \
|
q->prev->next = q->next;
|
||||||
QUEUE_NEXT(q) = (h); \
|
q->next->prev = q->prev;
|
||||||
QUEUE_PREV(q) = QUEUE_PREV(h); \
|
}
|
||||||
QUEUE_PREV_NEXT(q) = (q); \
|
|
||||||
QUEUE_PREV(h) = (q); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#define QUEUE_REMOVE(q) \
|
|
||||||
do { \
|
|
||||||
QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \
|
|
||||||
QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#endif /* QUEUE_H_ */
|
#endif /* QUEUE_H_ */
|
||||||
|
|||||||
@ -82,7 +82,7 @@ static void uv__random_done(struct uv__work* w, int status) {
|
|||||||
uv_random_t* req;
|
uv_random_t* req;
|
||||||
|
|
||||||
req = container_of(w, uv_random_t, work_req);
|
req = container_of(w, uv_random_t, work_req);
|
||||||
uv__req_unregister(req->loop, req);
|
uv__req_unregister(req->loop);
|
||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
status = req->status;
|
status = req->status;
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
|
|
||||||
/* Copies up to |n-1| bytes from |d| to |s| and always zero-terminates
|
/* Copies up to |n-1| bytes from |s| to |d| and always zero-terminates
|
||||||
* the result, except when |n==0|. Returns the number of bytes copied
|
* the result, except when |n==0|. Returns the number of bytes copied
|
||||||
* or UV_E2BIG if |d| is too small.
|
* or UV_E2BIG if |d| is too small.
|
||||||
*
|
*
|
||||||
|
|||||||
52
src/strtok.c
Normal file
52
src/strtok.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* Copyright libuv project contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "strtok.h"
|
||||||
|
|
||||||
|
char* uv__strtok(char* str, const char* sep, char** itr) {
|
||||||
|
const char* sep_itr;
|
||||||
|
char* tmp;
|
||||||
|
char* start;
|
||||||
|
|
||||||
|
if (str == NULL)
|
||||||
|
start = tmp = *itr;
|
||||||
|
else
|
||||||
|
start = tmp = str;
|
||||||
|
|
||||||
|
if (tmp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (*tmp != '\0') {
|
||||||
|
sep_itr = sep;
|
||||||
|
while (*sep_itr != '\0') {
|
||||||
|
if (*tmp == *sep_itr) {
|
||||||
|
*itr = tmp + 1;
|
||||||
|
*tmp = '\0';
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
sep_itr++;
|
||||||
|
}
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
*itr = NULL;
|
||||||
|
return start;
|
||||||
|
}
|
||||||
27
src/strtok.h
Normal file
27
src/strtok.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* Copyright libuv project contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UV_STRTOK_H_
|
||||||
|
#define UV_STRTOK_H_
|
||||||
|
|
||||||
|
char* uv__strtok(char* str, const char* sep, char** itr);
|
||||||
|
|
||||||
|
#endif /* UV_STRTOK_H_ */
|
||||||
175
src/thread-common.c
Normal file
175
src/thread-common.c
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/* Copyright libuv project contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "uv-common.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
STATIC_ASSERT(sizeof(uv_barrier_t) == sizeof(pthread_barrier_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Note: guard clauses should match uv_barrier_t's in include/uv/unix.h. */
|
||||||
|
#if defined(_AIX) || \
|
||||||
|
defined(__OpenBSD__) || \
|
||||||
|
!defined(PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
|
||||||
|
int rc;
|
||||||
|
#ifdef _WIN32
|
||||||
|
uv_barrier_t* b;
|
||||||
|
b = barrier;
|
||||||
|
|
||||||
|
if (barrier == NULL || count == 0)
|
||||||
|
return UV_EINVAL;
|
||||||
|
#else
|
||||||
|
struct _uv_barrier* b;
|
||||||
|
|
||||||
|
if (barrier == NULL || count == 0)
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
|
b = uv__malloc(sizeof(*b));
|
||||||
|
if (b == NULL)
|
||||||
|
return UV_ENOMEM;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
b->in = 0;
|
||||||
|
b->out = 0;
|
||||||
|
b->threshold = count;
|
||||||
|
|
||||||
|
rc = uv_mutex_init(&b->mutex);
|
||||||
|
if (rc != 0)
|
||||||
|
goto error2;
|
||||||
|
|
||||||
|
/* TODO(vjnash): remove these uv_cond_t casts in v2. */
|
||||||
|
rc = uv_cond_init((uv_cond_t*) &b->cond);
|
||||||
|
if (rc != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
barrier->b = b;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
uv_mutex_destroy(&b->mutex);
|
||||||
|
error2:
|
||||||
|
#ifndef _WIN32
|
||||||
|
uv__free(b);
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_barrier_wait(uv_barrier_t* barrier) {
|
||||||
|
int last;
|
||||||
|
#ifdef _WIN32
|
||||||
|
uv_barrier_t* b;
|
||||||
|
b = barrier;
|
||||||
|
#else
|
||||||
|
struct _uv_barrier* b;
|
||||||
|
|
||||||
|
if (barrier == NULL || barrier->b == NULL)
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
|
b = barrier->b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uv_mutex_lock(&b->mutex);
|
||||||
|
|
||||||
|
while (b->out != 0)
|
||||||
|
uv_cond_wait((uv_cond_t*) &b->cond, &b->mutex);
|
||||||
|
|
||||||
|
if (++b->in == b->threshold) {
|
||||||
|
b->in = 0;
|
||||||
|
b->out = b->threshold;
|
||||||
|
uv_cond_broadcast((uv_cond_t*) &b->cond);
|
||||||
|
} else {
|
||||||
|
do
|
||||||
|
uv_cond_wait((uv_cond_t*) &b->cond, &b->mutex);
|
||||||
|
while (b->in != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
last = (--b->out == 0);
|
||||||
|
if (last)
|
||||||
|
uv_cond_broadcast((uv_cond_t*) &b->cond);
|
||||||
|
|
||||||
|
uv_mutex_unlock(&b->mutex);
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_barrier_destroy(uv_barrier_t* barrier) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
uv_barrier_t* b;
|
||||||
|
b = barrier;
|
||||||
|
#else
|
||||||
|
struct _uv_barrier* b;
|
||||||
|
b = barrier->b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uv_mutex_lock(&b->mutex);
|
||||||
|
|
||||||
|
assert(b->in == 0);
|
||||||
|
while (b->out != 0)
|
||||||
|
uv_cond_wait((uv_cond_t*) &b->cond, &b->mutex);
|
||||||
|
|
||||||
|
if (b->in != 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
uv_mutex_unlock(&b->mutex);
|
||||||
|
uv_mutex_destroy(&b->mutex);
|
||||||
|
uv_cond_destroy((uv_cond_t*) &b->cond);
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
uv__free(barrier->b);
|
||||||
|
barrier->b = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
|
||||||
|
return UV__ERR(pthread_barrier_init(barrier, NULL, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_barrier_wait(uv_barrier_t* barrier) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = pthread_barrier_wait(barrier);
|
||||||
|
if (rc != 0)
|
||||||
|
if (rc != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
return rc == PTHREAD_BARRIER_SERIAL_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_barrier_destroy(uv_barrier_t* barrier) {
|
||||||
|
if (pthread_barrier_destroy(barrier))
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
102
src/threadpool.c
102
src/threadpool.c
@ -37,10 +37,10 @@ static unsigned int slow_io_work_running;
|
|||||||
static unsigned int nthreads;
|
static unsigned int nthreads;
|
||||||
static uv_thread_t* threads;
|
static uv_thread_t* threads;
|
||||||
static uv_thread_t default_threads[4];
|
static uv_thread_t default_threads[4];
|
||||||
static QUEUE exit_message;
|
static struct uv__queue exit_message;
|
||||||
static QUEUE wq;
|
static struct uv__queue wq;
|
||||||
static QUEUE run_slow_work_message;
|
static struct uv__queue run_slow_work_message;
|
||||||
static QUEUE slow_io_pending_wq;
|
static struct uv__queue slow_io_pending_wq;
|
||||||
|
|
||||||
static unsigned int slow_work_thread_threshold(void) {
|
static unsigned int slow_work_thread_threshold(void) {
|
||||||
return (nthreads + 1) / 2;
|
return (nthreads + 1) / 2;
|
||||||
@ -56,9 +56,10 @@ static void uv__cancelled(struct uv__work* w) {
|
|||||||
*/
|
*/
|
||||||
static void worker(void* arg) {
|
static void worker(void* arg) {
|
||||||
struct uv__work* w;
|
struct uv__work* w;
|
||||||
QUEUE* q;
|
struct uv__queue* q;
|
||||||
int is_slow_work;
|
int is_slow_work;
|
||||||
|
|
||||||
|
uv_thread_setname("libuv-worker");
|
||||||
uv_sem_post((uv_sem_t*) arg);
|
uv_sem_post((uv_sem_t*) arg);
|
||||||
arg = NULL;
|
arg = NULL;
|
||||||
|
|
||||||
@ -68,49 +69,49 @@ static void worker(void* arg) {
|
|||||||
|
|
||||||
/* Keep waiting while either no work is present or only slow I/O
|
/* Keep waiting while either no work is present or only slow I/O
|
||||||
and we're at the threshold for that. */
|
and we're at the threshold for that. */
|
||||||
while (QUEUE_EMPTY(&wq) ||
|
while (uv__queue_empty(&wq) ||
|
||||||
(QUEUE_HEAD(&wq) == &run_slow_work_message &&
|
(uv__queue_head(&wq) == &run_slow_work_message &&
|
||||||
QUEUE_NEXT(&run_slow_work_message) == &wq &&
|
uv__queue_next(&run_slow_work_message) == &wq &&
|
||||||
slow_io_work_running >= slow_work_thread_threshold())) {
|
slow_io_work_running >= slow_work_thread_threshold())) {
|
||||||
idle_threads += 1;
|
idle_threads += 1;
|
||||||
uv_cond_wait(&cond, &mutex);
|
uv_cond_wait(&cond, &mutex);
|
||||||
idle_threads -= 1;
|
idle_threads -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
q = QUEUE_HEAD(&wq);
|
q = uv__queue_head(&wq);
|
||||||
if (q == &exit_message) {
|
if (q == &exit_message) {
|
||||||
uv_cond_signal(&cond);
|
uv_cond_signal(&cond);
|
||||||
uv_mutex_unlock(&mutex);
|
uv_mutex_unlock(&mutex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUEUE_REMOVE(q);
|
uv__queue_remove(q);
|
||||||
QUEUE_INIT(q); /* Signal uv_cancel() that the work req is executing. */
|
uv__queue_init(q); /* Signal uv_cancel() that the work req is executing. */
|
||||||
|
|
||||||
is_slow_work = 0;
|
is_slow_work = 0;
|
||||||
if (q == &run_slow_work_message) {
|
if (q == &run_slow_work_message) {
|
||||||
/* If we're at the slow I/O threshold, re-schedule until after all
|
/* If we're at the slow I/O threshold, re-schedule until after all
|
||||||
other work in the queue is done. */
|
other work in the queue is done. */
|
||||||
if (slow_io_work_running >= slow_work_thread_threshold()) {
|
if (slow_io_work_running >= slow_work_thread_threshold()) {
|
||||||
QUEUE_INSERT_TAIL(&wq, q);
|
uv__queue_insert_tail(&wq, q);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we encountered a request to run slow I/O work but there is none
|
/* If we encountered a request to run slow I/O work but there is none
|
||||||
to run, that means it's cancelled => Start over. */
|
to run, that means it's cancelled => Start over. */
|
||||||
if (QUEUE_EMPTY(&slow_io_pending_wq))
|
if (uv__queue_empty(&slow_io_pending_wq))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
is_slow_work = 1;
|
is_slow_work = 1;
|
||||||
slow_io_work_running++;
|
slow_io_work_running++;
|
||||||
|
|
||||||
q = QUEUE_HEAD(&slow_io_pending_wq);
|
q = uv__queue_head(&slow_io_pending_wq);
|
||||||
QUEUE_REMOVE(q);
|
uv__queue_remove(q);
|
||||||
QUEUE_INIT(q);
|
uv__queue_init(q);
|
||||||
|
|
||||||
/* If there is more slow I/O work, schedule it to be run as well. */
|
/* If there is more slow I/O work, schedule it to be run as well. */
|
||||||
if (!QUEUE_EMPTY(&slow_io_pending_wq)) {
|
if (!uv__queue_empty(&slow_io_pending_wq)) {
|
||||||
QUEUE_INSERT_TAIL(&wq, &run_slow_work_message);
|
uv__queue_insert_tail(&wq, &run_slow_work_message);
|
||||||
if (idle_threads > 0)
|
if (idle_threads > 0)
|
||||||
uv_cond_signal(&cond);
|
uv_cond_signal(&cond);
|
||||||
}
|
}
|
||||||
@ -118,13 +119,13 @@ static void worker(void* arg) {
|
|||||||
|
|
||||||
uv_mutex_unlock(&mutex);
|
uv_mutex_unlock(&mutex);
|
||||||
|
|
||||||
w = QUEUE_DATA(q, struct uv__work, wq);
|
w = uv__queue_data(q, struct uv__work, wq);
|
||||||
w->work(w);
|
w->work(w);
|
||||||
|
|
||||||
uv_mutex_lock(&w->loop->wq_mutex);
|
uv_mutex_lock(&w->loop->wq_mutex);
|
||||||
w->work = NULL; /* Signal uv_cancel() that the work req is done
|
w->work = NULL; /* Signal uv_cancel() that the work req is done
|
||||||
executing. */
|
executing. */
|
||||||
QUEUE_INSERT_TAIL(&w->loop->wq, &w->wq);
|
uv__queue_insert_tail(&w->loop->wq, &w->wq);
|
||||||
uv_async_send(&w->loop->wq_async);
|
uv_async_send(&w->loop->wq_async);
|
||||||
uv_mutex_unlock(&w->loop->wq_mutex);
|
uv_mutex_unlock(&w->loop->wq_mutex);
|
||||||
|
|
||||||
@ -139,12 +140,12 @@ static void worker(void* arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void post(QUEUE* q, enum uv__work_kind kind) {
|
static void post(struct uv__queue* q, enum uv__work_kind kind) {
|
||||||
uv_mutex_lock(&mutex);
|
uv_mutex_lock(&mutex);
|
||||||
if (kind == UV__WORK_SLOW_IO) {
|
if (kind == UV__WORK_SLOW_IO) {
|
||||||
/* Insert into a separate queue. */
|
/* Insert into a separate queue. */
|
||||||
QUEUE_INSERT_TAIL(&slow_io_pending_wq, q);
|
uv__queue_insert_tail(&slow_io_pending_wq, q);
|
||||||
if (!QUEUE_EMPTY(&run_slow_work_message)) {
|
if (!uv__queue_empty(&run_slow_work_message)) {
|
||||||
/* Running slow I/O tasks is already scheduled => Nothing to do here.
|
/* Running slow I/O tasks is already scheduled => Nothing to do here.
|
||||||
The worker that runs said other task will schedule this one as well. */
|
The worker that runs said other task will schedule this one as well. */
|
||||||
uv_mutex_unlock(&mutex);
|
uv_mutex_unlock(&mutex);
|
||||||
@ -153,7 +154,7 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
|
|||||||
q = &run_slow_work_message;
|
q = &run_slow_work_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUEUE_INSERT_TAIL(&wq, q);
|
uv__queue_insert_tail(&wq, q);
|
||||||
if (idle_threads > 0)
|
if (idle_threads > 0)
|
||||||
uv_cond_signal(&cond);
|
uv_cond_signal(&cond);
|
||||||
uv_mutex_unlock(&mutex);
|
uv_mutex_unlock(&mutex);
|
||||||
@ -191,6 +192,7 @@ void uv__threadpool_cleanup(void) {
|
|||||||
|
|
||||||
|
|
||||||
static void init_threads(void) {
|
static void init_threads(void) {
|
||||||
|
uv_thread_options_t config;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char* val;
|
const char* val;
|
||||||
uv_sem_t sem;
|
uv_sem_t sem;
|
||||||
@ -219,15 +221,18 @@ static void init_threads(void) {
|
|||||||
if (uv_mutex_init(&mutex))
|
if (uv_mutex_init(&mutex))
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
QUEUE_INIT(&wq);
|
uv__queue_init(&wq);
|
||||||
QUEUE_INIT(&slow_io_pending_wq);
|
uv__queue_init(&slow_io_pending_wq);
|
||||||
QUEUE_INIT(&run_slow_work_message);
|
uv__queue_init(&run_slow_work_message);
|
||||||
|
|
||||||
if (uv_sem_init(&sem, 0))
|
if (uv_sem_init(&sem, 0))
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
|
config.flags = UV_THREAD_HAS_STACK_SIZE;
|
||||||
|
config.stack_size = 8u << 20; /* 8 MB */
|
||||||
|
|
||||||
for (i = 0; i < nthreads; i++)
|
for (i = 0; i < nthreads; i++)
|
||||||
if (uv_thread_create(threads + i, worker, &sem))
|
if (uv_thread_create_ex(threads + i, &config, worker, &sem))
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
for (i = 0; i < nthreads; i++)
|
for (i = 0; i < nthreads; i++)
|
||||||
@ -271,15 +276,19 @@ void uv__work_submit(uv_loop_t* loop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO(bnoordhuis) teach libuv how to cancel file operations
|
||||||
|
* that go through io_uring instead of the thread pool.
|
||||||
|
*/
|
||||||
static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
|
static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
|
||||||
int cancelled;
|
int cancelled;
|
||||||
|
|
||||||
|
uv_once(&once, init_once); /* Ensure |mutex| is initialized. */
|
||||||
uv_mutex_lock(&mutex);
|
uv_mutex_lock(&mutex);
|
||||||
uv_mutex_lock(&w->loop->wq_mutex);
|
uv_mutex_lock(&w->loop->wq_mutex);
|
||||||
|
|
||||||
cancelled = !QUEUE_EMPTY(&w->wq) && w->work != NULL;
|
cancelled = !uv__queue_empty(&w->wq) && w->work != NULL;
|
||||||
if (cancelled)
|
if (cancelled)
|
||||||
QUEUE_REMOVE(&w->wq);
|
uv__queue_remove(&w->wq);
|
||||||
|
|
||||||
uv_mutex_unlock(&w->loop->wq_mutex);
|
uv_mutex_unlock(&w->loop->wq_mutex);
|
||||||
uv_mutex_unlock(&mutex);
|
uv_mutex_unlock(&mutex);
|
||||||
@ -289,7 +298,7 @@ static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
|
|||||||
|
|
||||||
w->work = uv__cancelled;
|
w->work = uv__cancelled;
|
||||||
uv_mutex_lock(&loop->wq_mutex);
|
uv_mutex_lock(&loop->wq_mutex);
|
||||||
QUEUE_INSERT_TAIL(&loop->wq, &w->wq);
|
uv__queue_insert_tail(&loop->wq, &w->wq);
|
||||||
uv_async_send(&loop->wq_async);
|
uv_async_send(&loop->wq_async);
|
||||||
uv_mutex_unlock(&loop->wq_mutex);
|
uv_mutex_unlock(&loop->wq_mutex);
|
||||||
|
|
||||||
@ -300,22 +309,39 @@ static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
|
|||||||
void uv__work_done(uv_async_t* handle) {
|
void uv__work_done(uv_async_t* handle) {
|
||||||
struct uv__work* w;
|
struct uv__work* w;
|
||||||
uv_loop_t* loop;
|
uv_loop_t* loop;
|
||||||
QUEUE* q;
|
struct uv__queue* q;
|
||||||
QUEUE wq;
|
struct uv__queue wq;
|
||||||
int err;
|
int err;
|
||||||
|
int nevents;
|
||||||
|
|
||||||
loop = container_of(handle, uv_loop_t, wq_async);
|
loop = container_of(handle, uv_loop_t, wq_async);
|
||||||
uv_mutex_lock(&loop->wq_mutex);
|
uv_mutex_lock(&loop->wq_mutex);
|
||||||
QUEUE_MOVE(&loop->wq, &wq);
|
uv__queue_move(&loop->wq, &wq);
|
||||||
uv_mutex_unlock(&loop->wq_mutex);
|
uv_mutex_unlock(&loop->wq_mutex);
|
||||||
|
|
||||||
while (!QUEUE_EMPTY(&wq)) {
|
nevents = 0;
|
||||||
q = QUEUE_HEAD(&wq);
|
|
||||||
QUEUE_REMOVE(q);
|
while (!uv__queue_empty(&wq)) {
|
||||||
|
q = uv__queue_head(&wq);
|
||||||
|
uv__queue_remove(q);
|
||||||
|
|
||||||
w = container_of(q, struct uv__work, wq);
|
w = container_of(q, struct uv__work, wq);
|
||||||
err = (w->work == uv__cancelled) ? UV_ECANCELED : 0;
|
err = (w->work == uv__cancelled) ? UV_ECANCELED : 0;
|
||||||
w->done(w, err);
|
w->done(w, err);
|
||||||
|
nevents++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This check accomplishes 2 things:
|
||||||
|
* 1. Even if the queue was empty, the call to uv__work_done() should count
|
||||||
|
* as an event. Which will have been added by the event loop when
|
||||||
|
* calling this callback.
|
||||||
|
* 2. Prevents accidental wrap around in case nevents == 0 events == 0.
|
||||||
|
*/
|
||||||
|
if (nevents > 1) {
|
||||||
|
/* Subtract 1 to counter the call to uv__work_done(). */
|
||||||
|
uv__metrics_inc_events(loop, nevents - 1);
|
||||||
|
if (uv__get_internal_fields(loop)->current_timeout == 0)
|
||||||
|
uv__metrics_inc_events_waiting(loop, nevents - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +357,7 @@ static void uv__queue_done(struct uv__work* w, int err) {
|
|||||||
uv_work_t* req;
|
uv_work_t* req;
|
||||||
|
|
||||||
req = container_of(w, uv_work_t, work_req);
|
req = container_of(w, uv_work_t, work_req);
|
||||||
uv__req_unregister(req->loop, req);
|
uv__req_unregister(req->loop);
|
||||||
|
|
||||||
if (req->after_work_cb == NULL)
|
if (req->after_work_cb == NULL)
|
||||||
return;
|
return;
|
||||||
|
|||||||
43
src/timer.c
43
src/timer.c
@ -40,8 +40,8 @@ static int timer_less_than(const struct heap_node* ha,
|
|||||||
const uv_timer_t* a;
|
const uv_timer_t* a;
|
||||||
const uv_timer_t* b;
|
const uv_timer_t* b;
|
||||||
|
|
||||||
a = container_of(ha, uv_timer_t, heap_node);
|
a = container_of(ha, uv_timer_t, node.heap);
|
||||||
b = container_of(hb, uv_timer_t, heap_node);
|
b = container_of(hb, uv_timer_t, node.heap);
|
||||||
|
|
||||||
if (a->timeout < b->timeout)
|
if (a->timeout < b->timeout)
|
||||||
return 1;
|
return 1;
|
||||||
@ -60,6 +60,7 @@ int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
|||||||
handle->timer_cb = NULL;
|
handle->timer_cb = NULL;
|
||||||
handle->timeout = 0;
|
handle->timeout = 0;
|
||||||
handle->repeat = 0;
|
handle->repeat = 0;
|
||||||
|
uv__queue_init(&handle->node.queue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +74,7 @@ int uv_timer_start(uv_timer_t* handle,
|
|||||||
if (uv__is_closing(handle) || cb == NULL)
|
if (uv__is_closing(handle) || cb == NULL)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (uv__is_active(handle))
|
uv_timer_stop(handle);
|
||||||
uv_timer_stop(handle);
|
|
||||||
|
|
||||||
clamped_timeout = handle->loop->time + timeout;
|
clamped_timeout = handle->loop->time + timeout;
|
||||||
if (clamped_timeout < timeout)
|
if (clamped_timeout < timeout)
|
||||||
@ -87,7 +87,7 @@ int uv_timer_start(uv_timer_t* handle,
|
|||||||
handle->start_id = handle->loop->timer_counter++;
|
handle->start_id = handle->loop->timer_counter++;
|
||||||
|
|
||||||
heap_insert(timer_heap(handle->loop),
|
heap_insert(timer_heap(handle->loop),
|
||||||
(struct heap_node*) &handle->heap_node,
|
(struct heap_node*) &handle->node.heap,
|
||||||
timer_less_than);
|
timer_less_than);
|
||||||
uv__handle_start(handle);
|
uv__handle_start(handle);
|
||||||
|
|
||||||
@ -96,14 +96,16 @@ int uv_timer_start(uv_timer_t* handle,
|
|||||||
|
|
||||||
|
|
||||||
int uv_timer_stop(uv_timer_t* handle) {
|
int uv_timer_stop(uv_timer_t* handle) {
|
||||||
if (!uv__is_active(handle))
|
if (uv__is_active(handle)) {
|
||||||
return 0;
|
heap_remove(timer_heap(handle->loop),
|
||||||
|
(struct heap_node*) &handle->node.heap,
|
||||||
heap_remove(timer_heap(handle->loop),
|
timer_less_than);
|
||||||
(struct heap_node*) &handle->heap_node,
|
uv__handle_stop(handle);
|
||||||
timer_less_than);
|
} else {
|
||||||
uv__handle_stop(handle);
|
uv__queue_remove(&handle->node.queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv__queue_init(&handle->node.queue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +150,7 @@ int uv__next_timeout(const uv_loop_t* loop) {
|
|||||||
if (heap_node == NULL)
|
if (heap_node == NULL)
|
||||||
return -1; /* block indefinitely */
|
return -1; /* block indefinitely */
|
||||||
|
|
||||||
handle = container_of(heap_node, uv_timer_t, heap_node);
|
handle = container_of(heap_node, uv_timer_t, node.heap);
|
||||||
if (handle->timeout <= loop->time)
|
if (handle->timeout <= loop->time)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -163,17 +165,30 @@ int uv__next_timeout(const uv_loop_t* loop) {
|
|||||||
void uv__run_timers(uv_loop_t* loop) {
|
void uv__run_timers(uv_loop_t* loop) {
|
||||||
struct heap_node* heap_node;
|
struct heap_node* heap_node;
|
||||||
uv_timer_t* handle;
|
uv_timer_t* handle;
|
||||||
|
struct uv__queue* queue_node;
|
||||||
|
struct uv__queue ready_queue;
|
||||||
|
|
||||||
|
uv__queue_init(&ready_queue);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
heap_node = heap_min(timer_heap(loop));
|
heap_node = heap_min(timer_heap(loop));
|
||||||
if (heap_node == NULL)
|
if (heap_node == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
handle = container_of(heap_node, uv_timer_t, heap_node);
|
handle = container_of(heap_node, uv_timer_t, node.heap);
|
||||||
if (handle->timeout > loop->time)
|
if (handle->timeout > loop->time)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
uv_timer_stop(handle);
|
uv_timer_stop(handle);
|
||||||
|
uv__queue_insert_tail(&ready_queue, &handle->node.queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!uv__queue_empty(&ready_queue)) {
|
||||||
|
queue_node = uv__queue_head(&ready_queue);
|
||||||
|
uv__queue_remove(queue_node);
|
||||||
|
uv__queue_init(queue_node);
|
||||||
|
handle = container_of(queue_node, uv_timer_t, node.queue);
|
||||||
|
|
||||||
uv_timer_again(handle);
|
uv_timer_again(handle);
|
||||||
handle->timer_cb(handle);
|
handle->timer_cb(handle);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,11 +131,12 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
|||||||
|
|
||||||
|
|
||||||
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||||
|
uv__loop_internal_fields_t* lfields;
|
||||||
struct pollfd events[1024];
|
struct pollfd events[1024];
|
||||||
struct pollfd pqry;
|
struct pollfd pqry;
|
||||||
struct pollfd* pe;
|
struct pollfd* pe;
|
||||||
struct poll_ctl pc;
|
struct poll_ctl pc;
|
||||||
QUEUE* q;
|
struct uv__queue* q;
|
||||||
uv__io_t* w;
|
uv__io_t* w;
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
@ -150,16 +151,18 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
int reset_timeout;
|
int reset_timeout;
|
||||||
|
|
||||||
if (loop->nfds == 0) {
|
if (loop->nfds == 0) {
|
||||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
assert(uv__queue_empty(&loop->watcher_queue));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
|
lfields = uv__get_internal_fields(loop);
|
||||||
q = QUEUE_HEAD(&loop->watcher_queue);
|
|
||||||
QUEUE_REMOVE(q);
|
|
||||||
QUEUE_INIT(q);
|
|
||||||
|
|
||||||
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
while (!uv__queue_empty(&loop->watcher_queue)) {
|
||||||
|
q = uv__queue_head(&loop->watcher_queue);
|
||||||
|
uv__queue_remove(q);
|
||||||
|
uv__queue_init(q);
|
||||||
|
|
||||||
|
w = uv__queue_data(q, uv__io_t, watcher_queue);
|
||||||
assert(w->pevents != 0);
|
assert(w->pevents != 0);
|
||||||
assert(w->fd >= 0);
|
assert(w->fd >= 0);
|
||||||
assert(w->fd < (int) loop->nwatchers);
|
assert(w->fd < (int) loop->nwatchers);
|
||||||
@ -217,7 +220,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
base = loop->time;
|
base = loop->time;
|
||||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||||
|
|
||||||
if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
|
if (lfields->flags & UV_METRICS_IDLE_TIME) {
|
||||||
reset_timeout = 1;
|
reset_timeout = 1;
|
||||||
user_timeout = timeout;
|
user_timeout = timeout;
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
@ -232,6 +235,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
if (timeout != 0)
|
if (timeout != 0)
|
||||||
uv__metrics_set_provider_entry_time(loop);
|
uv__metrics_set_provider_entry_time(loop);
|
||||||
|
|
||||||
|
/* Store the current timeout in a location that's globally accessible so
|
||||||
|
* other locations like uv__work_done() can determine whether the queue
|
||||||
|
* of events in the callback were waiting when poll was called.
|
||||||
|
*/
|
||||||
|
lfields->current_timeout = timeout;
|
||||||
|
|
||||||
nfds = pollset_poll(loop->backend_fd,
|
nfds = pollset_poll(loop->backend_fd,
|
||||||
events,
|
events,
|
||||||
ARRAY_SIZE(events),
|
ARRAY_SIZE(events),
|
||||||
@ -321,9 +330,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
nevents++;
|
nevents++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv__metrics_inc_events(loop, nevents);
|
||||||
if (reset_timeout != 0) {
|
if (reset_timeout != 0) {
|
||||||
timeout = user_timeout;
|
timeout = user_timeout;
|
||||||
reset_timeout = 0;
|
reset_timeout = 0;
|
||||||
|
uv__metrics_inc_events_waiting(loop, nevents);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_signals != 0) {
|
if (have_signals != 0) {
|
||||||
@ -389,6 +400,11 @@ uint64_t uv_get_constrained_memory(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t uv_get_available_memory(void) {
|
||||||
|
return uv_get_free_memory();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_loadavg(double avg[3]) {
|
void uv_loadavg(double avg[3]) {
|
||||||
perfstat_cpu_total_t ps_total;
|
perfstat_cpu_total_t ps_total;
|
||||||
int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
|
int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
|
||||||
@ -425,7 +441,7 @@ static char* uv__rawname(const char* cp, char (*dst)[FILENAME_MAX+1]) {
|
|||||||
static int uv__path_is_a_directory(char* filename) {
|
static int uv__path_is_a_directory(char* filename) {
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
if (stat(filename, &statbuf) < 0)
|
if (uv__stat(filename, &statbuf) < 0)
|
||||||
return -1; /* failed: not a directory, assume it is a file */
|
return -1; /* failed: not a directory, assume it is a file */
|
||||||
|
|
||||||
if (statbuf.st_type == VDIR)
|
if (statbuf.st_type == VDIR)
|
||||||
@ -1104,6 +1120,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
struct ifreq *ifr, *p, flg;
|
struct ifreq *ifr, *p, flg;
|
||||||
struct in6_ifreq if6;
|
struct in6_ifreq if6;
|
||||||
struct sockaddr_dl* sa_addr;
|
struct sockaddr_dl* sa_addr;
|
||||||
|
size_t namelen;
|
||||||
|
char* name;
|
||||||
|
|
||||||
ifc.ifc_req = NULL;
|
ifc.ifc_req = NULL;
|
||||||
sock6fd = -1;
|
sock6fd = -1;
|
||||||
@ -1140,6 +1158,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
|
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
|
||||||
|
|
||||||
/* Count all up and running ipv4/ipv6 addresses */
|
/* Count all up and running ipv4/ipv6 addresses */
|
||||||
|
namelen = 0;
|
||||||
ifr = ifc.ifc_req;
|
ifr = ifc.ifc_req;
|
||||||
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
|
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
|
||||||
p = ifr;
|
p = ifr;
|
||||||
@ -1159,6 +1178,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
|
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
namelen += strlen(ent->ifa_name) + 1;
|
||||||
(*count)++;
|
(*count)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1166,8 +1186,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Alloc the return interface structs */
|
/* Alloc the return interface structs */
|
||||||
*addresses = uv__calloc(*count, sizeof(**addresses));
|
*addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen);
|
||||||
if (!(*addresses)) {
|
if (*addresses == NULL) {
|
||||||
r = UV_ENOMEM;
|
r = UV_ENOMEM;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -1194,7 +1214,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
|
|
||||||
/* All conditions above must match count loop */
|
/* All conditions above must match count loop */
|
||||||
|
|
||||||
address->name = uv__strdup(p->ifr_name);
|
namelen = strlen(p->ifr_name) + 1;
|
||||||
|
address->name = memcpy(name, p->ifr_name, namelen);
|
||||||
|
name += namelen;
|
||||||
|
|
||||||
if (inet6)
|
if (inet6)
|
||||||
address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
|
address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
|
||||||
@ -1266,13 +1288,7 @@ cleanup:
|
|||||||
|
|
||||||
|
|
||||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||||
int count) {
|
int count) {
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; ++i) {
|
|
||||||
uv__free(addresses[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__free(addresses);
|
uv__free(addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,713 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2013, Kenneth MacKay
|
|
||||||
Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement #289016)
|
|
||||||
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.
|
|
||||||
|
|
||||||
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 HOLDER 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uv/android-ifaddrs.h"
|
|
||||||
#include "uv-common.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/if_arp.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <linux/netlink.h>
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
#include <linux/if_packet.h>
|
|
||||||
|
|
||||||
typedef struct NetlinkList
|
|
||||||
{
|
|
||||||
struct NetlinkList *m_next;
|
|
||||||
struct nlmsghdr *m_data;
|
|
||||||
unsigned int m_size;
|
|
||||||
} NetlinkList;
|
|
||||||
|
|
||||||
static int netlink_socket(pid_t *p_pid)
|
|
||||||
{
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
socklen_t l_len;
|
|
||||||
|
|
||||||
int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
||||||
if(l_socket < 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&l_addr, 0, sizeof(l_addr));
|
|
||||||
l_addr.nl_family = AF_NETLINK;
|
|
||||||
if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
|
|
||||||
{
|
|
||||||
close(l_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_len = sizeof(l_addr);
|
|
||||||
if(getsockname(l_socket, (struct sockaddr *)&l_addr, &l_len) < 0)
|
|
||||||
{
|
|
||||||
close(l_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*p_pid = l_addr.nl_pid;
|
|
||||||
|
|
||||||
return l_socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int netlink_send(int p_socket, int p_request)
|
|
||||||
{
|
|
||||||
char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
|
|
||||||
|
|
||||||
struct nlmsghdr *l_hdr;
|
|
||||||
struct rtgenmsg *l_msg;
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
|
|
||||||
memset(l_buffer, 0, sizeof(l_buffer));
|
|
||||||
|
|
||||||
l_hdr = (struct nlmsghdr *)l_buffer;
|
|
||||||
l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
|
|
||||||
|
|
||||||
l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
|
|
||||||
l_hdr->nlmsg_type = p_request;
|
|
||||||
l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
|
|
||||||
l_hdr->nlmsg_pid = 0;
|
|
||||||
l_hdr->nlmsg_seq = p_socket;
|
|
||||||
l_msg->rtgen_family = AF_UNSPEC;
|
|
||||||
|
|
||||||
memset(&l_addr, 0, sizeof(l_addr));
|
|
||||||
l_addr.nl_family = AF_NETLINK;
|
|
||||||
return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
|
|
||||||
{
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
struct msghdr l_msg;
|
|
||||||
|
|
||||||
struct iovec l_iov;
|
|
||||||
l_iov.iov_base = p_buffer;
|
|
||||||
l_iov.iov_len = p_len;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
int l_result;
|
|
||||||
l_msg.msg_name = (void *)&l_addr;
|
|
||||||
l_msg.msg_namelen = sizeof(l_addr);
|
|
||||||
l_msg.msg_iov = &l_iov;
|
|
||||||
l_msg.msg_iovlen = 1;
|
|
||||||
l_msg.msg_control = NULL;
|
|
||||||
l_msg.msg_controllen = 0;
|
|
||||||
l_msg.msg_flags = 0;
|
|
||||||
l_result = recvmsg(p_socket, &l_msg, 0);
|
|
||||||
|
|
||||||
if(l_result < 0)
|
|
||||||
{
|
|
||||||
if(errno == EINTR)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buffer was too small */
|
|
||||||
if(l_msg.msg_flags & MSG_TRUNC)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return l_result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nlmsghdr *getNetlinkResponse(int p_socket, pid_t p_pid, int *p_size, int *p_done)
|
|
||||||
{
|
|
||||||
size_t l_size = 4096;
|
|
||||||
void *l_buffer = NULL;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
int l_read;
|
|
||||||
|
|
||||||
uv__free(l_buffer);
|
|
||||||
l_buffer = uv__malloc(l_size);
|
|
||||||
if (l_buffer == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_read = netlink_recv(p_socket, l_buffer, l_size);
|
|
||||||
*p_size = l_read;
|
|
||||||
if(l_read == -2)
|
|
||||||
{
|
|
||||||
uv__free(l_buffer);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(l_read >= 0)
|
|
||||||
{
|
|
||||||
struct nlmsghdr *l_hdr;
|
|
||||||
for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
|
|
||||||
{
|
|
||||||
if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
|
||||||
{
|
|
||||||
*p_done = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_ERROR)
|
|
||||||
{
|
|
||||||
uv__free(l_buffer);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_size *= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
|
|
||||||
{
|
|
||||||
NetlinkList *l_item = uv__malloc(sizeof(NetlinkList));
|
|
||||||
if (l_item == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_item->m_next = NULL;
|
|
||||||
l_item->m_data = p_data;
|
|
||||||
l_item->m_size = p_size;
|
|
||||||
return l_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void freeResultList(NetlinkList *p_list)
|
|
||||||
{
|
|
||||||
NetlinkList *l_cur;
|
|
||||||
while(p_list)
|
|
||||||
{
|
|
||||||
l_cur = p_list;
|
|
||||||
p_list = p_list->m_next;
|
|
||||||
uv__free(l_cur->m_data);
|
|
||||||
uv__free(l_cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NetlinkList *getResultList(int p_socket, int p_request, pid_t p_pid)
|
|
||||||
{
|
|
||||||
int l_size;
|
|
||||||
int l_done;
|
|
||||||
NetlinkList *l_list;
|
|
||||||
NetlinkList *l_end;
|
|
||||||
|
|
||||||
if(netlink_send(p_socket, p_request) < 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_list = NULL;
|
|
||||||
l_end = NULL;
|
|
||||||
|
|
||||||
l_done = 0;
|
|
||||||
while(!l_done)
|
|
||||||
{
|
|
||||||
NetlinkList *l_item;
|
|
||||||
|
|
||||||
struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, p_pid, &l_size, &l_done);
|
|
||||||
/* Error */
|
|
||||||
if(!l_hdr)
|
|
||||||
{
|
|
||||||
freeResultList(l_list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_item = newListItem(l_hdr, l_size);
|
|
||||||
if (!l_item)
|
|
||||||
{
|
|
||||||
freeResultList(l_list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(!l_list)
|
|
||||||
{
|
|
||||||
l_list = l_item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_end->m_next = l_item;
|
|
||||||
}
|
|
||||||
l_end = l_item;
|
|
||||||
}
|
|
||||||
return l_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t maxSize(size_t a, size_t b)
|
|
||||||
{
|
|
||||||
return (a > b ? a : b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
|
|
||||||
{
|
|
||||||
switch(p_family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
return sizeof(struct sockaddr_in);
|
|
||||||
case AF_INET6:
|
|
||||||
return sizeof(struct sockaddr_in6);
|
|
||||||
case AF_PACKET:
|
|
||||||
return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
|
|
||||||
default:
|
|
||||||
return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
|
|
||||||
{
|
|
||||||
switch(p_family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
|
|
||||||
break;
|
|
||||||
case AF_PACKET:
|
|
||||||
memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
|
|
||||||
((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
memcpy(p_dest->sa_data, p_data, p_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p_dest->sa_family = p_family;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
|
|
||||||
{
|
|
||||||
if(!*p_resultList)
|
|
||||||
{
|
|
||||||
*p_resultList = p_entry;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct ifaddrs *l_cur = *p_resultList;
|
|
||||||
while(l_cur->ifa_next)
|
|
||||||
{
|
|
||||||
l_cur = l_cur->ifa_next;
|
|
||||||
}
|
|
||||||
l_cur->ifa_next = p_entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
|
|
||||||
{
|
|
||||||
struct ifaddrs *l_entry;
|
|
||||||
|
|
||||||
char *l_index;
|
|
||||||
char *l_name;
|
|
||||||
char *l_addr;
|
|
||||||
char *l_data;
|
|
||||||
|
|
||||||
struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
|
|
||||||
|
|
||||||
size_t l_nameSize = 0;
|
|
||||||
size_t l_addrSize = 0;
|
|
||||||
size_t l_dataSize = 0;
|
|
||||||
|
|
||||||
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
|
||||||
struct rtattr *l_rta;
|
|
||||||
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFLA_ADDRESS:
|
|
||||||
case IFLA_BROADCAST:
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
|
|
||||||
break;
|
|
||||||
case IFLA_IFNAME:
|
|
||||||
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
|
|
||||||
break;
|
|
||||||
case IFLA_STATS:
|
|
||||||
l_dataSize += NLMSG_ALIGN(l_rtaSize);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
|
|
||||||
if (l_entry == NULL)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset(l_entry, 0, sizeof(struct ifaddrs));
|
|
||||||
l_entry->ifa_name = "";
|
|
||||||
|
|
||||||
l_index = ((char *)l_entry) + sizeof(struct ifaddrs);
|
|
||||||
l_name = l_index + sizeof(int);
|
|
||||||
l_addr = l_name + l_nameSize;
|
|
||||||
l_data = l_addr + l_addrSize;
|
|
||||||
|
|
||||||
/* Save the interface index so we can look it up when handling the
|
|
||||||
* addresses.
|
|
||||||
*/
|
|
||||||
memcpy(l_index, &l_info->ifi_index, sizeof(int));
|
|
||||||
|
|
||||||
l_entry->ifa_flags = l_info->ifi_flags;
|
|
||||||
|
|
||||||
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
|
||||||
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
void *l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFLA_ADDRESS:
|
|
||||||
case IFLA_BROADCAST:
|
|
||||||
{
|
|
||||||
size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
|
|
||||||
makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
|
||||||
((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
|
|
||||||
((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
|
|
||||||
if(l_rta->rta_type == IFLA_ADDRESS)
|
|
||||||
{
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
l_addr += NLMSG_ALIGN(l_addrLen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IFLA_IFNAME:
|
|
||||||
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
|
||||||
l_name[l_rtaDataSize] = '\0';
|
|
||||||
l_entry->ifa_name = l_name;
|
|
||||||
break;
|
|
||||||
case IFLA_STATS:
|
|
||||||
memcpy(l_data, l_rtaData, l_rtaDataSize);
|
|
||||||
l_entry->ifa_data = l_data;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addToEnd(p_resultList, l_entry);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks)
|
|
||||||
{
|
|
||||||
int l_num = 0;
|
|
||||||
struct ifaddrs *l_cur = *p_links;
|
|
||||||
while(l_cur && l_num < p_numLinks)
|
|
||||||
{
|
|
||||||
char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs);
|
|
||||||
int l_index;
|
|
||||||
memcpy(&l_index, l_indexPtr, sizeof(int));
|
|
||||||
if(l_index == p_index)
|
|
||||||
{
|
|
||||||
return l_cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_cur = l_cur->ifa_next;
|
|
||||||
++l_num;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks)
|
|
||||||
{
|
|
||||||
struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
|
|
||||||
struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks);
|
|
||||||
|
|
||||||
size_t l_nameSize = 0;
|
|
||||||
size_t l_addrSize = 0;
|
|
||||||
|
|
||||||
int l_addedNetmask = 0;
|
|
||||||
|
|
||||||
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
|
||||||
struct rtattr *l_rta;
|
|
||||||
struct ifaddrs *l_entry;
|
|
||||||
|
|
||||||
char *l_name;
|
|
||||||
char *l_addr;
|
|
||||||
|
|
||||||
for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
if(l_info->ifa_family == AF_PACKET)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFA_ADDRESS:
|
|
||||||
case IFA_LOCAL:
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
|
||||||
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
|
|
||||||
{
|
|
||||||
/* Make room for netmask */
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
|
||||||
l_addedNetmask = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IFA_BROADCAST:
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
|
||||||
break;
|
|
||||||
case IFA_LABEL:
|
|
||||||
l_nameSize += NLMSG_ALIGN(l_rtaDataSize + 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
|
|
||||||
if (l_entry == NULL)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset(l_entry, 0, sizeof(struct ifaddrs));
|
|
||||||
l_entry->ifa_name = (l_interface ? l_interface->ifa_name : "");
|
|
||||||
|
|
||||||
l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
|
|
||||||
l_addr = l_name + l_nameSize;
|
|
||||||
|
|
||||||
l_entry->ifa_flags = l_info->ifa_flags;
|
|
||||||
if(l_interface)
|
|
||||||
{
|
|
||||||
l_entry->ifa_flags |= l_interface->ifa_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
|
||||||
for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
void *l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFA_ADDRESS:
|
|
||||||
case IFA_BROADCAST:
|
|
||||||
case IFA_LOCAL:
|
|
||||||
{
|
|
||||||
size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
|
|
||||||
makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
|
||||||
if(l_info->ifa_family == AF_INET6)
|
|
||||||
{
|
|
||||||
if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
|
|
||||||
{
|
|
||||||
((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apparently in a point-to-point network IFA_ADDRESS contains
|
|
||||||
* the dest address and IFA_LOCAL contains the local address
|
|
||||||
*/
|
|
||||||
if(l_rta->rta_type == IFA_ADDRESS)
|
|
||||||
{
|
|
||||||
if(l_entry->ifa_addr)
|
|
||||||
{
|
|
||||||
l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(l_rta->rta_type == IFA_LOCAL)
|
|
||||||
{
|
|
||||||
if(l_entry->ifa_addr)
|
|
||||||
{
|
|
||||||
l_entry->ifa_dstaddr = l_entry->ifa_addr;
|
|
||||||
}
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
l_addr += NLMSG_ALIGN(l_addrLen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IFA_LABEL:
|
|
||||||
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
|
||||||
l_name[l_rtaDataSize] = '\0';
|
|
||||||
l_entry->ifa_name = l_name;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
|
|
||||||
{
|
|
||||||
unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
|
|
||||||
unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
|
|
||||||
unsigned char l_mask[16] = {0};
|
|
||||||
unsigned i;
|
|
||||||
for(i=0; i<(l_prefix/8); ++i)
|
|
||||||
{
|
|
||||||
l_mask[i] = 0xff;
|
|
||||||
}
|
|
||||||
if(l_prefix % 8)
|
|
||||||
{
|
|
||||||
l_mask[i] = 0xff << (8 - (l_prefix % 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
|
|
||||||
l_entry->ifa_netmask = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
addToEnd(p_resultList, l_entry);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interpretLinks(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
|
|
||||||
{
|
|
||||||
|
|
||||||
int l_numLinks = 0;
|
|
||||||
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
|
|
||||||
{
|
|
||||||
unsigned int l_nlsize = p_netlinkList->m_size;
|
|
||||||
struct nlmsghdr *l_hdr;
|
|
||||||
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
|
|
||||||
{
|
|
||||||
if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == RTM_NEWLINK)
|
|
||||||
{
|
|
||||||
if(interpretLink(l_hdr, p_resultList) == -1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
++l_numLinks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l_numLinks;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interpretAddrs(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
|
|
||||||
{
|
|
||||||
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
|
|
||||||
{
|
|
||||||
unsigned int l_nlsize = p_netlinkList->m_size;
|
|
||||||
struct nlmsghdr *l_hdr;
|
|
||||||
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
|
|
||||||
{
|
|
||||||
if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == RTM_NEWADDR)
|
|
||||||
{
|
|
||||||
if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getifaddrs(struct ifaddrs **ifap)
|
|
||||||
{
|
|
||||||
int l_socket;
|
|
||||||
int l_result;
|
|
||||||
int l_numLinks;
|
|
||||||
pid_t l_pid;
|
|
||||||
NetlinkList *l_linkResults;
|
|
||||||
NetlinkList *l_addrResults;
|
|
||||||
|
|
||||||
if(!ifap)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*ifap = NULL;
|
|
||||||
|
|
||||||
l_socket = netlink_socket(&l_pid);
|
|
||||||
if(l_socket < 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_linkResults = getResultList(l_socket, RTM_GETLINK, l_pid);
|
|
||||||
if(!l_linkResults)
|
|
||||||
{
|
|
||||||
close(l_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_addrResults = getResultList(l_socket, RTM_GETADDR, l_pid);
|
|
||||||
if(!l_addrResults)
|
|
||||||
{
|
|
||||||
close(l_socket);
|
|
||||||
freeResultList(l_linkResults);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_result = 0;
|
|
||||||
l_numLinks = interpretLinks(l_socket, l_pid, l_linkResults, ifap);
|
|
||||||
if(l_numLinks == -1 || interpretAddrs(l_socket, l_pid, l_addrResults, ifap, l_numLinks) == -1)
|
|
||||||
{
|
|
||||||
l_result = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
freeResultList(l_linkResults);
|
|
||||||
freeResultList(l_addrResults);
|
|
||||||
close(l_socket);
|
|
||||||
return l_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeifaddrs(struct ifaddrs *ifa)
|
|
||||||
{
|
|
||||||
struct ifaddrs *l_cur;
|
|
||||||
while(ifa)
|
|
||||||
{
|
|
||||||
l_cur = ifa;
|
|
||||||
ifa = ifa->ifa_next;
|
|
||||||
uv__free(l_cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
249
src/unix/async.c
249
src/unix/async.c
@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "atomic-ops.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
#include <stdio.h> /* snprintf() */
|
#include <stdio.h> /* snprintf() */
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -38,8 +38,37 @@
|
|||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if UV__KQUEUE_EVFILT_USER
|
||||||
|
static uv_once_t kqueue_runtime_detection_guard = UV_ONCE_INIT;
|
||||||
|
static int kqueue_evfilt_user_support = 1;
|
||||||
|
|
||||||
|
|
||||||
|
static void uv__kqueue_runtime_detection(void) {
|
||||||
|
int kq;
|
||||||
|
struct kevent ev[2];
|
||||||
|
struct timespec timeout = {0, 0};
|
||||||
|
|
||||||
|
/* Perform the runtime detection to ensure that kqueue with
|
||||||
|
* EVFILT_USER actually works. */
|
||||||
|
kq = kqueue();
|
||||||
|
EV_SET(ev, UV__KQUEUE_EVFILT_USER_IDENT, EVFILT_USER,
|
||||||
|
EV_ADD | EV_CLEAR, 0, 0, 0);
|
||||||
|
EV_SET(ev + 1, UV__KQUEUE_EVFILT_USER_IDENT, EVFILT_USER,
|
||||||
|
0, NOTE_TRIGGER, 0, 0);
|
||||||
|
if (kevent(kq, ev, 2, ev, 1, &timeout) < 1 ||
|
||||||
|
ev[0].filter != EVFILT_USER ||
|
||||||
|
ev[0].ident != UV__KQUEUE_EVFILT_USER_IDENT ||
|
||||||
|
ev[0].flags & EV_ERROR)
|
||||||
|
/* If we wind up here, we can assume that EVFILT_USER is defined but
|
||||||
|
* broken on the current system. */
|
||||||
|
kqueue_evfilt_user_support = 0;
|
||||||
|
uv__close(kq);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void uv__async_send(uv_loop_t* loop);
|
static void uv__async_send(uv_loop_t* loop);
|
||||||
static int uv__async_start(uv_loop_t* loop);
|
static int uv__async_start(uv_loop_t* loop);
|
||||||
|
static void uv__cpu_relax(void);
|
||||||
|
|
||||||
|
|
||||||
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
||||||
@ -52,8 +81,9 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
|||||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC);
|
uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC);
|
||||||
handle->async_cb = async_cb;
|
handle->async_cb = async_cb;
|
||||||
handle->pending = 0;
|
handle->pending = 0;
|
||||||
|
handle->u.fd = 0; /* This will be used as a busy flag. */
|
||||||
|
|
||||||
QUEUE_INSERT_TAIL(&loop->async_handles, &handle->queue);
|
uv__queue_insert_tail(&loop->async_handles, &handle->queue);
|
||||||
uv__handle_start(handle);
|
uv__handle_start(handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -61,46 +91,54 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
|||||||
|
|
||||||
|
|
||||||
int uv_async_send(uv_async_t* handle) {
|
int uv_async_send(uv_async_t* handle) {
|
||||||
|
_Atomic int* pending;
|
||||||
|
_Atomic int* busy;
|
||||||
|
|
||||||
|
pending = (_Atomic int*) &handle->pending;
|
||||||
|
busy = (_Atomic int*) &handle->u.fd;
|
||||||
|
|
||||||
/* Do a cheap read first. */
|
/* Do a cheap read first. */
|
||||||
if (ACCESS_ONCE(int, handle->pending) != 0)
|
if (atomic_load_explicit(pending, memory_order_relaxed) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Tell the other thread we're busy with the handle. */
|
/* Set the loop to busy. */
|
||||||
if (cmpxchgi(&handle->pending, 0, 1) != 0)
|
atomic_fetch_add(busy, 1);
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Wake up the other thread's event loop. */
|
/* Wake up the other thread's event loop. */
|
||||||
uv__async_send(handle->loop);
|
if (atomic_exchange(pending, 1) == 0)
|
||||||
|
uv__async_send(handle->loop);
|
||||||
|
|
||||||
/* Tell the other thread we're done. */
|
/* Set the loop to not-busy. */
|
||||||
if (cmpxchgi(&handle->pending, 1, 2) != 1)
|
atomic_fetch_add(busy, -1);
|
||||||
abort();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Only call this from the event loop thread. */
|
/* Wait for the busy flag to clear before closing.
|
||||||
static int uv__async_spin(uv_async_t* handle) {
|
* Only call this from the event loop thread. */
|
||||||
|
static void uv__async_spin(uv_async_t* handle) {
|
||||||
|
_Atomic int* pending;
|
||||||
|
_Atomic int* busy;
|
||||||
int i;
|
int i;
|
||||||
int rc;
|
|
||||||
|
pending = (_Atomic int*) &handle->pending;
|
||||||
|
busy = (_Atomic int*) &handle->u.fd;
|
||||||
|
|
||||||
|
/* Set the pending flag first, so no new events will be added by other
|
||||||
|
* threads after this function returns. */
|
||||||
|
atomic_store(pending, 1);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* 997 is not completely chosen at random. It's a prime number, acyclical
|
/* 997 is not completely chosen at random. It's a prime number, acyclic by
|
||||||
* by nature, and should therefore hopefully dampen sympathetic resonance.
|
* nature, and should therefore hopefully dampen sympathetic resonance.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 997; i++) {
|
for (i = 0; i < 997; i++) {
|
||||||
/* rc=0 -- handle is not pending.
|
if (atomic_load(busy) == 0)
|
||||||
* rc=1 -- handle is pending, other thread is still working with it.
|
return;
|
||||||
* rc=2 -- handle is pending, other thread is done.
|
|
||||||
*/
|
|
||||||
rc = cmpxchgi(&handle->pending, 2, 0);
|
|
||||||
|
|
||||||
if (rc != 1)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/* Other thread is busy with this handle, spin until it's done. */
|
/* Other thread is busy with this handle, spin until it's done. */
|
||||||
cpu_relax();
|
uv__cpu_relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Yield the CPU. We may have preempted the other thread while it's
|
/* Yield the CPU. We may have preempted the other thread while it's
|
||||||
@ -114,7 +152,7 @@ static int uv__async_spin(uv_async_t* handle) {
|
|||||||
|
|
||||||
void uv__async_close(uv_async_t* handle) {
|
void uv__async_close(uv_async_t* handle) {
|
||||||
uv__async_spin(handle);
|
uv__async_spin(handle);
|
||||||
QUEUE_REMOVE(&handle->queue);
|
uv__queue_remove(&handle->queue);
|
||||||
uv__handle_stop(handle);
|
uv__handle_stop(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,13 +160,18 @@ void uv__async_close(uv_async_t* handle) {
|
|||||||
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
QUEUE queue;
|
struct uv__queue queue;
|
||||||
QUEUE* q;
|
struct uv__queue* q;
|
||||||
uv_async_t* h;
|
uv_async_t* h;
|
||||||
|
_Atomic int *pending;
|
||||||
|
|
||||||
assert(w == &loop->async_io_watcher);
|
assert(w == &loop->async_io_watcher);
|
||||||
|
|
||||||
|
#if UV__KQUEUE_EVFILT_USER
|
||||||
|
for (;!kqueue_evfilt_user_support;) {
|
||||||
|
#else
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
#endif
|
||||||
r = read(w->fd, buf, sizeof(buf));
|
r = read(w->fd, buf, sizeof(buf));
|
||||||
|
|
||||||
if (r == sizeof(buf))
|
if (r == sizeof(buf))
|
||||||
@ -146,16 +189,18 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
QUEUE_MOVE(&loop->async_handles, &queue);
|
uv__queue_move(&loop->async_handles, &queue);
|
||||||
while (!QUEUE_EMPTY(&queue)) {
|
while (!uv__queue_empty(&queue)) {
|
||||||
q = QUEUE_HEAD(&queue);
|
q = uv__queue_head(&queue);
|
||||||
h = QUEUE_DATA(q, uv_async_t, queue);
|
h = uv__queue_data(q, uv_async_t, queue);
|
||||||
|
|
||||||
QUEUE_REMOVE(q);
|
uv__queue_remove(q);
|
||||||
QUEUE_INSERT_TAIL(&loop->async_handles, q);
|
uv__queue_insert_tail(&loop->async_handles, q);
|
||||||
|
|
||||||
if (0 == uv__async_spin(h))
|
/* Atomically fetch and clear pending flag */
|
||||||
continue; /* Not pending. */
|
pending = (_Atomic int*) &h->pending;
|
||||||
|
if (atomic_exchange(pending, 0) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (h->async_cb == NULL)
|
if (h->async_cb == NULL)
|
||||||
continue;
|
continue;
|
||||||
@ -182,6 +227,17 @@ static void uv__async_send(uv_loop_t* loop) {
|
|||||||
len = sizeof(val);
|
len = sizeof(val);
|
||||||
fd = loop->async_io_watcher.fd; /* eventfd */
|
fd = loop->async_io_watcher.fd; /* eventfd */
|
||||||
}
|
}
|
||||||
|
#elif UV__KQUEUE_EVFILT_USER
|
||||||
|
struct kevent ev;
|
||||||
|
|
||||||
|
if (kqueue_evfilt_user_support) {
|
||||||
|
fd = loop->async_io_watcher.fd; /* magic number for EVFILT_USER */
|
||||||
|
EV_SET(&ev, fd, EVFILT_USER, 0, NOTE_TRIGGER, 0, 0);
|
||||||
|
r = kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL);
|
||||||
|
if (r == 0)
|
||||||
|
return;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -202,6 +258,9 @@ static void uv__async_send(uv_loop_t* loop) {
|
|||||||
static int uv__async_start(uv_loop_t* loop) {
|
static int uv__async_start(uv_loop_t* loop) {
|
||||||
int pipefd[2];
|
int pipefd[2];
|
||||||
int err;
|
int err;
|
||||||
|
#if UV__KQUEUE_EVFILT_USER
|
||||||
|
struct kevent ev;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (loop->async_io_watcher.fd != -1)
|
if (loop->async_io_watcher.fd != -1)
|
||||||
return 0;
|
return 0;
|
||||||
@ -213,6 +272,36 @@ static int uv__async_start(uv_loop_t* loop) {
|
|||||||
|
|
||||||
pipefd[0] = err;
|
pipefd[0] = err;
|
||||||
pipefd[1] = -1;
|
pipefd[1] = -1;
|
||||||
|
#elif UV__KQUEUE_EVFILT_USER
|
||||||
|
uv_once(&kqueue_runtime_detection_guard, uv__kqueue_runtime_detection);
|
||||||
|
if (kqueue_evfilt_user_support) {
|
||||||
|
/* In order not to break the generic pattern of I/O polling, a valid
|
||||||
|
* file descriptor is required to take up a room in loop->watchers,
|
||||||
|
* thus we create one for that, but this fd will not be actually used,
|
||||||
|
* it's just a placeholder and magic number which is going to be closed
|
||||||
|
* during the cleanup, as other FDs. */
|
||||||
|
err = uv__open_cloexec("/", O_RDONLY);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
pipefd[0] = err;
|
||||||
|
pipefd[1] = -1;
|
||||||
|
|
||||||
|
/* When using EVFILT_USER event to wake up the kqueue, this event must be
|
||||||
|
* registered beforehand. Otherwise, calling kevent() to issue an
|
||||||
|
* unregistered EVFILT_USER event will get an ENOENT.
|
||||||
|
* Since uv__async_send() may happen before uv__io_poll() with multi-threads,
|
||||||
|
* we can't defer this registration of EVFILT_USER event as we did for other
|
||||||
|
* events, but must perform it right away. */
|
||||||
|
EV_SET(&ev, err, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, 0);
|
||||||
|
err = kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL);
|
||||||
|
if (err < 0)
|
||||||
|
return UV__ERR(errno);
|
||||||
|
} else {
|
||||||
|
err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
|
err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@ -223,24 +312,39 @@ static int uv__async_start(uv_loop_t* loop) {
|
|||||||
uv__io_start(loop, &loop->async_io_watcher, POLLIN);
|
uv__io_start(loop, &loop->async_io_watcher, POLLIN);
|
||||||
loop->async_wfd = pipefd[1];
|
loop->async_wfd = pipefd[1];
|
||||||
|
|
||||||
|
#if UV__KQUEUE_EVFILT_USER
|
||||||
|
/* Prevent the EVFILT_USER event from being added to kqueue redundantly
|
||||||
|
* and mistakenly later in uv__io_poll(). */
|
||||||
|
if (kqueue_evfilt_user_support)
|
||||||
|
loop->async_io_watcher.events = loop->async_io_watcher.pevents;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv__async_fork(uv_loop_t* loop) {
|
|
||||||
if (loop->async_io_watcher.fd == -1) /* never started */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uv__async_stop(loop);
|
|
||||||
|
|
||||||
return uv__async_start(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv__async_stop(uv_loop_t* loop) {
|
void uv__async_stop(uv_loop_t* loop) {
|
||||||
|
struct uv__queue queue;
|
||||||
|
struct uv__queue* q;
|
||||||
|
uv_async_t* h;
|
||||||
|
|
||||||
if (loop->async_io_watcher.fd == -1)
|
if (loop->async_io_watcher.fd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Make sure no other thread is accessing the async handle fd after the loop
|
||||||
|
* cleanup.
|
||||||
|
*/
|
||||||
|
uv__queue_move(&loop->async_handles, &queue);
|
||||||
|
while (!uv__queue_empty(&queue)) {
|
||||||
|
q = uv__queue_head(&queue);
|
||||||
|
h = uv__queue_data(q, uv_async_t, queue);
|
||||||
|
|
||||||
|
uv__queue_remove(q);
|
||||||
|
uv__queue_insert_tail(&loop->async_handles, q);
|
||||||
|
|
||||||
|
uv__async_spin(h);
|
||||||
|
}
|
||||||
|
|
||||||
if (loop->async_wfd != -1) {
|
if (loop->async_wfd != -1) {
|
||||||
if (loop->async_wfd != loop->async_io_watcher.fd)
|
if (loop->async_wfd != loop->async_io_watcher.fd)
|
||||||
uv__close(loop->async_wfd);
|
uv__close(loop->async_wfd);
|
||||||
@ -251,3 +355,58 @@ void uv__async_stop(uv_loop_t* loop) {
|
|||||||
uv__close(loop->async_io_watcher.fd);
|
uv__close(loop->async_io_watcher.fd);
|
||||||
loop->async_io_watcher.fd = -1;
|
loop->async_io_watcher.fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv__async_fork(uv_loop_t* loop) {
|
||||||
|
struct uv__queue queue;
|
||||||
|
struct uv__queue* q;
|
||||||
|
uv_async_t* h;
|
||||||
|
|
||||||
|
if (loop->async_io_watcher.fd == -1) /* never started */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uv__queue_move(&loop->async_handles, &queue);
|
||||||
|
while (!uv__queue_empty(&queue)) {
|
||||||
|
q = uv__queue_head(&queue);
|
||||||
|
h = uv__queue_data(q, uv_async_t, queue);
|
||||||
|
|
||||||
|
uv__queue_remove(q);
|
||||||
|
uv__queue_insert_tail(&loop->async_handles, q);
|
||||||
|
|
||||||
|
/* The state of any thread that set pending is now likely corrupt in this
|
||||||
|
* child because the user called fork, so just clear these flags and move
|
||||||
|
* on. Calling most libc functions after `fork` is declared to be undefined
|
||||||
|
* behavior anyways, unless async-signal-safe, for multithreaded programs
|
||||||
|
* like libuv, and nothing interesting in pthreads is async-signal-safe.
|
||||||
|
*/
|
||||||
|
h->pending = 0;
|
||||||
|
/* This is the busy flag, and we just abruptly lost all other threads. */
|
||||||
|
h->u.fd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recreate these, since they still exist, but belong to the wrong pid now. */
|
||||||
|
if (loop->async_wfd != -1) {
|
||||||
|
if (loop->async_wfd != loop->async_io_watcher.fd)
|
||||||
|
uv__close(loop->async_wfd);
|
||||||
|
loop->async_wfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv__io_stop(loop, &loop->async_io_watcher, POLLIN);
|
||||||
|
uv__close(loop->async_io_watcher.fd);
|
||||||
|
loop->async_io_watcher.fd = -1;
|
||||||
|
|
||||||
|
return uv__async_start(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void uv__cpu_relax(void) {
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
__asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */
|
||||||
|
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
|
||||||
|
__asm__ __volatile__ ("yield" ::: "memory");
|
||||||
|
#elif (defined(__ppc__) || defined(__ppc64__)) && defined(__APPLE__)
|
||||||
|
__asm volatile ("" : : : "memory");
|
||||||
|
#elif !defined(__APPLE__) && (defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__))
|
||||||
|
__asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@ -1,63 +0,0 @@
|
|||||||
/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UV_ATOMIC_OPS_H_
|
|
||||||
#define UV_ATOMIC_OPS_H_
|
|
||||||
|
|
||||||
#include "internal.h" /* UV_UNUSED */
|
|
||||||
|
|
||||||
#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
|
||||||
#include <atomic.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval));
|
|
||||||
UV_UNUSED(static void cpu_relax(void));
|
|
||||||
|
|
||||||
/* Prefer hand-rolled assembly over the gcc builtins because the latter also
|
|
||||||
* issue full memory barriers.
|
|
||||||
*/
|
|
||||||
UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
int out;
|
|
||||||
__asm__ __volatile__ ("lock; cmpxchg %2, %1;"
|
|
||||||
: "=a" (out), "+m" (*(volatile int*) ptr)
|
|
||||||
: "r" (newval), "0" (oldval)
|
|
||||||
: "memory");
|
|
||||||
return out;
|
|
||||||
#elif defined(__MVS__)
|
|
||||||
unsigned int op4;
|
|
||||||
if (__plo_CSST(ptr, (unsigned int*) &oldval, newval,
|
|
||||||
(unsigned int*) ptr, *ptr, &op4))
|
|
||||||
return oldval;
|
|
||||||
else
|
|
||||||
return op4;
|
|
||||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
|
||||||
return atomic_cas_uint((uint_t *)ptr, (uint_t)oldval, (uint_t)newval);
|
|
||||||
#else
|
|
||||||
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
UV_UNUSED(static void cpu_relax(void)) {
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
__asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */
|
|
||||||
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
|
|
||||||
__asm__ __volatile__ ("yield" ::: "memory");
|
|
||||||
#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)
|
|
||||||
__asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* UV_ATOMIC_OPS_H_ */
|
|
||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#if !defined(__CYGWIN__) && !defined(__MSYS__)
|
#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__GNU__)
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
|
|||||||
return 1;
|
return 1;
|
||||||
if (ent->ifa_addr == NULL)
|
if (ent->ifa_addr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
#if !defined(__CYGWIN__) && !defined(__MSYS__)
|
#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__GNU__)
|
||||||
/*
|
/*
|
||||||
* If `exclude_type` is `UV__EXCLUDE_IFPHYS`, return whether `sa_family`
|
* If `exclude_type` is `UV__EXCLUDE_IFPHYS`, return whether `sa_family`
|
||||||
* equals `AF_LINK`. Otherwise, the result depends on the operating
|
* equals `AF_LINK`. Otherwise, the result depends on the operating
|
||||||
@ -65,13 +65,13 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO(bnoordhuis) share with linux.c */
|
||||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||||
|
uv_interface_address_t* address;
|
||||||
struct ifaddrs* addrs;
|
struct ifaddrs* addrs;
|
||||||
struct ifaddrs* ent;
|
struct ifaddrs* ent;
|
||||||
uv_interface_address_t* address;
|
size_t namelen;
|
||||||
#if !(defined(__CYGWIN__) || defined(__MSYS__))
|
char* name;
|
||||||
int i;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
*addresses = NULL;
|
*addresses = NULL;
|
||||||
@ -80,9 +80,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
return UV__ERR(errno);
|
return UV__ERR(errno);
|
||||||
|
|
||||||
/* Count the number of interfaces */
|
/* Count the number of interfaces */
|
||||||
|
namelen = 0;
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||||
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
|
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
|
||||||
continue;
|
continue;
|
||||||
|
namelen += strlen(ent->ifa_name) + 1;
|
||||||
(*count)++;
|
(*count)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,20 +94,22 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the memory is initiallized to zero using calloc() */
|
/* Make sure the memory is initiallized to zero using calloc() */
|
||||||
*addresses = uv__calloc(*count, sizeof(**addresses));
|
*addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen);
|
||||||
|
|
||||||
if (*addresses == NULL) {
|
if (*addresses == NULL) {
|
||||||
freeifaddrs(addrs);
|
freeifaddrs(addrs);
|
||||||
return UV_ENOMEM;
|
return UV_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = (char*) &(*addresses)[*count];
|
||||||
address = *addresses;
|
address = *addresses;
|
||||||
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||||
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
|
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
address->name = uv__strdup(ent->ifa_name);
|
namelen = strlen(ent->ifa_name) + 1;
|
||||||
|
address->name = memcpy(name, ent->ifa_name, namelen);
|
||||||
|
name += namelen;
|
||||||
|
|
||||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
if (ent->ifa_addr->sa_family == AF_INET6) {
|
||||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
||||||
@ -126,9 +130,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
address++;
|
address++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !(defined(__CYGWIN__) || defined(__MSYS__))
|
#if !(defined(__CYGWIN__) || defined(__MSYS__)) && !defined(__GNU__)
|
||||||
/* Fill in physical addresses for each interface */
|
/* Fill in physical addresses for each interface */
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||||
|
int i;
|
||||||
|
|
||||||
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
|
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -151,13 +157,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO(bnoordhuis) share with linux.c */
|
||||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||||
int count) {
|
int count) {
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
uv__free(addresses[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__free(addresses);
|
uv__free(addresses);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ static void init_process_title_mutex_once(void) {
|
|||||||
|
|
||||||
|
|
||||||
void uv__process_title_cleanup(void) {
|
void uv__process_title_cleanup(void) {
|
||||||
|
uv_once(&process_title_mutex_once, init_process_title_mutex_once);
|
||||||
uv_mutex_destroy(&process_title_mutex);
|
uv_mutex_destroy(&process_title_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
801
src/unix/core.c
801
src/unix/core.c
File diff suppressed because it is too large
Load Diff
@ -36,9 +36,45 @@ int uv_uptime(double* uptime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int uv_resident_set_memory(size_t* rss) {
|
int uv_resident_set_memory(size_t* rss) {
|
||||||
/* FIXME: read /proc/meminfo? */
|
char buf[1024];
|
||||||
*rss = 0;
|
const char* s;
|
||||||
|
long val;
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
struct sysinfo si;
|
||||||
|
|
||||||
|
/* rss: 24th element */
|
||||||
|
rc = uv__slurp("/proc/self/stat", buf, sizeof(buf));
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* find the last ')' */
|
||||||
|
s = strrchr(buf, ')');
|
||||||
|
if (s == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
for (i = 1; i <= 22; i++) {
|
||||||
|
s = strchr(s + 1, ' ');
|
||||||
|
if (s == NULL)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
val = strtol(s, NULL, 10);
|
||||||
|
if (val < 0 || errno != 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
do
|
||||||
|
rc = sysinfo(&si);
|
||||||
|
while (rc == -1 && errno == EINTR);
|
||||||
|
if (rc == -1)
|
||||||
|
return UV__ERR(errno);
|
||||||
|
|
||||||
|
*rss = val * si.mem_unit;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||||
@ -51,3 +87,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|||||||
uint64_t uv_get_constrained_memory(void) {
|
uint64_t uv_get_constrained_memory(void) {
|
||||||
return 0; /* Memory constraints are unknown. */
|
return 0; /* Memory constraints are unknown. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t uv_get_available_memory(void) {
|
||||||
|
return uv_get_free_memory();
|
||||||
|
}
|
||||||
|
|||||||
@ -33,25 +33,9 @@
|
|||||||
#include "darwin-stub.h"
|
#include "darwin-stub.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int uv__pthread_setname_np(const char* name) {
|
|
||||||
char namebuf[64]; /* MAXTHREADNAMESIZE */
|
|
||||||
int err;
|
|
||||||
|
|
||||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
|
||||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
|
||||||
|
|
||||||
err = pthread_setname_np(namebuf);
|
|
||||||
if (err)
|
|
||||||
return UV__ERR(err);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv__set_process_title(const char* title) {
|
int uv__set_process_title(const char* title) {
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
return uv__pthread_setname_np(title);
|
return uv__thread_setname(title);
|
||||||
#else
|
#else
|
||||||
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
||||||
const char*,
|
const char*,
|
||||||
@ -177,7 +161,7 @@ int uv__set_process_title(const char* title) {
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv__pthread_setname_np(title); /* Don't care if it fails. */
|
uv__thread_setname(title); /* Don't care if it fails. */
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|||||||
@ -27,7 +27,6 @@
|
|||||||
struct CFArrayCallBacks;
|
struct CFArrayCallBacks;
|
||||||
struct CFRunLoopSourceContext;
|
struct CFRunLoopSourceContext;
|
||||||
struct FSEventStreamContext;
|
struct FSEventStreamContext;
|
||||||
struct CFRange;
|
|
||||||
|
|
||||||
typedef double CFAbsoluteTime;
|
typedef double CFAbsoluteTime;
|
||||||
typedef double CFTimeInterval;
|
typedef double CFTimeInterval;
|
||||||
@ -43,23 +42,13 @@ typedef unsigned CFStringEncoding;
|
|||||||
typedef void* CFAllocatorRef;
|
typedef void* CFAllocatorRef;
|
||||||
typedef void* CFArrayRef;
|
typedef void* CFArrayRef;
|
||||||
typedef void* CFBundleRef;
|
typedef void* CFBundleRef;
|
||||||
typedef void* CFDataRef;
|
|
||||||
typedef void* CFDictionaryRef;
|
typedef void* CFDictionaryRef;
|
||||||
typedef void* CFMutableDictionaryRef;
|
|
||||||
typedef struct CFRange CFRange;
|
|
||||||
typedef void* CFRunLoopRef;
|
typedef void* CFRunLoopRef;
|
||||||
typedef void* CFRunLoopSourceRef;
|
typedef void* CFRunLoopSourceRef;
|
||||||
typedef void* CFStringRef;
|
typedef void* CFStringRef;
|
||||||
typedef void* CFTypeRef;
|
typedef void* CFTypeRef;
|
||||||
typedef void* FSEventStreamRef;
|
typedef void* FSEventStreamRef;
|
||||||
|
|
||||||
typedef uint32_t IOOptionBits;
|
|
||||||
typedef unsigned int io_iterator_t;
|
|
||||||
typedef unsigned int io_object_t;
|
|
||||||
typedef unsigned int io_service_t;
|
|
||||||
typedef unsigned int io_registry_entry_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*FSEventStreamCallback)(const FSEventStreamRef,
|
typedef void (*FSEventStreamCallback)(const FSEventStreamRef,
|
||||||
void*,
|
void*,
|
||||||
size_t,
|
size_t,
|
||||||
@ -80,11 +69,6 @@ struct FSEventStreamContext {
|
|||||||
void* pad[3];
|
void* pad[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CFRange {
|
|
||||||
CFIndex location;
|
|
||||||
CFIndex length;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const CFStringEncoding kCFStringEncodingUTF8 = 0x8000100;
|
static const CFStringEncoding kCFStringEncodingUTF8 = 0x8000100;
|
||||||
static const OSStatus noErr = 0;
|
static const OSStatus noErr = 0;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user