Compare commits
655 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e5b47d6da | ||
|
|
bd120c774d | ||
|
|
0a9c5d456b | ||
|
|
e66b691549 | ||
|
|
97e445f78d | ||
|
|
b74eb61949 | ||
|
|
f0193d27f3 | ||
|
|
7b23f50f9d | ||
|
|
78a9dd7bc5 | ||
|
|
3d6fba6802 | ||
|
|
2d0ea1e3bb | ||
|
|
9cebc2993b | ||
|
|
2ce5d61c38 | ||
|
|
a4298bec56 | ||
|
|
ec7b0d5737 | ||
|
|
70feb515c3 | ||
|
|
565f0e3725 | ||
|
|
c0a4ebebff | ||
|
|
c2631cdc8a | ||
|
|
f9628646d1 | ||
|
|
c9f7a32c82 | ||
|
|
04848e0766 | ||
|
|
4c761eeba0 | ||
|
|
7ecbe87047 | ||
|
|
6b71e5bfe5 | ||
|
|
1c317adbda | ||
|
|
9b73fd1730 | ||
|
|
27a8818ea8 | ||
|
|
f84b736022 | ||
|
|
0888992863 | ||
|
|
76dc827e29 | ||
|
|
b06ea01a18 | ||
|
|
a9e048b483 | ||
|
|
5ae6dd3a7c | ||
|
|
abc3417623 | ||
|
|
fcbb159766 | ||
|
|
fccbccbc09 | ||
|
|
60459effaa | ||
|
|
abff9a6954 | ||
|
|
8fde7fb4f3 | ||
|
|
c078a9cef8 | ||
|
|
7a3e52b647 | ||
|
|
3fe84c5ace | ||
|
|
5e9b225a2e | ||
|
|
2f577c136c | ||
|
|
b1918c1e31 | ||
|
|
e1eac6657d | ||
|
|
d73b4eb470 | ||
|
|
82f24149d9 | ||
|
|
32ca04dda8 | ||
|
|
c8a7179ab8 | ||
|
|
a721794da7 | ||
|
|
5bee899f25 | ||
|
|
22db10da16 | ||
|
|
92f5e5775d | ||
|
|
bd3a030da8 | ||
|
|
688e821f3a | ||
|
|
a018720511 | ||
|
|
e7d186eaf8 | ||
|
|
1a8620f03e | ||
|
|
f278ba656b | ||
|
|
d925772857 | ||
|
|
bbfb69ed8d | ||
|
|
012ee68199 | ||
|
|
6225602777 | ||
|
|
79cb473b6a | ||
|
|
02afb98f38 | ||
|
|
6e3e14448a | ||
|
|
b3c1fef110 | ||
|
|
73b09f4976 | ||
|
|
4cd8a41ce5 | ||
|
|
3bb8536494 | ||
|
|
6d678eca60 | ||
|
|
42f0b9be21 | ||
|
|
840669563c | ||
|
|
81fdbdebd9 | ||
|
|
f1bb532307 | ||
|
|
0252dd1905 | ||
|
|
a2339b9219 | ||
|
|
cc04994d12 | ||
|
|
fad25a3b11 | ||
|
|
438863ebd9 | ||
|
|
431e87f95c | ||
|
|
069a40ac46 | ||
|
|
09e2926c7b | ||
|
|
6890166376 | ||
|
|
51f5a2fc99 | ||
|
|
252af56144 | ||
|
|
278a8dac05 | ||
|
|
0b76aa2de1 | ||
|
|
8477dec61f | ||
|
|
8931954d28 | ||
|
|
954ba66027 | ||
|
|
4e1677a38f | ||
|
|
e349b3ab94 | ||
|
|
3f88273d0f | ||
|
|
fa41fcbe40 | ||
|
|
9dd130afb6 | ||
|
|
423709b795 | ||
|
|
fd9fed2262 | ||
|
|
68429f03f2 | ||
|
|
7a9407d7ab | ||
|
|
c8e18c1b4d | ||
|
|
fab9ef6147 | ||
|
|
4352a1df59 | ||
|
|
f399b354e6 | ||
|
|
6d4e284ab1 | ||
|
|
85936ff34c | ||
|
|
ee197893e7 | ||
|
|
64a98452e3 | ||
|
|
4081935904 | ||
|
|
f88cc071fc | ||
|
|
127af22c34 | ||
|
|
7f7e63fee1 | ||
|
|
16bef44e5d | ||
|
|
f2626442b6 | ||
|
|
32c6888e1b | ||
|
|
0d323db997 | ||
|
|
8604d4643a | ||
|
|
1bb4293967 | ||
|
|
eb91f6701c | ||
|
|
079357c242 | ||
|
|
267ed50dc7 | ||
|
|
51c7dea070 | ||
|
|
768c2c02e7 | ||
|
|
47408ed14c | ||
|
|
648bf6a808 | ||
|
|
17da152e22 | ||
|
|
bc1cd15852 | ||
|
|
5a06c118c8 | ||
|
|
ccb5be72dd | ||
|
|
8b2b03482f | ||
|
|
7629cf818a | ||
|
|
bdd495acae | ||
|
|
b0cdaddebc | ||
|
|
9471488796 | ||
|
|
4459ca0ad8 | ||
|
|
67ed5d1f21 | ||
|
|
9d0be21cc1 | ||
|
|
b2c2d9b7d6 | ||
|
|
4497e8d5f4 | ||
|
|
2d3db2036b | ||
|
|
1b7c161f7f | ||
|
|
f40c25723d | ||
|
|
0d33e8a872 | ||
|
|
83d22ce164 | ||
|
|
08bf6a1081 | ||
|
|
862abba4cb | ||
|
|
bd0c759af3 | ||
|
|
15415b5590 | ||
|
|
2aea693faf | ||
|
|
ca8eda8090 | ||
|
|
00bb3d1e67 | ||
|
|
1ad6ff03b3 | ||
|
|
4f1f7dd83b | ||
|
|
8750ff8807 | ||
|
|
28a01eb572 | ||
|
|
dfe6515809 | ||
|
|
76bd45cb45 | ||
|
|
6d3b70251c | ||
|
|
6d38cc1f76 | ||
|
|
77f1fc0504 | ||
|
|
6ebbf0dd8c | ||
|
|
8d33108dd8 | ||
|
|
5798574d62 | ||
|
|
0cb495bdb3 | ||
|
|
69c7f0b065 | ||
|
|
ab94bb46f2 | ||
|
|
7f5fc4356b | ||
|
|
9079c8aa53 | ||
|
|
c85bd908a3 | ||
|
|
5e0bf53fec | ||
|
|
b7e46b8b02 | ||
|
|
cafebf2428 | ||
|
|
547a9b3ebc | ||
|
|
e6a883bc5f | ||
|
|
fdb21252b0 | ||
|
|
130d98463c | ||
|
|
ded1f3572d | ||
|
|
cc656981c0 | ||
|
|
fb3314ea45 | ||
|
|
73a64bc89f | ||
|
|
96b082d3e4 | ||
|
|
aedea0da37 | ||
|
|
b7f8f17227 | ||
|
|
8d5cdc3747 | ||
|
|
f1a59aa64a | ||
|
|
6767f5089f | ||
|
|
59a0fa9364 | ||
|
|
a5fe64a8ad | ||
|
|
fcd0a4c75d | ||
|
|
d05f2e6062 | ||
|
|
e09066cfab | ||
|
|
40838579af | ||
|
|
9f53417a8d | ||
|
|
29490f24c7 | ||
|
|
ab78480d54 | ||
|
|
63d2d8de33 | ||
|
|
68bcc77885 | ||
|
|
b0a330f22a | ||
|
|
01dcbed948 | ||
|
|
edafb56273 | ||
|
|
f354f880cc | ||
|
|
6f41e11804 | ||
|
|
64c45961ff | ||
|
|
b3afbea7cf | ||
|
|
41502f9525 | ||
|
|
716f2679a7 | ||
|
|
b1a8b2f20e | ||
|
|
6fee83900e | ||
|
|
6d11cba513 | ||
|
|
c8946b4fc2 | ||
|
|
633ef60514 | ||
|
|
d86723d62a | ||
|
|
e2461e97ff | ||
|
|
75da9fd454 | ||
|
|
152e8865cc | ||
|
|
69e8c4b48e | ||
|
|
5708855c36 | ||
|
|
4b1fd8cba0 | ||
|
|
163cf7971d | ||
|
|
a2d511b6e9 | ||
|
|
8eed4cdd88 | ||
|
|
ee40ee789c | ||
|
|
c710a3a898 | ||
|
|
2de36d3273 | ||
|
|
c4a1208d6e | ||
|
|
9cb65e5408 | ||
|
|
2a9d05248f | ||
|
|
752549d1c8 | ||
|
|
8fec9d6e00 | ||
|
|
5824f98972 | ||
|
|
9d03275c53 | ||
|
|
b5fe4abfa8 | ||
|
|
95b916ecd4 | ||
|
|
cbfbce54f9 | ||
|
|
b3a1fe9c6b | ||
|
|
83dfc7980d | ||
|
|
69d1063067 | ||
|
|
9b6e270b97 | ||
|
|
fc4119094f | ||
|
|
fd2edfe94c | ||
|
|
01a50b5165 | ||
|
|
658bd0b570 | ||
|
|
a8fd14aae1 | ||
|
|
87a6688c17 | ||
|
|
ae518f6e3e | ||
|
|
3ba5bf943e | ||
|
|
846ef343e3 | ||
|
|
6bdb8f911a | ||
|
|
0bf17be9e3 | ||
|
|
0bcfbd0ffc | ||
|
|
34f0374ca5 | ||
|
|
3755b9eaad | ||
|
|
edf1ad0362 | ||
|
|
bb51281d9c | ||
|
|
fd7a934ce3 | ||
|
|
f14bfaab24 | ||
|
|
a218bfd75c | ||
|
|
3f11fd1665 | ||
|
|
ebc3834661 | ||
|
|
f85c3249ab | ||
|
|
3ff49fc9b2 | ||
|
|
2bf6d88607 | ||
|
|
3c91c17369 | ||
|
|
5b9bee82a5 | ||
|
|
a9d4204d43 | ||
|
|
0c73bb9448 | ||
|
|
c8d9d5e952 | ||
|
|
c838d5d870 | ||
|
|
ddaa6e4eb6 | ||
|
|
60a0c7f181 | ||
|
|
80dd66a58d | ||
|
|
1ae2ab1de6 | ||
|
|
5caaf2d13c | ||
|
|
3ca42fc838 | ||
|
|
ad2bb0725d | ||
|
|
2d4e143987 | ||
|
|
e83bc13a5e | ||
|
|
23e22313f1 | ||
|
|
564a527489 | ||
|
|
8a42190e39 | ||
|
|
f405b444a3 | ||
|
|
a28a561d8a | ||
|
|
8ab1f34df4 | ||
|
|
c91fe7b7d7 | ||
|
|
05367f1b33 | ||
|
|
09b93f10f7 | ||
|
|
659916cb16 | ||
|
|
f3ff337a41 | ||
|
|
77ffc94677 | ||
|
|
ec576dd088 | ||
|
|
fe61d46153 | ||
|
|
1a0ba81d0d | ||
|
|
0e28ff55c6 | ||
|
|
3cf2d9057f | ||
|
|
e374ee4658 | ||
|
|
ba6a32fefb | ||
|
|
aff46bd19a | ||
|
|
39b068cf0a | ||
|
|
41bd895cd5 | ||
|
|
32c2775940 | ||
|
|
5754dc136e | ||
|
|
f8b746287e | ||
|
|
e7416ce144 | ||
|
|
9e1ebf8d0f | ||
|
|
42a3b4fbfd | ||
|
|
511b2e4f5c | ||
|
|
dbe2a890ec | ||
|
|
fc8ad6b9ec | ||
|
|
8857d0bb4e | ||
|
|
c980613bd8 | ||
|
|
80b64d6a30 | ||
|
|
271e1811e3 | ||
|
|
7dd5e217f6 | ||
|
|
ea1ebd0a7c | ||
|
|
722d5eeba7 | ||
|
|
286bfc5215 | ||
|
|
6e01fd9c3d | ||
|
|
2b7781c8d9 | ||
|
|
9170d79ffe | ||
|
|
3019a5fb07 | ||
|
|
2efb1d0373 | ||
|
|
ca9ef80760 | ||
|
|
475296ad49 | ||
|
|
e2e40a4b9f | ||
|
|
f24dafa1e0 | ||
|
|
312fdee91d | ||
|
|
a3b5ced30b | ||
|
|
4b18edc586 | ||
|
|
e63f14bc95 | ||
|
|
b1ece5d8d2 | ||
|
|
894771e789 | ||
|
|
f5b9db9583 | ||
|
|
7b9b2b19d3 | ||
|
|
56cc1a638a | ||
|
|
b6defc6a7f | ||
|
|
4e1a5eefff | ||
|
|
0ba29b2eff | ||
|
|
5ad46f557c | ||
|
|
d90f4d7976 | ||
|
|
5bdd9ddca6 | ||
|
|
7eba398792 | ||
|
|
0dc2746d68 | ||
|
|
1a70f1e347 | ||
|
|
3fd8d4515c | ||
|
|
b24d7c6da6 | ||
|
|
84426ea334 | ||
|
|
52f654a5a3 | ||
|
|
83fa03dd40 | ||
|
|
a591857c30 | ||
|
|
6ad30c92bb | ||
| a3354f5db9 | |||
|
|
0b374ef8a6 | ||
|
|
6ad61aea32 | ||
|
|
e1e389a2dd | ||
|
|
502366fdc3 | ||
|
|
b32127c5de | ||
|
|
3f0e633fd1 | ||
|
|
d35447fa0d | ||
|
|
0c52d41e95 | ||
|
|
dbb8d232ee | ||
|
|
b93601bc22 | ||
|
|
9e37ab649b | ||
|
|
0a2020e2fc | ||
|
|
bfde24907c | ||
|
|
da6228f135 | ||
|
|
3009091875 | ||
|
|
6a0d5e0e87 | ||
|
|
97636a45e0 | ||
|
|
a50c66b6ff | ||
|
|
88ae947c84 | ||
|
|
22540ac743 | ||
|
|
197e992241 | ||
|
|
b0cf5c256a | ||
|
|
76e967c960 | ||
|
|
25f70a1bd7 | ||
|
|
4ac35ab85c | ||
|
|
4209abe2cf | ||
|
|
90d1d9568c | ||
|
|
082df89090 | ||
|
|
78a4e462d5 | ||
|
|
841d66993a | ||
|
|
d24ed309e9 | ||
|
|
7adb9c3881 | ||
|
|
55c89335fd | ||
|
|
aab841e279 | ||
|
|
b38e48642e | ||
|
|
bd82554299 | ||
|
|
1a3e7414b3 | ||
|
|
773eb1b33d | ||
|
|
9ab6f89604 | ||
|
|
0a86ec01fa | ||
|
|
570993e32b | ||
|
|
93be1400c1 | ||
|
|
176ee926ad | ||
|
|
2d52067484 | ||
|
|
4d64941bd2 | ||
|
|
66209118f6 | ||
|
|
f146f9ea6e | ||
|
|
280ff742c5 | ||
|
|
6f67091628 | ||
|
|
d6dab34ae9 | ||
|
|
36d801682b | ||
|
|
4d54b91a3a | ||
|
|
bf3bdec7b3 | ||
|
|
052f0992d2 | ||
|
|
6a6e527fc1 | ||
|
|
3cccdd8134 | ||
|
|
034388f009 | ||
|
|
3d8bf34177 | ||
|
|
4b44881744 | ||
|
|
42f4c3a0a5 | ||
|
|
16c252d8aa | ||
|
|
ed5adebd47 | ||
|
|
da80d11db9 | ||
|
|
91ef05b5dc | ||
|
|
34267b31b7 | ||
|
|
be516ddac0 | ||
|
|
1b51a4796d | ||
|
|
61cc341132 | ||
|
|
38037f0873 | ||
|
|
2ad468dd38 | ||
|
|
2bf4b36639 | ||
|
|
72d65c60a4 | ||
|
|
b58380fc69 | ||
|
|
6814b09fad | ||
|
|
2d3a828acd | ||
|
|
4ae048572a | ||
|
|
ec0f64140a | ||
|
|
e49210a3ea | ||
|
|
c61d0b43bb | ||
|
|
d25eff3af7 | ||
|
|
01041abd32 | ||
|
|
2ecf8803c3 | ||
|
|
01f0fdbf1e | ||
|
|
3219ea0608 | ||
|
|
fb983fe382 | ||
|
|
ffa96d36e1 | ||
|
|
859024d155 | ||
|
|
515f882c7b | ||
|
|
a9a3298d51 | ||
|
|
d3b6d01807 | ||
|
|
8a28858ada | ||
|
|
f2891d72e5 | ||
|
|
75a5f19d2e | ||
|
|
98deef5004 | ||
|
|
cec9bd3aa9 | ||
|
|
c187d8c13a | ||
|
|
c96db4c877 | ||
|
|
1289f99e30 | ||
|
|
ec9568d096 | ||
|
|
a9be8957bc | ||
|
|
4564346722 | ||
|
|
9d9f345278 | ||
|
|
c4d6e2a61e | ||
|
|
2be5e15346 | ||
|
|
ef5d88d3e5 | ||
|
|
93449dccb8 | ||
|
|
863e8fdd3b | ||
|
|
2eb48f43eb | ||
|
|
d36f6aa84f | ||
|
|
ee9c0ba409 | ||
|
|
7f82c2f32e | ||
|
|
7addfc8ddd | ||
|
|
e0bc071de3 | ||
|
|
5e5ea11658 | ||
|
|
de2495d276 | ||
|
|
fedaf622ac | ||
|
|
711e82b1a6 | ||
|
|
deb1fe8c7c | ||
|
|
8db3d7391b | ||
|
|
4780fb2fe5 | ||
|
|
6ee8a39047 | ||
|
|
7ff7c37dc7 | ||
|
|
a4fed4fe1a | ||
|
|
6347b1daf9 | ||
|
|
593e313fab | ||
|
|
34744264e1 | ||
|
|
5ac686fafd | ||
|
|
7e347b2de9 | ||
|
|
8d7a241d04 | ||
|
|
5bc15b72a1 | ||
|
|
880db9d4af | ||
|
|
97c6d1a903 | ||
|
|
04ccf9db0d | ||
|
|
fabc8d06a9 | ||
|
|
f661299a81 | ||
|
|
2c8eb630cb | ||
|
|
fb21c7c6e7 | ||
|
|
738c135ed8 | ||
|
|
58c031238b | ||
|
|
b27439ce7b | ||
|
|
53c5aaa9ee | ||
|
|
880d714a0f | ||
|
|
ddadd9b62e | ||
|
|
c1318e7d55 | ||
|
|
8abb1ed255 | ||
|
|
d6f5b50550 | ||
|
|
f824246baa | ||
|
|
3718cfa673 | ||
|
|
f9a0c82a63 | ||
|
|
90b9965caf | ||
|
|
64a2e4e19b | ||
|
|
a4edc46a5f | ||
|
|
4f9928bc3c | ||
|
|
738b8ca55f | ||
|
|
82560b552e | ||
|
|
3196844602 | ||
|
|
76911e4ae9 | ||
|
|
c29a8bd268 | ||
|
|
d85d1f0e56 | ||
|
|
c5602af1b4 | ||
|
|
c767958539 | ||
|
|
7264146fd1 | ||
|
|
34e24699e6 | ||
|
|
f2c9ddc412 | ||
|
|
8400e74606 | ||
|
|
1b0ff46d33 | ||
|
|
92d52cc415 | ||
|
|
4f6040d35b | ||
|
|
451c4cc854 | ||
|
|
038a1140f4 | ||
|
|
d63dffcd34 | ||
|
|
f5b7693a58 | ||
|
|
3fb529373f | ||
|
|
af2693241f | ||
|
|
89d000be08 | ||
|
|
615fd741b9 | ||
|
|
a0798939b3 | ||
|
|
a5999242b0 | ||
|
|
9e484306d6 | ||
|
|
835199a45d | ||
|
|
0df6f849d6 | ||
|
|
75e32c9086 | ||
|
|
04ff9eb8a1 | ||
|
|
475fc8e122 | ||
|
|
b7018dd16d | ||
|
|
afb182a3cd | ||
|
|
79b499d4c5 | ||
|
|
5a498e26a1 | ||
|
|
85ed3b9f4e | ||
|
|
319ed9b394 | ||
|
|
79bc3f2265 | ||
|
|
3498a6d4e0 | ||
|
|
f90f021309 | ||
|
|
c1203076f2 | ||
|
|
753622315c | ||
|
|
910ab38af6 | ||
|
|
0e990bbe0c | ||
|
|
ef5688f8de | ||
|
|
d622bbad05 | ||
|
|
416cf68fd1 | ||
|
|
cbde3ea9fd | ||
|
|
fc12c72809 | ||
|
|
b64bc41d6b | ||
|
|
080e362743 | ||
|
|
01819b0b02 | ||
|
|
f2716f88f3 | ||
|
|
d741c10635 | ||
|
|
6f9c2db8a8 | ||
|
|
e01a428059 | ||
|
|
77c837bcbe | ||
|
|
02348e770b | ||
|
|
d27747a7f3 | ||
|
|
2e4f6443e0 | ||
|
|
493d6014b9 | ||
|
|
01276d952f | ||
|
|
d69f3904d7 | ||
|
|
7778c0c3ff | ||
|
|
f320cbcecd | ||
|
|
809633d698 | ||
|
|
1f573172b3 | ||
|
|
d6f72900f8 | ||
|
|
5b1d3a7725 | ||
|
|
7d79a83519 | ||
|
|
6fd9fb3066 | ||
|
|
28c7fe12f3 | ||
|
|
36be0aa783 | ||
|
|
694ac0a650 | ||
|
|
5ce291facf | ||
|
|
b86c4107c1 | ||
|
|
e3f59fd5c2 | ||
|
|
b8eec29e43 | ||
|
|
69d8be78d3 | ||
|
|
fc61cc34ce | ||
|
|
3f18327d2d | ||
|
|
a977edfaa6 | ||
|
|
f9135c39cd | ||
|
|
c06f3cd9a0 | ||
|
|
35a2793c23 | ||
|
|
c9da766e9e | ||
|
|
7f21c8eec1 | ||
|
|
e889336458 | ||
|
|
2613c62b40 | ||
|
|
7cac267a4b | ||
|
|
71079ede4b | ||
|
|
ab7d73c537 | ||
|
|
7d37c31cc5 | ||
|
|
26173c1e0d | ||
|
|
9c1b8ba952 | ||
|
|
f0c88c3d3c | ||
|
|
a05f022e44 | ||
|
|
f519b63a6f | ||
|
|
eb908c6ebf | ||
|
|
2f25d7c9c9 | ||
|
|
68bde36d75 | ||
|
|
e94ffd48fa | ||
|
|
d8812cbee3 | ||
|
|
0f7cb737bb | ||
|
|
ea725ad1a2 | ||
|
|
37407c94e0 | ||
|
|
12909bfb1d | ||
|
|
ca441a2a0e | ||
|
|
ecba376d72 | ||
|
|
047bdc9200 | ||
|
|
2485c1fb1c | ||
|
|
a106129c9b | ||
|
|
c574722a9b | ||
|
|
4790578953 | ||
|
|
7e6e38060f | ||
|
|
d2d40b901a | ||
|
|
29a9ad3f90 | ||
|
|
709b6ef2f3 | ||
|
|
29c6d34be4 | ||
|
|
dad89d5bba | ||
|
|
169b30081a | ||
|
|
a19e1d21da | ||
|
|
c48e92b1a8 | ||
|
|
d86db4e6b6 | ||
|
|
56c812f990 | ||
|
|
874cebb63d | ||
|
|
43393096ac | ||
|
|
29a8efa781 | ||
|
|
1ac8ff6378 | ||
|
|
7da070bca3 | ||
|
|
f29e995103 | ||
|
|
786a01b59c | ||
|
|
5c2ef73c4a | ||
|
|
958aa02320 | ||
|
|
0faff0f03e | ||
|
|
93f7caebc4 | ||
|
|
1faae9c3ed | ||
|
|
f0633d0d16 | ||
|
|
eb8bac8afb | ||
|
|
a80ec2e0bf | ||
|
|
05377e5886 | ||
|
|
c93c7b5e36 | ||
|
|
b993e29fad | ||
|
|
685e6b0937 | ||
|
|
b4c7f4542e | ||
|
|
d9013bffe9 | ||
|
|
282d67caef | ||
|
|
c11aec5d76 | ||
|
|
b71aa81a47 |
@@ -6,3 +6,4 @@
|
||||
./include
|
||||
./templates
|
||||
**/O.*
|
||||
./QtC-*
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
# in the file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
#
|
||||
# $Revision-Id$
|
||||
|
||||
#
|
||||
# Common build definitions
|
||||
#
|
||||
@@ -82,8 +83,6 @@ endif
|
||||
-include $(CONFIG)/os/CONFIG_SITE.Common.$(T_A)
|
||||
-include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
endif
|
||||
|
||||
# Include <top>/cfg/CONFIG* definitions from tops defined in RELEASE* files
|
||||
#
|
||||
ifneq ($(CONFIG),$(TOP)/configure)
|
||||
@@ -96,12 +95,12 @@ endif
|
||||
|
||||
# Include $(INSTALL_CFG)/CONFIG* definitions
|
||||
#
|
||||
ifndef T_A
|
||||
TOP_CFG_CONFIGS = $(wildcard $(INSTALL_CFG)/CONFIG*)
|
||||
ifneq ($(TOP_CFG_CONFIGS),)
|
||||
include $(TOP_CFG_CONFIGS)
|
||||
endif
|
||||
endif
|
||||
|
||||
endif # ifdef T_A
|
||||
|
||||
# User specific definitions
|
||||
#
|
||||
@@ -111,3 +110,4 @@ ifdef T_A
|
||||
-include $(HOME)/configure/CONFIG_USER.Common.$(T_A)
|
||||
-include $(HOME)/configure/CONFIG_USER.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
|
||||
@@ -412,17 +412,6 @@ USR_LIBS += $(USR_LIBS_DEFAULT)
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# concat specific include files
|
||||
#
|
||||
ifneq ($(strip $(INC_$(OS_CLASS))),)
|
||||
INC += $(subst -nil-,,$(INC_$(OS_CLASS)))
|
||||
else
|
||||
ifdef INC_DEFAULT
|
||||
INC+=$(INC_DEFAULT)
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# concat specific library contents (if defined) to SYS_PROD_LIBS
|
||||
#
|
||||
|
||||
@@ -62,6 +62,7 @@ DBTORECORDTYPEH = $(PERL) $(TOOLS)/dbdToRecordtypeH.pl
|
||||
DBTOMENUH = $(PERL) $(TOOLS)/dbdToMenuH.pl
|
||||
REGISTERRECORDDEVICEDRIVER = $(PERL) $(TOOLS)/registerRecordDeviceDriver.pl
|
||||
CONVERTRELEASE = $(PERL) $(TOOLS)/convertRelease.pl
|
||||
FULLPATHNAME = $(PERL) $(TOOLS)/fullPathName.pl
|
||||
|
||||
#-------------------------------------------------------
|
||||
# tools for installing libraries and products
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
# EPICS_SITE_VERSION is defined in CONFIG_SITE for sites that want a local
|
||||
# version number to be included in the reported version string.
|
||||
|
||||
BASE_3_14 = YES
|
||||
# In 3.15 we still define BASE_3_14 so "ifdef BASE_3_14" means
|
||||
# 3.14 or later, but "ifeq ($(BASE_3_14),YES)" means 3.14 only.
|
||||
BASE_3_14 = NO
|
||||
BASE_3_15 = YES
|
||||
|
||||
# EPICS_VERSION must be a number >0 and <256
|
||||
@@ -31,7 +33,7 @@ EPICS_MODIFICATION = 0
|
||||
|
||||
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
||||
# Not included if zero
|
||||
EPICS_PATCH_LEVEL = 1
|
||||
EPICS_PATCH_LEVEL = 2
|
||||
|
||||
# This will end in -DEV between official releases
|
||||
#EPICS_DEV_SNAPSHOT=-DEV
|
||||
|
||||
@@ -74,11 +74,13 @@ INSTALL_TEMPLATES = $(INSTALL_LOCATION)/templates
|
||||
INSTALL_DBD = $(INSTALL_LOCATION)/dbd
|
||||
INSTALL_DB = $(INSTALL_LOCATION)/db
|
||||
INSTALL_CONFIG = $(INSTALL_LOCATION)/configure
|
||||
INSTALL_JAVA = $(INSTALL_LOCATION)/javalib
|
||||
|
||||
#Directory for OS independant build created files
|
||||
# Directory for OS independant build created files
|
||||
COMMON_DIR = ../O.Common
|
||||
|
||||
# IOC's absolute path to $(TOP), may be overridden inside the application
|
||||
IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))
|
||||
|
||||
#-------------------------------------------------------
|
||||
# Make echo output - suppress echoing if make's '-s' flag is set
|
||||
NOP = :
|
||||
@@ -163,9 +165,6 @@ TESTPRODNAME = $(addsuffix $(EXE),$(basename $(TESTPROD)))
|
||||
SHRLIBNAME = $(SHRLIBNAME_$(SHARED_LIBRARIES))
|
||||
TESTSHRLIBNAME = $(TESTSHRLIBNAME_$(SHARED_LIBRARIES))
|
||||
|
||||
JAVA =
|
||||
JAR =
|
||||
|
||||
#--------------------------------------------------
|
||||
# obj files
|
||||
|
||||
@@ -344,9 +343,11 @@ HDEPENDS.c = $(HDEPENDS_$(HDEPENDS_METHOD).c)
|
||||
HDEPENDS.cpp = $(HDEPENDS_$(HDEPENDS_METHOD).cpp)
|
||||
|
||||
#--------------------------------------------------
|
||||
# depends definition
|
||||
# Dependency files
|
||||
|
||||
TARGET_SRCS = $(foreach name, $(TESTPROD) $(PROD) $(TESTLIBRARY) $(LIBRARY) $(LOADABLE_LIBRARY), $($(name)_SRCS))
|
||||
TARGET_SRCS = $(foreach name, \
|
||||
$(TESTPROD) $(PROD) $(TESTLIBRARY) $(LIBRARY) $(LOADABLE_LIBRARY), \
|
||||
$($(name)_SRCS))
|
||||
SRC_FILES = $(LIB_SRCS) $(LIBSRCS) $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(TARGET_SRCS)
|
||||
HDEPENDS_FILES = $(addsuffix $(DEP),$(notdir $(basename $(SRC_FILES))))
|
||||
|
||||
@@ -381,6 +382,7 @@ INSTALL_LIB_INSTALLS = $(addprefix $(INSTALL_LIB)/,$(notdir $(LIB_INSTALLS)))
|
||||
# Installed file permissions
|
||||
BIN_PERMISSIONS = 555
|
||||
LIB_PERMISSIONS = 444
|
||||
SHRLIB_PERMISSIONS = 555
|
||||
INSTALL_PERMISSIONS = 444
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in the file LICENSE that is included with this distribution.
|
||||
# in the file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
# $Revision-Id$
|
||||
#
|
||||
@@ -12,7 +12,7 @@
|
||||
#
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Module developers can now define a new type of file, e.g. ABC,
|
||||
# Module developers can now define a new type of file, e.g. ABC,
|
||||
# so that files of type ABC will be installed into a directory
|
||||
# defined by INSTALL_ABC. This is done by creating a new CONFIG<name>
|
||||
# file, e.g. CONFIG_ABC, with the following lines:
|
||||
@@ -24,8 +24,14 @@
|
||||
# $(INSTALL_LOCATION). The file type ABC should be target
|
||||
# architecture independent (alh files, medm files, edm files).
|
||||
#
|
||||
# Optional rules necessary for files of type ABC should be put in
|
||||
# a RULES_ABC file.
|
||||
# Files of type ABC are then installed into the INSTALL_ABC
|
||||
# directory by adding a line like the following to a Makefile.
|
||||
#
|
||||
# ABC += <filename1> <filename2> <filename3>
|
||||
#
|
||||
# Rules necessary to create files of type ABC should be put in
|
||||
# a RULES_ABC file. Variables used by those rules should appear
|
||||
# in a CONFIG_ABC file.
|
||||
#
|
||||
# The module developer installs new CONFIG* or RULES* files
|
||||
# into the directory $(INSTALL_LOCATION)/cfg by including the
|
||||
@@ -33,16 +39,11 @@
|
||||
#
|
||||
# CFG += CONFIG_ABC RULES_ABC
|
||||
#
|
||||
# Files of type ABC are installed into INSTALL_ABC directory
|
||||
# by adding a line like the following to a Makefile.
|
||||
#
|
||||
# ABC += <filename1> <filename2> <filename3>
|
||||
#
|
||||
# Files in $(INSTALL_LOCATION)/cfg directory are now included by
|
||||
# the base config files so the definitions and rules are available
|
||||
# for use by later src directory Makefiles in the same module or
|
||||
# by other modules with a RELEASE line pointing to the TOP of
|
||||
# the module with RULES_ABC.
|
||||
# CONFIG and RULES files in the $(INSTALL_LOCATION)/cfg directory
|
||||
# are included by the Base config files so their definitions and
|
||||
# rules are available for use by later src directory Makefiles in
|
||||
# the same module, or by other modules with a RELEASE line that
|
||||
# points to the TOP of the module providing these files.
|
||||
|
||||
FILE_TYPE += ADL
|
||||
INSTALL_ADL = $(INSTALL_LOCATION)/adl
|
||||
@@ -59,6 +60,9 @@ INSTALL_EDL = $(INSTALL_LOCATION)/edl
|
||||
FILE_TYPE += PERL_MODULES
|
||||
INSTALL_PERL_MODULES = $(INSTALL_LOCATION_LIB)/perl
|
||||
|
||||
INSTALLS_CFG= $(CFG:%= $(INSTALL_CFG)/%)
|
||||
FILE_TYPE += PKGCONFIG
|
||||
INSTALL_PKGCONFIG = $(INSTALL_LOCATION_LIB)/pkgconfig
|
||||
|
||||
INSTALLS_CFG = $(CFG:%= $(INSTALL_CFG)/%)
|
||||
DIRECTORY_TARGETS += $(foreach type, $(FILE_TYPE),$(INSTALL_$(type)))
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#
|
||||
# Currently Supporting:
|
||||
# cygwin-x86 (cygwin compiler used for host builds)
|
||||
# cygwin-x86_64 (cygwin compiler used for host builds)
|
||||
# darwin-ppc (PowerPC based Apple running OSX)
|
||||
# darwin-ppcx86 (Universal binaries for both CPUs)
|
||||
# darwin-x86 (Intel based Apple running OSX)
|
||||
@@ -37,6 +38,7 @@
|
||||
# win32-x86 (MS Visual C++ compiler used for host builds)
|
||||
# win32-x86-mingw (MinGW compiler used for host builds)
|
||||
# windows-x64 (MS Visual C++ compiler used for host builds)
|
||||
# windows-x64-mingw (MinGW compiler used for host builds)
|
||||
|
||||
# Debugging builds:
|
||||
# linux-x86-debug (GNU compiler with -g option for host builds)
|
||||
@@ -68,6 +70,7 @@
|
||||
# linux-cris (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-cris_v10 (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-cris_v32 (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-microblaze
|
||||
# linux-xscale_be
|
||||
# vxWorks-486
|
||||
# vxWorks-68040
|
||||
|
||||
@@ -8,16 +8,21 @@
|
||||
#*************************************************************************
|
||||
#RULES.Db
|
||||
|
||||
# Set db substitutions file suffix
|
||||
SUBST_SUFFIX ?= .substitutions
|
||||
|
||||
##################################################### vpath
|
||||
|
||||
vpath %.dbd $(USR_VPATH) $(GENERIC_SRC_DIRS) $(dir $(DBD))
|
||||
vpath %.db $(USR_VPATH) $(GENERIC_SRC_DIRS) $(dir $(DB))
|
||||
vpath %.vdb $(USR_VPATH) $(GENERIC_SRC_DIRS) $(dir $(DB))
|
||||
vpath %.substitutions $(USR_VPATH) $(GENERIC_SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.template $(USR_VPATH) $(GENERIC_SRC_DIRS) $(COMMON_DIR)
|
||||
vpath bpt%.data $(USR_VPATH) $(GENERIC_SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.acf $(USR_VPATH) $(GENERIC_SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.acs $(USR_VPATH) $(GENERIC_SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.pm $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD))
|
||||
vpath %.pod $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD))
|
||||
vpath %.dbd $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD))
|
||||
vpath %.db $(USR_VPATH) $(SRC_DIRS) $(dir $(DB))
|
||||
vpath %.vdb $(USR_VPATH) $(SRC_DIRS) $(dir $(DB))
|
||||
vpath %$(SUBST_SUFFIX) $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.template $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR)
|
||||
vpath bpt%.data $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.acf $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.acs $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR)
|
||||
|
||||
##################################################### dbflags dbdflags
|
||||
|
||||
@@ -26,6 +31,7 @@ DB_SEARCH_DIRS = . .. $(COMMON_DIR) $(SRC_DIRS) $(INSTALL_DB) $(RELEASE_DB_DIRS)
|
||||
|
||||
DBDFLAGS = $(USR_DBDFLAGS) $(addprefix -I,$(DBD_SEARCH_DIRS))
|
||||
DBFLAGS = $($*_DBFLAGS) $(USR_DBFLAGS) $(addprefix -I,$(DB_SEARCH_DIRS))
|
||||
REGRDDFLAGS = $(DBDFLAGS) $($*_REGRDDFLAGS) $(USR_REGRDDFLAGS)
|
||||
|
||||
##################################################### Targets
|
||||
|
||||
@@ -42,6 +48,21 @@ DBD += $(foreach type, $(CROSS_TARGET_OS_TYPES), $(DBD_$(type)))
|
||||
# DBD_RTEMS += abcRTEMS.dbd
|
||||
# DBD_solaris += abcSolaris.dbd
|
||||
#
|
||||
# ---------------------------------------------------
|
||||
# DBD concatination files
|
||||
|
||||
COMMON_DBDCATS += $(addprefix $(COMMON_DIR)/,$(DBDCAT))
|
||||
DBDCAT_SOURCES += $(foreach file, $($*_DBD), $(DBDCAT_SOURCE) )
|
||||
DBDCAT_SOURCE = $(firstword $(wildcard $(file) $(foreach dir, \
|
||||
$(DBD_SEARCH_DIRS),$(addsuffix /$(file),$(dir)))) \
|
||||
$(COMMON_DIR)/$(file))
|
||||
|
||||
DBDCAT_COMMAND = $(if $(DBDCAT_SOURCES),\
|
||||
$(CAT) $(DBDCAT_SOURCES) > $(notdir $@),\
|
||||
@echo "No input files for $(notdir $@)")
|
||||
|
||||
INSTALL_DBDS += $(addprefix $(INSTALL_DBD)/,$(DBDCAT))
|
||||
|
||||
# ---------------------------------------------------
|
||||
|
||||
DBDINC_NAME = $(patsubst %.h,%,$(patsubst %.dbd,%,$(DBDINC)))
|
||||
@@ -65,7 +86,7 @@ SOURCE_DB_bbb = $(foreach dir, $(GENERIC_SRC_DIRS), $(SOURCE_DB_aaa) )
|
||||
SOURCE_DB_aaa = $(addsuffix /$(file), $(dir) )
|
||||
|
||||
COMMONS = $(COMMON_DIR)/*.dbd $(COMMON_DIR)/*.db $(COMMON_DIR)/*.h \
|
||||
$(COMMON_DIR)/*.substitutions $(COMMON_DIR)/*.template
|
||||
$(COMMON_DIR)/*$(SUBST_SUFFIX) $(COMMON_DIR)/*.template
|
||||
|
||||
# Remove trailing numbers (to 99) on stem
|
||||
TEMPLATE1=$(patsubst %0,%,$(patsubst %1,%,$(patsubst %2,%,$(patsubst %3,%,$(patsubst %4,%, \
|
||||
@@ -116,6 +137,9 @@ DBDDEPENDS_FILES += $(addsuffix $(DEP),$(HINC) \
|
||||
|
||||
ifndef T_A
|
||||
|
||||
DEP = .d
|
||||
TEMPLATE3+=$(addsuffix .template, $(TEMPLATE2))
|
||||
|
||||
COMMON_DIR = .
|
||||
INSTALL_DBDS =
|
||||
INSTALL_DBS =
|
||||
@@ -128,7 +152,7 @@ ACTIONS += build
|
||||
ACTIONS += install
|
||||
ACTIONS += buildInstall
|
||||
ACTIONS += browse
|
||||
ACTIONS += runtests
|
||||
ACTIONS += runtests tapfiles
|
||||
|
||||
actionArchTargets = $(foreach x, $(ACTIONS),\ $(foreach arch,$(BUILD_ARCHS), $(x)$(DIVIDER)$(arch)))
|
||||
|
||||
@@ -136,6 +160,12 @@ cleanArchTargets = $(foreach arch,$(BUILD_ARCHS), clean$(DIVIDER)$(arch))
|
||||
-include $(TOP)/configure/CONFIG_APP_INCLUDE
|
||||
|
||||
all: install
|
||||
ifeq ($(EPICS_HOST_ARCH),$T_A)
|
||||
host: install
|
||||
else
|
||||
# Do nothing
|
||||
host:
|
||||
endif
|
||||
|
||||
install: buildInstall
|
||||
|
||||
@@ -143,10 +173,10 @@ buildInstall : build
|
||||
|
||||
rebuild: clean install
|
||||
|
||||
.PHONY: all inc build install clean rebuild buildInstall
|
||||
.PHONY: all host $(ACTIONS)
|
||||
|
||||
$(actionArchTargets) $(BUILD_ARCHS):install
|
||||
$(cleanArchTargets):clean
|
||||
$(actionArchTargets) $(BUILD_ARCHS): install
|
||||
$(cleanArchTargets): clean
|
||||
|
||||
.PHONY: $(BUILD_ARCHS) $(actionArchTargets) $(cleanArchTargets)
|
||||
|
||||
@@ -160,7 +190,7 @@ endif
|
||||
|
||||
inc : $(COMMON_INC) $(INSTALL_INC)
|
||||
|
||||
build : $(COMMON_DBDS) $(COMMON_DBS) \
|
||||
build : $(COMMON_DBDS) $(COMMON_DBS) $(COMMON_DBDCATS) \
|
||||
$(INSTALL_DBDS) $(INSTALL_DBS) \
|
||||
$(DBDDEPENDS_FILES) $(TARGETS) \
|
||||
$(INSTALL_DB_INSTALLS) $(INSTALL_DBD_INSTALLS)
|
||||
@@ -188,6 +218,11 @@ realclean: clean
|
||||
@$(DBTORECORDTYPEH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
%Record.h$(DEP): ../%Record.dbd
|
||||
@$(RM) $@
|
||||
@$(DBTORECORDTYPEH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
menu%.h$(DEP): $(COMMON_DIR)/menu%.dbd
|
||||
@$(RM) $@
|
||||
@$(DBTOMENUH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@@ -198,7 +233,7 @@ menu%.h$(DEP): menu%.dbd
|
||||
@$(DBTOMENUH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
%.dbd$(DEP): $(COMMON_DIR)/%Include.dbd
|
||||
%.dbd$(DEP): %.dbd.pod
|
||||
@$(RM) $@
|
||||
@$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
@@ -208,7 +243,23 @@ menu%.h$(DEP): menu%.dbd
|
||||
@$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
%.db$(RAW)$(DEP): %.substitutions
|
||||
%.dbd$(DEP): ../%Include.dbd
|
||||
@$(RM) $@
|
||||
@$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
%.dbd$(DEP):
|
||||
@$(RM) $@
|
||||
@$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $($*_DBD) > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
%.db$(RAW)$(DEP): %$(SUBST_SUFFIX)
|
||||
@$(RM) $@
|
||||
$(MKMF) -m$@ $(DBFLAGS) $(COMMONDEP_TARGET) $< $(TEMPLATE_FILENAME)
|
||||
@echo "$(COMMONDEP_TARGET): $(TEMPLATE_FILENAME)" >> $@
|
||||
@echo "$@: $(TEMPLATE_FILENAME)" >> $@
|
||||
|
||||
%.db$(RAW)$(DEP): ../%$(SUBST_SUFFIX)
|
||||
@$(RM) $@
|
||||
$(MKMF) -m$@ $(DBFLAGS) $(COMMONDEP_TARGET) $< $(TEMPLATE_FILENAME)
|
||||
@echo "$(COMMONDEP_TARGET): $(TEMPLATE_FILENAME)" >> $@
|
||||
@@ -218,10 +269,18 @@ menu%.h$(DEP): menu%.dbd
|
||||
@$(RM) $@
|
||||
$(MKMF) -m$@ $(DBFLAGS) $(COMMONDEP_TARGET) $<
|
||||
|
||||
%.db$(RAW)$(DEP): ../%.template
|
||||
@$(RM) $@
|
||||
$(MKMF) -m$@ $(DBFLAGS) $(COMMONDEP_TARGET) $<
|
||||
|
||||
%.acf$(DEP): %.acs
|
||||
@$(RM) $@
|
||||
@$(ACFDEPENDS_CMD)
|
||||
|
||||
%.acf$(DEP): ../%.acs
|
||||
@$(RM) $@
|
||||
@$(ACFDEPENDS_CMD)
|
||||
|
||||
##################################################### CapFast filter
|
||||
|
||||
$(COMMON_DIR)/%.edf: ../%.sch $(DEPSCHS)
|
||||
@@ -234,17 +293,21 @@ $(COMMON_DIR)/%.edf: ../%.sch $(DEPSCHS)
|
||||
# WARNING: CREATESUBSTITUTIONS script needs output dir on command line
|
||||
|
||||
ifdef CREATESUBSTITUTIONS
|
||||
$(COMMON_DIR)/%.substitutions:
|
||||
$(COMMON_DIR)/%$(SUBST_SUFFIX):
|
||||
$(ECHO) "Create substitutions"
|
||||
@$(RM) $@
|
||||
$(CREATESUBSTITUTIONS) $@
|
||||
endif
|
||||
|
||||
$(INSTALL_DB)/%.substitutions: %.substitutions
|
||||
$(INSTALL_DB)/%$(SUBST_SUFFIX): %$(SUBST_SUFFIX)
|
||||
$(ECHO) "Installing db file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%.substitutions
|
||||
$(INSTALL_DB)/%$(SUBST_SUFFIX): ../%$(SUBST_SUFFIX)
|
||||
$(ECHO) "Installing db file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%$(SUBST_SUFFIX)
|
||||
|
||||
##################################################### Template files
|
||||
|
||||
@@ -258,6 +321,10 @@ $(INSTALL_DB)/%.template: %.template
|
||||
$(ECHO) "Installing db file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_DB)/%.template: ../%.template
|
||||
$(ECHO) "Installing db file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%.template
|
||||
|
||||
##################################################### INC files
|
||||
@@ -272,6 +339,11 @@ $(COMMON_DIR)/%Record.h: %Record.dbd
|
||||
$(DBTORECORDTYPEH) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%Record.h: ../%Record.dbd
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBTORECORDTYPEH) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/menu%.h: $(COMMON_DIR)/menu%.dbd
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBTOMENUH) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@@ -282,30 +354,53 @@ $(COMMON_DIR)/menu%.h: menu%.dbd
|
||||
$(DBTOMENUH) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/menu%.h: ../menu%.dbd
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBTOMENUH) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%.h
|
||||
|
||||
##################################################### DBD files
|
||||
|
||||
$(COMMON_DIR)/bpt%.dbd: bpt%.data
|
||||
$(COMMON_DIR)/bpt%.dbd: bpt%.data
|
||||
@$(RM) $(notdir $@)
|
||||
$(MAKEBPT) $< $(notdir $@)
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.dbd: $(COMMON_DIR)/%Include.dbd
|
||||
$(ECHO) "Expanding created dbd file $(notdir $<)"
|
||||
$(COMMON_DIR)/%.dbd: %.dbd.pod
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.dbd: %Include.dbd
|
||||
$(COMMON_DIR)/%.dbd: %Include.dbd
|
||||
$(ECHO) "Expanding dbd file $<"
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%Include.dbd:
|
||||
$(COMMON_DIR)/%.dbd: ../%Include.dbd
|
||||
$(ECHO) "Expanding dbd file $<"
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/makeIncludeDbd.pl $($*_DBD) $(notdir $@)
|
||||
$(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
# Make DBDCAT file x depend on x_DBD source files
|
||||
define DBDCAT_template
|
||||
$$(COMMON_DIR)/$(1).dbd : ../Makefile $$(foreach file, $$($(1)_DBD),$$(DBDCAT_SOURCE) )
|
||||
endef
|
||||
$(foreach name,$(subst .dbd,,$(DBDCAT)), $(eval $(call DBDCAT_template,$(name))))
|
||||
|
||||
$(COMMON_DBDCATS):$(COMMON_DIR)/%.dbd:
|
||||
$(ECHO) "Creating dbd file $(notdir $@)"
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBDCAT_COMMAND)
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.dbd:
|
||||
$(ECHO) "Creating dbd file $(notdir $@)"
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $($*_DBD)
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(INSTALL_DBD)/%: $(COMMON_DIR)/%
|
||||
@@ -316,6 +411,10 @@ $(INSTALL_DBD)/%: %
|
||||
$(ECHO) "Installing dbd file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_DBD)/%: ../%
|
||||
$(ECHO) "Installing dbd file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
define DBD_INSTALLS_template
|
||||
$$(INSTALL_DBD)/$$(notdir $(1)) : $(1)
|
||||
$(ECHO) "Installing $$@"
|
||||
@@ -325,6 +424,30 @@ $(foreach file, $(DBD_INSTALLS), $(eval $(call DBD_INSTALLS_template, $(file))))
|
||||
|
||||
.PRECIOUS: $(COMMON_DBDS) $(COMMON_DIR)/%Include.dbd
|
||||
|
||||
##################################################### HTML files
|
||||
|
||||
$(COMMON_DIR)/%.html: %.dbd.pod $(TOOLS)/dbdToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/dbdToHtml.pl $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.html: %.pod $(TOOLS)/podToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.html: %.pm $(TOOLS)/podToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.html: ../%.pm $(TOOLS)/podToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%.html %.html
|
||||
|
||||
##################################################### DB files
|
||||
|
||||
$(COMMON_DIR)/%.db$(RAW): $(COMMON_DIR)/%.edf
|
||||
@@ -332,7 +455,13 @@ $(COMMON_DIR)/%.db$(RAW): $(COMMON_DIR)/%.edf
|
||||
@$(REPLACEVAR) < $*.VAR > $@
|
||||
@$(RM) $*.VAR
|
||||
|
||||
$(COMMON_DIR)/%.db$(RAW): %.substitutions
|
||||
$(COMMON_DIR)/%.db$(RAW): %$(SUBST_SUFFIX)
|
||||
$(ECHO) "Inflating database from $< $(TEMPLATE_FILENAME)"
|
||||
@$(RM) $@ $*.tmp
|
||||
$(MSI) $(DBFLAGS) -S$< $(TEMPLATE_FILENAME) > $*.tmp
|
||||
$(MV) $*.tmp $@
|
||||
|
||||
$(COMMON_DIR)/%.db$(RAW): ../%$(SUBST_SUFFIX)
|
||||
$(ECHO) "Inflating database from $< $(TEMPLATE_FILENAME)"
|
||||
@$(RM) $@ $*.tmp
|
||||
$(MSI) $(DBFLAGS) -S$< $(TEMPLATE_FILENAME) > $*.tmp
|
||||
@@ -344,11 +473,22 @@ $(COMMON_DIR)/%.db$(RAW): %.template
|
||||
$(MSI) $(DBFLAGS) $< > $*.tmp
|
||||
$(MV) $*.tmp $@
|
||||
|
||||
$(COMMON_DIR)/%.db$(RAW): ../%.template
|
||||
$(ECHO) "Inflating database from $<"
|
||||
@$(RM) $@ $*.tmp
|
||||
$(MSI) $(DBFLAGS) $< > $*.tmp
|
||||
$(MV) $*.tmp $@
|
||||
|
||||
$(COMMON_DIR)/%.acf: %.acs
|
||||
$(ECHO) "Creating acf file $@"
|
||||
@$(RM) $@
|
||||
$(ACF_CMD)
|
||||
|
||||
$(COMMON_DIR)/%.acf: ../%.acs
|
||||
$(ECHO) "Creating acf file $@"
|
||||
@$(RM) $@
|
||||
$(ACF_CMD)
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%.acf
|
||||
|
||||
# dbst based database optimization
|
||||
@@ -370,6 +510,10 @@ else
|
||||
$(INSTALL_DB)/%: %
|
||||
$(ECHO) "Installing db file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_DB)/%: ../%
|
||||
$(ECHO) "Installing db file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
endif
|
||||
|
||||
$(INSTALL_DB)/%.db: $(COMMON_DIR)/%.db
|
||||
@@ -388,18 +532,18 @@ $(foreach file, $(DB_INSTALLS), $(eval $(call DB_INSTALLS_template, $(file))))
|
||||
|
||||
##################################################### register record,device,driver support
|
||||
|
||||
IOC_INST_TOP := $(firstword $(IOCS_APPL_TOP) \
|
||||
$(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION) ) )
|
||||
|
||||
%_registerRecordDeviceDriver.cpp: $(COMMON_DIR)/%.dbd
|
||||
@$(RM) $@ $*.tmp
|
||||
$(REGISTERRECORDDEVICEDRIVER) $(DBDFLAGS) $< $(basename $@) $(IOC_INST_TOP) > $*.tmp
|
||||
$(MV) $*.tmp $@
|
||||
%_registerRecordDeviceDriver.cpp: $(COMMON_DIR)/%.dbd
|
||||
@$(RM) $@
|
||||
$(REGISTERRECORDDEVICEDRIVER) $(REGRDDFLAGS) -o $@ $< $(basename $@) $(IOCS_APPL_TOP)
|
||||
|
||||
%_registerRecordDeviceDriver.cpp: %.dbd
|
||||
@$(RM) $@ $*.tmp
|
||||
$(REGISTERRECORDDEVICEDRIVER) $(DBDFLAGS) $< $(basename $@) $(IOC_INST_TOP) > $*.tmp
|
||||
$(MV) $*.tmp $@
|
||||
%_registerRecordDeviceDriver.cpp: %.dbd
|
||||
@$(RM) $@
|
||||
$(REGISTERRECORDDEVICEDRIVER) $(REGRDDFLAGS) -o $@ $< $(basename $@) $(IOCS_APPL_TOP)
|
||||
|
||||
%_registerRecordDeviceDriver.cpp: ../%.dbd
|
||||
@$(RM) $@
|
||||
$(REGISTERRECORDDEVICEDRIVER) $(REGRDDFLAGS) -o $@ $< $(basename $@) $(IOCS_APPL_TOP)
|
||||
|
||||
.PRECIOUS: %_registerRecordDeviceDriver.cpp
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
#RULES.ioc
|
||||
|
||||
include $(CONFIG)/RULES_DIRS
|
||||
|
||||
build$(DIVIDER)$(ARCH) build: buildInstall
|
||||
@@ -15,23 +15,18 @@ install$(DIVIDER)$(ARCH) install: buildInstall
|
||||
$(ARCH): buildInstall
|
||||
|
||||
ifeq ($(filter $(ARCH),$(BUILD_ARCHS)),$(ARCH))
|
||||
buildInstall$(DIVIDER)$(ARCH) buildInstall: $(TARGETS)
|
||||
buildInstall$(DIVIDER)$(ARCH) buildInstall: $(TARGETS)
|
||||
|
||||
clean$(DIVIDER)$(ARCH) clean:
|
||||
clean$(DIVIDER)$(ARCH) clean:
|
||||
$(RM) cdCommands envPaths dllPath.bat
|
||||
|
||||
else
|
||||
buildInstall$(DIVIDER)$(ARCH) buildInstall:
|
||||
clean$(DIVIDER)$(ARCH) clean:
|
||||
else
|
||||
buildInstall$(DIVIDER)$(ARCH) buildInstall:
|
||||
clean$(DIVIDER)$(ARCH) clean:
|
||||
endif
|
||||
|
||||
cdCommands envPaths dllPath.bat: $(wildcard $(TOP)/configure/RELEASE*) \
|
||||
$(TOP)/configure/CONFIG $(INSTALL_BIN)
|
||||
ifeq ($(IOCS_APPL_TOP),)
|
||||
$(PERL) $(TOOLS)/convertRelease.pl -a $(ARCH) $@
|
||||
else
|
||||
$(PERL) $(TOOLS)/convertRelease.pl -a $(ARCH) -t $(IOCS_APPL_TOP) $@
|
||||
endif
|
||||
$(wildcard $(TOP)/configure/CONFIG_SITE*) $(INSTALL_BIN)
|
||||
$(CONVERTRELEASE) -a $(ARCH) -t $(IOCS_APPL_TOP) $@
|
||||
|
||||
realclean:
|
||||
$(RM) cdCommands envPaths dllPath.bat
|
||||
|
||||
@@ -11,13 +11,14 @@
|
||||
#
|
||||
|
||||
all: install
|
||||
host: install$(DIVIDER)$(EPICS_HOST_ARCH)
|
||||
|
||||
ACTIONS = inc
|
||||
ACTIONS += build
|
||||
ACTIONS += install
|
||||
ACTIONS += buildInstall
|
||||
ACTIONS += browse
|
||||
ACTIONS += runtests
|
||||
ACTIONS += runtests tapfiles
|
||||
#ACTIONS += rebuild
|
||||
|
||||
actionPart = $(word 1, $(subst $(DIVIDER), ,$@))
|
||||
@@ -94,4 +95,4 @@ realclean :
|
||||
.PHONY : $(actionArchTargets)
|
||||
.PHONY : $(cleanArchTargets)
|
||||
.PHONY : $(BUILD_ARCHS) rebuild arch_common_clean
|
||||
.PHONY : $(ACTIONS) clean realclean archclean all
|
||||
.PHONY : $(ACTIONS) clean realclean archclean host all
|
||||
|
||||
@@ -21,6 +21,7 @@ vpath %.cc $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.cpp $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.rc $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.h $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.hpp $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.html $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.skel.static $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.y $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
@@ -67,27 +68,36 @@ else
|
||||
INSTALL_TEMPLATES_SUBDIR = $(INSTALL_TEMPLATES)
|
||||
endif
|
||||
|
||||
HTMLS_DIR ?= .
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# First target
|
||||
|
||||
all: install
|
||||
all: install
|
||||
ifeq ($(EPICS_HOST_ARCH),$T_A)
|
||||
host: install
|
||||
else
|
||||
# Do nothing
|
||||
host:
|
||||
endif
|
||||
|
||||
-include $(CONFIG)/RULES.Db
|
||||
|
||||
-include $(CONFIG)/RULES_JAVA
|
||||
#---------------------------------------------------------------
|
||||
# Include defines and rules for prod, library and test* targets
|
||||
|
||||
#ifneq (,$(strip $(PROD) $(TESTPROD) $(LIBRARY) $(TESTLIBRARY) $(LOADABLE_LIBRARY) ))
|
||||
include $(CONFIG)/RULES_TARGET
|
||||
#endif
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Read dependency files
|
||||
|
||||
ifneq (,$(strip $(HDEPENDS_FILES)))
|
||||
$(filter-out $(wildcard *$(DEP)), $(HDEPENDS_FILES)): $(COMMON_INC)
|
||||
-include $(HDEPENDS_FILES)
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Included defines and rules for prod,testprod, and library targets
|
||||
|
||||
#ifneq (,$(strip $(PROD) $(TESTPROD) $(LIBRARY) $(TESTLIBRARY) $(LOADABLE_LIBRARY) ))
|
||||
include $(CONFIG)/RULES_TARGET
|
||||
#endif
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Products and Object libraries
|
||||
#
|
||||
@@ -100,6 +110,8 @@ ifneq (,$(strip $(TESTS)))
|
||||
TARGETS += testspec
|
||||
endif
|
||||
|
||||
TAPFILES += $(TESTSCRIPTS:.t=.tap)
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Libraries
|
||||
#
|
||||
@@ -149,7 +161,8 @@ build_clean:
|
||||
$(LOADABLE_SHRLIBNAME) \
|
||||
$(INC) $(TARGETS) $(TDS) $(CLEANS) \
|
||||
*.out MakefileInclude *.manifest *.exp \
|
||||
$(COMMON_INC) $(HDEPENDS_FILES) $(PRODTARGETS) $(TESTSCRIPTS)
|
||||
$(COMMON_INC) $(HDEPENDS_FILES) $(PRODTARGETS) \
|
||||
$(TESTSCRIPTS) $(TAPFILES)
|
||||
ifdef RES
|
||||
@$(RM) *$(RES)
|
||||
endif
|
||||
@@ -186,18 +199,11 @@ endif
|
||||
|
||||
$(TESTPRODNAME) $(PRODNAME): $(PRODUCT_OBJS) $(PROD_RESS) $(PROD_DEPLIBS)
|
||||
|
||||
$(TESTPRODNAME) $(PRODNAME):%$(EXE):
|
||||
$(TESTPRODNAME) $(PRODNAME): %$(EXE):
|
||||
@$(RM) $@
|
||||
$(DEBUGCMD) $(LINK.cpp)
|
||||
$(MT_EXE_COMMAND)
|
||||
|
||||
# object libs for R3.13 vxWorks compatibility only
|
||||
$(OBJLIBNAME): $(OBJLIB_LD_OBJS)
|
||||
|
||||
$(OBJLIBNAME):%$(OBJ):
|
||||
@$(RM) $@
|
||||
$(OBJLIB_LINK.cpp)
|
||||
|
||||
%_ctdt$(OBJ) : %_ctdt.c
|
||||
@$(RM) $@
|
||||
$(COMPILE.ctdt) $<
|
||||
@@ -214,15 +220,21 @@ $(OBJLIBNAME):%$(OBJ):
|
||||
@$(RM) $@
|
||||
$(HDEPENDS.cpp) $<
|
||||
|
||||
%$(OBJ): %.c
|
||||
# Cancel GNUMake's built-in rules, which don't have our _INC
|
||||
# dependencies so could get used in some circumstances (gdd)
|
||||
%.o : %.c
|
||||
%.o : %.cc
|
||||
%.o : %.cpp
|
||||
|
||||
%$(OBJ): %.c $(COMMON_INC) $(INSTALL_INC)
|
||||
@$(RM) $@
|
||||
$(COMPILE.c) -c $<
|
||||
|
||||
%$(OBJ): %.cc
|
||||
%$(OBJ): %.cc $(COMMON_INC) $(INSTALL_INC)
|
||||
@$(RM) $@
|
||||
$(COMPILE.cpp) -c $<
|
||||
|
||||
%$(OBJ): %.cpp
|
||||
%$(OBJ): %.cpp $(COMMON_INC) $(INSTALL_INC)
|
||||
@$(RM) $@
|
||||
$(COMPILE.cpp) -c $<
|
||||
|
||||
@@ -284,8 +296,13 @@ endif # RANLIB
|
||||
$(SHRLIBNAME) $(DLLSTUB_LIBNAME) $(TESTSHRLIBNAME) $(TESTDLLSTUB_LIBNAME): \
|
||||
$(LIBRARY_OBJS) $(LIBRARY_RESS) $(SHRLIB_DEPLIBS)
|
||||
|
||||
$(SHRLIBNAME) $(TESTSHRLIBNAME): $(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX):
|
||||
$(RM) $@
|
||||
$(SHRLIBNAME): $(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX):
|
||||
@$(RM) $@
|
||||
$(LINK.shrlib)
|
||||
$(MT_DLL_COMMAND)
|
||||
|
||||
$(TESTSHRLIBNAME): $(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX):
|
||||
@$(RM) $@
|
||||
$(LINK.shrlib)
|
||||
$(MT_DLL_COMMAND)
|
||||
|
||||
@@ -322,10 +339,10 @@ $(OBJLIB_MUNCHNAME): %.munch: %_ctdt$(OBJ) %$(OBJ)
|
||||
#---------------------------------------------------------------
|
||||
# Automated testing
|
||||
|
||||
runtests: $(TESTSCRIPTS_$(BUILD_CLASS))
|
||||
runtests: $(TESTSCRIPTS)
|
||||
-$(PERL) -MTest::Harness -e 'runtests @ARGV if @ARGV;' $^
|
||||
|
||||
testspec: $(TESTSCRIPTS_$(BUILD_CLASS))
|
||||
testspec: $(TESTSCRIPTS)
|
||||
@$(RM) $@
|
||||
@echo OS-class: $(OS_CLASS) > $@
|
||||
@echo Target-arch: $(T_A) >> $@
|
||||
@@ -333,16 +350,22 @@ testspec: $(TESTSCRIPTS_$(BUILD_CLASS))
|
||||
$(if $(TESTFILES), @echo Files: $(TESTFILES) >> $@)
|
||||
$(if $(TESTSPEC_$(OS_CLASS)), @echo "Harness: $(TESTSPEC_$(OS_CLASS))" >> $@)
|
||||
|
||||
tapfiles: $(TESTSCRIPTS) $(TAPFILES)
|
||||
|
||||
# A .tap file is the output from running the associated test script
|
||||
%.tap: %.t
|
||||
-HARNESS_ACTIVE=1 $(PERL) $< > $@
|
||||
|
||||
# If there's a perl test script (.plt) available, use it
|
||||
%.t: ../%.plt
|
||||
@$(RM) $@
|
||||
@$(CP) $< $@
|
||||
$(CP) $< $@
|
||||
|
||||
# Some versions of Test::Harness expect test programs in perl only.
|
||||
# Test programs (.t files) must be written in Perl.
|
||||
# Generate a perl program to exec the real test binary.
|
||||
%.t: %$(EXE)
|
||||
@$(RM) $@
|
||||
@$(PERL) $(TOOLS)/makeTestfile.pl $@ $<
|
||||
$(PERL) $(TOOLS)/makeTestfile.pl $@ $<
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Install rules for BIN_INSTALLS and LIB_INSTALLS
|
||||
@@ -387,7 +410,7 @@ endif # SUFFIX
|
||||
|
||||
$(INSTALL_SHRLIBS): $(INSTALL_SHRLIB)/%: %
|
||||
$(ECHO) "Installing shared library $@"
|
||||
@$(INSTALL_LIBRARY) -d -m $(LIB_PERMISSIONS) $< $(INSTALL_SHRLIB)
|
||||
@$(INSTALL_LIBRARY) -d -m $(SHRLIB_PERMISSIONS) $< $(INSTALL_SHRLIB)
|
||||
ifneq ($(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE))
|
||||
ifneq (,$(strip $(SHRLIB_VERSION)))
|
||||
@$(RM) $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
|
||||
@@ -411,7 +434,7 @@ $(INSTALL_TCLLIB)/$(TCLINDEX): $(INSTALL_TCLLIBS)
|
||||
|
||||
$(INSTALL_LOADABLE_SHRLIBS): $(INSTALL_SHRLIB)/%: %
|
||||
$(ECHO) "Installing loadable shared library $@"
|
||||
@$(INSTALL_LIBRARY) -d -m 555 $< $(INSTALL_SHRLIB)
|
||||
@$(INSTALL_LIBRARY) -d -m $(SHRLIB_PERMISSIONS) $< $(INSTALL_SHRLIB)
|
||||
ifneq ($(LOADABLE_SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE))
|
||||
ifneq (,$(strip $(LOADABLE_SHRLIB_VERSION)))
|
||||
@$(RM) $(subst $(LOADABLE_SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
|
||||
@@ -459,6 +482,10 @@ $(INSTALL_HTML)/$(HTMLS_DIR)/%: ../%
|
||||
$(ECHO) "Installing html $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_HTML)/$(HTMLS_DIR)/%: $(COMMON_DIR)/%
|
||||
$(ECHO) "Installing generated html $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_TEMPLATES_SUBDIR)/%: ../%
|
||||
$(ECHO) "Installing $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
@@ -472,8 +499,8 @@ $(INSTALL_TEMPLATES_SUBDIR)/%: %
|
||||
.PRECIOUS: %.i %.o %.c %.nm %.cpp %.cc
|
||||
.PRECIOUS: $(COMMON_INC)
|
||||
|
||||
.PHONY: all inc build install clean rebuild buildInstall build_clean
|
||||
.PHONY: runtests checkRelease warnRelease noCheckRelease
|
||||
.PHONY: all host inc build install clean rebuild buildInstall build_clean
|
||||
.PHONY: runtests tapfiles checkRelease warnRelease noCheckRelease
|
||||
|
||||
endif # BASE_RULES_BUILD
|
||||
# EOF RULES_BUILD
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
|
||||
ARCHS += $(BUILD_ARCHS)
|
||||
ACTIONS += inc build install buildInstall clean realclean archclean runtests
|
||||
ACTIONS += inc build install buildInstall clean realclean archclean
|
||||
ACTIONS += runtests tapfiles
|
||||
|
||||
dirPart = $(join $(dir $@), $(word 1, $(subst $(DIVIDER), ,$(notdir $@))))
|
||||
|
||||
@@ -33,7 +34,8 @@ actionArchTargets = $(foreach action, $(ACTIONS),\
|
||||
$(foreach arch, $(ARCHS), \
|
||||
$(action)$(DIVIDER)$(arch)))
|
||||
|
||||
all : install
|
||||
all: install
|
||||
host: install$(DIVIDER)$(EPICS_HOST_ARCH)
|
||||
|
||||
# Allows rebuild to work with parallel builds option, -j.
|
||||
ifeq (rebuild,$(filter rebuild,$(MAKECMDGOALS)))
|
||||
@@ -72,7 +74,7 @@ $(DIRS) $(dirActionTargets) $(dirArchTargets) $(dirActionArchTargets) :
|
||||
$(ARCHS) $(ACTIONS) $(actionArchTargets) :%: \
|
||||
$(foreach dir, $(DIRS), $(dir)$(DIVIDER)%)
|
||||
|
||||
.PHONY : $(DIRS) all rebuild
|
||||
.PHONY : $(DIRS) all host rebuild
|
||||
.PHONY : $(ARCHS) $(ACTIONS)
|
||||
.PHONY : $(dirActionTargets) $(dirArchTargets)
|
||||
.PHONY : $(dirActionArchTargets)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# <top>/configure/RULES_EXPAND
|
||||
|
||||
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
|
||||
vpath %@ $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
|
||||
# Default settings
|
||||
EXPAND_TOOL ?= $(PERL) $(TOOLS)/expandVars.pl
|
||||
@@ -8,11 +8,12 @@ EXPAND_TOOL ?= $(PERL) $(TOOLS)/expandVars.pl
|
||||
EXPANDFLAGS += -t $(INSTALL_LOCATION) -a $(T_A)
|
||||
EXPANDFLAGS += $(addprefix -D ,$(EXPAND_VARS))
|
||||
|
||||
# The names of files to be expanded must end with '@'
|
||||
EXPANDED = $(EXPAND:%@=%)
|
||||
|
||||
buildInstall: $(EXPANDED)
|
||||
|
||||
$(EXPANDED): %: ../%@
|
||||
$(EXPANDED): %: %@
|
||||
$(ECHO) "Expanding $< to $@"
|
||||
@$(RM) $@
|
||||
@$(EXPAND_TOOL) $(EXPANDFLAGS) $($@_EXPANDFLAGS) $< $@
|
||||
@@ -23,5 +24,3 @@ expand_clean:
|
||||
@$(RM) $(EXPANDED)
|
||||
|
||||
.PHONY : expand_clean
|
||||
|
||||
endif
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in the file LICENSE that is included with this distribution.
|
||||
# in the file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
# $Revision-Id$
|
||||
#
|
||||
@@ -36,13 +36,11 @@ endif
|
||||
endif
|
||||
|
||||
#---------------------------------------------
|
||||
# Include existing and new $(INSTALL_CFG)/* definitions
|
||||
# Include our own $(INSTALL_CFG)/RULES* definitions
|
||||
#
|
||||
TOP_CFG_FILES = $(sort $(wildcard $(INSTALL_CFG)/RULES*) \
|
||||
$(wildcard $(INSTALL_CFG)/CONFIG*) \
|
||||
$(addprefix $(INSTALL_CFG)/,$(CFG)))
|
||||
ifneq ($(TOP_CFG_FILES),)
|
||||
include $(TOP_CFG_FILES)
|
||||
TOP_CFG_RULES = $(wildcard $(INSTALL_CFG)/RULES*)
|
||||
ifneq ($(TOP_CFG_RULES),)
|
||||
include $(TOP_CFG_RULES)
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------
|
||||
|
||||
@@ -50,13 +50,13 @@ $(1)_RESS = $$(if $(RES),$$(addsuffix $(RES),$$(basename $$($(1)_RCS))),)
|
||||
$(1)_OBJSNAME = $$(addsuffix $(OBJ),$$(basename $$($(1)_OBJS) $$($(1)_SRCS) ))
|
||||
$(1)_DEPLIBS = $$(foreach lib, $$($(1)_LDLIBS), \
|
||||
$$(firstword $$(wildcard \
|
||||
$$(addsuffix /$(SHRLIB_PREFIX)$$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
$$(addsuffix /$(DLLSTUB_PREFIX)$$(lib)$(DLLSTUB_SUFFIX), \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
$$(addsuffix /$(SHRLIB_PREFIX)$$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
$$(addsuffix /$(LIB_PREFIX)$$(lib)$(LIB_SUFFIX), \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS))) \
|
||||
$$(addsuffix /$(BUILDLIB_PREFIX)$$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
) $$(addsuffix /$(BUILDLIB_PREFIX)$$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$$(firstword $$($$(lib)_DIR) $(SHRLIB_SEARCH_DIRS)))))
|
||||
endef
|
||||
|
||||
@@ -79,27 +79,26 @@ define LIBRARY_template
|
||||
|
||||
$(1)_DLL_DEPLIBS=$$(foreach lib, $$($(1)_DLL_LIBS), \
|
||||
$$(firstword $$(wildcard \
|
||||
$$(addsuffix /$(SHRLIB_PREFIX)$$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
$$(addsuffix /$(DLLSTUB_PREFIX)$$(lib)$(DLLSTUB_SUFFIX), \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
$$(addsuffix /$(SHRLIB_PREFIX)$$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
$$(addsuffix /$(LIB_PREFIX)$$(lib)$(LIB_SUFFIX), \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS))) \
|
||||
$$(addsuffix /$(BUILDLIB_PREFIX)$$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \
|
||||
) $$(addsuffix /$(BUILDLIB_PREFIX)$$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$$(firstword $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)))))
|
||||
|
||||
$$(LIB_PREFIX)$(1)$$(LIB_SUFFIX):$$($(1)_OBJSNAME) $$($(1)_RESS)
|
||||
$$(LIB_PREFIX)$(1)$$(LIB_SUFFIX):$$($(1)_DEPLIBS)
|
||||
|
||||
ifeq ($$(SHARED_LIBRARIES),YES)
|
||||
|
||||
ifdef SHRLIB_SUFFIX
|
||||
$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX):$$($(1)_OBJSNAME) $$($(1)_RESS)
|
||||
$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX):$$($(1)_DEPLIBS)
|
||||
$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX):$$($(1)_DLL_DEPLIBS)
|
||||
|
||||
# Needed for -j parallel builds option
|
||||
ifeq ($$(SHARED_LIBRARIES),YES)
|
||||
ifdef SHRLIB_SUFFIX
|
||||
$$(INSTALL_LIB)/$$(LIB_PREFIX)$(1)$$(LIB_SUFFIX): \
|
||||
$$(INSTALL_SHRLIB)/$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
endef
|
||||
@@ -111,6 +110,14 @@ $(foreach target, $(LIBRARY) $(TESTLIBRARY), \
|
||||
|
||||
define LIBRARY2_template
|
||||
BUILD_LIBRARY += $$(if $$(strip $$($(1)_OBJSNAME) $$(LIBRARY_OBJS)),$(1),)
|
||||
|
||||
# Needed for -j parallel builds option
|
||||
ifeq ($$(SHARED_LIBRARIES),YES)
|
||||
ifdef SHRLIB_SUFFIX
|
||||
$$(INSTALL_LIB)/$$(DLLSTUB_PREFIX)$(1)$$(DLLSTUB_SUFFIX): \
|
||||
$$(INSTALL_SHRLIB)/$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX)
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
$(foreach target, $(LIBRARY), \
|
||||
@@ -119,6 +126,7 @@ $(foreach target, $(LIBRARY), \
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
define LIBRARY3_template
|
||||
$(1)_DIR = .
|
||||
TESTBUILD_LIBRARY += $$(if $$(strip $$($(1)_OBJSNAME) $$(LIBRARY_OBJS)),$(1),)
|
||||
endef
|
||||
|
||||
|
||||
@@ -22,9 +22,8 @@ realuninstall: uninstallDirs
|
||||
$(RMDIR) $(INSTALL_LOCATION_BIN)
|
||||
$(RMDIR) $(INSTALL_LOCATION_LIB)
|
||||
|
||||
UNINSTALL_DIRS += $(INSTALL_DBD) $(INSTALL_INCLUDE) $(INSTALL_DOC)\
|
||||
$(INSTALL_HTML) $(INSTALL_JAVA) $(INSTALL_TEMPLATES) \
|
||||
$(INSTALL_DB)
|
||||
UNINSTALL_DIRS += $(INSTALL_DBD) $(INSTALL_INCLUDE) $(INSTALL_DOC)
|
||||
UNINSTALL_DIRS += $(INSTALL_HTML) $(INSTALL_TEMPLATES) $(INSTALL_DB)
|
||||
UNINSTALL_DIRS += $(DIRECTORY_TARGETS)
|
||||
uninstallDirs:
|
||||
$(RMDIR) $(UNINSTALL_DIRS)
|
||||
@@ -64,11 +63,12 @@ help:
|
||||
@echo " rebuild - Same as clean install"
|
||||
@echo " archclean - Removes O.<arch> dirs but not O.Common dir"
|
||||
@echo "\"Partial\" build targets supported by Makefiles:"
|
||||
@echo " inc.<arch> - Installs <arch> only header files."
|
||||
@echo " build.<arch> - Builds and installs <arch> only."
|
||||
@echo " install.<arch> - Builds and installs <arch> only."
|
||||
@echo " clean.<arch> - Cleans <arch> binaries in O.<arch> dirs only."
|
||||
@echo " uninstall.<arch> - Remove bin & lib directories for <arch> only."
|
||||
@echo " host - Builds and installs $(EPICS_HOST_ARCH) only."
|
||||
@echo " inc$(DIVIDER)<arch> - Installs <arch> only header files."
|
||||
@echo " build$(DIVIDER)<arch> - Builds and installs <arch> only."
|
||||
@echo " install$(DIVIDER)<arch> - Builds and installs <arch> only."
|
||||
@echo " clean$(DIVIDER)<arch> - Cleans <arch> binaries in O.<arch> dirs only."
|
||||
@echo " uninstall$(DIVIDER)<arch> - Remove bin & lib directories for <arch> only."
|
||||
@echo "Targets supported by top level Makefile:"
|
||||
@echo " archuninstall - Remove bin & lib directories created by this hostarch."
|
||||
@echo " uninstall - Remove install directories created by this hostarch."
|
||||
|
||||
0
configure/Sample.Makefile
Executable file → Normal file
0
configure/Sample.Makefile
Executable file → Normal file
@@ -20,8 +20,8 @@ OBJ = .o
|
||||
LIB_PREFIX = lib
|
||||
LIB_SUFFIX = .a
|
||||
SHRLIB_SUFFIX_BASE = .so
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE).$(SHRLIB_VERSION)
|
||||
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE).$(LOADABLE_SHRLIB_VERSION)
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(SHRLIB_VERSION))
|
||||
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(LOADABLE_SHRLIB_VERSION))
|
||||
LOADABLE_SHRLIB_PREFIX = lib
|
||||
|
||||
#-------------------------------------------------------
|
||||
@@ -42,13 +42,14 @@ LIB_LIBS += $(SHRLIB_LIBS)
|
||||
|
||||
SHRLIB_DEPLIBS = $(foreach lib, $(LIB_LIBS) $(USR_LIBS), \
|
||||
$(firstword $(wildcard \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS))) \
|
||||
$(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), $(INSTALL_LIB))))
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB)))))
|
||||
|
||||
SHRLIB_LDLIBS = $(addprefix -l, $($*_LDLIBS) $(LIB_LIBS) $(USR_LIBS)) \
|
||||
$(STATIC_LDLIBS) \
|
||||
@@ -57,7 +58,7 @@ SHRLIB_LDLIBS = $(addprefix -l, $($*_LDLIBS) $(LIB_LIBS) $(USR_LIBS)) \
|
||||
|
||||
SHRLIB_DEPLIB_DIRS = $(foreach word, \
|
||||
$(sort $(dir $($*_DEPLIBS) $(SHRLIB_DEPLIBS))), \
|
||||
$(shell $(PERL) $(TOOLS)/fullPathName.pl $(word)))
|
||||
$(shell $(FULLPATHNAME) $(word)))
|
||||
|
||||
SHRLIBDIR_LDFLAGS += $(SHRLIB_DEPLIB_DIRS:%=-L%)
|
||||
|
||||
@@ -66,13 +67,14 @@ SHRLIBDIR_LDFLAGS += $(SHRLIB_DEPLIB_DIRS:%=-L%)
|
||||
|
||||
PROD_DEPLIBS = $(foreach lib, $(PROD_LIBS) $(USR_LIBS), \
|
||||
$(firstword $(wildcard \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS))) \
|
||||
$(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), $(INSTALL_LIB))))
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB)))))
|
||||
|
||||
PROD_LDLIBS = $(addprefix -l, $($*_LDLIBS) $(PROD_LIBS) $(USR_LIBS)) \
|
||||
$(STATIC_LDLIBS) \
|
||||
@@ -85,7 +87,7 @@ PROD_LDLIBS += $($(firstword $(LDLIBS_STATIC_$(STATIC_BUILD)) \
|
||||
|
||||
PROD_DEPLIB_DIRS = $(foreach word, \
|
||||
$(sort $(dir $($*_DEPLIBS) $(PROD_DEPLIBS))), \
|
||||
$(shell $(PERL) $(TOOLS)/fullPathName.pl $(word)))
|
||||
$(shell $(FULLPATHNAME) $(word)))
|
||||
|
||||
PRODDIR_LDFLAGS += $(PROD_DEPLIB_DIRS:%=-L%)
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ SHRLIB_PREFIX =
|
||||
SHRLIB_SUFFIX_BASE = .dll
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
SHRLIBNAME_YES = $(BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX))
|
||||
TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX))
|
||||
TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX_BASE))
|
||||
LOADABLE_SHRLIBNAME = $(LOADABLE_BUILD_LIBRARY:%=%$(LOADABLE_SHRLIB_SUFFIX))
|
||||
|
||||
#
|
||||
@@ -74,6 +74,8 @@ LIB_PREFIX_YES = lib
|
||||
LIB_SUFFIX_YES = .dll.a
|
||||
LIB_PREFIX = $(LIB_PREFIX_$(SHARED_LIBRARIES))
|
||||
LIB_SUFFIX = $(LIB_SUFFIX_$(SHARED_LIBRARIES))
|
||||
DLLSTUB_PREFIX = lib
|
||||
DLLSTUB_SUFFIX = .dll.a
|
||||
|
||||
DLLSTUB_LIBNAME_YES = $(BUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX))
|
||||
DLLSTUB_LIBNAME = $(DLLSTUB_LIBNAME_$(SHARED_LIBRARIES))
|
||||
|
||||
14
configure/os/CONFIG.Common.cygwin-x86_64
Normal file
14
configure/os/CONFIG.Common.cygwin-x86_64
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.cygwin-x86_64
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for cygwin-x86_64 target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.cygwin-x86_64
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.cygwin-x86
|
||||
|
||||
ARCH_DEP_CFLAGS = -m64
|
||||
ARCH_DEP_LDFLAGS = -m64
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
IOS_PLATFORM = iPhoneOS
|
||||
|
||||
OP_SYS_CFLAGS += -fno-inline-functions
|
||||
OP_SYS_CFLAGS += -miphoneos-version-min=$(IOS_DEPLOYMENT_TARGET)
|
||||
OP_SYS_LDFLAGS += -miphoneos-version-min=$(IOS_DEPLOYMENT_TARGET)
|
||||
|
||||
# iOS optimization flags for arm architecture
|
||||
OPT_CFLAGS_YES = -O2
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
IOS_PLATFORM = iPhoneSimulator
|
||||
|
||||
OP_SYS_CFLAGS += -mios-simulator-version-min=$(IOS_DEPLOYMENT_TARGET)
|
||||
OP_SYS_LDFLAGS += -mios-simulator-version-min=$(IOS_DEPLOYMENT_TARGET)
|
||||
|
||||
#
|
||||
# Architecture-specific information
|
||||
#
|
||||
|
||||
@@ -40,7 +40,8 @@ ARCH_DEP_LDFLAGS += $(ARCH_DEP_FLAGS)
|
||||
|
||||
#--------------------------------------------------
|
||||
# Operating system flags
|
||||
OP_SYS_CFLAGS += -isysroot $(SDK_DIR) -D__IPHONE_OS_VERSION_MIN_REQUIRED=30200
|
||||
OP_SYS_CFLAGS += -isysroot $(SDK_DIR)
|
||||
OP_SYS_LDFLAGS += -isysroot $(SDK_DIR)
|
||||
|
||||
#--------------------------------------------------
|
||||
# Always compile in debugging symbol table information
|
||||
@@ -54,17 +55,20 @@ OPT_CXXFLAGS_YES += -g
|
||||
CC_GNU = gcc
|
||||
CCC_GNU = g++
|
||||
CMPLR_CLASS_GNU = gcc
|
||||
CC_LLVM = llvm-gcc
|
||||
CCC_LLVM = llvm-g++
|
||||
CMPLR_CLASS_LLVM = gcc
|
||||
|
||||
CC_LLVM_GNU = llvm-gcc
|
||||
CCC_LLVM_GNU = llvm-g++
|
||||
CMPLR_CLASS_LLVM_GNU = gcc
|
||||
|
||||
CC_CLANG = clang
|
||||
CCC_CLANG = clang++
|
||||
CMPLR_CLASS_CLANG = clang
|
||||
|
||||
CC = $(firstword $(wildcard $(GNU_BIN)/$(CC_$(COMPILER))) $(CC_$(COMPILER)))
|
||||
CCC = $(firstword $(wildcard $(GNU_BIN)/$(CCC_$(COMPILER))) $(CCC_$(COMPILER)))
|
||||
CMPLR_CLASS = $(CMPLR_CLASS_$(COMPLER))
|
||||
|
||||
# Convert the iOS platform to lowercase for passing to xcrun's sdk parameter
|
||||
XCRUN_SDK_BASE = $(shell echo $(IOS_PLATFORM) | tr A-Z a-z)
|
||||
|
||||
#-------------------------------------------------------
|
||||
# Linker flags
|
||||
GNU_LDLIBS_YES =
|
||||
@@ -74,7 +78,7 @@ OP_SYS_LDFLAGS += -dynamic -Z -L$(SDK_DIR)/usr/lib -L$(SDK_DIR)/usr/lib/system
|
||||
# Shared libraries
|
||||
SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)
|
||||
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \
|
||||
-install_name $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LIB))/$@ \
|
||||
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
|
||||
-compatibility_version $(EPICS_VERSION).$(EPICS_REVISION) \
|
||||
-current_version $(SHRLIB_VERSION)
|
||||
SHRLIB_SUFFIX_BASE = .dylib
|
||||
@@ -103,3 +107,11 @@ HDEPENDS_METHOD = MKMF
|
||||
# Allow site overrides
|
||||
-include $(CONFIG)/os/CONFIG_SITE.Common.iosCommon
|
||||
-include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).iosCommon
|
||||
|
||||
#--------------------------------------------------
|
||||
# Find the Xcode programs for the selected SDK
|
||||
CC := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find $(CC_$(COMPILER)))
|
||||
CCC := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find $(CCC_$(COMPILER)))
|
||||
AR := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find ar) -rc
|
||||
LD := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find ld) -r
|
||||
RANLIB := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find ranlib)
|
||||
|
||||
@@ -17,7 +17,7 @@ ifeq ($(BUILD_CLASS),CROSS)
|
||||
|
||||
# prefix of compiler tools
|
||||
CMPLR_SUFFIX =
|
||||
CMPLR_PREFIX = $(GNU_TARGET)-
|
||||
CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET))
|
||||
|
||||
# Provide a link-time path for shared libraries
|
||||
SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%)
|
||||
|
||||
@@ -12,17 +12,16 @@ include $(CONFIG)/os/CONFIG.Common.UnixCommon
|
||||
|
||||
OS_CLASS = Linux
|
||||
|
||||
CODE_CPPFLAGS = -D_REENTRANT
|
||||
|
||||
POSIX_CPPFLAGS = -D_POSIX_C_SOURCE=199506L -D_POSIX_THREADS -D_XOPEN_SOURCE=500
|
||||
# Define _GNU_SOURCE and _DEFAULT_SOURCE for maximum portability
|
||||
POSIX_CPPFLAGS = -D_GNU_SOURCE -D_DEFAULT_SOURCE
|
||||
POSIX_LDLIBS = -lpthread
|
||||
|
||||
# -D_BSD_SOURCE for gethostname() in unistd.h as needed by cacChannelIO.cpp.
|
||||
OP_SYS_CPPFLAGS += -D_BSD_SOURCE
|
||||
OP_SYS_CPPFLAGS += -Dlinux
|
||||
OP_SYS_LDLIBS += -lrt -ldl
|
||||
# Use -rdynamic to maximize symbols available for stacktrace
|
||||
OP_SYS_LDFLAGS += -rdynamic
|
||||
|
||||
# Added here for cross-target builds which include this file
|
||||
# Linker flags for static & shared-library builds
|
||||
STATIC_LDFLAGS_YES= -Wl,-Bstatic
|
||||
STATIC_LDFLAGS_NO=
|
||||
STATIC_LDLIBS_YES= -Wl,-Bdynamic
|
||||
|
||||
@@ -20,12 +20,11 @@ COMPILER_LDFLAGS += -mt
|
||||
|
||||
SOLARIS_VERSION = $(subst 5.,,$(shell uname -r))
|
||||
|
||||
POSIX_CPPFLAGS += -D_POSIX_C_SOURCE=199506L $(POSIX_CPPFLAGS_$(SOLARIS_VERSION))
|
||||
POSIX_CPPFLAGS += -D_XOPEN_SOURCE=500
|
||||
POSIX_LDLIBS += -lposix4 -lpthread $(POSIX_LDLIBS_$(SOLARIS_VERSION))
|
||||
POSIX_CFLAGS = -xc99 -D_POSIX_C_SOURCE=200112L
|
||||
POSIX_LDLIBS += -lposix4 -lpthread
|
||||
|
||||
OP_SYS_CPPFLAGS += -DSOLARIS=$(SOLARIS_VERSION) $(COMPILER_CPPFLAGS)
|
||||
OP_SYS_LDFLAGS += $(COMPILER_LDFLAGS)
|
||||
OP_SYS_LDFLAGS += $(COMPILER_LDFLAGS)
|
||||
|
||||
# Set runtime path for shared libraries
|
||||
SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-R%)
|
||||
|
||||
@@ -9,13 +9,15 @@
|
||||
|
||||
# Include definitions common to all solaris-sparc target archs
|
||||
include $(CONFIG)/os/CONFIG.Common.solaris-sparc
|
||||
# CONFIG.Common.solaris-sparc
|
||||
|
||||
COMPILER_CPPFLAGS = -D_REENTRANT
|
||||
COMPILER_CPPFLAGS = -D_REENTRANT
|
||||
|
||||
POSIX_CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200112L
|
||||
|
||||
STLPORT_LDLIBS_NO =
|
||||
|
||||
OP_SYS_LDLIBS_8 = -ldl
|
||||
OP_SYS_LDLIBS_9 = -ldl
|
||||
OP_SYS_LDLIBS_10 =
|
||||
OP_SYS_LDLIBS_11 = -lc
|
||||
|
||||
|
||||
@@ -20,9 +20,8 @@ COMPILER_LDFLAGS += -mt
|
||||
|
||||
SOLARIS_VERSION = $(subst 5.,,$(shell uname -r))
|
||||
|
||||
POSIX_CPPFLAGS += -D_POSIX_C_SOURCE=199506L $(POSIX_CPPFLAGS_$(SOLARIS_VERSION))
|
||||
POSIX_CPPFLAGS += -D_XOPEN_SOURCE=500
|
||||
POSIX_LDLIBS += -lposix4 -lpthread $(POSIX_LDLIBS_$(SOLARIS_VERSION))
|
||||
POSIX_CFLAGS = -xc99 -D_POSIX_C_SOURCE=200112L
|
||||
POSIX_LDLIBS += -lposix4 -lpthread
|
||||
|
||||
OP_SYS_CPPFLAGS += -DSOLARIS=$(SOLARIS_VERSION) $(COMPILER_CPPFLAGS)
|
||||
OP_SYS_LDFLAGS += $(COMPILER_LDFLAGS)
|
||||
@@ -53,6 +52,7 @@ OP_SYS_LDLIBS += -lsocket -lnsl
|
||||
OP_SYS_LDLIBS_8 += -ldl -lCrun -lc
|
||||
OP_SYS_LDLIBS_9 += -ldl -lCrun -lc
|
||||
OP_SYS_LDLIBS_10 += -lCrun -lc
|
||||
OP_SYS_LDLIBS_11 += -lCrun -lc
|
||||
OP_SYS_LDLIBS += $(OP_SYS_LDLIBS_$(SOLARIS_VERSION))
|
||||
OP_SYS_LDLIBS += $(STLPORT_LDLIBS_$(USE_STLPORT))
|
||||
|
||||
|
||||
@@ -12,9 +12,12 @@ include $(CONFIG)/os/CONFIG.Common.solaris-x86
|
||||
|
||||
COMPILER_CPPFLAGS = -D_REENTRANT
|
||||
|
||||
POSIX_CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200112L
|
||||
|
||||
STLPORT_LDLIBS_NO =
|
||||
|
||||
OP_SYS_LDLIBS_8 = -ldl -lc
|
||||
OP_SYS_LDLIBS_9 = -ldl -lc
|
||||
OP_SYS_LDLIBS_10 = -lc
|
||||
OP_SYS_LDLIBS_11 = -lc
|
||||
|
||||
|
||||
@@ -11,14 +11,13 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorksCommon
|
||||
|
||||
# Vx GNU cross compiler suffix
|
||||
CMPLR_SUFFIX = 386
|
||||
CMPLR_SUFFIX = pentium
|
||||
|
||||
ARCH_CLASS = pc486
|
||||
ARCH_CLASS = x86
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -DCPU=I80486 -D_X86_
|
||||
ARCH_DEP_CFLAGS = -m486
|
||||
ARCH_DEP_CXXFLAGS += -x 'c++'
|
||||
ARCH_DEP_CFLAGS += -fno-defer-pop
|
||||
ARCH_DEP_CPPFLAGS = -DCPU=I80486 -D_X86_
|
||||
ARCH_DEP_CFLAGS = -mtune=i486 -march=i486
|
||||
ARCH_DEP_CFLAGS += -fno-zero-initialized-in-bss -fno-defer-pop
|
||||
|
||||
# Allow site overrides
|
||||
-include $(CONFIG)/os/CONFIG_SITE.Common.vxWorks-486
|
||||
|
||||
@@ -11,12 +11,14 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorksCommon
|
||||
|
||||
# Vx GNU cross compiler suffix
|
||||
CMPLR_SUFFIX = 386
|
||||
|
||||
ARCH_CLASS = pcPentium
|
||||
CMPLR_SUFFIX = pentium
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -DCPU=PENTIUM -D_X86_
|
||||
ARCH_DEP_CFLAGS = -mpentium
|
||||
ARCH_DEP_CXXFLAGS += -x 'c++'
|
||||
ARCH_DEP_CFLAGS += -fno-defer-pop
|
||||
ARCH_CLASS = x86
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -DCPU=PENTIUM -D_X86_
|
||||
ARCH_DEP_CFLAGS = -mtune=pentium -march=pentium
|
||||
ARCH_DEP_CFLAGS += -fno-zero-initialized-in-bss -fno-defer-pop
|
||||
|
||||
# Allow site overrides
|
||||
-include $(CONFIG)/os/CONFIG_SITE.Common.vxWorks-pentium
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ PROD_DEPLIBS = $(foreach lib,$(PROD_LIBS) $(USR_LIBS), \
|
||||
$(firstword $(wildcard \
|
||||
$(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS))) \
|
||||
$(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), $(INSTALL_LIB))))
|
||||
$(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \
|
||||
$(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB)))))
|
||||
|
||||
|
||||
PROD_LDLIBS = $(addprefix -l,$($*_LDLIBS) $(PROD_LIBS) $(USR_LIBS) \
|
||||
$($*_SYS_LIBS) $(PROD_SYS_LIBS) $(USR_SYS_LIBS))
|
||||
|
||||
@@ -12,6 +12,7 @@ include $(CONFIG)/os/CONFIG.Common.UnixCommon
|
||||
|
||||
OS_CLASS = WIN32
|
||||
ARCH_CLASS = x86
|
||||
POSIX = NO
|
||||
|
||||
# Definitions used when COMMANDLINE_LIBRARY is READLINE
|
||||
LDLIBS_READLINE = -lreadline -lcurses
|
||||
@@ -61,7 +62,7 @@ SHRLIB_PREFIX =
|
||||
SHRLIB_SUFFIX_BASE = .dll
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
SHRLIBNAME_YES = $(BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX))
|
||||
TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX))
|
||||
TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX_BASE))
|
||||
LOADABLE_SHRLIB_PREFIX =
|
||||
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
LOADABLE_SHRLIBNAME = $(LOADABLE_BUILD_LIBRARY:%=%$(LOADABLE_SHRLIB_SUFFIX))
|
||||
|
||||
15
configure/os/CONFIG.Common.windows-x64-mingw
Normal file
15
configure/os/CONFIG.Common.windows-x64-mingw
Normal file
@@ -0,0 +1,15 @@
|
||||
# CONFIG.Common.windows-x64-mingw
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for windows-x64-mingw target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.windows-x64-mingw
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.win32-x86-mingw
|
||||
|
||||
ARCH_CLASS = x64
|
||||
|
||||
ARCH_DEP_CFLAGS = -m64
|
||||
ARCH_DEP_LDFLAGS = -m64
|
||||
@@ -13,6 +13,7 @@ MV = mv
|
||||
RM = rm -f
|
||||
MKDIR = mkdir
|
||||
RMDIR = rm -rf
|
||||
CAT = cat
|
||||
|
||||
# Allow site overrides
|
||||
-include $(CONFIG)/os/CONFIG_SITE.UnixCommon.Common
|
||||
|
||||
10
configure/os/CONFIG.cygwin-x86_64.Common
Normal file
10
configure/os/CONFIG.cygwin-x86_64.Common
Normal file
@@ -0,0 +1,10 @@
|
||||
# CONFIG.cygwin-x86_64.Common
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for cygwin-x86_64 host archs
|
||||
# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.Common
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.cygwin-x86.Common
|
||||
11
configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64
Normal file
11
configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64
Normal file
@@ -0,0 +1,11 @@
|
||||
# CONFIG.cygwin-x86_64.cygwin-x86_64
|
||||
#
|
||||
# $Revision-Id$
|
||||
#
|
||||
# Definitions for cygwin-x86_64 host - cygwin-x86_64 target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.cygwin-x86_64
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include common gnu compiler definitions
|
||||
include $(CONFIG)/os/CONFIG.cygwin-x86.cygwin-x86
|
||||
|
||||
@@ -59,15 +59,18 @@ COMMANDLINE_LIBRARY=READLINE
|
||||
|
||||
GNU_DIR = /usr
|
||||
|
||||
CC = $(GNU_BIN)/cc
|
||||
CCC = $(GNU_BIN)/c++
|
||||
# Apple soft-links these compilers to clang/clang++
|
||||
CMPLR_CLASS = clang
|
||||
CC = cc
|
||||
CCC = c++
|
||||
GNU = NO
|
||||
|
||||
#
|
||||
# Darwin shared libraries
|
||||
#
|
||||
SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)
|
||||
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \
|
||||
-install_name $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LIB))/$@ \
|
||||
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
|
||||
-compatibility_version $(EPICS_VERSION).$(EPICS_REVISION) \
|
||||
-current_version $(SHRLIB_VERSION)
|
||||
SHRLIB_SUFFIX_BASE = .dylib
|
||||
|
||||
@@ -12,6 +12,8 @@ CMPLR_CLASS = solStudio
|
||||
SPARCWORKS = /opt/SUNWspro
|
||||
GNU = NO
|
||||
|
||||
# SPARCWORKS path is set in a CONFIG_SITE file
|
||||
|
||||
CC = $(SPARCWORKS)/bin/cc
|
||||
CCC = $(SPARCWORKS)/bin/CC
|
||||
CPP = $(CC) -E -Qn
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for win32-x86-cygwin host archs
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86-cygwin.Common
|
||||
# Definitions for win32-x86-mingw host archs
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86-mingw.Common
|
||||
#-------------------------------------------------------
|
||||
|
||||
#Include definitions common to unix hosts
|
||||
@@ -19,6 +19,7 @@ RM = $(PERL) -MExtUtils::Command -e rm_f
|
||||
MKDIR = $(PERL) -MExtUtils::Command -e mkpath
|
||||
RMDIR = $(PERL) -MExtUtils::Command -e rm_rf
|
||||
NOP = $(PERL) -e ''
|
||||
CAT = $(PERL) -MExtUtils::Command -e cat
|
||||
|
||||
WIND_HOST_TYPE = x86-win32
|
||||
OSITHREAD_USE_DEFAULT_STACK = NO
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
# Include common gnu compiler definitions
|
||||
include $(CONFIG)/CONFIG.gnuCommon
|
||||
|
||||
# gcc, g++, ar, ld, and ranlib must be in user's path
|
||||
CC = gcc
|
||||
CCC = g++
|
||||
AR = ar -rc
|
||||
LD = ld -r
|
||||
RANLIB = ranlib
|
||||
RES=.coff
|
||||
RCCMD = windres $(INCLUDES) $< $@
|
||||
CMPLR_PREFIX =
|
||||
|
||||
CC = $(CMPLR_PREFIX)gcc
|
||||
CCC = $(CMPLR_PREFIX)g++
|
||||
AR = $(CMPLR_PREFIX)ar -rc
|
||||
LD = $(CMPLR_PREFIX)ld -r
|
||||
RANLIB = $(CMPLR_PREFIX)ranlib
|
||||
RES = .coff
|
||||
RCCMD = $(CMPLR_PREFIX)windres $(INCLUDES) $< $@
|
||||
|
||||
# No -fPIC avoids "-fPIC ignored for target (all code is position independent)"
|
||||
SHRLIB_CFLAGS =
|
||||
@@ -28,4 +29,4 @@ LOADABLE_SHRLIB_LDFLAGS = -shared \
|
||||
# Override linking with gcc library from CONFIG.gnuCommon
|
||||
GNU_LDLIBS_YES =
|
||||
|
||||
OP_SYS_LDLIBS = -lws2_32
|
||||
OP_SYS_LDLIBS = -lws2_32
|
||||
|
||||
11
configure/os/CONFIG.win32-x86-static.Common
Normal file
11
configure/os/CONFIG.win32-x86-static.Common
Normal file
@@ -0,0 +1,11 @@
|
||||
# CONFIG.win32-x86-static.Common
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for win32-x86-static host archs
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86-static.Common
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.win32-x86.Common
|
||||
|
||||
13
configure/os/CONFIG.win32-x86-static.win32-x86-static
Normal file
13
configure/os/CONFIG.win32-x86-static.win32-x86-static
Normal file
@@ -0,0 +1,13 @@
|
||||
# CONFIG.win32-x86-static.win32-x86.static
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for win32-x86-static target archs when host arch is win32-x86-static
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86-static.win32-x86-static
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.win32-x86.win32-x86
|
||||
|
||||
SHARED_LIBRARIES = NO
|
||||
STATIC_BUILD = YES
|
||||
@@ -16,6 +16,7 @@ RM = $(PERL) -MExtUtils::Command -e rm_f
|
||||
MKDIR = $(PERL) -MExtUtils::Command -e mkpath
|
||||
RMDIR = $(PERL) -MExtUtils::Command -e rm_rf
|
||||
NOP = $(PERL) -e ''
|
||||
CAT = $(PERL) -MExtUtils::Command -e cat
|
||||
|
||||
WIND_HOST_TYPE = x86-win32
|
||||
OSITHREAD_USE_DEFAULT_STACK = NO
|
||||
|
||||
@@ -15,9 +15,6 @@ CMPLR_CLASS = msvc
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
#
|
||||
# "\ " forces gnu make to keep this as one token
|
||||
#
|
||||
WINLINK = link
|
||||
|
||||
RCCMD = rc -l 0x409 $(INCLUDES) -fo $@ $<
|
||||
@@ -43,19 +40,13 @@ WARN_CFLAGS_NO = -W1
|
||||
|
||||
#
|
||||
# -Ox maximum optimizations
|
||||
# -MD use MSVCRT (run-time as DLL, multi-thread support)
|
||||
# -GL whole program optimization
|
||||
# -Zi generate program database for debugging information
|
||||
OPT_CFLAGS_YES = -Ox -GL
|
||||
# -Oy- re-enable creation of frame pointers
|
||||
OPT_CFLAGS_YES = -Ox -GL -Oy-
|
||||
|
||||
#
|
||||
# -Zi generate program database for debugging information
|
||||
# -Z7 include debugging info in object files
|
||||
# -Fr create source browser file
|
||||
# -GZ catch bugs occurring only in optimized code
|
||||
# -D_CRTDBG_MAP_ALLOC
|
||||
# -RTCsu catch bugs occuring only inoptimized code
|
||||
# -DEPICS_FREELIST_DEBUG good for detecting mem mrg bugs
|
||||
OPT_CFLAGS_NO = -Zi -RTCsu
|
||||
|
||||
# specify object file name and location
|
||||
@@ -81,23 +72,18 @@ STATIC_CFLAGS_NO= -MD$(VISC_CFLAGS_DEBUG) $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL
|
||||
|
||||
# OS vendor c preprocessor
|
||||
CPP = cl -C -E
|
||||
#GNU c preprocessor
|
||||
#CPP = gcc -x c -E
|
||||
|
||||
# Configure OS vendor C++ compiler
|
||||
#
|
||||
# __STDC__=0 is a real great idea of Jeff that gives us both:
|
||||
# __STDC__=0 gives us both:
|
||||
# 1) define STDC for code (pretend ANSI conformance)
|
||||
# 2) set it to 0 to use MS C "extensions" (open for _open etc.)
|
||||
# because MS uses: if __STDC__ ... disable many nice things
|
||||
#
|
||||
# Use of -Za would dissable DLL import/export keywords which
|
||||
# include/excludes using architecture neutral macros
|
||||
#
|
||||
# -EHsc - generate code for exceptions
|
||||
# -GR - generate code for run time type identification
|
||||
#
|
||||
CCC = cl -nologo -EHsc -GR
|
||||
CCC = cl -EHsc -GR
|
||||
CODE_CPPFLAGS += -nologo -D__STDC__=0
|
||||
CODE_CPPFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
|
||||
|
||||
@@ -111,16 +97,12 @@ WARN_CXXFLAGS_NO = -W1
|
||||
#
|
||||
# -Ox maximum optimizations
|
||||
# -GL whole program optimization
|
||||
# -Zi generate program database for debugging information
|
||||
OPT_CXXFLAGS_YES = -Ox -GL
|
||||
# -Oy- re-enable creation of frame pointers
|
||||
OPT_CXXFLAGS_YES = -Ox -GL -Oy-
|
||||
|
||||
#
|
||||
# -Zi generate program database for debugging information
|
||||
# -Z7 include debugging info in object files
|
||||
# -Fr create source browser file
|
||||
# -D_CRTDBG_MAP_ALLOC
|
||||
# -RTCsu catch bugs occurring only in optimized code
|
||||
# -DEPICS_FREELIST_DEBUG good for detecting mem mrg bugs
|
||||
OPT_CXXFLAGS_NO = -RTCsu -Zi
|
||||
|
||||
# specify object file name and location
|
||||
@@ -143,10 +125,12 @@ STATIC_LDLIBS_NO=
|
||||
STATIC_LDFLAGS=
|
||||
RANLIB=
|
||||
|
||||
#
|
||||
# add -profile here to run the ms profiler
|
||||
# -LTCG - whole program optimization
|
||||
# -fixed:no good for programs such as purify and quantify
|
||||
# -debug good for programs such as purify and quantify
|
||||
# -LTCG whole program optimization
|
||||
# -incremental:no full linking
|
||||
# -fixed:no generate relocatable code
|
||||
# -debug generate debugging info
|
||||
LINK_OPT_FLAGS_YES = -LTCG -incremental:no -opt:ref \
|
||||
-release $(PROD_VERSION:%=-version:%)
|
||||
LINK_OPT_FLAGS_NO = -debug -incremental:no -fixed:no
|
||||
@@ -177,16 +161,13 @@ COMPILER_CXXFLAGS = -TP
|
||||
OP_SYS_CFLAGS =
|
||||
OP_SYS_CXXFLAGS = $(COMPILER_CXXFLAGS)
|
||||
|
||||
#
|
||||
# Files and flags needed to link DLLs (used in RULES_BUILD)
|
||||
#
|
||||
# Strange but seems to work without: WIN32_DLLFLAGS should contain
|
||||
# an entry point:
|
||||
# '-entry:_DllMainCRTStartup$(DLLENTRY)'
|
||||
DLLENTRY = @12
|
||||
|
||||
WIN32_DLLFLAGS = -subsystem:windows -dll $(OPT_LDFLAGS) $(USR_LDFLAGS) $(TARGET_LDFLAGS) $(LIB_LDFLAGS)
|
||||
WIN32_DLLFLAGS = -subsystem:windows -dll \
|
||||
$(OPT_LDFLAGS) $(USR_LDFLAGS) $(TARGET_LDFLAGS) $(LIB_LDFLAGS)
|
||||
|
||||
#
|
||||
# specify dll .def file only if it exists
|
||||
#
|
||||
DLL_DEF_FLAG = $(addprefix -def:,$(wildcard ../$(addsuffix .def,$*)))
|
||||
@@ -197,9 +178,9 @@ DLL_DEF_FLAG = $(addprefix -def:,$(wildcard ../$(addsuffix .def,$*)))
|
||||
# x.lib: what you link to progs that use the dll (DLLSTUB_LIBNAME)
|
||||
# x.exp: what you need to build the dll (in no variable)
|
||||
#
|
||||
LINK.shrlib = $(WINLINK) -nologo $(WIN32_DLLFLAGS) -implib:$*.lib -out:$*.dll \
|
||||
LINK.shrlib = $(WINLINK) -nologo $(WIN32_DLLFLAGS) -out:$@ \
|
||||
-implib:$(@:%$(SHRLIB_SUFFIX)=%$(LIB_SUFFIX)) \
|
||||
$(DLL_DEF_FLAG) $(LIBRARY_LD_OBJS) $(LIBRARY_LD_RESS) $(SHRLIB_LDLIBS)
|
||||
#MUNCH_CMD = $(CCC) -Fo $@ $^
|
||||
|
||||
|
||||
# adjust names of libraries to build
|
||||
@@ -208,12 +189,13 @@ SHRLIB_SUFFIX_BASE = .dll
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
SHRLIBNAME_YES = $(BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX))
|
||||
LOADABLE_SHRLIBNAME = $(LOADABLE_BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX))
|
||||
TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX))
|
||||
TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX_BASE))
|
||||
|
||||
#
|
||||
# When SHARED_LIBRARIES is YES we are building a DLL link library
|
||||
# and when SHARED_LIBRARIES is NO we are building an object library
|
||||
#
|
||||
DLLSTUB_SUFFIX = .lib
|
||||
DLLSTUB_LIBNAME_YES = $(BUILD_LIBRARY:%=%.lib)
|
||||
DLLSTUB_LIBNAME = $(DLLSTUB_LIBNAME_$(SHARED_LIBRARIES))
|
||||
TESTDLLSTUB_LIBNAME_YES = $(TESTBUILD_LIBRARY:%=%.lib)
|
||||
@@ -235,13 +217,15 @@ INSTALL_SHRLIB = $(INSTALL_BIN)
|
||||
|
||||
PROD_DEPLIBS = $(foreach lib, $(PROD_LIBS) $(USR_LIBS), \
|
||||
$(firstword $(wildcard \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS))) \
|
||||
$(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), $(INSTALL_LIB))))
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB)))))
|
||||
|
||||
|
||||
PROD_LDLIBS += $($*_DEPLIBS) $(PROD_DEPLIBS)
|
||||
PROD_LDLIBS += $(addsuffix .lib, \
|
||||
@@ -261,13 +245,14 @@ PROD_LDLIBS += $(STATIC_LDLIBS) \
|
||||
|
||||
SHRLIB_DEPLIBS = $(foreach lib, $(LIB_LIBS) $(USR_LIBS), \
|
||||
$(firstword $(wildcard \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
$(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS))) \
|
||||
$(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), $(INSTALL_LIB))))
|
||||
$($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \
|
||||
) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \
|
||||
$(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB)))))
|
||||
|
||||
|
||||
SHRLIB_LDLIBS += $($*_DLL_DEPLIBS) $($*_DEPLIBS) $(SHRLIB_DEPLIBS)
|
||||
|
||||
14
configure/os/CONFIG.win32-x86.win32-x86-static
Normal file
14
configure/os/CONFIG.win32-x86.win32-x86-static
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.win32-x86.win32-x86-static
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for win32-x86-static target archs when host arch is win32-x86
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86.win32-x86-static
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.win32-x86.win32-x86
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
SHARED_LIBRARIES = NO
|
||||
STATIC_BUILD = YES
|
||||
11
configure/os/CONFIG.windows-x64-mingw.Common
Normal file
11
configure/os/CONFIG.windows-x64-mingw.Common
Normal file
@@ -0,0 +1,11 @@
|
||||
# CONFIG.windows-x64-mingw.Common
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for windows-x64-mingw host archs
|
||||
# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.Common
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.win32-x86-mingw.Common
|
||||
|
||||
11
configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw
Normal file
11
configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw
Normal file
@@ -0,0 +1,11 @@
|
||||
# CONFIG.windows-x64-mingw.windows-x64-mingw
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for windows-x64-mingw target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.windows-x64-mingw
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include common gnu compiler definitions
|
||||
include $(CONFIG)/os/CONFIG.win32-x86-mingw.win32-x86-mingw
|
||||
11
configure/os/CONFIG.windows-x64-static.Common
Normal file
11
configure/os/CONFIG.windows-x64-static.Common
Normal file
@@ -0,0 +1,11 @@
|
||||
# CONFIG.windows-x64-static.Common
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for windows-x64-static host archs
|
||||
# Sites may override these definitions in CONFIG_SITE.windows-x64-static.Common
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.windows-x64.Common
|
||||
|
||||
13
configure/os/CONFIG.windows-x64-static.windows-x64-static
Normal file
13
configure/os/CONFIG.windows-x64-static.windows-x64-static
Normal file
@@ -0,0 +1,13 @@
|
||||
# CONFIG.windows-x64-static.windows-x64-static
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for windows-x64-static target archs when host arch is windows-x64-static
|
||||
# Sites may override these definitions in CONFIG_SITE.windows-x64-static.windows-x64-static
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.windows-x64.windows-x64
|
||||
|
||||
SHARED_LIBRARIES = NO
|
||||
STATIC_BUILD= YES
|
||||
14
configure/os/CONFIG.windows-x64.windows-x64-static
Normal file
14
configure/os/CONFIG.windows-x64.windows-x64-static
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.windows-x86.windows-x86-static
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for windows-x64-static target archs when host arch is windows-x64
|
||||
# Sites may override these definitions in CONFIG_SITE.windows-x64.windows-x64-static
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.windows-x64.windows-x64
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
SHARED_LIBRARIES = NO
|
||||
STATIC_BUILD = YES
|
||||
@@ -5,21 +5,22 @@
|
||||
|
||||
# Where to find RTEMS
|
||||
#
|
||||
RTEMS_VERSION=4.9.2
|
||||
RTEMS_BASE=/usr/local/rtems/rtems-$(RTEMS_VERSION)
|
||||
RTEMS_VERSION = 4.10.2
|
||||
RTEMS_BASE = /usr/local/rtems/rtems-$(RTEMS_VERSION)
|
||||
|
||||
# Cross-compile toolchain in $(RTEMS_TOOLS)/bin
|
||||
#
|
||||
RTEMS_TOOLS=$(RTEMS_BASE)
|
||||
RTEMS_TOOLS = $(RTEMS_BASE)
|
||||
|
||||
|
||||
# If you're using neither BOOTP/DHCP nor FLASH to pick up your IOC
|
||||
# network configuration you must uncomment and specify your Internet
|
||||
# network configuration you must uncomment and specify your Internet
|
||||
# Domain Name here
|
||||
#
|
||||
#OP_SYS_CFLAGS += -DRTEMS_NETWORK_CONFIG_DNS_DOMAINNAME=<domainname>
|
||||
|
||||
#
|
||||
# Specify your desired command-line-input library
|
||||
# Select the command-line-input library to use
|
||||
#
|
||||
COMMANDLINE_LIBRARY = EPICS
|
||||
#COMMANDLINE_LIBRARY = LIBTECLA
|
||||
#COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
# $Revision-Id$
|
||||
#
|
||||
# Site Specific definitions for cygwin-x86 target
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# Currently the Cygwin build only works without shared libraries.
|
||||
SHARED_LIBRARIES = NO
|
||||
STATIC_BUILD = YES
|
||||
|
||||
# Depending on your version of Cygwin you'll want one of the following
|
||||
# lines to enable command-line editing and history in iocsh. If you're
|
||||
@@ -23,4 +18,3 @@ COMMANDLINE_LIBRARY = READLINE_NCURSESW
|
||||
|
||||
# No other libraries needed
|
||||
#COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
|
||||
14
configure/os/CONFIG_SITE.Common.cygwin-x86_64
Normal file
14
configure/os/CONFIG_SITE.Common.cygwin-x86_64
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG_SITE.Common.cygwin-x86_64
|
||||
#
|
||||
# $Revision-Id$
|
||||
#
|
||||
# Site Specific definitions for cygwin-x86_64 target
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# If readline is installed uncomment the following line
|
||||
# to add command-line editing and history support
|
||||
#COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
# Uncomment the following line if readline has problems
|
||||
#LDLIBS_READLINE = -lreadline -lcurses
|
||||
|
||||
@@ -7,16 +7,33 @@
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Select which CPU architecture(s) to include in your MacOS binaries:
|
||||
# i386
|
||||
# x86_64 - Needs MacOS 10.4 with the Universal SDK, or 10.5 and later
|
||||
# i386, x86_64, or both (fat binaries).
|
||||
|
||||
ARCH_CLASS = i386
|
||||
#ARCH_CLASS = x86_64
|
||||
#ARCH_CLASS = i386
|
||||
ARCH_CLASS = x86_64
|
||||
#ARCH_CLASS = i386 x86_64
|
||||
|
||||
# Uncomment the followings lines to build with CLANG instead of GCC.
|
||||
#
|
||||
#GNU = NO
|
||||
#CMPLR_CLASS = clang
|
||||
#CC = clang
|
||||
#CCC = clang++
|
||||
# Uncomment the following 3 lines to build with Apple's GCC instead of CLANG.
|
||||
#
|
||||
#CMPLR_CLASS = gcc
|
||||
#CC = gcc
|
||||
#CCC = g++
|
||||
#GNU = YES
|
||||
|
||||
|
||||
# To use MacPorts GCC uncomment (and modify if necessary) the following:
|
||||
|
||||
#GNU_DIR = /opt/local
|
||||
#CMPLR_CLASS = gcc
|
||||
#CC = $(GNU_BIN)/gcc -m64
|
||||
#CCC = $(GNU_BIN)/g++ -m64
|
||||
#GNU = YES
|
||||
|
||||
# If you see this or similar errors while building in the src/cap5 directory
|
||||
# gcc: error: unrecognized option '-no-cpp-precomp'
|
||||
# the problem is due to the ccflags configuration that your version of Perl
|
||||
# was built with. You can replace the Cap5_CFLAGS setting in the Makefile
|
||||
# with a hand-edited set of flags for building that Perl library, or ignore
|
||||
# this problem if you don't need to use Channel Access from Perl.
|
||||
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
# CONFIG_SITE.Common.ios-arm
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Site-specific settings for ios-arm target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Which ARM instruction set(s) to generate code for:
|
||||
# Most iOS devices can run programs compiled for both the
|
||||
# ARMv6 and ARMv7 instruction sets. ARMv7 code is usually
|
||||
# more efficient, but the older devices listed below can only
|
||||
# use the ARMv6 instruction set. Including both architectures
|
||||
# generates a Universal binary, which is larger and takes
|
||||
# longer to compile but runs efficiently on all devices.
|
||||
# Most iOS devices can run programs compiled for older
|
||||
# instruction sets, although the newer instructions are
|
||||
# more efficient.
|
||||
#
|
||||
# ARMv6-only devices: iPhone 1 or 3G, iPod Touch Gen 1 or 2
|
||||
# Apple's compilers can build for multiple architectures,
|
||||
# generating a Universal binary. This is larger and takes
|
||||
# longer to compile, but runs efficiently on all devices.
|
||||
#
|
||||
ARCH_CLASS = armv7
|
||||
# Xcode 4.5 dropped support for the ARMv6.
|
||||
#
|
||||
# ARMv8 (arm64) devices: iPhone 5S
|
||||
# ARMv7s devices: iPhone 5 and 5C, iPad Gen 4
|
||||
# ARMv7 devices: iPhone 3GS, 4 and 4S, iPod Touch Gen 3 to 5
|
||||
# iPad Gen 1 to 3, iPad Mini, Apple TV Gen 2 and 3
|
||||
# ARMv6 devices: iPhone 1 and 3G, iPod Touch Gen 1 and 2
|
||||
|
||||
#ARCH_CLASS = arm64
|
||||
#ARCH_CLASS = armv7s arm64
|
||||
ARCH_CLASS = armv7 armv7s arm64
|
||||
#ARCH_CLASS = armv7 armv7s
|
||||
#ARCH_CLASS = armv7
|
||||
#ARCH_CLASS = armv6 armv7
|
||||
#ARCH_CLASS = armv6
|
||||
|
||||
@@ -1,27 +1,39 @@
|
||||
# CONFIG_SITE.Common.iosCommon
|
||||
#
|
||||
# $Revision-Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Site-specific settings for Apple iOS builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# iOS Version number
|
||||
# iOS SDK Version number (not the XCode version).
|
||||
# We haven't tested our current build rules on the older
|
||||
# versions of either XCode or the iOS SDK, be warned!
|
||||
|
||||
#IOS_VERSION = 3.2
|
||||
#IOS_VERSION = 4.1
|
||||
#IOS_VERSION = 4.2
|
||||
#IOS_VERSION = 4.3
|
||||
IOS_VERSION = 5.0
|
||||
#IOS_VERSION = 5.0
|
||||
#IOS_VERSION = 5.1
|
||||
#IOS_VERSION = 6.0
|
||||
#IOS_VERSION = 6.1
|
||||
#IOS_VERSION = 7.0
|
||||
IOS_VERSION = 8.0
|
||||
|
||||
# Minimum version of iOS the executables must run on.
|
||||
# Earlier versions may work, if XCode supports them.
|
||||
|
||||
#IOS_DEPLOYMENT_TARGET = 5.0
|
||||
#IOS_DEPLOYMENT_TARGET = 5.1
|
||||
#IOS_DEPLOYMENT_TARGET = 6.0
|
||||
#IOS_DEPLOYMENT_TARGET = 6.1
|
||||
IOS_DEPLOYMENT_TARGET = 7.0
|
||||
#IOS_DEPLOYMENT_TARGET = 8.0
|
||||
|
||||
|
||||
# Which compiler to use:
|
||||
# CLANG is preferred for recent versions of Xcode
|
||||
# LLVM uses the llvm-gcc and llvm-g++ compilers
|
||||
# CLANG is required for Xcode 5.0 and later
|
||||
# LLVM_GNU uses the llvm-gcc and llvm-g++ compilers
|
||||
# GNU is needed for older versions of Xcode
|
||||
|
||||
COMPILER = CLANG
|
||||
#COMPILER = LLVM
|
||||
#COMPILER = LLVM_GNU
|
||||
#COMPILER = GNU
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ COMMANDLINE_LIBRARY = READLINE
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
|
||||
# Tune GNU compiler output for a specific cpu-type
|
||||
|
||||
@@ -46,3 +46,4 @@ COMMANDLINE_LIBRARY = READLINE
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
# Site Specific definitions for solaris-sparc target
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# If readline is installed uncomment the following macro definition
|
||||
# to include command-line editing and history support
|
||||
#
|
||||
# location of the Solaris Studio (was SunPro) compilers
|
||||
SPARCWORKS = /opt/SUNWspro
|
||||
#SPARCWORKS = /opt/solarisstudio12.3
|
||||
|
||||
# Readline library provides command-line editing and history in IOC shell
|
||||
# If readline is installed, uncomment the following macro definition
|
||||
# to use it for command-line editing and history support
|
||||
#COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
# Use stLport library instead of default Cstd library
|
||||
|
||||
11
configure/os/CONFIG_SITE.Common.solaris-x86
Normal file
11
configure/os/CONFIG_SITE.Common.solaris-x86
Normal file
@@ -0,0 +1,11 @@
|
||||
# CONFIG_SITE.Common.solaris-x86
|
||||
#
|
||||
# $Revision-Id$
|
||||
#
|
||||
# Site Specific definitions for solaris-x86 targets
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# location of the Solaris Studio (was SunPro) compilers
|
||||
SPARCWORKS = /opt/SUNWspro
|
||||
#SPARCWORKS = /opt/solarisstudio12.3
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Site Specific definitions for solaris-x86_64 target
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# Include definitions common to all solaris-x86_64 target archs
|
||||
# Include definitions common to all solaris-x86 target archs
|
||||
-include $(CONFIG)/os/CONFIG_SITE.Common.solaris-x86
|
||||
|
||||
COMMANDLINE_LIBRARY = EPICS
|
||||
|
||||
@@ -4,7 +4,4 @@
|
||||
#
|
||||
# Site specific override definitions for solaris-sparc host builds
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
#INSTALL_LOCATION = /home/phoebus/JBA/testBaseNew
|
||||
|
||||
#CROSS_COMPILER_TARGET_ARCHS += vxWorks-ppc604 vxWorks-ppc603 vxWorks-68040
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# CONFIG_SITE.windows-x64-mingw.windows-x64-mingw
|
||||
#
|
||||
# $Revision-Id$
|
||||
#
|
||||
# Site Specific definitions for windows-x64-mingw target
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# Prefix for mingw compiler from cygwin
|
||||
#CMPLR_PREFIX = x86_64-w64-mingw32-
|
||||
@@ -4,17 +4,17 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>Known Problems in R3.15.0.1</title>
|
||||
<title>Known Problems in R3.15.0.2</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 style="text-align: center">EPICS Base R3.15.0.1: Known Problems</h1>
|
||||
<h1 style="text-align: center">EPICS Base R3.15.0.2: Known Problems</h1>
|
||||
|
||||
<p>Any patch files linked below should be applied at the root of the
|
||||
base-3.15.0.1 tree. Download them, then use the GNU Patch program as
|
||||
base-3.15.0.2 tree. Download them, then use the GNU Patch program as
|
||||
follows:</p>
|
||||
|
||||
<blockquote><pre>% <b>cd <i>/path/to/</i>base-3.15.0.1</b>
|
||||
<blockquote><pre>% <b>cd <i>/path/to/</i>base-3.15.0.2</b>
|
||||
% <b>patch -p0 < <i>/path/to/</i>file.patch</b></pre></blockquote>
|
||||
|
||||
<p>The following significant problems have been reported with this
|
||||
@@ -24,6 +24,10 @@ version of EPICS Base:</p>
|
||||
<li>64-bit Windows builds may not work with some tool-sets, the code in
|
||||
<tt>src/legacy/gdd</tt> is not comptible with the LLP64 model that Windows
|
||||
uses for its 64-bit ABI.</li>
|
||||
<li>The <tt>-x</tt> option to the softIoc program loads a standard database
|
||||
that is supposed to be able to exit the running IOC. In this release that
|
||||
causes an assertion failure which prints a stack trace and suspends the
|
||||
program wihout exiting.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Installation Instructions
|
||||
|
||||
EPICS Base Release 3.15.0.1
|
||||
EPICS Base Release 3.15.0.2
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* Software requirements
|
||||
* Host system storage requirements
|
||||
* Documentation
|
||||
* WWW pages
|
||||
* Directory Structure
|
||||
* Build related components
|
||||
* Building EPICS base (Unix and Win32)
|
||||
@@ -198,7 +197,6 @@
|
||||
RULES_DIRS Definitions and rules for building subdirectories
|
||||
RULES_EXPAND
|
||||
RULES_FILE_TYPE
|
||||
RULES_JAVA Definitions and rules for java jars and classes
|
||||
RULES_TARGET
|
||||
RULES_TOP Rules specific to a <top> dir (uninstall and tar)
|
||||
Sample.Makefile Sample makefile with comments
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<BODY>
|
||||
<CENTER>
|
||||
<H1>Installation Instructions</H1>
|
||||
<H2>EPICS Base Release 3.15.0.1</H2><BR>
|
||||
<H2>EPICS Base Release 3.15.0.2</H2><BR>
|
||||
</CENTER>
|
||||
<HR>
|
||||
<H3> Table of Contents</H3>
|
||||
@@ -22,7 +22,6 @@
|
||||
<LI><A HREF="#0_0_6"> Software requirements</A></LI>
|
||||
<LI><A HREF="#0_0_7"> Host system storage requirements</A></LI>
|
||||
<LI><A HREF="#0_0_8"> Documentation</A></LI>
|
||||
<LI><A HREF="#0_0_9"> WWW pages</A></LI>
|
||||
<LI><A HREF="#0_0_10"> Directory Structure</A></LI>
|
||||
<LI><A HREF="#0_0_11"> Build related components</A></LI>
|
||||
<LI><A HREF="#0_0_12"> Building EPICS base (Unix and Win32)</A></LI>
|
||||
@@ -209,7 +208,6 @@
|
||||
RULES_DIRS Definitions and rules for building subdirectories
|
||||
RULES_EXPAND
|
||||
RULES_FILE_TYPE
|
||||
RULES_JAVA Definitions and rules for java jars and classes
|
||||
RULES_TARGET
|
||||
RULES_TOP Rules specific to a <top> dir (uninstall and tar)
|
||||
Sample.Makefile Sample makefile with comments
|
||||
|
||||
@@ -7,14 +7,489 @@
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
<h1 align="center">EPICS Base Release 3.15.0.1</h1>
|
||||
<h1 align="center">EPICS Base Release 3.15.0.2</h1>
|
||||
|
||||
<p>
|
||||
EPICS Base 3.15.0.x releases are not intended for use in production systems.</p>
|
||||
|
||||
<h2 align="center">Changes between 3.14.x and 3.15.0.1</h2>
|
||||
<h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>New iocshLoad command</h3>
|
||||
|
||||
<p>A new command <tt>iocshLoad</tt> has been added to iocsh which executes a
|
||||
named iocsh script and can also set one or more shell macro variables at the
|
||||
same time, the values of which will be forgotten immediately after the named
|
||||
script finishes executing. The following example shows the syntax:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
iocshLoad "serial.cmd", "DEV=/dev/ttyS0,PORT=com1,TYPE=RS485"
|
||||
iocshLoad "radmon.cmd", "PORT=com1,ADDR=0"
|
||||
</pre></blockquote>
|
||||
|
||||
<h3>Support routines for 64-bit integers</h3>
|
||||
|
||||
<p>The libCom library now provides support for 64-bit integer types on all
|
||||
supported architectures. The epicsTypes.h header file defines epicsInt64 and
|
||||
epicsUInt64 type definitions for both C and C++ code. The epicsStdlib.h header
|
||||
also declares the following for parsing strings into the relevent sized integer
|
||||
variables: Functions epicsParseLLong(), epicsParseULLong() with related macros
|
||||
epicsScanLLong() and epicsScanULLong(), and the functions epicsParseInt64()
|
||||
and epicsParseUInt64(). Use the first two functions and the macros for long long
|
||||
and unsigned long long integer types, and the last two functions for the
|
||||
epicsInt64 and epicsUInt64 types. Note that the latter can map to the types long
|
||||
and unsigned long on some 64-bit architectures such as linux-x86_64, not to the
|
||||
two long long types.</p>
|
||||
|
||||
<p>This version does not provide the ability to define 64-bit record fields, the
|
||||
use of the 64-bit types in the IOC database will come in a later release of
|
||||
EPICS Base.</p>
|
||||
|
||||
<h3>Full support for loadable support modules</h3>
|
||||
|
||||
<p>Apparently later versions of Base 3.14 permitted support modules to be loaded
|
||||
from a shared library at runtime without the IOC having been linked against that
|
||||
shared library; the registerRecordDeviceDriver.pl program would accept a partial
|
||||
DBD file containing just the entries needed for the library and generate the
|
||||
appropriate registration code. In 3.15 however the registerRecordDeviceDriver.pl
|
||||
program was replaced by one using the new DBD file parser, and in this a device
|
||||
support entry would only be accepted after first loading the record type that it
|
||||
depended on.</p>
|
||||
|
||||
<p>The parser has been modified to accept device entries without having seen the
|
||||
record type first, although a warning is given when that happens. To remove the
|
||||
warning the DBD file can provide a record type declaration instead (no fields
|
||||
can be defined, so the braces must be empty), before the device() entry. The
|
||||
result will generate the correct registration code for the device entry without
|
||||
including anything for any merely declared record types. The generated code can
|
||||
be linked into a shared library and loaded by an IOC at runtime using dlload.
|
||||
</p>
|
||||
|
||||
<h3>Parallel callback threads</h3>
|
||||
|
||||
<p>The general purpose callback facility can run multiple parallel callback
|
||||
threads per priority level. This makes better use of SMP architectures (e.g.
|
||||
processors with multiple cores), as callback work - which includes second
|
||||
stage processing of records with asynchronuous device support and I/O
|
||||
scanned processing - can be distributed over the available CPUs.</p>
|
||||
|
||||
<p>Note that by using parallel callback threads the order of scan callback
|
||||
requests in the queue is not retained. If a device support needs to be
|
||||
informed when scanIoRequest processing has finished, it should use the new
|
||||
scanIoSetComplete() feature to add a user function that will be called after
|
||||
the scanIoRequest record processing has finished.</p>
|
||||
|
||||
<p>Parallel callback threads have to be explicitly configured, by default
|
||||
the IOC keeps the old behavior of running one callback thread per priority.</p>
|
||||
|
||||
<h3>Merge MMIO API from devLib2</h3>
|
||||
|
||||
<p>Added calls to handle 8, 16, and 32 bit Memory Mapped I/O reads and writes.
|
||||
The calls added include <tt><i>X</i>_iowrite<i>Y</i>()</tt> and
|
||||
<tt><i>X</i>_ioread<i>Y</i>()</tt>
|
||||
where <tt><i>X</i></tt> is <tt>nat</tt> (native), <tt>be</tt> or <tt>le</tt>,
|
||||
and <tt><i>Y</i></tt> is <tt>16</tt> or <tt>32</tt>.
|
||||
Also added are <tt>ioread8()</tt> and <tt>iowrite8()</tt>.</p>
|
||||
|
||||
<h3>Added optional dbServer API to database</h3>
|
||||
|
||||
<p>A server layer that sits on top of the IOC database may now register itself
|
||||
as such by calling <tt>dbRegisterServer()</tt> and providing optional routines
|
||||
that other components can use. The initial purpose of this API allows the Trace
|
||||
Processing implementation in <tt>dbProcess()</tt> to identify a client that
|
||||
causes a record to process when TPRO is set.</p>
|
||||
|
||||
<p>To support the client idenfication, the server provides a routine that
|
||||
returns that identity string when called by one of its own processing
|
||||
threads.</p>
|
||||
|
||||
<h3>Concatenated database definition files</h3>
|
||||
|
||||
<p>A series of database definition (dbd) files can now be concatenated during
|
||||
the build process into a newly-created dbd file with result being installed into
|
||||
$(INSTALL_LOCATION)/dbd without expanding it.</p>
|
||||
|
||||
<p>The following lines in an EPICS Makefile will create a file name.dbd in the
|
||||
O.Common build directory containing the contents of file1.dbd followed by
|
||||
file2.dbd then file3.dbd. The new file will then be installed into
|
||||
$(INSTALL_LOCATION)/dbd without expanding any of its include statements.</p>
|
||||
|
||||
<blockquote><pre>
|
||||
DBDCAT += name.dbd
|
||||
name_DBD += file1.dbd file2.dbd file3.dbd
|
||||
</pre></blockquote>
|
||||
|
||||
<p>The source files file1.dbd, file2.dbd and file3.dbd may be created by the
|
||||
current Makefile, be located in the parent directory or any other directory in
|
||||
the SRC_DIRS list, be specified by their full pathname, exist in the install dbd
|
||||
directory, or be found in any dbd directory linked from the application's
|
||||
RELEASE files.</p>
|
||||
|
||||
<h3>Posix: Drop SCHED_FIFO before exec() in child process</h3>
|
||||
|
||||
<p>If Base is compiled with <tt>USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES</tt>
|
||||
in configure/CONFIG_SITE or related files, the Posix implementation of the
|
||||
libCom <tt>osiSpawnDetachedProcess()</tt> routine will switch the child process
|
||||
to use the normal SCHED_OTHER (non real-time) scheduler before executing the
|
||||
named executable program. If it needs to use the real-time scheduler the new
|
||||
program can request that for itself.</p>
|
||||
|
||||
<h3>Posix: Lock all memory when running with FIFO scheduler</h3>
|
||||
|
||||
<p>On Posix systems, an IOC application's ability to meet timing deadlines is
|
||||
often dependent on its ability to lock part or all of the process's virtual
|
||||
address space into RAM, preventing that memory from being paged to the swap
|
||||
area. This change will attempt to lock the process's virtual address space into
|
||||
RAM if the process has the ability to run threads with different priorities. If
|
||||
unsuccessful, it prints an message to stderr and continues.</p>
|
||||
|
||||
<p>On Linux, one can grant a process the ability to run threads with different
|
||||
priorities by using the command <code>ulimit -r unlimited</code>. To use the
|
||||
FIFO scheduler for an IOC, use a command like this:</p>
|
||||
|
||||
<blockquote><pre>chrt -f 1 softIoc -d test.db</pre></blockquote>
|
||||
|
||||
<p>On Linux, one can grant a process the ability to lock itself into memory
|
||||
using the command <code>ulimit -l unlimited</code>. These limits can also be
|
||||
configured on a per user/per group basis by changing /etc/security/limits.conf
|
||||
or its equivalent.</p>
|
||||
|
||||
<p>A child process created via fork() normally inherits its parent's resource
|
||||
limits, so a child of a real-time soft-IOC will get its parent's real-time
|
||||
priority and memlock limits. The memory locks themselves however are not
|
||||
inherited by child processes.</p>
|
||||
|
||||
<h3>Implement EPICS_CAS_INTF_ADDR_LIST in rsrv</h3>
|
||||
|
||||
<p>The IOC server can now bind to a single IP address (and optional port number)
|
||||
read from the standard environment parameter EPICS_CAS_INTF_ADDR_LIST.
|
||||
Additional addresses included in that parameter after the first will be ignored
|
||||
and a warning message displayed at iocInit time.</p>
|
||||
|
||||
<h3>alarmString.h deprecated again</h3>
|
||||
|
||||
<p>The string arrays that provide string versions of the alarm status and
|
||||
severity values have been moved into libCom and the header file that used to
|
||||
instanciate them is no longer required, although a copy is still provided for
|
||||
backwards compatibility reasons. Only the alarm.h header needs to be included
|
||||
now to declare the epicsAlarmSeverityStrings and epicsAlarmConditionStrings
|
||||
arrays.</p>
|
||||
|
||||
<h3>General purpose thread pool</h3>
|
||||
|
||||
<p>
|
||||
A general purpose threaded work queue API epicsThreadPool is added.
|
||||
Multiple pools can be created with controlable priority and number
|
||||
of worker threads. Lazy worker startup is supported.</p>
|
||||
|
||||
<h3>Database field setting updates</h3>
|
||||
|
||||
<p>A database (.db) file loaded by an IOC does not have to repeat the record
|
||||
type of a record that has already been loaded. It may replace the first
|
||||
parameter of the <tt>record(type, name)</tt> statement with an asterisk
|
||||
character inside double-quotes, <tt>"*"</tt> instead. Thus the following is a
|
||||
legal database file:</p>
|
||||
|
||||
<blockquote><pre>record(ao, "ao1") {}
|
||||
record("*", "ao1") {
|
||||
field(VAL, 10)
|
||||
}</pre></blockquote>
|
||||
|
||||
<p>Note that database configuration tools will not be expected to have to
|
||||
understand this syntax, which is provided for scripted and hand-coded database
|
||||
and template instantiation only. Setting the IOC's <tt>dbRecordsOnceOnly</tt>
|
||||
flag also makes this syntax illegal, since its purpose is to prevent
|
||||
multiply-defined records from being collapsed into a single instance.</p>
|
||||
|
||||
<h3>Added echo command to iocsh</h3>
|
||||
|
||||
<p>The single argument string may contain escaped characters, which will be
|
||||
translated to their raw form before being printed (enclose the string in quotes
|
||||
to avoid double-translation). A newline is always appended to the output, and
|
||||
output stream redirection is supported.</p>
|
||||
|
||||
<h3>Added macro EPICS_UNUSED to compilerDependencies.h</h3>
|
||||
|
||||
<p>To prevent the compiler from warning about a known-unused variable, mark it
|
||||
with the macro EPICS_UNUSED. On gcc and clang this will expand to
|
||||
<tt>__attribute__((unused))</tt> to prevent the warning.</p>
|
||||
|
||||
<h3>User specified db substitution file suffix</h3>
|
||||
|
||||
<p>Per Dirk Zimoch's suggestion, a user specified db substitution file suffix is
|
||||
now allowed by setting the variable SUBST_SUFFIX in a configuration directory
|
||||
CONFIG_SITE file or in a Makefile before the include $(TOP)/configure/RULES
|
||||
line. The default for SUBST_SUFFIX is <tt>.substitutions</tt></p>
|
||||
|
||||
<h3>NTP Time Provider adjusts to OS tick rate changes</h3>
|
||||
|
||||
<p>Dirk Zimoch provided code that allows the NTP Time provider (used on VxWorks
|
||||
and RTEMS only) to adapt to changes in the OS clock tick rate after the provider
|
||||
has been initialized. Note that changing the tick rate after iocInit() is not
|
||||
advisable, and that other software might still misbehave if initialized before
|
||||
an OS tick rate change.</p>
|
||||
|
||||
<h3>Added newEpicsMutex macro</h3>
|
||||
|
||||
<p>Internal C++ uses of <tt>new epicsMutex()</tt> have been replaced with a new
|
||||
macro which calls a new constructor, passing it the file name and line number of
|
||||
the mutex creation code. C code that creates mutexes has been using a similar
|
||||
macro for a long time, but there was no equivalent constructor for the C++
|
||||
wrapper class, so identifying a specific mutex was much harder to do.</p>
|
||||
|
||||
<h3>Post DBE_PROPERTY events automatically</h3>
|
||||
|
||||
<p>A new record field attribute "prop(YES)" has been added to identify fields
|
||||
holding meta-data. External changes to these fields will cause a CA monitor
|
||||
event to be sent to all record subscribers who have asked for DBE_PROPERTY
|
||||
updates. Meta-data fields have been marked for all Base record types.</p>
|
||||
|
||||
<h3>errlogRemoveListener() routine changed</h3>
|
||||
|
||||
<p>Code that calls <tt>errlogRemoveListener(myfunc)</tt> must be modified to use
|
||||
the new, safer routine <tt>errlogRemoveListeners(myfunc, &pvt)</tt> instead.
|
||||
The replacement routine takes a second argument which must be the same private
|
||||
pointer that was passed to <tt>errlogAddListener()</tt> when adding that
|
||||
listener. It also deletes all matching listeners (hence the new plural name) and
|
||||
returns how many were actually deleted, whereas the previous routine only
|
||||
removed the first listener that matched.</p>
|
||||
|
||||
<h3>Simplified generation of .dbd files</h3>
|
||||
|
||||
<p>The Perl script <tt>makeIncludeDbd.pl</tt> has been removed and the rules
|
||||
that created an intermediate <tt><i>xxx</i>Include.dbd</tt> file from the
|
||||
Makefile variable <tt>xxx_DBD</tt> have been modified to generate the target
|
||||
<tt><i>xxx</i>.dbd</tt> file directly. This should simplify applications that
|
||||
might have had to provide dependency rules for the intermediate files in 3.15.
|
||||
Applications which provide their own <tt><i>xxx</i>Include.dbd</tt> source file
|
||||
will continue to have it expanded as before.</p>
|
||||
|
||||
<h3>New Undefined Severity field UDFS</h3>
|
||||
|
||||
<p>A new field has been added to dbCommon which configures the alarm severity
|
||||
associated with the record being undefined (when UDF=TRUE). The default value is
|
||||
INVALID so old databases will not be affected, but now individual records can be
|
||||
configured to have a lower severity or even no alarm when undefined. Be careful
|
||||
when changing this on applications where the IVOA field of output records is
|
||||
used, IVOA still requires an INVALID severity to trigger value replacement.</p>
|
||||
|
||||
<h3>New build target <q>tapfiles</q></h3>
|
||||
|
||||
<p>This new make target runs the same tests as the <q>runtests</q> target, but
|
||||
instead of summarizing or displaying the output for each test script it creates
|
||||
a <q>.tap</q> file inside the architecture build directory which contains the
|
||||
detailed test output. The output file can be parsed by continuous integration
|
||||
packages such as <a href="http://www.jenkins-ci.org/">Jenkins</a> to show the
|
||||
test results.</p>
|
||||
|
||||
<h3>Array field double-buffering</h3>
|
||||
|
||||
<p>Array data can now be moved, without copying, into and out of the VAL field
|
||||
of the waveform, aai, and aao record types by replacing the pointer in BPTR.
|
||||
The basic rules which device support must follow are:</p>
|
||||
|
||||
<ol>
|
||||
<li>BPTR, and the memory it is currently pointing to, can only be accessed
|
||||
while the record is locked.</li>
|
||||
<li>NELM may not be changed; NORD should be updated whenever the number of
|
||||
valid data elements changes.</li>
|
||||
<li>When BPTR is replaced it must always point to a block of memory large
|
||||
enough to hold the maximum number of elements, as given by the NELM and
|
||||
FTVL fields.</li>
|
||||
</ol>
|
||||
|
||||
<h3>Spin-locks API added</h3>
|
||||
|
||||
<p>The new header file epicsSpin.h adds a portable spin-locks API which is
|
||||
intended for locking very short sections of code (typically one or two lines of
|
||||
C or C++) to provide a critical section that protects against race conditions.
|
||||
On Posix platforms this uses the pthread_spinlock_t type if it's available and
|
||||
the build is not configured to use Posix thread priorities, but otherwise it
|
||||
falls back to a pthread_mutex_t. On the UP VxWorks and RTEMS platforms the
|
||||
implementations lock out CPU interrupts and disable task preemption while a
|
||||
spin-lock is held. The default implementation (used when no other implementation
|
||||
is provided) uses an epicsMutex. Spin-locks may not be taken recursively, and
|
||||
the code inside the critical section should be short and deterministic.</p>
|
||||
|
||||
<h3>Improvements to aToIPAddr()</h3>
|
||||
|
||||
<p>The libCom routine aToIPAddr() and the vxWorks implementation of the
|
||||
associated hostToIPAddr() function have been modified to be able to look up
|
||||
hostnames that begin with one or more digits. The epicsSockResolveTest program
|
||||
was added to check this functionality.</p>
|
||||
|
||||
<h3>mbboDirect and mbbiDirect records</h3>
|
||||
|
||||
<p>These record types have undergone some significant rework, and will behave
|
||||
slightly differently than they did in their 3.14 versions. The externally
|
||||
visible changes are as follows:</p>
|
||||
|
||||
<h5>mbbiDirect</h5>
|
||||
|
||||
<ul>
|
||||
<li>If the MASK field is set in a database file, it will not be over-written
|
||||
when the record is initialized. This allows non-contiguous masks to be set,
|
||||
although only the device support actually uses the MASK field.</li>
|
||||
<li>If process() finds the UDF field to be set, the record will raise a
|
||||
UDF/INVALID alarm.</li>
|
||||
</ul>
|
||||
|
||||
<h5>mbboDirect</h5>
|
||||
|
||||
<ul>
|
||||
<li>If the MASK field is set in a database file, it will not be over-written
|
||||
when the record is initialized. This allows non-contiguous masks to be set,
|
||||
although only the device support actually uses the MASK field.</li>
|
||||
<li>After the device support's init_record() routine returns during record
|
||||
initialization, if OMSL is <q>supervisory</q> and UDF is clear the fields
|
||||
B0-BF will be set from the current VAL field.</li>
|
||||
<li>When a put to the OMSL field sets it to <q>supervisory</q>, the fields
|
||||
B0-BF will be set from the current VAL field. This did not used to happen,
|
||||
the individual bit fields were previously never modified by the record.
|
||||
Note that this change may require some databases to be modified, if they
|
||||
were designed to take advantage of the previous behavior.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Redirection of the errlog console stream</h3>
|
||||
|
||||
<p>A new routine has been added to the errlog facility which allows the console
|
||||
error message stream to be redirected from stderr to some other already open
|
||||
file stream:</p>
|
||||
|
||||
<blockquote><pre>int errlogSetConsole(FILE *stream);
|
||||
</pre></blockquote>
|
||||
|
||||
<p>The stream argument must be a FILE* pointer as returned by fopen() that is
|
||||
open for output. If NULL is passed in, the errlog thread's stderr output stream
|
||||
will be used instead. Note that messages to the console can be disabled and
|
||||
re-enabled using the eltc routine which is also an iocsh command, but there is
|
||||
no iocsh command currently provided for calling errlogSetConsole.</p>
|
||||
|
||||
<h3>Add cleanup subroutine to aSub record</h3>
|
||||
|
||||
<p>An aSub routine may set the CADR field with a function pointer which will be
|
||||
run before a new routine in the event that a change to the SNAM field changes
|
||||
the record's process subroutine.</p>
|
||||
|
||||
<p>This can be used to free any resources the routine needs to allocate. It can
|
||||
also be used to determine if this is the first time this routine has been called
|
||||
by this record instance. The CADR field is set to NULL immediately after the
|
||||
routine it points to is called.</p>
|
||||
|
||||
<p>Example:</p>
|
||||
|
||||
<blockquote><pre>void cleanup(aSubRecord* prec) {
|
||||
free(prec->dpvt);
|
||||
prec->dpvt = NULL;
|
||||
}
|
||||
|
||||
long myAsubRoutine(aSubRecord* prec) {
|
||||
if (!prec->cadr) {
|
||||
/* check types of inputs and outputs */
|
||||
if (prec->ftva != menuFtypeDOUBLE)
|
||||
return 1; /* oops */
|
||||
|
||||
dpvt = malloc(42);
|
||||
prec->cadr = &cleanup;
|
||||
}
|
||||
|
||||
/* normal processing */
|
||||
}
|
||||
epicsRegisterFunction(myAsubRoutine);
|
||||
</pre></blockquote>
|
||||
|
||||
<h3>Sequence record enhancements</h3>
|
||||
|
||||
<p>The sequence record type now has 16 link groups numbered 0 through 9 and A
|
||||
through F, instead of the previous 10 groups numbered 1 through 9 and A. The
|
||||
changes to this record are directly equivalent to those described below for the
|
||||
fanout record. The fields OFFS and SHFT have been added and operate on the SELN
|
||||
value exactly the same way. The result is backwards compatible with the 3.14
|
||||
version of the sequence record as long as none of the new fields are modified
|
||||
and the application does not rely on the SOFT/INVALID alarm that was generated
|
||||
when the selection number exceeded 10. The record also now posts monitors on the
|
||||
SELN field at the end of the sequence if its value changed when read through the
|
||||
SELL link.
|
||||
|
||||
<h3>Fanout record enhancements</h3>
|
||||
|
||||
<p>The fanout record type now has 16 output links LNK0-LNK9 and LNKA-LNKF, plus
|
||||
two additional fields which make the result backwards compatible with 3.14
|
||||
databases, but also allow the link selection to be shifted without having to
|
||||
process the SELN value through a calc or calcout record first.</p>
|
||||
|
||||
<p>Previously there was no LNK0 field, so when SELM is <q>Mask</q> bit 0 of SELN
|
||||
controls whether the LNK1 link field was activated; bit 1 controls LNK2 and so
|
||||
on. When SELM is <q>Specified</q> and SELN is zero no output link would be
|
||||
activated at all; LNK1 gets activated when SELN is 1 and so on. Only 6 links
|
||||
were provided, LNK1 through LNK6. The updated record type maintains the original
|
||||
behavior when the new fields are not configured, except that the SOFT/INVALID
|
||||
alarm is not generated when SELN is 7 through 15.</p>
|
||||
|
||||
<p>The update involved adding a LNK0 field, as well as fields LNK7 through LNK9
|
||||
and LNKA through LNKF. To add flexibility and maintain backwards compatibility,
|
||||
two additional fields have been added:</p>
|
||||
|
||||
<dl>
|
||||
<dt><b>OFFS</b></dt>
|
||||
|
||||
<dd>This field holds a signed offset which is added to SELN to select which link
|
||||
to activate when SELM is <q>Specified</q>. If the resulting value is outside the
|
||||
range 0 .. 15 the record will go into a SOFT/INVALID alarm state. The default
|
||||
value of OFFS is zero, so if it is not explicitly set and SELN is 1 the LNK1
|
||||
link will be activated.</dd>
|
||||
|
||||
<dt><b>SHFT</b></dt>
|
||||
|
||||
<dd>When SELM is <q>Mask</q> the signed field SHFT is used to shift the SELN
|
||||
value by SHFT bits (positive means right-wards, values outside the range -15 ..
|
||||
15 will result in a SOFT/INVALID alarm), before using the resulting bit-pattern
|
||||
to control which links to activate. The default value is -1, so if SHFT is not
|
||||
explicitly set bit 0 of SELN will be used to control whether LNK1 gets
|
||||
activated.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<p>The record also now posts monitors on the SELN field if it changes as a
|
||||
result of record processing (i.e. when read through the SELL link).</p>
|
||||
|
||||
<h3>Deleted Java build rules</h3>
|
||||
|
||||
<p>Java has its own build systems now, so we've deleted the rules and associated
|
||||
variables from Base, although they might get added to the Extensions build rules
|
||||
for a while in case anyone still needs them.</p>
|
||||
|
||||
<h2 align="center">Changes between 3.14.x and 3.15.0.1</h2>
|
||||
|
||||
<h3>Application clean rules</h3>
|
||||
|
||||
<p>The <tt>clean</tt> Makefile target has changed between a single-colon rule
|
||||
and a double-colon rule more than once in the life of the EPICS build rules, and
|
||||
it just changed back to a single-colon rule, but now we recommend that
|
||||
applications that wish to provide a Makefile that is backwards compatible with
|
||||
the 3.14 build rules use the construct shown below. The 3.15 rules now support
|
||||
a variable called <tt>CLEANS</tt> to which a Makefile can add a list of files to
|
||||
be deleted when the user does a <tt>make clean</tt> like this:</p>
|
||||
|
||||
<blockquote><pre>CLEANS += <list of files to be cleaned>
|
||||
|
||||
ifndef BASE_3_15
|
||||
clean::
|
||||
$(RM) $(CLEANS)
|
||||
endif</pre></blockquote>
|
||||
|
||||
<p>The conditional rule provides compatibility for use with the 3.14 build
|
||||
system.</p>
|
||||
|
||||
<h3>MSI included with Base</h3>
|
||||
|
||||
<p>An enhanced version of the Macro Substitution and Include program <q>msi</q>
|
||||
has been included with Base. Both this new version of msi and the IOC's
|
||||
<tt>dbLoadTemplates</tt> command now support setting global macros in
|
||||
substitution files, and <tt>dbLoadTemplates</tt> can now take a list of global
|
||||
macro settings as the second argument on its command line. The substitution file
|
||||
syntax is documented in the Application Developers Guide.</p>
|
||||
|
||||
<h3>Cross-builds targeting win32-x86-mingw</h3>
|
||||
|
||||
<p>Some Linux distributions now package the MinGW cross-compiler which makes it
|
||||
@@ -106,10 +581,10 @@ that number of seconds.</p>
|
||||
|
||||
<h3>Post events on Waveform record's NORD field</h3>
|
||||
|
||||
<p>When the record type or soft device support modify the NORD field of a
|
||||
waveform record they now also post a DBE_VALUE and DBE_LOG event, signalling the
|
||||
array length change to any clients monitoring the NORD field. Input device
|
||||
support routines should be modified to do this as well.</p>
|
||||
<p>When the record type or device support modify the NORD field of a waveform
|
||||
record, the record support code now posts DBE_VALUE and DBE_LOG events for that
|
||||
field, signalling the array length change to any client monitoring the NORD
|
||||
field.</p>
|
||||
|
||||
<h3>Attributes of Non-VAL Fields</h3>
|
||||
|
||||
@@ -195,7 +670,7 @@ Code that will not work with a version of Base before 3.15.0 can now be
|
||||
written like this to prevent it from compiling:</p>
|
||||
|
||||
<pre style="margin: 0 2em;">
|
||||
#if defined(VERSION_INT) && EPICS_VERSION_INT < VERSION_INT(3,15,0,0)
|
||||
#if defined(VERSION_INT) && EPICS_VERSION_INT < VERSION_INT(3,15,0,0)
|
||||
# error EPICS Base R3.15.0 or later is required
|
||||
#endif
|
||||
</pre>
|
||||
|
||||
@@ -75,6 +75,8 @@ std_DEPEND_DIRS = ioc libCom/RTEMS
|
||||
DIRS += std/filters/test
|
||||
std/filters/test_DEPEND_DIRS = std
|
||||
|
||||
DIRS += std/rec/test
|
||||
std/rec/test_DEPEND_DIRS = std
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "cac.h"
|
||||
#include "sgAutoPtr.h"
|
||||
|
||||
casgRecycle::~casgRecycle () {}
|
||||
|
||||
CASG::CASG ( epicsGuard < epicsMutex > & guard, ca_client_context & cacIn ) :
|
||||
client ( cacIn ), magic ( CASG_MAGIC )
|
||||
{
|
||||
@@ -37,13 +35,14 @@ CASG::~CASG ()
|
||||
{
|
||||
}
|
||||
|
||||
void CASG::destructor (
|
||||
void CASG::destructor (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
|
||||
if ( this->verify ( guard ) ) {
|
||||
this->reset ( guard );
|
||||
this->reset ( cbGuard, guard );
|
||||
this->client.uninstallCASG ( guard, *this );
|
||||
this->magic = 0;
|
||||
}
|
||||
@@ -61,9 +60,9 @@ bool CASG::verify ( epicsGuard < epicsMutex > & ) const
|
||||
/*
|
||||
* CASG::block ()
|
||||
*/
|
||||
int CASG::block (
|
||||
epicsGuard < epicsMutex > * pcbGuard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
int CASG::block (
|
||||
epicsGuard < epicsMutex > * pcbGuard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
double timeout )
|
||||
{
|
||||
epicsTime cur_time;
|
||||
@@ -75,7 +74,7 @@ int CASG::block (
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
|
||||
// prevent recursion nightmares by disabling blocking
|
||||
// for IO from within a CA callback.
|
||||
// for IO from within a CA callback.
|
||||
if ( epicsThreadPrivateGet ( caClientCallbackThreadId ) ) {
|
||||
return ECA_EVDISALLOW;
|
||||
}
|
||||
@@ -120,44 +119,45 @@ int CASG::block (
|
||||
}
|
||||
|
||||
/*
|
||||
* force a time update
|
||||
* force a time update
|
||||
*/
|
||||
cur_time = epicsTime::getCurrent ();
|
||||
|
||||
delay = cur_time - beg_time;
|
||||
}
|
||||
|
||||
this->reset ( guard );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void CASG::reset (
|
||||
void CASG::reset (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
this->destroyCompletedIO ( guard );
|
||||
this->destroyPendingIO ( guard );
|
||||
this->destroyCompletedIO ( cbGuard, guard );
|
||||
this->destroyPendingIO ( cbGuard, guard );
|
||||
}
|
||||
|
||||
// lock must be applied
|
||||
void CASG::destroyCompletedIO (
|
||||
void CASG::destroyCompletedIO (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
syncGroupNotify * pNotify;
|
||||
while ( ( pNotify = this->ioCompletedList.get () ) ) {
|
||||
pNotify->destroy ( guard, * this );
|
||||
pNotify->destroy ( cbGuard, guard );
|
||||
}
|
||||
}
|
||||
|
||||
void CASG::destroyPendingIO (
|
||||
void CASG::destroyPendingIO (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
while ( syncGroupNotify * pNotify = this->ioPendingList.first () ) {
|
||||
pNotify->cancel ( guard );
|
||||
// cancel must release the guard while
|
||||
pNotify->cancel ( cbGuard, guard );
|
||||
// cancel must release the guard while
|
||||
// canceling put callbacks so we
|
||||
// must double check list membership
|
||||
if ( pNotify->ioPending ( guard ) ) {
|
||||
@@ -166,7 +166,7 @@ void CASG::destroyPendingIO (
|
||||
else {
|
||||
this->ioCompletedList.remove ( *pNotify );
|
||||
}
|
||||
pNotify->destroy ( guard, *this );
|
||||
pNotify->destroy ( cbGuard, guard );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ void CASG::show ( unsigned level ) const
|
||||
this->show ( guard, level );
|
||||
}
|
||||
|
||||
void CASG::show (
|
||||
void CASG::show (
|
||||
epicsGuard < epicsMutex > & guard, unsigned level ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
@@ -184,14 +184,14 @@ void CASG::show (
|
||||
this->getId (), this->magic, this->ioPendingList.count () );
|
||||
if ( level ) {
|
||||
::printf ( "\tPending" );
|
||||
tsDLIterConst < syncGroupNotify > notifyPending =
|
||||
tsDLIterConst < syncGroupNotify > notifyPending =
|
||||
this->ioPendingList.firstIter ();
|
||||
while ( notifyPending.valid () ) {
|
||||
notifyPending->show ( guard, level - 1u );
|
||||
notifyPending++;
|
||||
}
|
||||
::printf ( "\tCompleted" );
|
||||
tsDLIterConst < syncGroupNotify > notifyCompleted =
|
||||
tsDLIterConst < syncGroupNotify > notifyCompleted =
|
||||
this->ioCompletedList.firstIter ();
|
||||
while ( notifyCompleted.valid () ) {
|
||||
notifyCompleted->show ( guard, level - 1u );
|
||||
@@ -201,10 +201,11 @@ void CASG::show (
|
||||
}
|
||||
|
||||
bool CASG::ioComplete (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
this->destroyCompletedIO ( guard );
|
||||
this->destroyCompletedIO ( cbGuard, guard );
|
||||
return this->ioPendingList.count () == 0u;
|
||||
}
|
||||
|
||||
@@ -212,9 +213,9 @@ void CASG::put ( epicsGuard < epicsMutex > & guard, chid pChan,
|
||||
unsigned type, arrayElementCount count, const void * pValue )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
sgAutoPtr < syncGroupWriteNotify > pNotify ( guard, *this, this->ioPendingList );
|
||||
sgAutoPtr < syncGroupWriteNotify > pNotify ( guard, *this );
|
||||
pNotify = syncGroupWriteNotify::factory (
|
||||
this->freeListWriteOP, *this, pChan );
|
||||
this->freeListWriteOP, *this, & CASG :: recycleWriteNotifyIO, pChan );
|
||||
pNotify->begin ( guard, type, count, pValue );
|
||||
pNotify.release ();
|
||||
}
|
||||
@@ -223,14 +224,14 @@ void CASG::get ( epicsGuard < epicsMutex > & guard, chid pChan,
|
||||
unsigned type, arrayElementCount count, void *pValue )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
sgAutoPtr < syncGroupReadNotify > pNotify ( guard, *this, this->ioPendingList );
|
||||
sgAutoPtr < syncGroupReadNotify > pNotify ( guard, *this );
|
||||
pNotify = syncGroupReadNotify::factory (
|
||||
this->freeListReadOP, *this, pChan, pValue );
|
||||
this->freeListReadOP, *this, & CASG :: recycleReadNotifyIO, pChan, pValue );
|
||||
pNotify->begin ( guard, type, count );
|
||||
pNotify.release ();
|
||||
}
|
||||
|
||||
void CASG::completionNotify (
|
||||
void CASG::completionNotify (
|
||||
epicsGuard < epicsMutex > & guard, syncGroupNotify & notify )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
@@ -241,56 +242,56 @@ void CASG::completionNotify (
|
||||
}
|
||||
}
|
||||
|
||||
void CASG::recycleSyncGroupWriteNotify (
|
||||
epicsGuard < epicsMutex > & guard, syncGroupWriteNotify & io )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
this->freeListWriteOP.release ( & io );
|
||||
}
|
||||
|
||||
void CASG::recycleSyncGroupReadNotify (
|
||||
epicsGuard < epicsMutex > & guard, syncGroupReadNotify & io )
|
||||
void CASG :: recycleReadNotifyIO ( epicsGuard < epicsMutex > & guard,
|
||||
syncGroupReadNotify & io )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
this->freeListReadOP.release ( & io );
|
||||
}
|
||||
|
||||
void CASG :: recycleWriteNotifyIO ( epicsGuard < epicsMutex > & guard,
|
||||
syncGroupWriteNotify & io )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
this->freeListWriteOP.release ( & io );
|
||||
}
|
||||
|
||||
int CASG :: printFormated ( const char *pformat, ... )
|
||||
{
|
||||
va_list theArgs;
|
||||
int status;
|
||||
|
||||
va_start ( theArgs, pformat );
|
||||
|
||||
|
||||
status = this->client.varArgsPrintFormated ( pformat, theArgs );
|
||||
|
||||
|
||||
va_end ( theArgs );
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void CASG::exception (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
int status, const char * pContext,
|
||||
void CASG::exception (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
if ( status != ECA_CHANDESTROY ) {
|
||||
this->client.exception (
|
||||
this->client.exception (
|
||||
guard, status, pContext, pFileName, lineNo );
|
||||
}
|
||||
}
|
||||
|
||||
void CASG::exception (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
void CASG::exception (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
unsigned type, arrayElementCount count, unsigned op )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->client.mutexRef() );
|
||||
if ( status != ECA_CHANDESTROY ) {
|
||||
this->client.exception (
|
||||
guard, status, pContext, pFileName,
|
||||
this->client.exception (
|
||||
guard, status, pContext, pFileName,
|
||||
lineNo, chan, type, count, op );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,8 @@ $Date$</span></small></p>
|
||||
<li><a href="#ca_pend_io">block for certain requests to complete</a></li>
|
||||
<li><a href="#ca_test_io">test to see if certain requests have
|
||||
completed</a></li>
|
||||
<li><a href="#ca_pend_event">process CA client library background activities</a></li>
|
||||
<li><a href="#ca_pend_event">process CA client library background
|
||||
activities</a></li>
|
||||
<li><a href="#ca_flush_io">flush outstanding requests to the server</a></li>
|
||||
<li><a href="#ca_add_exception_event">replace the default exception
|
||||
handler</a></li>
|
||||
@@ -454,26 +455,20 @@ Environment</a> below.</p>
|
||||
|
||||
<h3><a name="firewall">Firewalls</a></h3>
|
||||
|
||||
<p>If you want channel access clients on a machine to be able to see
|
||||
beacons and replies to broadcast PV search requests you need to permit
|
||||
inbound UDP packets with source port EPICS_CA_SERVER_PORT (default is 5064)
|
||||
or destination port EPICS_CA_REPEATER_PORT (default is 5065). On systems
|
||||
using iptables this can be accomplished by rules like</p>
|
||||
|
||||
<pre>
|
||||
-A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
|
||||
-A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT
|
||||
</pre>
|
||||
<p>If you want channel access clients on a machine to be able to see beacons
|
||||
and replies to broadcast PV search requests, you need to permit inbound UDP
|
||||
packets with source port EPICS_CA_SERVER_PORT (default is 5064) or destination
|
||||
port EPICS_CA_REPEATER_PORT (default is 5065). On systems using iptables this
|
||||
can be accomplished by rules like</p>
|
||||
<pre> -A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
|
||||
-A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT</pre>
|
||||
|
||||
<p>If you want channel access servers (e.g. "soft IOCs") on a machine to be
|
||||
able to see clients you need to permit inbound TCP or UDP packets with source
|
||||
port EPICS_CA_SERVER_PORT (default is 5064). On systems using iptables this
|
||||
can be accomplished by rules like</p>
|
||||
|
||||
<pre>
|
||||
-A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
|
||||
-A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT
|
||||
</pre>
|
||||
able to be seen by clients, you need to permit inbound TCP or UDP packets with
|
||||
destination port EPICS_CA_SERVER_PORT (default is 5064). On systems using
|
||||
iptables this can be accomplished by rules like</p>
|
||||
<pre> -A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
|
||||
-A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT</pre>
|
||||
|
||||
<p>In all cases the "-s 192.168.0.0/22" specifies the range of addresses from
|
||||
which you wish to accept packets.</p>
|
||||
@@ -498,9 +493,8 @@ broadcast address of that subnet is added to the list. For each point to point
|
||||
interface found, the destination address of that link is added to the list.
|
||||
This automatic server address list initialization can be disabled if the EPICS
|
||||
environment variable EPICS_CA_AUTO_ADDR_LIST exists and its value is either
|
||||
of "no" or "NO". The typical default is to enable network interface
|
||||
introspection driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES"
|
||||
or "yes".</p>
|
||||
"no" or "NO". The typical default is to enable network interface introspection
|
||||
driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES" or "yes".</p>
|
||||
|
||||
<p>Following network interface introspection, any IP addresses specified in the
|
||||
EPICS environment variable EPICS_CA_ADDR_LIST are added to the list of
|
||||
@@ -511,8 +505,8 @@ CA servers unless a CA proxy (gateway) is installed. The addresses in
|
||||
EPICS_CA_ADDR_LIST may be dotted IP addresses or host names if the local OS has
|
||||
support for host name to IP address translation. When multiple names are added
|
||||
to EPICS_CA_ADDR_LIST they must be separated by white space. There is no
|
||||
requirement that the addresses specified in the EPICS_CA_ADDR_LIST be
|
||||
broadcast addresses, but this will often be the most convenient choice.</p>
|
||||
requirement that the addresses specified in the EPICS_CA_ADDR_LIST be broadcast
|
||||
addresses, but this will often be the most convenient choice.</p>
|
||||
|
||||
<p>For any IP addresses specified in the EPICS environment variable
|
||||
EPICS_CA_NAME_SERVERS, TCP connections are opened and used for CA client name
|
||||
@@ -560,7 +554,7 @@ default to EPICS_CA_SERVER_PORT.</p>
|
||||
<p>Frequently vxWorks systems boot by default with routes limiting access only
|
||||
to the local subnet. If a EPICS system is operating in a WAN environment it may
|
||||
be necessary to configure routes into the vxWorks system which enable a vxWorks
|
||||
based CA server to respond to requests originating outside it's subnet. These
|
||||
based CA server to respond to requests originating outside its subnet. These
|
||||
routing restrictions can also apply to vxWorks base CA clients communicating
|
||||
with off subnet servers. An EPICS system manager can implement an rudimentary,
|
||||
but robust, form of access control for a particular host by not providing
|
||||
@@ -637,7 +631,7 @@ standard out for each CA client beacon anomaly detect event.</p>
|
||||
<p>See also <a href="#Client1">When a Client Does not See the Server's
|
||||
Beacon</a>.</p>
|
||||
|
||||
<h3><a name="Configurin3" id="Configurin3">Configuring the Maximum Search
|
||||
<h3><a name="Configurin3">Configuring the Maximum Search
|
||||
Period</a></h3>
|
||||
|
||||
<p>The rate at which name resolution (search) requests are sent exponentially
|
||||
@@ -802,7 +796,7 @@ been done to address this issue so far).</em></p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EPICS_CAS_BEACON_ADDR_LIST</td>
|
||||
<td>{N.N.N.NN.N.N.N:P...}</td>
|
||||
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
||||
<td>EPICS_CA_ADDR_LIST<sup>1</sup></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -817,12 +811,12 @@ been done to address this issue so far).</em></p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EPICS_CAS_INTF_ADDR_LIST</td>
|
||||
<td>{N.N.N.NN.N.N.N:P...}</td>
|
||||
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
||||
<td><none></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EPICS_CAS_IGNORE_ADDR_LIST</td>
|
||||
<td>{N.N.N.NN.N.N.N:P...}</td>
|
||||
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
||||
<td><none></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -865,8 +859,8 @@ the contents of EPICS_CA_ADDR_LIST is used to augment the list. Otherwise, the
|
||||
list is not augmented.</p>
|
||||
|
||||
<p>The EPICS_CAS_BEACON_PORT parameter specifies the destination port for
|
||||
server beacons. The only exception to this occurs when ports are specified
|
||||
in EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If
|
||||
server beacons. The only exception to this occurs when ports are specified in
|
||||
EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If
|
||||
EPICS_CAS_BEACON_PORT is not specified then beacons are sent to the port
|
||||
specified in EPICS_CA_REPEATER_PORT.</p>
|
||||
|
||||
@@ -874,14 +868,19 @@ specified in EPICS_CA_REPEATER_PORT.</p>
|
||||
|
||||
<p>The parameter EPICS_CAS_INTF_ADDR_LIST allows a ca server to bind itself to,
|
||||
and therefore accept messages only over, a limited set of the local host's
|
||||
network interfaces (each specified by it's IP address). On UNIX systems type
|
||||
network interfaces (each specified by its IP address). On UNIX systems type
|
||||
"netstat -i" (type "ipconfig" on windows) to see a list of the local host's
|
||||
network interfaces. Specifically, UDP search messages addressed to both the IP
|
||||
addresses in EPICS_CAS_INTF_ADDR_LIST and also to the broadcast addresses of
|
||||
the corresponding LAN interfaces will be accepted by the server. By default,
|
||||
the CA server is accessible from all network interfaces configured into its
|
||||
host. <em>In R3.14 and previous releases the CA server employed by iocCore does
|
||||
not implement this feature</em>.</p>
|
||||
host.</p>
|
||||
|
||||
<p>In R3.14 and previous releases the CA server employed by iocCore did not
|
||||
implement the EPICS_CAS_INTF_ADDR_LIST feature. In this release the iocCore
|
||||
server will read the first IP address from the parameter variable and use that
|
||||
to select which interface to bind to. Any additional IP addresses will be
|
||||
ignored and a warning message displayed during IOC initialization.</p>
|
||||
|
||||
<h4>Ignoring Process Variable Name Resolution Requests From Certain Hosts</h4>
|
||||
|
||||
@@ -897,9 +896,9 @@ feature.</em></p>
|
||||
<p>See also <a href="#Routing">Routing Restrictions on vxWorks Systems</a>.</p>
|
||||
<hr>
|
||||
|
||||
<h2><a name="Building" id="Building">Building an Application</a></h2>
|
||||
<h2><a name="Building">Building an Application</a></h2>
|
||||
|
||||
<h3><a name="Required1" id="Required1">Required Header (.h) Files</a></h3>
|
||||
<h3><a name="Required1">Required Header (.h) Files</a></h3>
|
||||
|
||||
<p>An application that uses the CA client library functions described in this
|
||||
document will need to include the cadef.h header files as follows.</p>
|
||||
@@ -911,7 +910,7 @@ many other header files (operating system specific and otherwise), and
|
||||
therefore the application must also specify "<EPICS
|
||||
base>/include/os/<arch>" in its header file search path.</p>
|
||||
|
||||
<h3><a name="Required" id="Required">Required Libraries</a></h3>
|
||||
<h3><a name="Required">Required Libraries</a></h3>
|
||||
|
||||
<p>An application that uses the Channel Access Client Library functions
|
||||
described in this document will need to link with the EPICS CA Client Library
|
||||
@@ -957,56 +956,58 @@ and Windows systems.</p>
|
||||
<p>The above libraries are located in "<EPICS
|
||||
base>/lib/<architechture>".</p>
|
||||
|
||||
<h3><a name="Compiler" id="Compiler">Compiler and System Specific Build
|
||||
<h3><a name="Compiler">Compiler and System Specific Build
|
||||
Options</a></h3>
|
||||
|
||||
<p>If you do not use the EPICS build environemnt (layered make files) then it
|
||||
<p>If you do not use the EPICS build environment (layered make files) then it
|
||||
may be helpful to run one of the EPICS make files and watch the compile/link
|
||||
lines. This may be the simplest way to capture the latest system and compiler
|
||||
specific options required by your build environment. I have included some
|
||||
snapshots of typical build lines below, but expect some risk of this
|
||||
information becoming dated.</p>
|
||||
specific options required by your build environment. Some snapshots of typical
|
||||
build lines are shown below, but this information may be out of date.</p>
|
||||
|
||||
<h4>Typical Linux Build Options</h4>
|
||||
|
||||
<p><code>/usr/bin/gcc -c -D_POSIX_C_SOURCE=199506L -D_POSIX_THREADS
|
||||
-D_XOPEN_SOURCE=500 -DOSITHREAD_USE_DEFAULT_STACK -D_X86_ -DUNIX -D_BSD_SOURCE
|
||||
-Dlinux -D_REENTRANT -ansi -O3 -Wall -I. -I.. -I../../../include/os/Linux
|
||||
-I../../../include ../acctst.c</code></p>
|
||||
<p><code>gcc -D_GNU_SOURCE -DOSITHREAD_USE_DEFAULT_STACK -D_X86_ -DUNIX -Dlinux
|
||||
-O3 -g -Wall -I. -I.. -I../../../../include/compiler/gcc
|
||||
-I../../../../include/os/Linux -I../../../../include -c ../acctst.c</code></p>
|
||||
|
||||
<p><code>/usr/bin/g++ -o acctst
|
||||
-L/home/user/epicsR3.14/epics/base/lib/linux-x86/
|
||||
-Wl,-rpath,/mnt/bogart_home/hill/epicsR3.14/epics/base/lib/linux-x86
|
||||
<p><code>g++ -o acctst -L/home/user/epics/base-3.15/lib/linux-x86
|
||||
-Wl,-rpath,/home/user/epics/base-3.15/lib/linux-x86
|
||||
acctstMain.o acctst.o -lca -lCom</code></p>
|
||||
|
||||
<h4>Typical Solaris Build Options</h4>
|
||||
|
||||
<p><code>/opt/SUNWspro/bin/cc -c -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=500
|
||||
-DOSITHREAD_USE_DEFAULT_STACK -DUNIX -DSOLARIS=9 -mt -D__EXTENSIONS__ -Xc -v
|
||||
-xO4 -I. -I.. -I./../../../include/os/solaris -I./../../../include
|
||||
../acctst.c</code></p>
|
||||
-xO4 -I. -I.. -I../../../../include/compiler/solStudio
|
||||
-I../../../../include/os/solaris -I../../../../include ../acctst.c</code></p>
|
||||
|
||||
<p><code>/opt/SUNWspro/bin/CC -o acctst
|
||||
-L/home/phoebus1/JHILL/epics/base/lib/solaris-sparc/ -mt -z ignore -z combreloc
|
||||
-z lazyload -R/home/disk1/user/epics/base/lib/solaris-sparc acctstMain.o
|
||||
-L/home/user/epics/base-3.15/lib/solaris-sparc/ -mt -z ignore -z combreloc
|
||||
-z lazyload -R/home/user/epics/base-3.15/lib/solaris-sparc acctstMain.o
|
||||
acctst.o -lca -lCom</code></p>
|
||||
|
||||
<h4>Typical Windows Build Options</h4>
|
||||
|
||||
<p><code>cl -c /nologo /D__STDC__=0 /Ox /GL /W3 /w44355 /MD -I. -I..
|
||||
-I..\\..\\..\\include\\os\\WIN32 -I..\\..\\..\\include ..\\acctst.c</code></p>
|
||||
-I..\\..\\..\\..\\include\\compiler\\msvc -I..\\..\\..\\..\\include\\os\\WIN32
|
||||
-I..\\..\\..\\..\\include ..\\acctst.c</code></p>
|
||||
|
||||
<p><code>link -nologo /LTCG /incremental:no /opt:ref /release /version:3.14
|
||||
<p><code>link -nologo /LTCG /incremental:no /opt:ref /release /version:3.15
|
||||
-out:acctst.exe acctstMain.obj acctst.obj
|
||||
d:/user/R3.14.clean/epics/base/lib/WIN32-x86/ca.lib
|
||||
d:/user/R3.14.clean/epics/base/lib/WIN32-x86/</code></p>
|
||||
d:/user/epics/base-3.15/lib/win32-x86/ca.lib
|
||||
d:/user/epics/base-3.15/lib/win32-x86/Com.lib</code></p>
|
||||
|
||||
<h4>Typical vxWorks Build Options</h4>
|
||||
|
||||
<p><code>/usr/local/xcomp/ppc/bin/ccppc -c -D_POSIX_SOURCE -DCPU=PPC603
|
||||
-DvxWorks -include /home/vx/tornado20/target/h/vxWorks.h -ansi -O3 -Wall
|
||||
-mcpu=603 -mstrict-align -fno-builtin -I. -I.. -I../../../include/os/vxWorks
|
||||
-I../../../include -I/home/vx/tornado20/target/h ../acctst.c</code></p>
|
||||
<p><code>/usr/local/vxWorks-6.9/gnu/4.3.3-vxworks-6.9/x86-linux2/bin/ccppc
|
||||
-DCPU=PPC32 -DvxWorks=vxWorks -O2 -Wall -mstrict-align -mlongcall -fno-builtin
|
||||
-include /usr/local/vxWorks-6.9/vxworks-6.9/target/h/vxWorks.h
|
||||
-I. -I../O.Common -I.. -I../../../../include/compiler/gcc
|
||||
-I../../../../include/os/vxWorks -I../../../../include
|
||||
-I/usr/local/vxWorks-6.9/vxworks-6.9/target/h
|
||||
-I/usr/local/vxWorks-6.9/vxworks-6.9/target/h/wrn/coreip
|
||||
-c ../acctst.c</code></p>
|
||||
|
||||
<h4>Other Systems and Compilers</h4>
|
||||
|
||||
@@ -1640,7 +1641,7 @@ etc.</p>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3><a name="excas" id="excas">excas</a></h3>
|
||||
<h3><a name="excas">excas</a></h3>
|
||||
|
||||
<p>excas [options]</p>
|
||||
|
||||
@@ -1885,7 +1886,7 @@ order to connect to this new beacon-out-of-range server. The typical situation
|
||||
where a client would not see the server's beacon might be when the client isnt
|
||||
on the same IP subnet as the server, and the client's EPICS_CA_ADDR_LIST was
|
||||
modified to include a destination address for the server, but the server's
|
||||
beacon address list was not modified so that it's beacons are received by the
|
||||
beacon address list was not modified so that its beacons are received by the
|
||||
client.</p>
|
||||
|
||||
<h4><a name="Server1">A Server's IP Address Was Changed</a></h4>
|
||||
@@ -1932,14 +1933,14 @@ made to build a new circuit. This behavior could result in undesirable resource
|
||||
consumption resulting from periodic circuit setup and teardown overhead
|
||||
(thrashing) during periods of CPU / network / IP kernel buffer congestion.</p>
|
||||
|
||||
<h3><a name="Requests" id="Requests">Put Requests Just Prior to Process
|
||||
<h3><a name="Requests">Put Requests Just Prior to Process
|
||||
Termination Appear to be Ignored</a></h3>
|
||||
|
||||
<p>Short lived CA client applications that issue a CA put request and then
|
||||
immediately exit the process (return from <code>main</code> or call
|
||||
<code>exit</code>) may find that there request isn't executed. To guarantee
|
||||
that the request is sent call <code>ca_flush</code> followed by
|
||||
<code>ca_context_destroy</code> prior to terminating the process.</p>
|
||||
that the request is sent call <code>ca_flush_io()</code> followed by
|
||||
<code>ca_context_destroy()</code> prior to terminating the process.</p>
|
||||
|
||||
<h3><a name="Problems">ENOBUFS Messages</a></h3>
|
||||
|
||||
@@ -2017,8 +2018,8 @@ OS and even between different versions of the same OS.</p>
|
||||
<p>If the subscription update producer in the server produces subscription
|
||||
updates faster than the subscription update consumer in the client consumes
|
||||
them, then events have to be discarded if the buffering in the server
|
||||
isn't allowed to grow to an infinite size. This is a law of nature
|
||||
- based on queuing theory of course.</p>
|
||||
isn't allowed to grow to an infinite size. This is a law of nature –
|
||||
based on queuing theory of course.</p>
|
||||
|
||||
<p>What is done depends on the version of the CA server. All server versions
|
||||
place quotas on the maximum number of subscription updates allowed on the
|
||||
@@ -2040,10 +2041,10 @@ server to resume with subscription updates. This prevents slow clients from
|
||||
getting time warped, but also guarantees that intervening events are discarded
|
||||
until the slow client catches up.</p>
|
||||
|
||||
<p>There is currently no message on the IOC's console when a
|
||||
particular client is slow on the uptake. A message of this type used to exist
|
||||
many years ago, but it was a source of confusion (and what we will call
|
||||
message noise) so it was removed. </p>
|
||||
<p>There is currently no message on the IOC's console when a particular client
|
||||
is slow on the uptake. A message of this type used to exist many years ago, but
|
||||
it was a source of confusion (and what we will call message noise) so it was
|
||||
removed.</p>
|
||||
|
||||
<p>There is unfortunately no field in the protocol allowing the server to
|
||||
indicate that an intervening subscription update was discarded. We should
|
||||
@@ -2320,7 +2321,7 @@ int main ( int argc, char ** argv )
|
||||
|
||||
<p>Certain CA client initiated requests asynchronously execute an application
|
||||
supplied call back in the client process when a response arrives. The functions
|
||||
ca_put_callback, ca_get_callback, and ca_add_event all request notification of
|
||||
ca_put_callback, ca_get_callback, and ca_create_subscription all request notification of
|
||||
asynchronous completion via this mechanism. The <code>event_handler_args
|
||||
</code>structure is passed <em>by value</em> to the application supplied
|
||||
callback. In this structure the <code>dbr</code> field is a void pointer to any
|
||||
@@ -2355,8 +2356,8 @@ void myCallback ( struct event_handler_args args )
|
||||
<h3><a name="Channel1">Channel Access Exceptions</a></h3>
|
||||
|
||||
<p>When the server detects a failure, and there is no client call back function
|
||||
attached to the request, an exception handler is executed in the client.
|
||||
The default exception handler prints a message on the console and exits if the
|
||||
attached to the request, an exception handler is executed in the client. The
|
||||
default exception handler prints a message on the console and exits if the
|
||||
exception condition is severe. Certain internal exceptions within the CA client
|
||||
library, and failures detected by the SEVCHK macro may also cause the exception
|
||||
handler to be invoked. To modify this behavior see <a
|
||||
@@ -2423,12 +2424,12 @@ same process).</p>
|
||||
all OS (in past releases the library was thread safe only on vxWorks). When the
|
||||
client library is initialized the programmer may specify if preemptive callback
|
||||
is to be enabled. Preemptive callback is disabled by default. If preemptive
|
||||
callback is enabled, then the user's callback functions might be called by
|
||||
CA's auxiliary threads when the main initiating channel access thread is not
|
||||
inside of a function in the channel access client library. Otherwise, the
|
||||
user's callback functions will be called only when the main initiating channel
|
||||
access thread is executing inside of the CA client library. When the CA client
|
||||
library invokes a user's callback function, it will always wait for the current
|
||||
callback is enabled, then the user's callback functions might be called by CA's
|
||||
auxiliary threads when the main initiating channel access thread is not inside
|
||||
of a function in the channel access client library. Otherwise, the user's
|
||||
callback functions will be called only when the main initiating channel access
|
||||
thread is executing inside of the CA client library. When the CA client library
|
||||
invokes a user's callback function, it will always wait for the current
|
||||
callback to complete prior to executing another callback function. Programmers
|
||||
enabling preemptive callback should be familiar with using mutex locks to
|
||||
create a reliable multi-threaded program.</p>
|
||||
@@ -2457,10 +2458,10 @@ address space (process) to be independent of each other. For example, the
|
||||
database CA links and the sequencer are designed to not use the same CA client
|
||||
library threads, network circuits, and data structures. Each thread that calls
|
||||
<a href="#ca_context_create">ca_context_create()</a> for the first time either
|
||||
directly or implicitly when calling any CA library function for the first
|
||||
time, creates a CA client library context. A CA client library context contains
|
||||
all of the threads, network circuits, and data structures required to connect
|
||||
and communicate with the channels that a CA client application has created. The
|
||||
directly or implicitly when calling any CA library function for the first time,
|
||||
creates a CA client library context. A CA client library context contains all
|
||||
of the threads, network circuits, and data structures required to connect and
|
||||
communicate with the channels that a CA client application has created. The
|
||||
priority of auxiliary threads spawned by the CA client library are at fixed
|
||||
offsets from the priority of the thread that called <a
|
||||
href="#ca_context_create">ca_context_create()</a>. An application specific
|
||||
@@ -2530,9 +2531,9 @@ questionable practice for the following reasons.</p>
|
||||
<ul>
|
||||
<li>The vxWorks shell thread runs at the very highest priority in the system
|
||||
and therefore socket calls are made at a priority that is above the
|
||||
priority of tNetTask - a practice that has caused the WRS IP kernel
|
||||
to get sick in the past. That symptom was observed some time ago, but we
|
||||
don't know if WRS has fixed the problem.</li>
|
||||
priority of tNetTask. This has caused problems with the WRS IP kernel in
|
||||
the past. That symptom was observed some time ago, but we don't know if
|
||||
WRS has fixed the problem.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>The vxWorks shell thread runs at the very highest priority in the system
|
||||
@@ -2554,7 +2555,7 @@ questionable practice for the following reasons.</p>
|
||||
is the same behavior as on all other OS.</li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="Calling1" id="Calling1">Calling CA Functions from POSIX signal
|
||||
<h3><a name="Calling1">Calling CA Functions from POSIX signal
|
||||
handlers</a></h3>
|
||||
|
||||
<p>As you might expect, it isnt safe to call the CA client library from a POSIX
|
||||
@@ -2648,7 +2649,7 @@ get called in the correct order.</p>
|
||||
resources used by the client library such as sockets and allocated memory are
|
||||
automatically released by the system when the process exits and
|
||||
ca_context_destroy() hasn't been called, but on light weight systems such as
|
||||
vxWorks or RTEMS no cleanup occurs unless the application call
|
||||
vxWorks or RTEMS no cleanup occurs unless the application calls
|
||||
ca_context_destroy().</p>
|
||||
|
||||
<h4>Returns</h4>
|
||||
@@ -2661,16 +2662,10 @@ ca_context_destroy().</p>
|
||||
|
||||
<h3><code><a name="ca_create_channel">ca_create_channel()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
typedef void ( *pCallBack ) (
|
||||
struct connection_handler_args );
|
||||
int ca_create_channel
|
||||
(
|
||||
const char *PROCESS_VARIABLE_NAME,
|
||||
caCh *USERFUNC,
|
||||
void *PUSER,
|
||||
capri priority,
|
||||
chid *PCHID
|
||||
);</pre>
|
||||
typedef void ( caCh ) (struct connection_handler_args);
|
||||
int ca_create_channel (const char *PVNAME,
|
||||
caCh *USERFUNC, void *PUSER,
|
||||
capri PRIORITY, chid *PCHID );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
@@ -2685,7 +2680,7 @@ on a channel.</p>
|
||||
|
||||
<p>The circuit may be initially connected or disconnected depending on the
|
||||
state of the network and the location of the channel. A channel will only enter
|
||||
a connected state after server's address is determined, and only if channel
|
||||
a connected state after the server's address is determined, and only if channel
|
||||
access successfully establishes a virtual circuit through the network to the
|
||||
server. Channel access routines that send a request to a server will return
|
||||
ECA_DISCONNCHID if the channel is currently disconnected.</p>
|
||||
@@ -2695,7 +2690,7 @@ a connected state.</p>
|
||||
<ul>
|
||||
<li>The first and simplest method requires that you call ca_pend_io(), and
|
||||
wait for successful completion, prior to using a channel that was created
|
||||
specifying a nil connection call back function pointer.</li>
|
||||
specifying a nill connection call back function pointer.</li>
|
||||
<li>The second method requires that you register a connection handler by
|
||||
supplying a valid connection callback function pointer. This connection
|
||||
handler is called whenever the connection state of the channel changes. If
|
||||
@@ -2719,7 +2714,7 @@ time.</p>
|
||||
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
<dt><code>PROCESS_VARIABLE_NAME</code></dt>
|
||||
<dt><code>PVNAME</code></dt>
|
||||
<dd>A nil terminated process variable name string. EPICS process control
|
||||
function block database variable names are of the form "<record
|
||||
name>.<field name>". If the field name and the period separator
|
||||
@@ -2731,10 +2726,10 @@ time.</p>
|
||||
<dt><code>USERFUNC</code></dt>
|
||||
<dd>Optional address of the user's call back function to be run when the
|
||||
connection state changes. Casual users of channel access may decide to
|
||||
set this field to nil or 0 if they do not need to have a call back
|
||||
set this field to nill or 0 if they do not need to have a call back
|
||||
function run in response to each connection state change event.
|
||||
<p>The following structure is passed <em>by value </em>to the user's
|
||||
connection connection callback function. The <code>op</code> field will
|
||||
connection callback function. The <code>op</code> field will
|
||||
be set by the CA client library to <code>CA_OP_CONN_UP</code> when the
|
||||
channel connects, and to <code>CA_OP_CONN_DOWN</code> when the channel
|
||||
disconnects. See <code><a href="#ca_puser">ca_puser</a></code> if the
|
||||
@@ -2751,7 +2746,7 @@ time.</p>
|
||||
<dd>The value of this void pointer argument is retained in
|
||||
storage associated with the specified channel. See the MACROS manual page
|
||||
for reading and writing this field. Casual users of channel access may
|
||||
wish to set this field to nil or 0.</dd>
|
||||
wish to set this field to nill or 0.</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><code>PRIORITY</code></dt>
|
||||
@@ -2818,29 +2813,27 @@ subscriptions (monitors) registered with the channel.</p>
|
||||
<pre>#include <cadef.h>
|
||||
int ca_put ( chtype TYPE,
|
||||
chid CHID, void *PVALUE );
|
||||
int ca_array_put ( chtype TYPE,
|
||||
unsigned long COUNT,
|
||||
int ca_array_put ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, const void *PVALUE);
|
||||
typedef void ( *pCallBack ) (struct event_handler_args );
|
||||
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
||||
int ca_put_callback ( chtype TYPE,
|
||||
chid CHID, const void *PVALUE,
|
||||
pCallBack PFUNC, void *USERARG );
|
||||
int ca_array_put_callback ( chtype TYPE,
|
||||
unsigned long COUNT,
|
||||
caEventCallBackFunc PFUNC, void *USERARG );
|
||||
int ca_array_put_callback ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, const void *PVALUE,
|
||||
pCallBack PFUNC, void *USERARG );</pre>
|
||||
caEventCallBackFunc PFUNC, void *USERARG );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
<p>Write a scalar or array value to a process variable.</p>
|
||||
|
||||
<p>When ca_array_put or ca_put are invoked the client will receive no response
|
||||
<p>When ca_put or ca_array_put are invoked the client will receive no response
|
||||
unless the request can not be fulfilled in the server. If unsuccessful an
|
||||
exception handler is run on the client side.</p>
|
||||
|
||||
<p>When ca_array_put_callback are invoked the user supplied asynchronous call
|
||||
back is called only after the initiated write operation, and all actions
|
||||
resulting from the initiating write operation, complete.</p>
|
||||
<p>When ca_put_callback or ca_array_put_callback are invoked the user supplied
|
||||
asynchronous call back is called only after the initiated write operation, and
|
||||
all actions resulting from the initiating write operation, complete.</p>
|
||||
|
||||
<p>If unsuccessful the call back function is invoked indicating failure status.
|
||||
</p>
|
||||
@@ -2861,7 +2854,7 @@ This allows several requests to be efficiently combined into one message.</p>
|
||||
<h4>Description (IOC Database Specific)</h4>
|
||||
|
||||
<p>A CA put request causes the record to process if the record's SCAN field is
|
||||
set to passive, and the field being written has it's process passive attribute
|
||||
set to passive, and the field being written has its process passive attribute
|
||||
set to true. If such a record is already processing when a put request is
|
||||
initiated the specified field is written immediately, and the record is
|
||||
scheduled to process again as soon as it finishes processing. Earlier instances
|
||||
@@ -2869,20 +2862,19 @@ of multiple put requests initiated while the record is being processing may be
|
||||
discarded, but the last put request initiated is always written and
|
||||
processed.</p>
|
||||
|
||||
<p>A CA put <span style="font-style: italic;">callback</span> request causes
|
||||
the record to process if the record's SCAN field is set to passive, and the
|
||||
field being written has it's process passive attribute set to true. For such a
|
||||
record, the user's put callback function is not called until after the record,
|
||||
and any records that the record links to, finish processing. If such a record
|
||||
is already processing when a put <span
|
||||
style="font-style: italic;">callback</span> request is initiated the put <span
|
||||
style="font-style: italic;">callback</span> request is postponed until the
|
||||
record, and any records it links to, finish processing.</p>
|
||||
<p>A CA put <em>callback</em> request causes the record to process if the
|
||||
record's SCAN field is set to passive, and the field being written has its
|
||||
process passive attribute set to true. For such a record, the user's put
|
||||
callback function is not called until after the record, and any records that
|
||||
the record links to, finish processing. If such a record is already processing
|
||||
when a put <em>callback</em> request is initiated the put <em>callback</em>
|
||||
request is postponed until the record, and any records it links to, finish
|
||||
processing.</p>
|
||||
|
||||
<p>If the record's SCAN field is not set to passive, or the field being written
|
||||
has it's process passive attribute set to false then the CA put or CA put
|
||||
callback request cause the specified field to be immediately written, but they
|
||||
do not cause the record to be processed.</p>
|
||||
has its process passive attribute set to false then the CA put or CA put
|
||||
<em>callback</em> request cause the specified field to be immediately written,
|
||||
but they do not cause the record to be processed.</p>
|
||||
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
@@ -2948,18 +2940,19 @@ int ca_get ( chtype TYPE,
|
||||
chid CHID, void *PVALUE );
|
||||
int ca_array_get ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, void *PVALUE );
|
||||
typedef void ( *pCallBack ) (struct event_handler_args );
|
||||
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
||||
int ca_get_callback ( chtype TYPE,
|
||||
chid CHID, pCallBack USERFUNC, void *USERARG);
|
||||
chid CHID,
|
||||
caEventCallBackFunc USERFUNC, void *USERARG);
|
||||
int ca_array_get_callback ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID,
|
||||
pCallBack USERFUNC, void *USERARG );</pre>
|
||||
caEventCallBackFunc USERFUNC, void *USERARG);</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
<p>Read a scalar or array value from a process variable.</p>
|
||||
|
||||
<p>When ca_get or ca_array_get are invoked the returned channel value cant be
|
||||
<p>When ca_get or ca_array_get are invoked the returned channel value can't be
|
||||
assumed to be stable in the application supplied buffer until after ECA_NORMAL
|
||||
is returned from ca_pend_io. If a connection is lost outstanding ca get
|
||||
requests are not automatically reissued following reconnect.</p>
|
||||
@@ -3051,11 +3044,10 @@ when a CA get request is initiated.</p>
|
||||
|
||||
<h3><code><a name="ca_add_event">ca_create_subscription()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
typedef void ( *pCallBack ) (
|
||||
struct event_handler_args );
|
||||
int ca_create_subscription ( chtype TYPE,
|
||||
unsigned long COUNT, chid CHID,
|
||||
unsigned long MASK, pCallBack USERFUNC, void *USERARG,
|
||||
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
||||
int ca_create_subscription ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, unsigned long MASK,
|
||||
caEventCallBackFunc USERFUNC, void *USERARG,
|
||||
evid *PEVID );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
@@ -3064,10 +3056,10 @@ int ca_create_subscription ( chtype TYPE,
|
||||
invoked whenever the process variable undergoes significant state changes. A
|
||||
significant change can be a change in the process variable's value, alarm
|
||||
status, or alarm severity. In the process control function block database the
|
||||
deadband field determines the magnitude of a significant change for for the
|
||||
deadband field determines the magnitude of a significant change for the
|
||||
process variable's value. Each call to this function consumes resources in the
|
||||
client library and potentially a CA server until one of ca_clear_channel or
|
||||
ca_clear_event is called.</p>
|
||||
ca_clear_subscription is called.</p>
|
||||
|
||||
<p>Subscriptions may be installed or canceled against both connected and
|
||||
disconnected channels. The specified USERFUNC is called once immediately after
|
||||
@@ -3075,7 +3067,7 @@ the subscription is installed with the process variable's current state if the
|
||||
process variable is connected. Otherwise, the specified USERFUNC is called
|
||||
immediately after establishing a connection (or reconnection) with the process
|
||||
variable. The specified USERFUNC is called immediately with the process
|
||||
variable's current state from within ca_add_event() if the client and the
|
||||
variable's current state from within ca_create_subscription() if the client and the
|
||||
process variable share the same address space.</p>
|
||||
|
||||
<p>If a subscription is installed on a channel in a disconnected state then the
|
||||
@@ -3132,8 +3124,8 @@ indicating the current state of the channel.</p>
|
||||
<dl>
|
||||
<dt><code>PEVID</code></dt>
|
||||
<dd>This is a pointer to user supplied event id which is overwritten if
|
||||
successful. This event id can later be used to clear a specific
|
||||
event. This option may may be omitted by passing a nil pointer.</dd>
|
||||
successful. This event id can later be used to clear a specific event.
|
||||
This option may be omitted by passing a nill pointer.</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><code>MASK</code></dt>
|
||||
@@ -3181,7 +3173,7 @@ int ca_clear_subscription ( evid EVID );</pre>
|
||||
|
||||
<p>Cancel a subscription.</p>
|
||||
|
||||
<p>All ca_clear_event() requests such as the above are accumulated (buffered)
|
||||
<p>All cancel-subscription requests such as the above are accumulated (buffered)
|
||||
and not forwarded to the server until one of ca_flush_io, ca_pend_io,
|
||||
ca_pend_event, or ca_sg_pend are called. This allows several requests to be
|
||||
efficiently sent together in one message.</p>
|
||||
@@ -3189,7 +3181,7 @@ efficiently sent together in one message.</p>
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
<dt>EVID</dt>
|
||||
<dd>event id returned by ca_add_event()</dd>
|
||||
<dd>event id returned by ca_create_subscription()</dd>
|
||||
</dl>
|
||||
|
||||
<h4>Returns</h4>
|
||||
@@ -3240,9 +3232,9 @@ activities</em>.</p>
|
||||
network delays such as Ethernet collision exponential back off until
|
||||
retransmission delays which can be quite long on overloaded networks.</p>
|
||||
|
||||
<p>Unlike <code><a href="#ca_pend_event">ca_pend_event</a></code>, this routine will
|
||||
not process CA's background activities if none of the selected IO requests are
|
||||
pending.</p>
|
||||
<p>Unlike <code><a href="#ca_pend_event">ca_pend_event</a></code>, this routine
|
||||
will not process CA's background activities if none of the selected IO requests
|
||||
are pending.</p>
|
||||
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
@@ -3305,7 +3297,7 @@ activity is processed for TIMEOUT seconds.</p>
|
||||
background activity is processed.</p>
|
||||
|
||||
<p>The ca_pend_event function will <em>not</em> return before the specified
|
||||
time-out expires and all unfinished channel access labor has been processed,
|
||||
timeout expires and all unfinished channel access labor has been processed,
|
||||
and unlike <code><a href="#ca_pend_io">ca_pend_io</a></code> returning from the
|
||||
function does <em>not </em>indicate anything about the status of pending IO
|
||||
requests.</p>
|
||||
@@ -3417,7 +3409,7 @@ field should not be used.</p>
|
||||
<dl>
|
||||
<dt><code>USERFUNC</code></dt>
|
||||
<dd>Address of user callback function to be executed when an exceptions
|
||||
occur. Passing a nil value causes the default exception handler to be
|
||||
occur. Passing a nill value causes the default exception handler to be
|
||||
reinstalled. The following structure is passed by value to the user's
|
||||
callback function. Currently, the <code>op</code> field can be one of
|
||||
<code>CA_OP_GET, CA_OP_PUT, CA_OP_CREATE_CHANNEL, CA_OP_ADD_EVENT,
|
||||
@@ -3540,7 +3532,7 @@ get the lowest latency response to the arrival of CA messages.</p>
|
||||
<h3><code><a name="ca_replace_printf_handler">ca_replace_printf_handler
|
||||
()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
typedef int caPrintfFunc ( const char *pFromat, va_list args );
|
||||
typedef int caPrintfFunc ( const char *pFormat, va_list args );
|
||||
int ca_replace_printf_handler ( caPrintfFunc *PFUNC );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
@@ -3552,7 +3544,7 @@ default handler uses fprintf to send messages to 'stderr'.</p>
|
||||
<dl>
|
||||
<dt><code>PFUNC</code></dt>
|
||||
<dd>The address of a user supplied call back handler to be invoked when CA
|
||||
prints diagnostic messages. Installing a nil pointer will cause the
|
||||
prints diagnostic messages. Installing a nill pointer will cause the
|
||||
default call back handler to be reinstalled.</dd>
|
||||
</dl>
|
||||
|
||||
@@ -3571,8 +3563,9 @@ SEVCHK ( status, "failed to install my printf handler" );</pre>
|
||||
|
||||
<h3><code><a name="ca_replace">ca_replace_access_rights_event()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
typedef void ( *pCallBack )( struct access_rights_handler_args );
|
||||
int ca_replace_access_rights_event ( chid CHAN, pCallBack PFUNC );</pre>
|
||||
typedef void ( caEventCallBackFunc )(struct access_rights_handler_args);
|
||||
int ca_replace_access_rights_event ( chid CHAN,
|
||||
caEventCallBackFunc PFUNC );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
@@ -3598,7 +3591,7 @@ specified channel.</p>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><code>PFUNC</code></dt>
|
||||
<dd>Address of user supplied call back function. A nil pointer uninstalls
|
||||
<dd>Address of user supplied call back function. A nill pointer uninstalls
|
||||
the current handler. The following arguments are passed <em>by value</em>
|
||||
to the supplied callback handler.
|
||||
<pre>typedef struct ca_access_rights {
|
||||
@@ -3941,12 +3934,12 @@ prints diagnostics to standard out.</p>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<pre>void ca_test_event ();
|
||||
status = ca_add_event ( type, chid, ca_test_event, NULL, NULL );
|
||||
status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL );
|
||||
SEVCHK ( status, .... );</pre>
|
||||
|
||||
<h4>See Also</h4>
|
||||
|
||||
<p><a href="#ca_add_event">ca_add_event</a>()</p>
|
||||
<p><a href="#ca_add_event">ca_create_subscription</a>()</p>
|
||||
|
||||
<h3><code><a name="ca_sg_create">ca_sg_create()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
@@ -4029,7 +4022,7 @@ SEVCHK ( status, Sync group delete failed );</pre>
|
||||
|
||||
<h3><code><a name="ca_sg_block">ca_sg_block()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
int ca_sg_block ( CA_SYNC_GID GID, double timeout );</pre>
|
||||
int ca_sg_block ( CA_SYNC_GID GID, double TIMEOUT );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
@@ -4050,13 +4043,16 @@ access background activity while it is waiting.</p>
|
||||
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
<dt>GID</dt>
|
||||
<dt><code>GID</code></dt>
|
||||
<dd>Identifier of the synchronous group.</dd>
|
||||
<dt><code>TIMEOUT</code></dt>
|
||||
<dd>The duration to block in this routine in seconds. A timeout of zero
|
||||
seconds blocks forever.</dd>
|
||||
</dl>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<pre>CA_SYNC_GID gid;
|
||||
status = ca_sg_block(gid);
|
||||
status = ca_sg_block(gid, 0.0);
|
||||
SEVCHK(status, Sync group block failed);</pre>
|
||||
|
||||
<h4>Returns</h4>
|
||||
@@ -4267,8 +4263,8 @@ reissued.</p>
|
||||
|
||||
<h3><code><a name="ca_client_status">ca_client_status()</a></code></h3>
|
||||
<pre>int ca_client_status ( unsigned level );
|
||||
int ca_context_status ( struct ca_client_context *,
|
||||
unsigned level );</pre>
|
||||
int ca_context_status ( struct ca_client_context *CONTEXT,
|
||||
unsigned LEVEL );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
@@ -4279,7 +4275,7 @@ ca_client_status() prints information about the calling threads CA context.</p>
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
<dt><code>CONTEXT</code></dt>
|
||||
<dd>A pointer to the CA context to join with.</dd>
|
||||
<dd>A pointer to the CA context to examine.</dd>
|
||||
<dt><code>LEVEL</code></dt>
|
||||
<dd>The interest level. Increasing level produces increasing detail.</dd>
|
||||
</dl>
|
||||
@@ -4289,7 +4285,7 @@ ca_client_status() prints information about the calling threads CA context.</p>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
<p>Returns a pointer to the current thread's CA context. If none then nil is
|
||||
<p>Returns a pointer to the current thread's CA context. If none then nill is
|
||||
returned.</p>
|
||||
|
||||
<h4>See Also</h4>
|
||||
@@ -4322,12 +4318,11 @@ preemptively from more than one thread.</p>
|
||||
|
||||
<h4>Returns</h4>
|
||||
|
||||
<p>ECA_ISATTACHED - already attached to a CA context</p>
|
||||
<p>ECA_NORMAL - Normal successful completion</p>
|
||||
|
||||
<p>ECA_NOTTHREADED - the specified context is non-preemptive and therefore does
|
||||
not allow other threads to join</p>
|
||||
<p>ECA_NOTTHREADED - Context is not preemptive so cannot be joined</p>
|
||||
|
||||
<p>ECA_ISATTACHED - the current thread is already attached to a CA context</p>
|
||||
<p>ECA_ISATTACHED - Thread already attached to a CA context</p>
|
||||
|
||||
<h4>See Also</h4>
|
||||
|
||||
|
||||
@@ -84,14 +84,19 @@ PROD_LIBS = ca Com
|
||||
# needed when its an object library build
|
||||
PROD_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
|
||||
|
||||
PROD_HOST += caRepeater catime acctst caConnTest casw caEventRate
|
||||
OBJS_vxWorks += catime acctst caConnTest casw caEventRate acctstRegister
|
||||
PROD_DEFAULT += caRepeater catime acctst caConnTest casw caEventRate
|
||||
PROD_vxWorks = -nil-
|
||||
PROD_RTEMS = -nil-
|
||||
PROD_iOS = -nil-
|
||||
|
||||
OBJS_vxWorks = catime acctst caConnTest casw caEventRate acctstRegister
|
||||
|
||||
caRepeater_SRCS = caRepeater.cpp
|
||||
catime_SRCS = catimeMain.c catime.c
|
||||
acctst_SRCS = acctstMain.c acctst.c
|
||||
catime_SRCS = catimeMain.c catime.c
|
||||
acctst_SRCS = acctstMain.c acctst.c
|
||||
caEventRate_SRCS = caEventRateMain.cpp caEventRate.cpp
|
||||
casw_SRCS = casw.cpp
|
||||
caConnTest_SRCS = caConnTestMain.cpp caConnTest.cpp
|
||||
caConnTest_SRCS = caConnTestMain.cpp caConnTest.cpp
|
||||
|
||||
casw_SYS_LIBS_solaris = socket
|
||||
|
||||
|
||||
0
src/ca/client/SearchDest.h
Executable file → Normal file
0
src/ca/client/SearchDest.h
Executable file → Normal file
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* allocate error message string array
|
||||
* allocate error message string array
|
||||
* here so I can use sizeof
|
||||
*/
|
||||
#define CA_ERROR_GLBLSOURCE
|
||||
@@ -182,7 +182,7 @@ int epicsShareAPI ca_task_initialize ( void )
|
||||
}
|
||||
|
||||
// extern "C"
|
||||
int epicsShareAPI ca_context_create (
|
||||
int epicsShareAPI ca_context_create (
|
||||
ca_preemptive_callback_select premptiveCallbackSelect )
|
||||
{
|
||||
ca_client_context *pcac;
|
||||
@@ -202,7 +202,7 @@ int epicsShareAPI ca_context_create (
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
pcac = new ca_client_context (
|
||||
pcac = new ca_client_context (
|
||||
premptiveCallbackSelect == ca_enable_preemptive_callback );
|
||||
if ( ! pcac ) {
|
||||
return ECA_ALLOCMEM;
|
||||
@@ -275,7 +275,7 @@ int epicsShareAPI ca_task_exit ()
|
||||
*/
|
||||
// extern "C"
|
||||
int epicsShareAPI ca_build_and_connect ( const char *name_str, chtype get_type,
|
||||
arrayElementCount get_count, chid * chan, void *pvalue,
|
||||
arrayElementCount get_count, chid * chan, void *pvalue,
|
||||
caCh *conn_func, void *puser )
|
||||
{
|
||||
if ( get_type != TYPENOTCONN && pvalue != 0 && get_count != 0 ) {
|
||||
@@ -286,14 +286,14 @@ int epicsShareAPI ca_build_and_connect ( const char *name_str, chtype get_type,
|
||||
}
|
||||
|
||||
/*
|
||||
* ca_search_and_connect()
|
||||
* ca_search_and_connect()
|
||||
*/
|
||||
// extern "C"
|
||||
int epicsShareAPI ca_search_and_connect (
|
||||
const char * name_str, chid * chanptr,
|
||||
caCh * conn_func, void * puser )
|
||||
{
|
||||
return ca_create_channel ( name_str, conn_func,
|
||||
return ca_create_channel ( name_str, conn_func,
|
||||
puser, CA_PRIORITY_DEFAULT, chanptr );
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ int epicsShareAPI ca_create_channel (
|
||||
CAFDHANDLER * pFunc = 0;
|
||||
void * pArg = 0;
|
||||
{
|
||||
epicsGuard < epicsMutex >
|
||||
epicsGuard < epicsMutex >
|
||||
guard ( pcac->mutex );
|
||||
if ( pcac->fdRegFuncNeedsToBeCalled ) {
|
||||
pFunc = pcac->fdRegFunc;
|
||||
@@ -327,9 +327,9 @@ int epicsShareAPI ca_create_channel (
|
||||
|
||||
try {
|
||||
epicsGuard < epicsMutex > guard ( pcac->mutex );
|
||||
oldChannelNotify * pChanNotify =
|
||||
new ( pcac->oldChannelNotifyFreeList )
|
||||
oldChannelNotify ( guard, *pcac, name_str,
|
||||
oldChannelNotify * pChanNotify =
|
||||
new ( pcac->oldChannelNotifyFreeList )
|
||||
oldChannelNotify ( guard, *pcac, name_str,
|
||||
conn_func, puser, priority );
|
||||
// make sure that their chan pointer is set prior to
|
||||
// calling connection call backs
|
||||
@@ -352,9 +352,9 @@ int epicsShareAPI ca_create_channel (
|
||||
return ECA_UNAVAILINSERV;
|
||||
}
|
||||
catch ( std :: exception & except ) {
|
||||
pcac->printFormated (
|
||||
pcac->printFormated (
|
||||
"ca_create_channel: "
|
||||
"unexpected exception was \"%s\"",
|
||||
"unexpected exception was \"%s\"",
|
||||
except.what () );
|
||||
return ECA_INTERNAL;
|
||||
}
|
||||
@@ -369,22 +369,42 @@ int epicsShareAPI ca_create_channel (
|
||||
* ca_clear_channel ()
|
||||
*
|
||||
* a known defect here is that there will be a
|
||||
* crash if they destroy the channel after destroying
|
||||
* crash if they destroy the channel after destroying
|
||||
* its context
|
||||
*/
|
||||
// extern "C"
|
||||
int epicsShareAPI ca_clear_channel ( chid pChan )
|
||||
{
|
||||
ca_client_context & cac = pChan->getClientCtx ();
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
try {
|
||||
pChan->eliminateExcessiveSendBacklog ( guard );
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
try {
|
||||
pChan->eliminateExcessiveSendBacklog ( guard );
|
||||
}
|
||||
catch ( cacChannel::notConnected & ) {
|
||||
// intentionally ignored
|
||||
}
|
||||
}
|
||||
catch ( cacChannel::notConnected & ) {
|
||||
// intentionally ignored
|
||||
if ( cac.pCallbackGuard.get() &&
|
||||
cac.createdByThread == epicsThreadGetIdSelf () ) {
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
pChan->destructor ( *cac.pCallbackGuard.get(), guard );
|
||||
cac.oldChannelNotifyFreeList.release ( pChan );
|
||||
}
|
||||
else {
|
||||
//
|
||||
// we will definately stall out here if all of the
|
||||
// following are true
|
||||
//
|
||||
// o user creates non-preemtive mode client library context
|
||||
// o user doesnt periodically call a ca function
|
||||
// o user calls this function from an auxiillary thread
|
||||
//
|
||||
CallbackGuard cbGuard ( cac.cbMutex );
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
pChan->destructor ( *cac.pCallbackGuard.get(), guard );
|
||||
cac.oldChannelNotifyFreeList.release ( pChan );
|
||||
}
|
||||
pChan->destructor ( guard );
|
||||
cac.oldChannelNotifyFreeList.release ( pChan );
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
@@ -399,7 +419,7 @@ int epicsShareAPI ca_add_exception_event ( caExceptionHandler *pfunc, void *arg
|
||||
if ( caStatus != ECA_NORMAL ) {
|
||||
return caStatus;
|
||||
}
|
||||
|
||||
|
||||
pcac->changeExceptionEvent ( pfunc, arg );
|
||||
|
||||
return ECA_NORMAL;
|
||||
@@ -408,10 +428,10 @@ int epicsShareAPI ca_add_exception_event ( caExceptionHandler *pfunc, void *arg
|
||||
/*
|
||||
* ca_add_masked_array_event
|
||||
*/
|
||||
int epicsShareAPI ca_add_masked_array_event (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
caEventCallBackFunc *pCallBack, void *pCallBackArg,
|
||||
ca_real, ca_real, ca_real,
|
||||
int epicsShareAPI ca_add_masked_array_event (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
caEventCallBackFunc *pCallBack, void *pCallBackArg,
|
||||
ca_real, ca_real, ca_real,
|
||||
evid *monixptr, long mask )
|
||||
{
|
||||
return ca_create_subscription ( type, count, pChan, mask,
|
||||
@@ -429,7 +449,7 @@ int epicsShareAPI ca_clear_event ( evid pMon )
|
||||
// extern "C"
|
||||
chid epicsShareAPI ca_evid_to_chid ( evid pMon )
|
||||
{
|
||||
return & pMon->channel ();
|
||||
return & pMon->channel ();
|
||||
}
|
||||
|
||||
// extern "C"
|
||||
@@ -498,7 +518,7 @@ int epicsShareAPI ca_pend_io ( ca_real timeout )
|
||||
|
||||
/*
|
||||
* ca_flush_io ()
|
||||
*/
|
||||
*/
|
||||
int epicsShareAPI ca_flush_io ()
|
||||
{
|
||||
ca_client_context * pcac;
|
||||
@@ -545,7 +565,7 @@ void epicsShareAPI ca_signal ( long ca_status, const char *message )
|
||||
* ca_message (long ca_status)
|
||||
*
|
||||
* - if it is an unknown error code then it possible
|
||||
* that the error string generated below
|
||||
* that the error string generated below
|
||||
* will be overwritten before (or while) the caller
|
||||
* of this routine is calling this routine
|
||||
* (if they call this routine again).
|
||||
@@ -567,7 +587,7 @@ const char * epicsShareAPI ca_message ( long ca_status )
|
||||
* ca_signal_with_file_and_lineno()
|
||||
*/
|
||||
// extern "C"
|
||||
void epicsShareAPI ca_signal_with_file_and_lineno ( long ca_status,
|
||||
void epicsShareAPI ca_signal_with_file_and_lineno ( long ca_status,
|
||||
const char *message, const char *pfilenm, int lineno )
|
||||
{
|
||||
ca_signal_formated ( ca_status, pfilenm, lineno, message );
|
||||
@@ -577,7 +597,7 @@ void epicsShareAPI ca_signal_with_file_and_lineno ( long ca_status,
|
||||
* ca_signal_formated()
|
||||
*/
|
||||
// extern "C"
|
||||
void epicsShareAPI ca_signal_formated ( long ca_status, const char *pfilenm,
|
||||
void epicsShareAPI ca_signal_formated ( long ca_status, const char *pfilenm,
|
||||
int lineno, const char *pFormat, ... )
|
||||
{
|
||||
ca_client_context *pcac;
|
||||
@@ -590,12 +610,12 @@ void epicsShareAPI ca_signal_formated ( long ca_status, const char *pfilenm,
|
||||
}
|
||||
|
||||
va_list theArgs;
|
||||
va_start ( theArgs, pFormat );
|
||||
va_start ( theArgs, pFormat );
|
||||
if ( pcac ) {
|
||||
pcac->vSignal ( ca_status, pfilenm, lineno, pFormat, theArgs );
|
||||
}
|
||||
else {
|
||||
fprintf ( stderr, "CA exception in thread w/o CA ctx: status=%s file=%s line=%d: \n",
|
||||
fprintf ( stderr, "CA exception in thread w/o CA ctx: status=%s file=%s line=%d: \n",
|
||||
ca_message ( ca_status ), pfilenm, lineno );
|
||||
if ( pFormat ) {
|
||||
vfprintf ( stderr, pFormat, theArgs );
|
||||
@@ -607,7 +627,7 @@ void epicsShareAPI ca_signal_formated ( long ca_status, const char *pfilenm,
|
||||
/*
|
||||
* CA_ADD_FD_REGISTRATION
|
||||
*
|
||||
* call their function with their argument whenever
|
||||
* call their function with their argument whenever
|
||||
* a new fd is added or removed
|
||||
* (for a manager of the select system call under UNIX)
|
||||
*
|
||||
@@ -631,7 +651,7 @@ int epicsShareAPI ca_add_fd_registration ( CAFDHANDLER * func, void * arg )
|
||||
* function that returns the CA version string
|
||||
*/
|
||||
// extern "C"
|
||||
const char * epicsShareAPI ca_version ()
|
||||
const char * epicsShareAPI ca_version ()
|
||||
{
|
||||
return CA_VERSION_STRING ( CA_MINOR_PROTOCOL_REVISION );
|
||||
}
|
||||
@@ -660,7 +680,7 @@ int epicsShareAPI ca_replace_printf_handler ( caPrintfFunc *ca_printf_func )
|
||||
* (for testing purposes only)
|
||||
*/
|
||||
// extern "C"
|
||||
unsigned epicsShareAPI ca_get_ioc_connection_count ()
|
||||
unsigned epicsShareAPI ca_get_ioc_connection_count ()
|
||||
{
|
||||
ca_client_context * pcac;
|
||||
int caStatus = fetchClientContext ( & pcac );
|
||||
@@ -720,7 +740,7 @@ struct ca_client_context * epicsShareAPI ca_current_context ()
|
||||
{
|
||||
struct ca_client_context *pCtx;
|
||||
if ( caClientContextId ) {
|
||||
pCtx = ( struct ca_client_context * )
|
||||
pCtx = ( struct ca_client_context * )
|
||||
epicsThreadPrivateGet ( caClientContextId );
|
||||
}
|
||||
else {
|
||||
@@ -749,7 +769,7 @@ int epicsShareAPI ca_attach_context ( struct ca_client_context * pCtx )
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
void epicsShareAPI ca_detach_context ()
|
||||
void epicsShareAPI ca_detach_context ()
|
||||
{
|
||||
if ( caClientContextId ) {
|
||||
epicsThreadPrivateSet ( caClientContextId, 0 );
|
||||
@@ -794,43 +814,43 @@ epicsShareDef const int epicsTypeToDBR_XXXX [lastEpicsType+1] = {
|
||||
// extern "C"
|
||||
epicsShareDef const epicsType DBR_XXXXToEpicsType [LAST_BUFFER_TYPE+1] = {
|
||||
epicsOldStringT,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsFloat64T,
|
||||
|
||||
epicsOldStringT,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsFloat64T,
|
||||
|
||||
epicsOldStringT,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsFloat64T,
|
||||
|
||||
epicsOldStringT,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsFloat64T,
|
||||
|
||||
epicsOldStringT,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsInt16T,
|
||||
epicsFloat32T,
|
||||
epicsEnum16T,
|
||||
epicsUInt8T,
|
||||
epicsInt32T,
|
||||
epicsFloat64T,
|
||||
|
||||
epicsUInt16T,
|
||||
@@ -939,7 +959,7 @@ epicsShareDef const unsigned short dbr_value_size[LAST_BUFFER_TYPE+1] = {
|
||||
sizeof(dbr_string_t), /* string max size */
|
||||
};
|
||||
|
||||
//extern "C"
|
||||
//extern "C"
|
||||
epicsShareDef const enum dbr_value_class dbr_value_class[LAST_BUFFER_TYPE+1] = {
|
||||
dbr_class_string, /* string max size */
|
||||
dbr_class_int, /* short */
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* Authors:
|
||||
* Jeff Hill
|
||||
* Murali Shankar - initial versions of verifyMultithreadSubscr
|
||||
* Michael Abbott - initial versions of multiSubscrDestroyNoLateCallbackTest
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1328,6 +1329,159 @@ void test_sync_groups ( chid chan, unsigned interestLevel )
|
||||
showProgressEnd ( interestLevel );
|
||||
}
|
||||
|
||||
#define multiSubscrDestroyNoLateCallbackEventCount 500
|
||||
|
||||
struct MultiSubscrDestroyNoLateCallbackEventData {
|
||||
evid m_id;
|
||||
size_t m_nCallback;
|
||||
int m_callbackIsOk;
|
||||
struct MultiSubscrDestroyNoLateCallbackTestData * m_pTestData;
|
||||
};
|
||||
|
||||
struct MultiSubscrDestroyNoLateCallbackTestData {
|
||||
const char * m_pChanName;
|
||||
chid m_chan;
|
||||
epicsMutexId m_mutex;
|
||||
epicsEventId m_testDoneEvent;
|
||||
unsigned m_interestLevel;
|
||||
struct MultiSubscrDestroyNoLateCallbackEventData
|
||||
m_eventData [multiSubscrDestroyNoLateCallbackEventCount];
|
||||
};
|
||||
|
||||
static void noLateCallbackDetect ( struct event_handler_args args )
|
||||
{
|
||||
int callbackIsOk;
|
||||
struct MultiSubscrDestroyNoLateCallbackEventData * const pEventData = args.usr;
|
||||
epicsMutexLockStatus lockStatus = epicsMutexLock ( pEventData->m_pTestData->m_mutex );
|
||||
callbackIsOk = pEventData->m_callbackIsOk;
|
||||
pEventData->m_nCallback++;
|
||||
epicsMutexUnlock ( pEventData->m_pTestData->m_mutex );
|
||||
verify ( lockStatus == epicsMutexLockOK );
|
||||
verify ( callbackIsOk );
|
||||
}
|
||||
|
||||
static void multiSubscrDestroyNoLateCallbackThread ( void * pParm )
|
||||
{
|
||||
struct MultiSubscrDestroyNoLateCallbackTestData * const pTestData =
|
||||
( struct MultiSubscrDestroyNoLateCallbackTestData * ) pParm;
|
||||
unsigned i, j;
|
||||
int status;
|
||||
|
||||
status = ca_context_create ( ca_enable_preemptive_callback );
|
||||
verify ( status == ECA_NORMAL );
|
||||
|
||||
status = ca_create_channel ( pTestData->m_pChanName, 0, 0,
|
||||
CA_PRIORITY_DEFAULT, &pTestData->m_chan );
|
||||
status = ca_pend_io ( timeoutToPendIO );
|
||||
SEVCHK ( status, "multiSubscrDestroyLateNoCallbackTest: channel connect failed" );
|
||||
verify ( status == ECA_NORMAL );
|
||||
|
||||
/*
|
||||
* create a set of subscriptions
|
||||
*/
|
||||
for ( i=0; i < 10000; i++ ) {
|
||||
unsigned int priorityOfTestThread;
|
||||
for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) {
|
||||
epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex );
|
||||
verify ( lockStatus == epicsMutexLockOK );
|
||||
pTestData->m_eventData[j].m_nCallback = 0;
|
||||
pTestData->m_eventData[j].m_callbackIsOk = TRUE;
|
||||
pTestData->m_eventData[j].m_pTestData = pTestData;
|
||||
epicsMutexUnlock ( pTestData->m_mutex );
|
||||
SEVCHK ( ca_add_event ( DBR_GR_FLOAT, pTestData->m_chan, noLateCallbackDetect,
|
||||
&pTestData->m_eventData[j], &pTestData->m_eventData[j].m_id ) , NULL );
|
||||
}
|
||||
SEVCHK ( ca_flush_io(), NULL );
|
||||
|
||||
/*
|
||||
* raise the priority of the current thread hoping to improve our
|
||||
* likelyhood of detecting a bug
|
||||
*/
|
||||
priorityOfTestThread = epicsThreadGetPrioritySelf ();
|
||||
epicsThreadSetPriority ( epicsThreadGetIdSelf(), epicsThreadPriorityHigh );
|
||||
|
||||
|
||||
/*
|
||||
* wait for the first subscription update to arrive
|
||||
*/
|
||||
{
|
||||
epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex );
|
||||
verify ( lockStatus == epicsMutexLockOK );
|
||||
while ( pTestData->m_eventData[0].m_nCallback == 0 ) {
|
||||
epicsMutexUnlock ( pTestData->m_mutex );
|
||||
epicsThreadSleep ( 50e-6 );
|
||||
lockStatus = epicsMutexLock ( pTestData->m_mutex );
|
||||
verify ( lockStatus == epicsMutexLockOK );
|
||||
}
|
||||
epicsMutexUnlock ( pTestData->m_mutex );
|
||||
}
|
||||
/*
|
||||
* try to destroy all of the subscriptions at precisely the same time that
|
||||
* their first callbacks are running
|
||||
*/
|
||||
for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) {
|
||||
epicsMutexLockStatus lockStatus;
|
||||
SEVCHK ( ca_clear_event ( pTestData->m_eventData[j].m_id ) , NULL );
|
||||
lockStatus = epicsMutexLock ( pTestData->m_mutex );
|
||||
verify ( lockStatus == epicsMutexLockOK );
|
||||
pTestData->m_eventData[j].m_callbackIsOk = FALSE;
|
||||
epicsMutexUnlock ( pTestData->m_mutex );
|
||||
}
|
||||
/*
|
||||
* return to the original priority
|
||||
*/
|
||||
epicsThreadSetPriority ( epicsThreadGetIdSelf(), priorityOfTestThread );
|
||||
|
||||
if ( i % 1000 == 0 ) {
|
||||
showProgress ( pTestData->m_interestLevel );
|
||||
}
|
||||
}
|
||||
|
||||
SEVCHK ( ca_clear_channel ( pTestData->m_chan ), NULL );
|
||||
|
||||
ca_context_destroy ();
|
||||
|
||||
epicsEventMustTrigger ( pTestData->m_testDoneEvent );
|
||||
}
|
||||
|
||||
/*
|
||||
* verify that, in a preemtive callback mode client, a subscription callback never
|
||||
* comes after the subscription is destroyed
|
||||
*/
|
||||
static void multiSubscrDestroyNoLateCallbackTest ( const char *pName, unsigned interestLevel )
|
||||
{
|
||||
struct MultiSubscrDestroyNoLateCallbackTestData * pTestData;
|
||||
|
||||
showProgressBegin ( "multiSubscrDestroyNoLateCallbackTest", interestLevel );
|
||||
|
||||
pTestData = calloc ( 1u, sizeof ( struct MultiSubscrDestroyNoLateCallbackTestData ) );
|
||||
verify ( pTestData );
|
||||
pTestData->m_mutex = epicsMutexMustCreate ();
|
||||
pTestData->m_testDoneEvent = epicsEventMustCreate ( epicsEventEmpty );
|
||||
pTestData->m_pChanName = pName;
|
||||
pTestData->m_interestLevel = interestLevel;
|
||||
epicsThreadMustCreate (
|
||||
"multiSubscrDestroyNoLateCallbackTest",
|
||||
epicsThreadPriorityLow,
|
||||
epicsThreadGetStackSize ( epicsThreadStackMedium ),
|
||||
multiSubscrDestroyNoLateCallbackThread,
|
||||
pTestData );
|
||||
|
||||
/*
|
||||
* wait for test to complete
|
||||
*/
|
||||
epicsEventMustWait ( pTestData->m_testDoneEvent );
|
||||
|
||||
/*
|
||||
* cleanup
|
||||
*/
|
||||
epicsMutexDestroy ( pTestData->m_mutex );
|
||||
epicsEventDestroy ( pTestData->m_testDoneEvent );
|
||||
free ( pTestData );
|
||||
|
||||
showProgressEnd ( interestLevel );
|
||||
}
|
||||
|
||||
/*
|
||||
* multiSubscriptionDeleteTest
|
||||
*
|
||||
@@ -3263,6 +3417,11 @@ int acctst ( const char * pName, unsigned interestLevel, unsigned channelCount,
|
||||
epicsEnvSet ( "EPICS_CA_MAX_ARRAY_BYTES", tmpString );
|
||||
}
|
||||
|
||||
/*
|
||||
* this test creates, and then destroys, a private CA context
|
||||
*/
|
||||
multiSubscrDestroyNoLateCallbackTest ( pName, interestLevel );
|
||||
|
||||
status = ca_context_create ( select );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
|
||||
0
src/ca/client/ca.rc
Executable file → Normal file
0
src/ca/client/ca.rc
Executable file → Normal file
@@ -4,19 +4,19 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
@@ -27,7 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string> // vxWorks 6.0 requires this include
|
||||
#include <string> // vxWorks 6.0 requires this include
|
||||
#include <stdio.h>
|
||||
|
||||
#include "epicsExit.h"
|
||||
@@ -57,7 +57,7 @@ extern "C" void cacOnceFunc ( void * )
|
||||
{
|
||||
caClientCallbackThreadId = epicsThreadPrivateCreate ();
|
||||
assert ( caClientCallbackThreadId );
|
||||
ca_client_context::pDefaultServiceInstallMutex = new epicsMutex;
|
||||
ca_client_context::pDefaultServiceInstallMutex = newEpicsMutex;
|
||||
epicsAtExit ( cacExitHandler,0 );
|
||||
}
|
||||
|
||||
@@ -67,11 +67,11 @@ cacService * ca_client_context::pDefaultService = 0;
|
||||
epicsMutex * ca_client_context::pDefaultServiceInstallMutex;
|
||||
|
||||
ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
|
||||
createdByThread ( epicsThreadGetIdSelf () ),
|
||||
ca_exception_func ( 0 ), ca_exception_arg ( 0 ),
|
||||
createdByThread ( epicsThreadGetIdSelf () ),
|
||||
ca_exception_func ( 0 ), ca_exception_arg ( 0 ),
|
||||
pVPrintfFunc ( errlogVprintf ), fdRegFunc ( 0 ), fdRegArg ( 0 ),
|
||||
pndRecvCnt ( 0u ), ioSeqNo ( 0u ), callbackThreadsPending ( 0u ),
|
||||
localPort ( 0 ), fdRegFuncNeedsToBeCalled ( false ),
|
||||
pndRecvCnt ( 0u ), ioSeqNo ( 0u ), callbackThreadsPending ( 0u ),
|
||||
localPort ( 0 ), fdRegFuncNeedsToBeCalled ( false ),
|
||||
noWakeupSincePend ( true )
|
||||
{
|
||||
static const unsigned short PORT_ANY = 0u;
|
||||
@@ -85,7 +85,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
|
||||
epicsGuard < epicsMutex > guard ( *ca_client_context::pDefaultServiceInstallMutex );
|
||||
if ( ca_client_context::pDefaultService ) {
|
||||
this->pServiceContext.reset (
|
||||
& ca_client_context::pDefaultService->contextCreate (
|
||||
& ca_client_context::pDefaultService->contextCreate (
|
||||
this->mutex, this->cbMutex, *this ) );
|
||||
}
|
||||
else {
|
||||
@@ -125,7 +125,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
|
||||
osiSockAddr addr;
|
||||
memset ( (char *)&addr, 0 , sizeof ( addr ) );
|
||||
addr.ia.sin_family = AF_INET;
|
||||
addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
|
||||
addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
|
||||
addr.ia.sin_port = htons ( PORT_ANY );
|
||||
int status = bind (this->sock, &addr.sa, sizeof (addr) );
|
||||
if ( status < 0 ) {
|
||||
@@ -139,7 +139,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
|
||||
throwWithLocation ( noSocket () );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
osiSockAddr tmpAddr;
|
||||
osiSocklen_t saddr_length = sizeof ( tmpAddr );
|
||||
@@ -159,9 +159,9 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
|
||||
this->localPort = htons ( tmpAddr.ia.sin_port );
|
||||
}
|
||||
|
||||
epics_auto_ptr < epicsGuard < epicsMutex > > pCBGuard;
|
||||
epics_auto_ptr < CallbackGuard > pCBGuard;
|
||||
if ( ! enablePreemptiveCallback ) {
|
||||
pCBGuard.reset ( new epicsGuard < epicsMutex > ( this->cbMutex ) );
|
||||
pCBGuard.reset ( new CallbackGuard ( this->cbMutex ) );
|
||||
}
|
||||
|
||||
// multiple steps ensure exception safety
|
||||
@@ -171,7 +171,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
|
||||
ca_client_context::~ca_client_context ()
|
||||
{
|
||||
if ( this->fdRegFunc ) {
|
||||
( *this->fdRegFunc )
|
||||
( *this->fdRegFunc )
|
||||
( this->fdRegArg, this->sock, false );
|
||||
}
|
||||
epicsSocketDestroy ( this->sock );
|
||||
@@ -179,9 +179,9 @@ ca_client_context::~ca_client_context ()
|
||||
osiSockRelease ();
|
||||
|
||||
// force a logical shutdown order
|
||||
// so that the cac class does not hang its
|
||||
// so that the cac class does not hang its
|
||||
// receive threads during their shutdown sequence
|
||||
// and so that classes using this classes mutex
|
||||
// and so that classes using this classes mutex
|
||||
// are destroyed before the mutex is destroyed
|
||||
if ( this->pCallbackGuard.get() ) {
|
||||
epicsGuardRelease < epicsMutex > unguard ( *this->pCallbackGuard );
|
||||
@@ -192,7 +192,7 @@ ca_client_context::~ca_client_context ()
|
||||
}
|
||||
}
|
||||
|
||||
void ca_client_context::destroyGetCopy (
|
||||
void ca_client_context::destroyGetCopy (
|
||||
epicsGuard < epicsMutex > & guard, getCopy & gc )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -200,7 +200,7 @@ void ca_client_context::destroyGetCopy (
|
||||
this->getCopyFreeList.release ( & gc );
|
||||
}
|
||||
|
||||
void ca_client_context::destroyGetCallback (
|
||||
void ca_client_context::destroyGetCallback (
|
||||
epicsGuard < epicsMutex > & guard, getCallback & gcb )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -208,7 +208,7 @@ void ca_client_context::destroyGetCallback (
|
||||
this->getCallbackFreeList.release ( & gcb );
|
||||
}
|
||||
|
||||
void ca_client_context::destroyPutCallback (
|
||||
void ca_client_context::destroyPutCallback (
|
||||
epicsGuard < epicsMutex > & guard, putCallback & pcb )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -216,7 +216,7 @@ void ca_client_context::destroyPutCallback (
|
||||
this->putCallbackFreeList.release ( & pcb );
|
||||
}
|
||||
|
||||
void ca_client_context::destroySubscription (
|
||||
void ca_client_context::destroySubscription (
|
||||
epicsGuard < epicsMutex > & guard, oldSubscription & os )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -224,7 +224,7 @@ void ca_client_context::destroySubscription (
|
||||
this->subscriptionFreeList.release ( & os );
|
||||
}
|
||||
|
||||
void ca_client_context::changeExceptionEvent (
|
||||
void ca_client_context::changeExceptionEvent (
|
||||
caExceptionHandler * pfunc, void * arg )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -233,7 +233,7 @@ void ca_client_context::changeExceptionEvent (
|
||||
// should block here until releated callback in progress completes
|
||||
}
|
||||
|
||||
void ca_client_context::replaceErrLogHandler (
|
||||
void ca_client_context::replaceErrLogHandler (
|
||||
caPrintfFunc * ca_printf_func )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -246,7 +246,7 @@ void ca_client_context::replaceErrLogHandler (
|
||||
// should block here until releated callback in progress completes
|
||||
}
|
||||
|
||||
void ca_client_context::registerForFileDescriptorCallBack (
|
||||
void ca_client_context::registerForFileDescriptorCallBack (
|
||||
CAFDHANDLER *pFunc, void *pArg )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -261,22 +261,22 @@ void ca_client_context::registerForFileDescriptorCallBack (
|
||||
// should block here until releated callback in progress completes
|
||||
}
|
||||
|
||||
int ca_client_context :: printFormated (
|
||||
int ca_client_context :: printFormated (
|
||||
const char *pformat, ... ) const
|
||||
{
|
||||
va_list theArgs;
|
||||
int status;
|
||||
|
||||
va_start ( theArgs, pformat );
|
||||
|
||||
|
||||
status = this->ca_client_context :: varArgsPrintFormated ( pformat, theArgs );
|
||||
|
||||
|
||||
va_end ( theArgs );
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int ca_client_context :: varArgsPrintFormated (
|
||||
int ca_client_context :: varArgsPrintFormated (
|
||||
const char *pformat, va_list args ) const
|
||||
{
|
||||
caPrintfFunc * pFunc;
|
||||
@@ -292,8 +292,8 @@ int ca_client_context :: varArgsPrintFormated (
|
||||
}
|
||||
}
|
||||
|
||||
void ca_client_context::exception (
|
||||
epicsGuard < epicsMutex > & guard, int stat, const char * pCtx,
|
||||
void ca_client_context::exception (
|
||||
epicsGuard < epicsMutex > & guard, int stat, const char * pCtx,
|
||||
const char * pFile, unsigned lineNo )
|
||||
{
|
||||
struct exception_handler_args args;
|
||||
@@ -321,9 +321,9 @@ void ca_client_context::exception (
|
||||
}
|
||||
}
|
||||
|
||||
void ca_client_context::exception (
|
||||
void ca_client_context::exception (
|
||||
epicsGuard < epicsMutex > & guard, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
unsigned type, arrayElementCount count, unsigned op )
|
||||
{
|
||||
struct exception_handler_args args;
|
||||
@@ -346,29 +346,29 @@ void ca_client_context::exception (
|
||||
( *pFunc ) ( args );
|
||||
}
|
||||
else {
|
||||
this->signal ( status, pFileName, lineNo,
|
||||
"op=%u, channel=%s, type=%s, count=%lu, ctx=\"%s\"",
|
||||
op, ca_name ( &chan ),
|
||||
dbr_type_to_text ( static_cast <int> ( type ) ),
|
||||
this->signal ( status, pFileName, lineNo,
|
||||
"op=%u, channel=%s, type=%s, count=%lu, ctx=\"%s\"",
|
||||
op, ca_name ( &chan ),
|
||||
dbr_type_to_text ( static_cast <int> ( type ) ),
|
||||
count, pContext );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ca_client_context::signal ( int ca_status, const char * pfilenm,
|
||||
void ca_client_context::signal ( int ca_status, const char * pfilenm,
|
||||
int lineno, const char * pFormat, ... )
|
||||
{
|
||||
va_list theArgs;
|
||||
va_start ( theArgs, pFormat );
|
||||
va_start ( theArgs, pFormat );
|
||||
this->vSignal ( ca_status, pfilenm, lineno, pFormat, theArgs);
|
||||
va_end ( theArgs );
|
||||
}
|
||||
|
||||
void ca_client_context :: vSignal (
|
||||
int ca_status, const char *pfilenm,
|
||||
void ca_client_context :: vSignal (
|
||||
int ca_status, const char *pfilenm,
|
||||
int lineno, const char *pFormat, va_list args )
|
||||
{
|
||||
static const char *severity[] =
|
||||
static const char *severity[] =
|
||||
{
|
||||
"Warning",
|
||||
"Success",
|
||||
@@ -379,11 +379,11 @@ void ca_client_context :: vSignal (
|
||||
"Fatal",
|
||||
"Fatal"
|
||||
};
|
||||
|
||||
|
||||
this->printFormated ( "CA.Client.Exception...............................................\n" );
|
||||
|
||||
this->printFormated ( " %s: \"%s\"\n",
|
||||
severity[ CA_EXTRACT_SEVERITY ( ca_status ) ],
|
||||
|
||||
this->printFormated ( " %s: \"%s\"\n",
|
||||
severity[ CA_EXTRACT_SEVERITY ( ca_status ) ],
|
||||
ca_message ( ca_status ) );
|
||||
|
||||
if ( pFormat ) {
|
||||
@@ -391,26 +391,26 @@ void ca_client_context :: vSignal (
|
||||
this->varArgsPrintFormated ( pFormat, args );
|
||||
this->printFormated ( "\"\n" );
|
||||
}
|
||||
|
||||
|
||||
if ( pfilenm ) {
|
||||
this->printFormated ( " Source File: %s line %d\n",
|
||||
pfilenm, lineno );
|
||||
}
|
||||
pfilenm, lineno );
|
||||
}
|
||||
|
||||
epicsTime current = epicsTime::getCurrent ();
|
||||
char date[64];
|
||||
current.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f");
|
||||
this->printFormated ( " Current Time: %s\n", date );
|
||||
|
||||
|
||||
/*
|
||||
* Terminate execution if unsuccessful
|
||||
*/
|
||||
if( ! ( ca_status & CA_M_SUCCESS ) &&
|
||||
if( ! ( ca_status & CA_M_SUCCESS ) &&
|
||||
CA_EXTRACT_SEVERITY ( ca_status ) != CA_K_WARNING ){
|
||||
errlogFlush ();
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
this->printFormated ( "..................................................................\n" );
|
||||
}
|
||||
|
||||
@@ -418,7 +418,7 @@ void ca_client_context::show ( unsigned level ) const
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
|
||||
::printf ( "ca_client_context at %p pndRecvCnt=%u ioSeqNo=%u\n",
|
||||
::printf ( "ca_client_context at %p pndRecvCnt=%u ioSeqNo=%u\n",
|
||||
static_cast <const void *> ( this ),
|
||||
this->pndRecvCnt, this->ioSeqNo );
|
||||
|
||||
@@ -443,7 +443,7 @@ void ca_client_context::attachToClientCtx ()
|
||||
epicsThreadPrivateSet ( caClientContextId, this );
|
||||
}
|
||||
|
||||
void ca_client_context::incrementOutstandingIO (
|
||||
void ca_client_context::incrementOutstandingIO (
|
||||
epicsGuard < epicsMutex > & guard, unsigned ioSeqNoIn )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -453,7 +453,7 @@ void ca_client_context::incrementOutstandingIO (
|
||||
}
|
||||
}
|
||||
|
||||
void ca_client_context::decrementOutstandingIO (
|
||||
void ca_client_context::decrementOutstandingIO (
|
||||
epicsGuard < epicsMutex > & guard, unsigned ioSeqNoIn )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -466,16 +466,16 @@ void ca_client_context::decrementOutstandingIO (
|
||||
}
|
||||
}
|
||||
|
||||
// !!!! This routine is only visible in the old interface - or in a new ST interface.
|
||||
// !!!! In the old interface we restrict thread attach so that calls from threads
|
||||
// !!!! other than the initializing thread are not allowed if preemptive callback
|
||||
// !!!! This routine is only visible in the old interface - or in a new ST interface.
|
||||
// !!!! In the old interface we restrict thread attach so that calls from threads
|
||||
// !!!! other than the initializing thread are not allowed if preemptive callback
|
||||
// !!!! is disabled. This prevents the preemptive callback lock from being released
|
||||
// !!!! by other threads than the one that locked it.
|
||||
//
|
||||
int ca_client_context::pendIO ( const double & timeout )
|
||||
{
|
||||
// prevent recursion nightmares by disabling calls to
|
||||
// pendIO () from within a CA callback.
|
||||
// prevent recursion nightmares by disabling calls to
|
||||
// pendIO () from within a CA callback.
|
||||
if ( epicsThreadPrivateGet ( caClientCallbackThreadId ) ) {
|
||||
return ECA_EVDISALLOW;
|
||||
}
|
||||
@@ -487,7 +487,7 @@ int ca_client_context::pendIO ( const double & timeout )
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
|
||||
this->flush ( guard );
|
||||
|
||||
|
||||
while ( this->pndRecvCnt > 0 ) {
|
||||
if ( remaining < CAC_SIGNIFICANT_DELAY ) {
|
||||
status = ECA_TIMEOUT;
|
||||
@@ -514,16 +514,16 @@ int ca_client_context::pendIO ( const double & timeout )
|
||||
return status;
|
||||
}
|
||||
|
||||
// !!!! This routine is only visible in the old interface - or in a new ST interface.
|
||||
// !!!! In the old interface we restrict thread attach so that calls from threads
|
||||
// !!!! other than the initializing thread are not allowed if preemptive callback
|
||||
// !!!! This routine is only visible in the old interface - or in a new ST interface.
|
||||
// !!!! In the old interface we restrict thread attach so that calls from threads
|
||||
// !!!! other than the initializing thread are not allowed if preemptive callback
|
||||
// !!!! is disabled. This prevents the preemptive callback lock from being released
|
||||
// !!!! by other threads than the one that locked it.
|
||||
//
|
||||
int ca_client_context::pendEvent ( const double & timeout )
|
||||
{
|
||||
// prevent recursion nightmares by disabling calls to
|
||||
// pendIO () from within a CA callback.
|
||||
// prevent recursion nightmares by disabling calls to
|
||||
// pendIO () from within a CA callback.
|
||||
if ( epicsThreadPrivateGet ( caClientCallbackThreadId ) ) {
|
||||
return ECA_EVDISALLOW;
|
||||
}
|
||||
@@ -541,17 +541,17 @@ int ca_client_context::pendEvent ( const double & timeout )
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
|
||||
//
|
||||
// This is needed because in non-preemptive callback mode
|
||||
// legacy applications that use file descriptor managers
|
||||
// This is needed because in non-preemptive callback mode
|
||||
// legacy applications that use file descriptor managers
|
||||
// will register for ca receive thread activity and keep
|
||||
// calling ca_pend_event until all of the socket data has
|
||||
// been read. We must guarantee that other threads get a
|
||||
// been read. We must guarantee that other threads get a
|
||||
// chance to run if there is data in any of the sockets.
|
||||
//
|
||||
if ( this->fdRegFunc ) {
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
|
||||
// remove short udp message sent to wake
|
||||
// remove short udp message sent to wake
|
||||
// up a file descriptor manager
|
||||
osiSockAddr tmpAddr;
|
||||
osiSocklen_t addrSize = sizeof ( tmpAddr.sa );
|
||||
@@ -592,7 +592,7 @@ int ca_client_context::pendEvent ( const double & timeout )
|
||||
return ECA_TIMEOUT;
|
||||
}
|
||||
|
||||
void ca_client_context::blockForEventAndEnableCallbacks (
|
||||
void ca_client_context::blockForEventAndEnableCallbacks (
|
||||
epicsEvent & event, const double & timeout )
|
||||
{
|
||||
if ( this->pCallbackGuard.get() ) {
|
||||
@@ -659,12 +659,12 @@ void ca_client_context::callbackProcessingCompleteNotify ()
|
||||
}
|
||||
}
|
||||
|
||||
cacChannel & ca_client_context::createChannel (
|
||||
epicsGuard < epicsMutex > & guard, const char * pChannelName,
|
||||
cacChannel & ca_client_context::createChannel (
|
||||
epicsGuard < epicsMutex > & guard, const char * pChannelName,
|
||||
cacChannelNotify & chan, cacChannel::priLev pri )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
return this->pServiceContext->createChannel (
|
||||
return this->pServiceContext->createChannel (
|
||||
guard, pChannelName, chan, pri );
|
||||
}
|
||||
|
||||
@@ -685,21 +685,21 @@ unsigned ca_client_context::beaconAnomaliesSinceProgramStart () const
|
||||
return this->pServiceContext->beaconAnomaliesSinceProgramStart ( guard );
|
||||
}
|
||||
|
||||
void ca_client_context::installCASG (
|
||||
void ca_client_context::installCASG (
|
||||
epicsGuard < epicsMutex > & guard, CASG & sg )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
this->sgTable.idAssignAdd ( sg );
|
||||
}
|
||||
|
||||
void ca_client_context::uninstallCASG (
|
||||
void ca_client_context::uninstallCASG (
|
||||
epicsGuard < epicsMutex > & guard, CASG & sg )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
this->sgTable.remove ( sg );
|
||||
}
|
||||
|
||||
CASG * ca_client_context::lookupCASG (
|
||||
CASG * ca_client_context::lookupCASG (
|
||||
epicsGuard < epicsMutex > & guard, unsigned idIn )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -724,7 +724,7 @@ epicsMutex & ca_client_context::mutexRef () const
|
||||
return this->mutex;
|
||||
}
|
||||
|
||||
cacContext & ca_client_context::createNetworkContext (
|
||||
cacContext & ca_client_context::createNetworkContext (
|
||||
epicsMutex & mutexIn, epicsMutex & cbMutexIn )
|
||||
{
|
||||
return * new cac ( mutexIn, cbMutexIn, *this );
|
||||
@@ -751,34 +751,54 @@ epicsShareFunc int epicsShareAPI ca_clear_subscription ( evid pMon )
|
||||
{
|
||||
oldChannelNotify & chan = pMon->channel ();
|
||||
ca_client_context & cac = chan.getClientCtx ();
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
try {
|
||||
// if this stalls out on a live circuit then an exception
|
||||
// can be forthcoming which we must ignore as the clear
|
||||
// request must always be successful
|
||||
chan.eliminateExcessiveSendBacklog ( guard );
|
||||
// !!!! the order in which we take the mutex here prevents deadlocks
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
try {
|
||||
// if this stalls out on a live circuit then an exception
|
||||
// can be forthcoming which we must ignore as the clear
|
||||
// request must always be successful
|
||||
chan.eliminateExcessiveSendBacklog ( guard );
|
||||
}
|
||||
catch ( cacChannel::notConnected & ) {
|
||||
// intentionally ignored
|
||||
}
|
||||
}
|
||||
catch ( cacChannel::notConnected & ) {
|
||||
// intentionally ignored
|
||||
if ( cac.pCallbackGuard.get() &&
|
||||
cac.createdByThread == epicsThreadGetIdSelf () ) {
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
pMon->cancel ( *cac.pCallbackGuard.get(), guard );
|
||||
}
|
||||
else {
|
||||
//
|
||||
// we will definately stall out here if all of the
|
||||
// following are true
|
||||
//
|
||||
// o user creates non-preemtive mode client library context
|
||||
// o user doesnt periodically call a ca function
|
||||
// o user calls this function from an auxiillary thread
|
||||
//
|
||||
CallbackGuard cbGuard ( cac.cbMutex );
|
||||
epicsGuard < epicsMutex > guard ( cac.mutex );
|
||||
pMon->cancel ( cbGuard, guard );
|
||||
}
|
||||
pMon->cancel ( guard );
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
void ca_client_context :: eliminateExcessiveSendBacklog (
|
||||
void ca_client_context :: eliminateExcessiveSendBacklog (
|
||||
epicsGuard < epicsMutex > & guard, cacChannel & chan )
|
||||
{
|
||||
if ( chan.requestMessageBytesPending ( guard ) >
|
||||
if ( chan.requestMessageBytesPending ( guard ) >
|
||||
ca_client_context :: flushBlockThreshold ) {
|
||||
if ( this->pCallbackGuard.get() &&
|
||||
if ( this->pCallbackGuard.get() &&
|
||||
this->createdByThread == epicsThreadGetIdSelf () ) {
|
||||
// we need to be very careful about lock hierarchy
|
||||
// we need to be very careful about lock hierarchy
|
||||
// inversion in this situation
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
{
|
||||
epicsGuardRelease < epicsMutex > cbunguard (
|
||||
* this->pCallbackGuard.get() );
|
||||
{
|
||||
{
|
||||
epicsGuard < epicsMutex > nestedGuard ( this->mutex );
|
||||
chan.flush ( nestedGuard );
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <string> // vxWorks 6.0 requires this include
|
||||
#include <string> // vxWorks 6.0 requires this include
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsGuard.h"
|
||||
@@ -50,12 +50,12 @@
|
||||
#include "autoPtrFreeList.h"
|
||||
#include "noopiiu.h"
|
||||
|
||||
static const char pVersionCAC[] =
|
||||
"@(#) " EPICS_VERSION_STRING
|
||||
static const char pVersionCAC[] =
|
||||
"@(#) " EPICS_VERSION_STRING
|
||||
", CA Client Library " __DATE__;
|
||||
|
||||
// TCP response dispatch table
|
||||
const cac::pProtoStubTCP cac::tcpJumpTableCAC [] =
|
||||
const cac::pProtoStubTCP cac::tcpJumpTableCAC [] =
|
||||
{
|
||||
&cac::versionAction,
|
||||
&cac::eventRespAction,
|
||||
@@ -68,7 +68,7 @@ const cac::pProtoStubTCP cac::tcpJumpTableCAC [] =
|
||||
&cac::badTCPRespAction,
|
||||
&cac::badTCPRespAction,
|
||||
// legacy CA_PROTO_READ_SYNC used as an echo with legacy server
|
||||
&cac::echoRespAction,
|
||||
&cac::echoRespAction,
|
||||
&cac::exceptionRespAction,
|
||||
&cac::clearChannelRespAction,
|
||||
&cac::badTCPRespAction,
|
||||
@@ -89,7 +89,7 @@ const cac::pProtoStubTCP cac::tcpJumpTableCAC [] =
|
||||
};
|
||||
|
||||
// TCP exception dispatch table
|
||||
const cac::pExcepProtoStubTCP cac::tcpExcepJumpTableCAC [] =
|
||||
const cac::pExcepProtoStubTCP cac::tcpExcepJumpTableCAC [] =
|
||||
{
|
||||
&cac::defaultExcep, // CA_PROTO_VERSION
|
||||
&cac::eventAddExcep, // CA_PROTO_EVENT_ADD
|
||||
@@ -109,7 +109,7 @@ const cac::pExcepProtoStubTCP cac::tcpExcepJumpTableCAC [] =
|
||||
&cac::readNotifyExcep, // CA_PROTO_READ_NOTIFY
|
||||
&cac::defaultExcep, // CA_PROTO_READ_BUILD
|
||||
&cac::defaultExcep, // REPEATER_CONFIRM
|
||||
&cac::defaultExcep, // CA_PROTO_CREATE_CHAN
|
||||
&cac::defaultExcep, // CA_PROTO_CREATE_CHAN
|
||||
&cac::writeNotifyExcep, // CA_PROTO_WRITE_NOTIFY
|
||||
&cac::defaultExcep, // CA_PROTO_CLIENT_NAME
|
||||
&cac::defaultExcep, // CA_PROTO_HOST_NAME
|
||||
@@ -124,9 +124,9 @@ const cac::pExcepProtoStubTCP cac::tcpExcepJumpTableCAC [] =
|
||||
//
|
||||
// cac::cac ()
|
||||
//
|
||||
cac::cac (
|
||||
epicsMutex & mutualExclusionIn,
|
||||
epicsMutex & callbackControlIn,
|
||||
cac::cac (
|
||||
epicsMutex & mutualExclusionIn,
|
||||
epicsMutex & callbackControlIn,
|
||||
cacContextNotify & notifyIn ) :
|
||||
_refLocalHostName ( localHostNameCache.getReference () ),
|
||||
programBeginTime ( epicsTime::getCurrent() ),
|
||||
@@ -134,7 +134,7 @@ cac::cac (
|
||||
mutex ( mutualExclusionIn ),
|
||||
cbMutex ( callbackControlIn ),
|
||||
ipToAEngine ( ipAddrToAsciiEngine::allocate () ),
|
||||
timerQueue ( epicsTimerQueueActive::allocate ( false,
|
||||
timerQueue ( epicsTimerQueueActive::allocate ( false,
|
||||
lowestPriorityLevelAbove(epicsThreadGetPrioritySelf()) ) ),
|
||||
pUserName ( 0 ),
|
||||
pudpiiu ( 0 ),
|
||||
@@ -157,8 +157,8 @@ cac::cac (
|
||||
long status;
|
||||
|
||||
/*
|
||||
* Certain os, such as HPUX, do not unblock a socket system call
|
||||
* when another thread asynchronously calls both shutdown() and
|
||||
* Certain os, such as HPUX, do not unblock a socket system call
|
||||
* when another thread asynchronously calls both shutdown() and
|
||||
* close(). To solve this problem we need to employ OS specific
|
||||
* mechanisms.
|
||||
*/
|
||||
@@ -179,7 +179,7 @@ cac::cac (
|
||||
strncpy ( this->pUserName, tmp, len );
|
||||
}
|
||||
|
||||
this->_serverPort =
|
||||
this->_serverPort =
|
||||
envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT,
|
||||
static_cast <unsigned short> (CA_SERVER_PORT) );
|
||||
|
||||
@@ -224,7 +224,7 @@ cac::cac (
|
||||
}
|
||||
unsigned bufsPerArray = this->maxRecvBytesTCP / comBuf::capacityBytes ();
|
||||
if ( bufsPerArray > 1u ) {
|
||||
maxContigFrames = bufsPerArray *
|
||||
maxContigFrames = bufsPerArray *
|
||||
contiguousMsgCountWhichTriggersFlowControl;
|
||||
}
|
||||
}
|
||||
@@ -275,8 +275,8 @@ cac::~cac ()
|
||||
// this blocks until the UDP thread exits so that
|
||||
// it will not sneak in any new clients
|
||||
//
|
||||
// lock intentionally not held here so that we dont deadlock
|
||||
// waiting for the UDP thread to exit while it is waiting to
|
||||
// lock intentionally not held here so that we dont deadlock
|
||||
// waiting for the UDP thread to exit while it is waiting to
|
||||
// get the lock.
|
||||
{
|
||||
epicsGuard < epicsMutex > cbGuard ( this->cbMutex );
|
||||
@@ -298,11 +298,11 @@ cac::~cac ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// wait for all tcp threads to exit
|
||||
//
|
||||
// this will block for oustanding sends to go out so dont
|
||||
// this will block for oustanding sends to go out so dont
|
||||
// hold a lock while waiting
|
||||
//
|
||||
{
|
||||
@@ -323,7 +323,7 @@ cac::~cac ()
|
||||
delete [] this->pUserName;
|
||||
|
||||
tsSLList < bhe > tmpBeaconList;
|
||||
this->beaconTable.removeAll ( tmpBeaconList );
|
||||
this->beaconTable.removeAll ( tmpBeaconList );
|
||||
while ( bhe * pBHE = tmpBeaconList.get() ) {
|
||||
pBHE->~bhe ();
|
||||
this->bheFreeList.release ( pBHE );
|
||||
@@ -338,7 +338,7 @@ cac::~cac ()
|
||||
osiSockRelease ();
|
||||
|
||||
// its ok for channels and subscriptions to still
|
||||
// exist at this point. The user created them and
|
||||
// exist at this point. The user created them and
|
||||
// its his responsibility to clean them up.
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ unsigned cac::lowestPriorityLevelAbove ( unsigned priority )
|
||||
{
|
||||
unsigned abovePriority;
|
||||
epicsThreadBooleanStatus tbs;
|
||||
tbs = epicsThreadLowestPriorityLevelAbove (
|
||||
tbs = epicsThreadLowestPriorityLevelAbove (
|
||||
priority, & abovePriority );
|
||||
if ( tbs != epicsThreadBooleanStatusSuccess ) {
|
||||
abovePriority = priority;
|
||||
@@ -358,7 +358,7 @@ unsigned cac::highestPriorityLevelBelow ( unsigned priority )
|
||||
{
|
||||
unsigned belowPriority;
|
||||
epicsThreadBooleanStatus tbs;
|
||||
tbs = epicsThreadHighestPriorityLevelBelow (
|
||||
tbs = epicsThreadHighestPriorityLevelBelow (
|
||||
priority, & belowPriority );
|
||||
if ( tbs != epicsThreadBooleanStatusSuccess ) {
|
||||
belowPriority = priority;
|
||||
@@ -379,21 +379,21 @@ void cac::flush ( epicsGuard < epicsMutex > & guard )
|
||||
}
|
||||
}
|
||||
|
||||
unsigned cac::circuitCount (
|
||||
unsigned cac::circuitCount (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
return this->circuitList.count ();
|
||||
}
|
||||
|
||||
void cac::show (
|
||||
void cac::show (
|
||||
epicsGuard < epicsMutex > & guard, unsigned level ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
|
||||
::printf ( "Channel Access Client Context at %p for user %s\n",
|
||||
::printf ( "Channel Access Client Context at %p for user %s\n",
|
||||
static_cast <const void *> ( this ), this->pUserName );
|
||||
// this also supresses the "defined, but not used"
|
||||
// this also supresses the "defined, but not used"
|
||||
// warning message
|
||||
::printf ( "\trevision \"%s\"\n", pVersionCAC );
|
||||
|
||||
@@ -451,7 +451,7 @@ void cac::beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime,
|
||||
/*
|
||||
* return if the beacon period has not changed significantly
|
||||
*/
|
||||
if ( ! pBHE->updatePeriod ( guard, this->programBeginTime,
|
||||
if ( ! pBHE->updatePeriod ( guard, this->programBeginTime,
|
||||
currentTime, beaconNumber, protocolRevision ) ) {
|
||||
return;
|
||||
}
|
||||
@@ -488,8 +488,8 @@ void cac::beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime,
|
||||
# endif
|
||||
}
|
||||
|
||||
cacChannel & cac::createChannel (
|
||||
epicsGuard < epicsMutex > & guard, const char * pName,
|
||||
cacChannel & cac::createChannel (
|
||||
epicsGuard < epicsMutex > & guard, const char * pName,
|
||||
cacChannelNotify & chan, cacChannel::priLev pri )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -503,19 +503,19 @@ cacChannel & cac::createChannel (
|
||||
}
|
||||
|
||||
if ( ! this->pudpiiu ) {
|
||||
this->pudpiiu = new udpiiu (
|
||||
guard, this->timerQueue, this->cbMutex,
|
||||
this->pudpiiu = new udpiiu (
|
||||
guard, this->timerQueue, this->cbMutex,
|
||||
this->mutex, this->notify, *this, this->_serverPort,
|
||||
this->searchDestList );
|
||||
}
|
||||
|
||||
nciu * pNetChan = new ( this->channelFreeList )
|
||||
nciu * pNetChan = new ( this->channelFreeList )
|
||||
nciu ( *this, noopIIU, chan, pName, pri );
|
||||
this->chanTable.idAssignAdd ( *pNetChan );
|
||||
return *pNetChan;
|
||||
}
|
||||
|
||||
bool cac::findOrCreateVirtCircuit (
|
||||
bool cac::findOrCreateVirtCircuit (
|
||||
epicsGuard < epicsMutex > & guard, const osiSockAddr & addr,
|
||||
unsigned priority, tcpiiu *& piiu, unsigned minorVersionNumber,
|
||||
SearchDestTCP * pSearchDest )
|
||||
@@ -532,14 +532,14 @@ bool cac::findOrCreateVirtCircuit (
|
||||
try {
|
||||
autoPtrFreeList < tcpiiu, 32, epicsMutexNOOP > pnewiiu (
|
||||
this->freeListVirtualCircuit,
|
||||
new ( this->freeListVirtualCircuit ) tcpiiu (
|
||||
*this, this->mutex, this->cbMutex, this->notify, this->connTMO,
|
||||
this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber,
|
||||
new ( this->freeListVirtualCircuit ) tcpiiu (
|
||||
*this, this->mutex, this->cbMutex, this->notify, this->connTMO,
|
||||
this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber,
|
||||
this->ipToAEngine, priority, pSearchDest ) );
|
||||
|
||||
bhe * pBHE = this->beaconTable.lookup ( addr.ia );
|
||||
if ( ! pBHE ) {
|
||||
pBHE = new ( this->bheFreeList )
|
||||
pBHE = new ( this->bheFreeList )
|
||||
bhe ( this->mutex, epicsTime (), 0u, addr.ia );
|
||||
if ( this->beaconTable.add ( *pBHE ) < 0 ) {
|
||||
return newIIU;
|
||||
@@ -553,13 +553,13 @@ bool cac::findOrCreateVirtCircuit (
|
||||
newIIU = true;
|
||||
}
|
||||
catch ( std :: exception & except ) {
|
||||
errlogPrintf (
|
||||
errlogPrintf (
|
||||
"CAC: exception during virtual circuit creation \"%s\"\n",
|
||||
except.what () );
|
||||
return newIIU;
|
||||
}
|
||||
catch ( ... ) {
|
||||
errlogPrintf (
|
||||
errlogPrintf (
|
||||
"CAC: Nonstandard exception during virtual circuit creation\n" );
|
||||
return newIIU;
|
||||
}
|
||||
@@ -567,9 +567,9 @@ bool cac::findOrCreateVirtCircuit (
|
||||
return newIIU;
|
||||
}
|
||||
|
||||
void cac::transferChanToVirtCircuit (
|
||||
void cac::transferChanToVirtCircuit (
|
||||
unsigned cid, unsigned sid,
|
||||
ca_uint16_t typeCode, arrayElementCount count,
|
||||
ca_uint16_t typeCode, arrayElementCount count,
|
||||
unsigned minorVersionNumber, const osiSockAddr & addr,
|
||||
const epicsTime & currentTime )
|
||||
{
|
||||
@@ -604,12 +604,12 @@ void cac::transferChanToVirtCircuit (
|
||||
char acc[64];
|
||||
pChan->getPIIU(guard)->getHostName ( guard, acc, sizeof ( acc ) );
|
||||
msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList )
|
||||
msgForMultiplyDefinedPV ( this->ipToAEngine,
|
||||
msgForMultiplyDefinedPV ( this->ipToAEngine,
|
||||
*this, pChan->pName ( guard ), acc );
|
||||
// It is possible for the ioInitiate call below to
|
||||
// call the callback directly if queue quota is exceeded.
|
||||
// This callback takes the callback lock and therefore we
|
||||
// must release the primary mutex here to avoid a lock
|
||||
// must release the primary mutex here to avoid a lock
|
||||
// hierarchy inversion.
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
pMsg->ioInitiate ( addr );
|
||||
@@ -625,9 +625,9 @@ void cac::transferChanToVirtCircuit (
|
||||
pChan->getPriority(guard), piiu, minorVersionNumber );
|
||||
|
||||
// must occur before moving to new iiu
|
||||
pChan->getPIIU(guard)->uninstallChanDueToSuccessfulSearchResponse (
|
||||
pChan->getPIIU(guard)->uninstallChanDueToSuccessfulSearchResponse (
|
||||
guard, *pChan, currentTime );
|
||||
piiu->installChannel (
|
||||
piiu->installChannel (
|
||||
guard, *pChan, sid, typeCode, count );
|
||||
|
||||
if ( newIIU ) {
|
||||
@@ -635,14 +635,14 @@ void cac::transferChanToVirtCircuit (
|
||||
}
|
||||
}
|
||||
|
||||
void cac::destroyChannel (
|
||||
void cac::destroyChannel (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
nciu & chan )
|
||||
nciu & chan )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
|
||||
// uninstall channel so that recv threads
|
||||
// will not start a new callback for this channel's IO.
|
||||
// will not start a new callback for this channel's IO.
|
||||
if ( this->chanTable.remove ( chan ) != & chan ) {
|
||||
throw std::logic_error ( "Invalid channel identifier" );
|
||||
}
|
||||
@@ -650,9 +650,9 @@ void cac::destroyChannel (
|
||||
this->channelFreeList.release ( & chan );
|
||||
}
|
||||
|
||||
void cac::disconnectAllIO (
|
||||
void cac::disconnectAllIO (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
nciu & chan, tsDLList < baseNMIU > & ioList )
|
||||
{
|
||||
cbGuard.assertIdenticalMutex ( this->cbMutex );
|
||||
@@ -672,8 +672,8 @@ void cac::disconnectAllIO (
|
||||
}
|
||||
}
|
||||
|
||||
int cac :: printFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
int cac :: printFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
const char * pformat, ... ) const
|
||||
{
|
||||
va_list theArgs;
|
||||
@@ -683,26 +683,26 @@ int cac :: printFormated (
|
||||
return status;
|
||||
}
|
||||
|
||||
netWriteNotifyIO & cac::writeNotifyRequest (
|
||||
netWriteNotifyIO & cac::writeNotifyRequest (
|
||||
epicsGuard < epicsMutex > & guard, nciu & chan, privateInterfaceForIO & icni,
|
||||
unsigned type, arrayElementCount nElem, const void * pValue, cacWriteNotify & notifyIn )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
autoPtrRecycle < netWriteNotifyIO > pIO (
|
||||
guard, this->ioTable, *this,
|
||||
autoPtrRecycle < netWriteNotifyIO > pIO (
|
||||
guard, this->ioTable, *this,
|
||||
netWriteNotifyIO::factory ( this->freeListWriteNotifyIO, icni, notifyIn ) );
|
||||
this->ioTable.idAssignAdd ( *pIO );
|
||||
chan.getPIIU(guard)->writeNotifyRequest (
|
||||
chan.getPIIU(guard)->writeNotifyRequest (
|
||||
guard, chan, *pIO, type, nElem, pValue );
|
||||
return *pIO.release();
|
||||
}
|
||||
|
||||
netReadNotifyIO & cac::readNotifyRequest (
|
||||
netReadNotifyIO & cac::readNotifyRequest (
|
||||
epicsGuard < epicsMutex > & guard, nciu & chan, privateInterfaceForIO & icni,
|
||||
unsigned type, arrayElementCount nElem, cacReadNotify & notifyIn )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
autoPtrRecycle < netReadNotifyIO > pIO (
|
||||
autoPtrRecycle < netReadNotifyIO > pIO (
|
||||
guard, this->ioTable, *this,
|
||||
netReadNotifyIO::factory ( this->freeListReadNotifyIO, icni, notifyIn ) );
|
||||
this->ioTable.idAssignAdd ( *pIO );
|
||||
@@ -711,7 +711,8 @@ netReadNotifyIO & cac::readNotifyRequest (
|
||||
}
|
||||
|
||||
bool cac::destroyIO (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const cacChannel::ioid & idIn, nciu & chan )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -720,18 +721,18 @@ bool cac::destroyIO (
|
||||
if ( pIO ) {
|
||||
class netSubscription * pSubscr = pIO->isSubscription ();
|
||||
if ( pSubscr ) {
|
||||
pSubscr->unsubscribeIfRequired ( guard, chan );
|
||||
pSubscr->unsubscribeIfRequired ( guard, chan );
|
||||
}
|
||||
|
||||
// this uninstalls from the list and destroys the IO
|
||||
pIO->exception ( guard, *this,
|
||||
ECA_CHANDESTROY, chan.pName ( guard ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cac::ioShow (
|
||||
void cac::ioShow (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const cacChannel::ioid & idIn, unsigned level ) const
|
||||
{
|
||||
@@ -741,8 +742,8 @@ void cac::ioShow (
|
||||
}
|
||||
}
|
||||
|
||||
void cac::ioExceptionNotify (
|
||||
unsigned idIn, int status, const char * pContext,
|
||||
void cac::ioExceptionNotify (
|
||||
unsigned idIn, int status, const char * pContext,
|
||||
unsigned type, arrayElementCount count )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -752,8 +753,8 @@ void cac::ioExceptionNotify (
|
||||
}
|
||||
}
|
||||
|
||||
void cac::ioExceptionNotifyAndUninstall (
|
||||
unsigned idIn, int status, const char * pContext,
|
||||
void cac::ioExceptionNotifyAndUninstall (
|
||||
unsigned idIn, int status, const char * pContext,
|
||||
unsigned type, arrayElementCount count )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -763,38 +764,38 @@ void cac::ioExceptionNotifyAndUninstall (
|
||||
}
|
||||
}
|
||||
|
||||
void cac::recycleReadNotifyIO (
|
||||
void cac::recycleReadNotifyIO (
|
||||
epicsGuard < epicsMutex > & guard, netReadNotifyIO & io )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
this->freeListReadNotifyIO.release ( & io );
|
||||
}
|
||||
|
||||
void cac::recycleWriteNotifyIO (
|
||||
void cac::recycleWriteNotifyIO (
|
||||
epicsGuard < epicsMutex > & guard, netWriteNotifyIO & io )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
this->freeListWriteNotifyIO.release ( & io );
|
||||
}
|
||||
|
||||
void cac::recycleSubscription (
|
||||
void cac::recycleSubscription (
|
||||
epicsGuard < epicsMutex > & guard, netSubscription & io )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
this->freeListSubscription.release ( & io );
|
||||
}
|
||||
|
||||
netSubscription & cac::subscriptionRequest (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
netSubscription & cac::subscriptionRequest (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
nciu & chan, privateInterfaceForIO & privChan,
|
||||
unsigned type,
|
||||
arrayElementCount nElem, unsigned mask,
|
||||
arrayElementCount nElem, unsigned mask,
|
||||
cacStateNotify & notifyIn,
|
||||
bool chanIsInstalled )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
autoPtrRecycle < netSubscription > pIO (
|
||||
guard, this->ioTable, *this,
|
||||
autoPtrRecycle < netSubscription > pIO (
|
||||
guard, this->ioTable, *this,
|
||||
netSubscription::factory ( this->freeListSubscription,
|
||||
privChan, type, nElem, mask, notifyIn ) );
|
||||
this->ioTable.idAssignAdd ( *pIO );
|
||||
@@ -804,23 +805,23 @@ netSubscription & cac::subscriptionRequest (
|
||||
return *pIO.release ();
|
||||
}
|
||||
|
||||
bool cac::versionAction ( callbackManager &, tcpiiu & iiu,
|
||||
bool cac::versionAction ( callbackManager &, tcpiiu & iiu,
|
||||
const epicsTime &, const caHdrLargeArray & msg, void * )
|
||||
{
|
||||
iiu.versionRespNotify ( msg );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::echoRespAction (
|
||||
callbackManager & mgr, tcpiiu & iiu,
|
||||
|
||||
bool cac::echoRespAction (
|
||||
callbackManager & mgr, tcpiiu & iiu,
|
||||
const epicsTime & /* current */, const caHdrLargeArray &, void * )
|
||||
{
|
||||
iiu.probeResponseNotify ( mgr.cbGuard );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::writeNotifyRespAction (
|
||||
callbackManager &, tcpiiu &,
|
||||
bool cac::writeNotifyRespAction (
|
||||
callbackManager &, tcpiiu &,
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -837,7 +838,7 @@ bool cac::writeNotifyRespAction (
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -856,13 +857,13 @@ bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
|
||||
baseNMIU * pmiu = this->ioTable.remove ( hdr.m_available );
|
||||
//
|
||||
// The IO destroy routines take the call back mutex
|
||||
// when uninstalling and deleting the baseNMIU so there is
|
||||
// The IO destroy routines take the call back mutex
|
||||
// when uninstalling and deleting the baseNMIU so there is
|
||||
// no need to worry here about the baseNMIU being deleted while
|
||||
// it is in use here.
|
||||
//
|
||||
if ( pmiu ) {
|
||||
// if its a circuit-becomes-responsive subscription update
|
||||
// if its a circuit-becomes-responsive subscription update
|
||||
// then we need to reinstall the IO into the table
|
||||
netSubscription * pSubscr = pmiu->isSubscription ();
|
||||
if ( pSubscr ) {
|
||||
@@ -874,7 +875,7 @@ bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
* convert the data buffer from net
|
||||
* format to host format
|
||||
*/
|
||||
caStatus = caNetConvert (
|
||||
caStatus = caNetConvert (
|
||||
hdr.m_dataType, pMsgBdy, pMsgBdy, false, hdr.m_count );
|
||||
}
|
||||
if ( caStatus == ECA_NORMAL ) {
|
||||
@@ -882,7 +883,7 @@ bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
hdr.m_dataType, hdr.m_count, pMsgBdy );
|
||||
}
|
||||
else {
|
||||
pmiu->exception ( guard, *this,
|
||||
pmiu->exception ( guard, *this,
|
||||
caStatus, "read failed",
|
||||
hdr.m_dataType, hdr.m_count );
|
||||
}
|
||||
@@ -890,8 +891,8 @@ bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::searchRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
const epicsTime & currentTime, const caHdrLargeArray & msg,
|
||||
bool cac::searchRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
const epicsTime & currentTime, const caHdrLargeArray & msg,
|
||||
void * /* pMsgBdy */ )
|
||||
{
|
||||
assert ( this->pudpiiu );
|
||||
@@ -899,13 +900,13 @@ bool cac::searchRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu,
|
||||
bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu,
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy )
|
||||
{
|
||||
{
|
||||
int caStatus;
|
||||
|
||||
/*
|
||||
* m_postsize = 0 used to be a subscription cancel confirmation,
|
||||
* m_postsize = 0 used to be a subscription cancel confirmation,
|
||||
* but is now a noop because the IO block is immediately deleted
|
||||
*/
|
||||
if ( ! hdr.m_postsize ) {
|
||||
@@ -926,8 +927,8 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu,
|
||||
}
|
||||
|
||||
//
|
||||
// The IO destroy routines take the call back mutex
|
||||
// when uninstalling and deleting the baseNMIU so there is
|
||||
// The IO destroy routines take the call back mutex
|
||||
// when uninstalling and deleting the baseNMIU so there is
|
||||
// no need to worry here about the baseNMIU being deleted while
|
||||
// it is in use here.
|
||||
//
|
||||
@@ -937,7 +938,7 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu,
|
||||
* convert the data buffer from net format to host format
|
||||
*/
|
||||
if ( caStatus == ECA_NORMAL ) {
|
||||
caStatus = caNetConvert (
|
||||
caStatus = caNetConvert (
|
||||
hdr.m_dataType, pMsgBdy, pMsgBdy, false, hdr.m_count );
|
||||
}
|
||||
if ( caStatus == ECA_NORMAL ) {
|
||||
@@ -945,7 +946,7 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu,
|
||||
hdr.m_dataType, hdr.m_count, pMsgBdy );
|
||||
}
|
||||
else {
|
||||
pmiu->exception ( guard, *this, caStatus,
|
||||
pmiu->exception ( guard, *this, caStatus,
|
||||
"subscription update read failed",
|
||||
hdr.m_dataType, hdr.m_count );
|
||||
}
|
||||
@@ -953,14 +954,14 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::readRespAction ( callbackManager &, tcpiiu &,
|
||||
bool cac::readRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
baseNMIU * pmiu = this->ioTable.remove ( hdr.m_available );
|
||||
//
|
||||
// The IO destroy routines take the call back mutex
|
||||
// when uninstalling and deleting the baseNMIU so there is
|
||||
// The IO destroy routines take the call back mutex
|
||||
// when uninstalling and deleting the baseNMIU so there is
|
||||
// no need to worry here about the baseNMIU being deleted while
|
||||
// it is in use here.
|
||||
//
|
||||
@@ -971,14 +972,14 @@ bool cac::readRespAction ( callbackManager &, tcpiiu &,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::clearChannelRespAction ( callbackManager &, tcpiiu &,
|
||||
bool cac::clearChannelRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime &, const caHdrLargeArray &, void * /* pMsgBody */ )
|
||||
{
|
||||
return true; // currently a noop
|
||||
}
|
||||
|
||||
bool cac::defaultExcep (
|
||||
callbackManager &, tcpiiu & iiu,
|
||||
bool cac::defaultExcep (
|
||||
callbackManager &, tcpiiu & iiu,
|
||||
const caHdrLargeArray &, const char * pCtx, unsigned status )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
@@ -990,69 +991,69 @@ bool cac::defaultExcep (
|
||||
return true;
|
||||
}
|
||||
|
||||
void cac::exception (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard, int status,
|
||||
void cac::exception (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard, int status,
|
||||
const char * pContext, const char * pFileName, unsigned lineNo )
|
||||
{
|
||||
cbGuard.assertIdenticalMutex ( this->cbMutex );
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
this->notify.exception ( guard, status, pContext,
|
||||
this->notify.exception ( guard, status, pContext,
|
||||
pFileName, lineNo );
|
||||
}
|
||||
|
||||
bool cac::eventAddExcep (
|
||||
callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray &hdr,
|
||||
bool cac::eventAddExcep (
|
||||
callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status )
|
||||
{
|
||||
this->ioExceptionNotify ( hdr.m_available, status, pCtx,
|
||||
this->ioExceptionNotify ( hdr.m_available, status, pCtx,
|
||||
hdr.m_dataType, hdr.m_count );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::readExcep ( callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray & hdr,
|
||||
bool cac::readExcep ( callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray & hdr,
|
||||
const char * pCtx, unsigned status )
|
||||
{
|
||||
this->ioExceptionNotifyAndUninstall ( hdr.m_available,
|
||||
this->ioExceptionNotifyAndUninstall ( hdr.m_available,
|
||||
status, pCtx, hdr.m_dataType, hdr.m_count );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::writeExcep (
|
||||
bool cac::writeExcep (
|
||||
callbackManager & mgr,
|
||||
tcpiiu &, const caHdrLargeArray & hdr,
|
||||
tcpiiu &, const caHdrLargeArray & hdr,
|
||||
const char * pCtx, unsigned status )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
nciu * pChan = this->chanTable.lookup ( hdr.m_available );
|
||||
if ( pChan ) {
|
||||
pChan->writeException ( mgr.cbGuard, guard, status, pCtx,
|
||||
pChan->writeException ( mgr.cbGuard, guard, status, pCtx,
|
||||
hdr.m_dataType, hdr.m_count );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::readNotifyExcep ( callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray &hdr,
|
||||
bool cac::readNotifyExcep ( callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status )
|
||||
{
|
||||
this->ioExceptionNotifyAndUninstall ( hdr.m_available,
|
||||
this->ioExceptionNotifyAndUninstall ( hdr.m_available,
|
||||
status, pCtx, hdr.m_dataType, hdr.m_count );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::writeNotifyExcep ( callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray &hdr,
|
||||
bool cac::writeNotifyExcep ( callbackManager &, tcpiiu &,
|
||||
const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status )
|
||||
{
|
||||
this->ioExceptionNotifyAndUninstall ( hdr.m_available,
|
||||
this->ioExceptionNotifyAndUninstall ( hdr.m_available,
|
||||
status, pCtx, hdr.m_dataType, hdr.m_count );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu,
|
||||
bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu,
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy )
|
||||
{
|
||||
const caHdr * pReq = reinterpret_cast < const caHdr * > ( pMsgBdy );
|
||||
@@ -1069,7 +1070,7 @@ bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu,
|
||||
req.m_available = AlignedWireRef < const epicsUInt32 > ( pReq->m_available );
|
||||
const ca_uint32_t * pLW = reinterpret_cast < const ca_uint32_t * > ( pReq + 1 );
|
||||
if ( req.m_postsize == 0xffff ) {
|
||||
static const unsigned annexSize =
|
||||
static const unsigned annexSize =
|
||||
sizeof ( req.m_postsize ) + sizeof ( req.m_count );
|
||||
bytesSoFar += annexSize;
|
||||
if ( hdr.m_postsize < bytesSoFar ) {
|
||||
@@ -1100,9 +1101,9 @@ bool cac::accessRightsRespAction (
|
||||
nciu * pChan = this->chanTable.lookup ( hdr.m_cid );
|
||||
if ( pChan ) {
|
||||
unsigned ar = hdr.m_available;
|
||||
caAccessRights accessRights (
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_READ ) ? true : false,
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_WRITE ) ? true : false);
|
||||
caAccessRights accessRights (
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_READ ) ? true : false,
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_WRITE ) ? true : false);
|
||||
pChan->accessRightsStateChange ( accessRights, mgr.cbGuard, guard );
|
||||
}
|
||||
|
||||
@@ -1125,11 +1126,11 @@ bool cac::createChannelRespAction (
|
||||
}
|
||||
bool wasExpected = iiu.connectNotify ( guard, *pChan );
|
||||
if ( wasExpected ) {
|
||||
pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp,
|
||||
pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp,
|
||||
mgr.cbGuard, guard );
|
||||
}
|
||||
else {
|
||||
errlogPrintf (
|
||||
errlogPrintf (
|
||||
"CA Client Library: Ignored duplicate create channel "
|
||||
"response from CA server?\n" );
|
||||
}
|
||||
@@ -1140,10 +1141,10 @@ bool cac::createChannelRespAction (
|
||||
iiu.clearChannelRequest ( guard, hdr.m_available, hdr.m_cid );
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cac::verifyAndDisconnectChan (
|
||||
bool cac::verifyAndDisconnectChan (
|
||||
callbackManager & mgr, tcpiiu &,
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ )
|
||||
{
|
||||
@@ -1168,18 +1169,18 @@ void cac::disconnectChannel (
|
||||
chan.unresponsiveCircuitNotify ( cbGuard, guard );
|
||||
}
|
||||
|
||||
bool cac::badTCPRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
bool cac::badTCPRespAction ( callbackManager &, tcpiiu & iiu,
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
char hostName[64];
|
||||
iiu.getHostName ( guard, hostName, sizeof ( hostName ) );
|
||||
errlogPrintf ( "CAC: Undecipherable TCP message ( bad response type %u ) from %s\n",
|
||||
errlogPrintf ( "CAC: Undecipherable TCP message ( bad response type %u ) from %s\n",
|
||||
hdr.m_cmmd, hostName );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cac::executeResponse ( callbackManager & mgr, tcpiiu & iiu,
|
||||
bool cac::executeResponse ( callbackManager & mgr, tcpiiu & iiu,
|
||||
const epicsTime & currentTime, caHdrLargeArray & hdr, char * pMshBody )
|
||||
{
|
||||
// execute the response message
|
||||
@@ -1193,7 +1194,7 @@ bool cac::executeResponse ( callbackManager & mgr, tcpiiu & iiu,
|
||||
return ( this->*pStub ) ( mgr, iiu, currentTime, hdr, pMshBody );
|
||||
}
|
||||
|
||||
void cac::selfTest (
|
||||
void cac::selfTest (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -1221,7 +1222,7 @@ void cac::destroyIIU ( tcpiiu & iiu )
|
||||
pBHE->unregisterIIU ( guard, iiu );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
assert ( this->pudpiiu );
|
||||
iiu.disconnectAllChannels ( mgr.cbGuard, guard, *this->pudpiiu );
|
||||
|
||||
@@ -1233,7 +1234,7 @@ void cac::destroyIIU ( tcpiiu & iiu )
|
||||
// so we must not hold the primary mutex here
|
||||
//
|
||||
// this waits for send/recv threads to exit
|
||||
// this also uses the cac free lists so cac must wait
|
||||
// this also uses the cac free lists so cac must wait
|
||||
// for this to finish before it shuts down
|
||||
|
||||
iiu.~tcpiiu ();
|
||||
@@ -1248,8 +1249,8 @@ void cac::destroyIIU ( tcpiiu & iiu )
|
||||
// do not touch "this" after lock is released above
|
||||
}
|
||||
|
||||
double cac::beaconPeriod (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
double cac::beaconPeriod (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const nciu & chan ) const
|
||||
{
|
||||
const netiiu * pIIU = chan.getConstPIIU ( guard );
|
||||
@@ -1266,8 +1267,8 @@ double cac::beaconPeriod (
|
||||
return - DBL_MAX;
|
||||
}
|
||||
|
||||
void cac::initiateConnect (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
void cac::initiateConnect (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
nciu & chan, netiiu * & piiu )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -1285,7 +1286,7 @@ void cacComBufMemoryManager::release ( void * pCadaver )
|
||||
this->freeList.release ( pCadaver );
|
||||
}
|
||||
|
||||
void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv,
|
||||
void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv,
|
||||
const char * pChannelName, const char * pAcc, const char * pRej )
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -57,11 +57,11 @@ class netSubscription;
|
||||
// is applied
|
||||
class cacRecycle {
|
||||
public:
|
||||
virtual void recycleReadNotifyIO (
|
||||
virtual void recycleReadNotifyIO (
|
||||
epicsGuard < epicsMutex > &, netReadNotifyIO &io ) = 0;
|
||||
virtual void recycleWriteNotifyIO (
|
||||
virtual void recycleWriteNotifyIO (
|
||||
epicsGuard < epicsMutex > &, netWriteNotifyIO &io ) = 0;
|
||||
virtual void recycleSubscription (
|
||||
virtual void recycleSubscription (
|
||||
epicsGuard < epicsMutex > &, netSubscription &io ) = 0;
|
||||
protected:
|
||||
virtual ~cacRecycle() {}
|
||||
@@ -96,85 +96,81 @@ private:
|
||||
|
||||
class callbackManager : public notifyGuard {
|
||||
public:
|
||||
callbackManager (
|
||||
cacContextNotify &,
|
||||
callbackManager (
|
||||
cacContextNotify &,
|
||||
epicsMutex & callbackControl );
|
||||
epicsGuard < epicsMutex > cbGuard;
|
||||
};
|
||||
|
||||
class cac :
|
||||
class cac :
|
||||
public cacContext,
|
||||
private cacRecycle,
|
||||
private cacRecycle,
|
||||
private callbackForMultiplyDefinedPV
|
||||
{
|
||||
public:
|
||||
cac (
|
||||
epicsMutex & mutualExclusion,
|
||||
epicsMutex & callbackControl,
|
||||
cac (
|
||||
epicsMutex & mutualExclusion,
|
||||
epicsMutex & callbackControl,
|
||||
cacContextNotify & );
|
||||
virtual ~cac ();
|
||||
|
||||
// beacon management
|
||||
void beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime,
|
||||
void beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime,
|
||||
ca_uint32_t beaconNumber, unsigned protocolRevision );
|
||||
unsigned beaconAnomaliesSinceProgramStart (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
|
||||
// IO management
|
||||
void flush ( epicsGuard < epicsMutex > & guard );
|
||||
bool executeResponse ( callbackManager &, tcpiiu &,
|
||||
bool executeResponse ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, caHdrLargeArray &, char *pMsgBody );
|
||||
|
||||
// channel routines
|
||||
void transferChanToVirtCircuit (
|
||||
unsigned cid, unsigned sid,
|
||||
ca_uint16_t typeCode, arrayElementCount count,
|
||||
void transferChanToVirtCircuit (
|
||||
unsigned cid, unsigned sid,
|
||||
ca_uint16_t typeCode, arrayElementCount count,
|
||||
unsigned minorVersionNumber, const osiSockAddr &,
|
||||
const epicsTime & currentTime );
|
||||
cacChannel & createChannel (
|
||||
epicsGuard < epicsMutex > & guard, const char * pChannelName,
|
||||
cacChannel & createChannel (
|
||||
epicsGuard < epicsMutex > & guard, const char * pChannelName,
|
||||
cacChannelNotify &, cacChannel::priLev );
|
||||
void destroyChannel (
|
||||
void destroyChannel (
|
||||
epicsGuard < epicsMutex > &, nciu & );
|
||||
void initiateConnect (
|
||||
void initiateConnect (
|
||||
epicsGuard < epicsMutex > &, nciu &, netiiu * & );
|
||||
nciu * lookupChannel (
|
||||
epicsGuard < epicsMutex > &, const cacChannel::ioid & );
|
||||
|
||||
// IO requests
|
||||
netWriteNotifyIO & writeNotifyRequest (
|
||||
netWriteNotifyIO & writeNotifyRequest (
|
||||
epicsGuard < epicsMutex > &, nciu &, privateInterfaceForIO &,
|
||||
unsigned type, arrayElementCount nElem, const void * pValue,
|
||||
unsigned type, arrayElementCount nElem, const void * pValue,
|
||||
cacWriteNotify & );
|
||||
netReadNotifyIO & readNotifyRequest (
|
||||
netReadNotifyIO & readNotifyRequest (
|
||||
epicsGuard < epicsMutex > &, nciu &, privateInterfaceForIO &,
|
||||
unsigned type, arrayElementCount nElem,
|
||||
unsigned type, arrayElementCount nElem,
|
||||
cacReadNotify & );
|
||||
netSubscription & subscriptionRequest (
|
||||
netSubscription & subscriptionRequest (
|
||||
epicsGuard < epicsMutex > &, nciu &, privateInterfaceForIO &,
|
||||
unsigned type, arrayElementCount nElem, unsigned mask,
|
||||
unsigned type, arrayElementCount nElem, unsigned mask,
|
||||
cacStateNotify &, bool channelIsInstalled );
|
||||
bool destroyIO (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const cacChannel::ioid & idIn,
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard,
|
||||
const cacChannel::ioid & idIn,
|
||||
nciu & chan );
|
||||
void disconnectAllIO (
|
||||
void disconnectAllIO (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
nciu &, tsDLList < baseNMIU > & ioList );
|
||||
|
||||
void ioShow (
|
||||
void ioShow (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const cacChannel::ioid &id, unsigned level ) const;
|
||||
|
||||
// sync group routines
|
||||
CASG * lookupCASG ( epicsGuard < epicsMutex > &, unsigned id );
|
||||
void installCASG ( epicsGuard < epicsMutex > &, CASG & );
|
||||
void uninstallCASG ( epicsGuard < epicsMutex > &, CASG & );
|
||||
|
||||
// exception generation
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo );
|
||||
@@ -189,11 +185,11 @@ public:
|
||||
// diagnostics
|
||||
unsigned circuitCount ( epicsGuard < epicsMutex > & ) const;
|
||||
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
|
||||
int printFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
int printFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
const char *pformat, ... ) const;
|
||||
int varArgsPrintFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
int varArgsPrintFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
const char *pformat, va_list args ) const;
|
||||
double connectionTimeout ( epicsGuard < epicsMutex > & );
|
||||
|
||||
@@ -210,17 +206,17 @@ public:
|
||||
unsigned getInitializingThreadsPriority () const;
|
||||
epicsMutex & mutexRef ();
|
||||
void attachToClientCtx ();
|
||||
void selfTest (
|
||||
void selfTest (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
double beaconPeriod (
|
||||
double beaconPeriod (
|
||||
epicsGuard < epicsMutex > &,
|
||||
const nciu & chan ) const;
|
||||
static unsigned lowestPriorityLevelAbove ( unsigned priority );
|
||||
static unsigned highestPriorityLevelBelow ( unsigned priority );
|
||||
void destroyIIU ( tcpiiu & iiu );
|
||||
void destroyIIU ( tcpiiu & iiu );
|
||||
|
||||
const char * pLocalHostName ();
|
||||
|
||||
|
||||
private:
|
||||
epicsSingleton < localHostName > :: reference _refLocalHostName;
|
||||
chronIntIdResTable < nciu > chanTable;
|
||||
@@ -229,11 +225,11 @@ private:
|
||||
// !!!! to maintain one IO table for all types of
|
||||
// !!!! IO. It would probably be better to maintain
|
||||
// !!!! an independent table for each IO type. The
|
||||
// !!!! new adaptive sized hash table will not
|
||||
// !!!! waste memory. Making this change will
|
||||
// !!!! avoid virtual function overhead when
|
||||
// !!!! new adaptive sized hash table will not
|
||||
// !!!! waste memory. Making this change will
|
||||
// !!!! avoid virtual function overhead when
|
||||
// !!!! accessing the different types of IO. This
|
||||
// !!!! approach would also probably be safer in
|
||||
// !!!! approach would also probably be safer in
|
||||
// !!!! terms of detecting damaged protocol.
|
||||
//
|
||||
chronIntIdResTable < baseNMIU > ioTable;
|
||||
@@ -241,23 +237,23 @@ private:
|
||||
resTable < tcpiiu, caServerID > serverTable;
|
||||
tsDLList < tcpiiu > circuitList;
|
||||
tsDLList < SearchDest > searchDestList;
|
||||
tsFreeList
|
||||
< class tcpiiu, 32, epicsMutexNOOP >
|
||||
tsFreeList
|
||||
< class tcpiiu, 32, epicsMutexNOOP >
|
||||
freeListVirtualCircuit;
|
||||
tsFreeList
|
||||
< class netReadNotifyIO, 1024, epicsMutexNOOP >
|
||||
tsFreeList
|
||||
< class netReadNotifyIO, 1024, epicsMutexNOOP >
|
||||
freeListReadNotifyIO;
|
||||
tsFreeList
|
||||
< class netWriteNotifyIO, 1024, epicsMutexNOOP >
|
||||
tsFreeList
|
||||
< class netWriteNotifyIO, 1024, epicsMutexNOOP >
|
||||
freeListWriteNotifyIO;
|
||||
tsFreeList
|
||||
< class netSubscription, 1024, epicsMutexNOOP >
|
||||
tsFreeList
|
||||
< class netSubscription, 1024, epicsMutexNOOP >
|
||||
freeListSubscription;
|
||||
tsFreeList
|
||||
< class nciu, 1024, epicsMutexNOOP >
|
||||
tsFreeList
|
||||
< class nciu, 1024, epicsMutexNOOP >
|
||||
channelFreeList;
|
||||
tsFreeList
|
||||
< class msgForMultiplyDefinedPV, 16 >
|
||||
tsFreeList
|
||||
< class msgForMultiplyDefinedPV, 16 >
|
||||
mdpvFreeList;
|
||||
cacComBufMemoryManager comBufMemMgr;
|
||||
bheFreeStore bheFreeList;
|
||||
@@ -285,74 +281,74 @@ private:
|
||||
unsigned iiuExistenceCount;
|
||||
bool cacShutdownInProgress;
|
||||
|
||||
void recycleReadNotifyIO (
|
||||
void recycleReadNotifyIO (
|
||||
epicsGuard < epicsMutex > &, netReadNotifyIO &io );
|
||||
void recycleWriteNotifyIO (
|
||||
void recycleWriteNotifyIO (
|
||||
epicsGuard < epicsMutex > &, netWriteNotifyIO &io );
|
||||
void recycleSubscription (
|
||||
void recycleSubscription (
|
||||
epicsGuard < epicsMutex > &, netSubscription &io );
|
||||
|
||||
void disconnectChannel (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void disconnectChannel (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard, nciu & chan );
|
||||
|
||||
void ioExceptionNotify ( unsigned id, int status,
|
||||
void ioExceptionNotify ( unsigned id, int status,
|
||||
const char * pContext, unsigned type, arrayElementCount count );
|
||||
void ioExceptionNotifyAndUninstall ( unsigned id, int status,
|
||||
void ioExceptionNotifyAndUninstall ( unsigned id, int status,
|
||||
const char * pContext, unsigned type, arrayElementCount count );
|
||||
|
||||
void pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv,
|
||||
void pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv,
|
||||
const char * pChannelName, const char * pAcc, const char * pRej );
|
||||
|
||||
// recv protocol stubs
|
||||
bool versionAction ( callbackManager &, tcpiiu &,
|
||||
bool versionAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool echoRespAction ( callbackManager &, tcpiiu &,
|
||||
bool echoRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool writeNotifyRespAction ( callbackManager &, tcpiiu &,
|
||||
bool writeNotifyRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool searchRespAction ( callbackManager &, tcpiiu &,
|
||||
bool searchRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool readNotifyRespAction ( callbackManager &, tcpiiu &,
|
||||
bool readNotifyRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool eventRespAction ( callbackManager &, tcpiiu &,
|
||||
bool eventRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool readRespAction ( callbackManager &, tcpiiu &,
|
||||
bool readRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool clearChannelRespAction ( callbackManager &, tcpiiu &,
|
||||
bool clearChannelRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool exceptionRespAction ( callbackManager &, tcpiiu &,
|
||||
bool exceptionRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool accessRightsRespAction ( callbackManager &, tcpiiu &,
|
||||
bool accessRightsRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool createChannelRespAction ( callbackManager &, tcpiiu &,
|
||||
bool createChannelRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool verifyAndDisconnectChan ( callbackManager &, tcpiiu &,
|
||||
bool verifyAndDisconnectChan ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool badTCPRespAction ( callbackManager &, tcpiiu &,
|
||||
bool badTCPRespAction ( callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
|
||||
typedef bool ( cac::*pProtoStubTCP ) (
|
||||
callbackManager &, tcpiiu &,
|
||||
typedef bool ( cac::*pProtoStubTCP ) (
|
||||
callbackManager &, tcpiiu &,
|
||||
const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy );
|
||||
static const pProtoStubTCP tcpJumpTableCAC [];
|
||||
|
||||
bool defaultExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool defaultExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool eventAddExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool eventAddExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool readExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool readExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool writeExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool writeExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool clearChanExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool clearChanExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool readNotifyExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool readNotifyExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool writeNotifyExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool writeNotifyExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
typedef bool ( cac::*pExcepProtoStubTCP ) (
|
||||
callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
typedef bool ( cac::*pExcepProtoStubTCP ) (
|
||||
callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
static const pExcepProtoStubTCP tcpExcepJumpTableCAC [];
|
||||
|
||||
@@ -375,8 +371,8 @@ inline epicsMutex & cac::mutexRef ()
|
||||
return this->mutex;
|
||||
}
|
||||
|
||||
inline int cac :: varArgsPrintFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
inline int cac :: varArgsPrintFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
const char *pformat, va_list args ) const
|
||||
{
|
||||
callbackControl.assertIdenticalMutex ( this->cbMutex );
|
||||
@@ -435,14 +431,14 @@ inline notifyGuard::~notifyGuard ()
|
||||
this->notify.callbackProcessingCompleteNotify ();
|
||||
}
|
||||
|
||||
inline callbackManager::callbackManager (
|
||||
inline callbackManager::callbackManager (
|
||||
cacContextNotify & notify, epicsMutex & callbackControl ) :
|
||||
notifyGuard ( notify ), cbGuard ( callbackControl )
|
||||
{
|
||||
}
|
||||
|
||||
inline nciu * cac::lookupChannel (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const cacChannel::ioid & idIn )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
@@ -458,11 +454,11 @@ inline unsigned cac ::
|
||||
maxContiguousFrames ( epicsGuard < epicsMutex > & ) const
|
||||
{
|
||||
return maxContigFrames;
|
||||
}
|
||||
}
|
||||
|
||||
inline double cac ::
|
||||
connectionTimeout ( epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
return this->connTMO;
|
||||
}
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
@@ -74,9 +74,9 @@ public:
|
||||
virtual ~cacWriteNotify () = 0;
|
||||
virtual void completion ( epicsGuard < epicsMutex > & ) = 0;
|
||||
// we should probably have a different vf for each type of exception ????
|
||||
virtual void exception (
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &,
|
||||
int status, const char * pContext,
|
||||
int status, const char * pContext,
|
||||
unsigned type, arrayElementCount count ) = 0;
|
||||
};
|
||||
|
||||
@@ -85,13 +85,13 @@ public:
|
||||
class epicsShareClass cacReadNotify {
|
||||
public:
|
||||
virtual ~cacReadNotify () = 0;
|
||||
virtual void completion (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
virtual void completion (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, const void * pData ) = 0;
|
||||
// we should probably have a different vf for each type of exception ????
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char * pContext, unsigned type,
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char * pContext, unsigned type,
|
||||
arrayElementCount count ) = 0;
|
||||
};
|
||||
|
||||
@@ -100,21 +100,21 @@ public:
|
||||
class epicsShareClass cacStateNotify {
|
||||
public:
|
||||
virtual ~cacStateNotify () = 0;
|
||||
virtual void current (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
virtual void current (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, const void * pData ) = 0;
|
||||
// we should probably have a different vf for each type of exception ????
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char *pContext, unsigned type,
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char *pContext, unsigned type,
|
||||
arrayElementCount count ) = 0;
|
||||
};
|
||||
|
||||
class caAccessRights {
|
||||
public:
|
||||
caAccessRights (
|
||||
bool readPermit = false,
|
||||
bool writePermit = false,
|
||||
caAccessRights (
|
||||
bool readPermit = false,
|
||||
bool writePermit = false,
|
||||
bool operatorConfirmationRequest = false);
|
||||
void setReadPermit ();
|
||||
void setWritePermit ();
|
||||
@@ -138,20 +138,30 @@ public:
|
||||
virtual void disconnectNotify ( epicsGuard < epicsMutex > & ) = 0;
|
||||
virtual void serviceShutdownNotify (
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
|
||||
virtual void accessRightsNotify (
|
||||
virtual void accessRightsNotify (
|
||||
epicsGuard < epicsMutex > &, const caAccessRights & ) = 0;
|
||||
virtual void exception (
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char *pContext ) = 0;
|
||||
// we should probably have a different vf for each type of exception ????
|
||||
virtual void readException (
|
||||
virtual void readException (
|
||||
epicsGuard < epicsMutex > &, int status, const char *pContext,
|
||||
unsigned type, arrayElementCount count, void *pValue ) = 0;
|
||||
// we should probably have a different vf for each type of exception ????
|
||||
virtual void writeException (
|
||||
virtual void writeException (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
unsigned type, arrayElementCount count ) = 0;
|
||||
};
|
||||
|
||||
class CallbackGuard :
|
||||
public epicsGuard < epicsMutex > {
|
||||
public:
|
||||
CallbackGuard ( epicsMutex & mutex ) :
|
||||
epicsGuard < epicsMutex > ( mutex ) {}
|
||||
private:
|
||||
CallbackGuard ( const CallbackGuard & );
|
||||
CallbackGuard & operator = ( const CallbackGuard & );
|
||||
};
|
||||
|
||||
//
|
||||
// Notes
|
||||
// 1) This interface assumes that when a channel is deleted then all
|
||||
@@ -174,43 +184,52 @@ public:
|
||||
|
||||
cacChannel ( cacChannelNotify & );
|
||||
virtual void destroy (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
|
||||
cacChannelNotify & notify () const; // required ?????
|
||||
virtual unsigned getName (
|
||||
epicsGuard < epicsMutex > &,
|
||||
epicsGuard < epicsMutex > &,
|
||||
char * pBuf, unsigned bufLen ) const throw () = 0;
|
||||
// !! deprecated, avoid use !!
|
||||
virtual const char * pName (
|
||||
epicsGuard < epicsMutex > & guard ) const throw () = 0;
|
||||
virtual void show (
|
||||
virtual void show (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned level ) const = 0;
|
||||
virtual void initiateConnect (
|
||||
epicsGuard < epicsMutex > & ) = 0;
|
||||
virtual unsigned requestMessageBytesPending (
|
||||
virtual unsigned requestMessageBytesPending (
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
|
||||
virtual void flush (
|
||||
virtual void flush (
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
|
||||
virtual ioStatus read (
|
||||
virtual ioStatus read (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
cacReadNotify &, ioid * = 0 ) = 0;
|
||||
virtual void write (
|
||||
virtual void write (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
const void *pValue ) = 0;
|
||||
virtual ioStatus write (
|
||||
virtual ioStatus write (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
const void *pValue, cacWriteNotify &, ioid * = 0 ) = 0;
|
||||
virtual void subscribe (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, unsigned mask, cacStateNotify &,
|
||||
virtual void subscribe (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, unsigned mask, cacStateNotify &,
|
||||
ioid * = 0 ) = 0;
|
||||
virtual void ioCancel (
|
||||
// The primary mutex must be released when calling the user's
|
||||
// callback, and therefore a finite interval exists when we are
|
||||
// moving forward with the intent to call the users callback
|
||||
// but the users IO could be deleted during this interval.
|
||||
// To prevent the user's callback from being called after
|
||||
// destroying his IO we must past a guard for the callback
|
||||
// mutex here.
|
||||
virtual void ioCancel (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard,
|
||||
const ioid & ) = 0;
|
||||
virtual void ioShow (
|
||||
virtual void ioShow (
|
||||
epicsGuard < epicsMutex > &,
|
||||
const ioid &, unsigned level ) const = 0;
|
||||
virtual short nativeType (
|
||||
@@ -226,9 +245,9 @@ public:
|
||||
virtual double receiveWatchdogDelay (
|
||||
epicsGuard < epicsMutex > & ) const; // negative DBL_MAX if UKN
|
||||
virtual bool ca_v42_ok (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
virtual bool connected (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
virtual unsigned getHostName (
|
||||
epicsGuard < epicsMutex > &,
|
||||
char * pBuf, unsigned bufLength ) const throw ();
|
||||
@@ -261,11 +280,11 @@ private:
|
||||
class epicsShareClass cacContext {
|
||||
public:
|
||||
virtual ~cacContext ();
|
||||
virtual cacChannel & createChannel (
|
||||
virtual cacChannel & createChannel (
|
||||
epicsGuard < epicsMutex > &,
|
||||
const char * pChannelName, cacChannelNotify &,
|
||||
const char * pChannelName, cacChannelNotify &,
|
||||
cacChannel::priLev = cacChannel::priorityDefault ) = 0;
|
||||
virtual void flush (
|
||||
virtual void flush (
|
||||
epicsGuard < epicsMutex > & ) = 0;
|
||||
virtual unsigned circuitCount (
|
||||
epicsGuard < epicsMutex > & ) const = 0;
|
||||
@@ -273,18 +292,18 @@ public:
|
||||
epicsGuard < epicsMutex > & ) const = 0;
|
||||
virtual unsigned beaconAnomaliesSinceProgramStart (
|
||||
epicsGuard < epicsMutex > & ) const = 0;
|
||||
virtual void show (
|
||||
virtual void show (
|
||||
epicsGuard < epicsMutex > &, unsigned level ) const = 0;
|
||||
};
|
||||
|
||||
class epicsShareClass cacContextNotify {
|
||||
public:
|
||||
virtual ~cacContextNotify () = 0;
|
||||
virtual cacContext & createNetworkContext (
|
||||
virtual cacContext & createNetworkContext (
|
||||
epicsMutex & mutualExclusion, epicsMutex & callbackControl ) = 0;
|
||||
// we should probably have a different vf for each type of exception ????
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
virtual void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo ) = 0;
|
||||
// perhaps this should be phased out in deference to the exception mechanism
|
||||
virtual int varArgsPrintFormated ( const char * pformat, va_list args ) const = 0;
|
||||
@@ -300,9 +319,9 @@ public:
|
||||
class epicsShareClass cacService {
|
||||
public:
|
||||
virtual ~cacService () = 0;
|
||||
virtual cacContext & contextCreate (
|
||||
epicsMutex & mutualExclusion,
|
||||
epicsMutex & callbackControl,
|
||||
virtual cacContext & contextCreate (
|
||||
epicsMutex & mutualExclusion,
|
||||
epicsMutex & callbackControl,
|
||||
cacContextNotify & ) = 0;
|
||||
};
|
||||
|
||||
@@ -320,9 +339,9 @@ inline cacChannelNotify & cacChannel::notify () const
|
||||
return this->callback;
|
||||
}
|
||||
|
||||
inline caAccessRights::caAccessRights (
|
||||
inline caAccessRights::caAccessRights (
|
||||
bool readPermit, bool writePermit, bool operatorConfirmationRequest) :
|
||||
f_readPermit ( readPermit ), f_writePermit ( writePermit ),
|
||||
f_readPermit ( readPermit ), f_writePermit ( writePermit ),
|
||||
f_operatorConfirmationRequest ( operatorConfirmationRequest ) {}
|
||||
|
||||
inline void caAccessRights::setReadPermit ()
|
||||
|
||||
@@ -57,9 +57,9 @@ void getCallback::completion (
|
||||
// fetch client context and destroy prior to releasing
|
||||
// the lock and calling cb in case they destroy channel there
|
||||
this->chan.getClientCtx().destroyGetCallback ( guard, *this );
|
||||
{
|
||||
if ( pFuncTmp ) {
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
( *pFuncTmp ) ( args );
|
||||
pFuncTmp ( args );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "envDefs.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsStdioRedirect.h"
|
||||
#include "errlog.h"
|
||||
#include "osiWireFormat.h"
|
||||
|
||||
|
||||
@@ -63,9 +63,7 @@ static const unsigned contiguousMsgCountWhichTriggersFlowControl = 10u;
|
||||
|
||||
class caErrorCode {
|
||||
public:
|
||||
caErrorCode ( int status ) : code ( status ) {};
|
||||
private:
|
||||
int code;
|
||||
caErrorCode ( int ) {};
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
*
|
||||
@@ -39,9 +39,9 @@
|
||||
#include "db_access.h" // for INVALID_DB_REQ
|
||||
#include "noopiiu.h"
|
||||
|
||||
nciu::nciu ( cac & cacIn, netiiu & iiuIn, cacChannelNotify & chanIn,
|
||||
nciu::nciu ( cac & cacIn, netiiu & iiuIn, cacChannelNotify & chanIn,
|
||||
const char *pNameIn, cacChannel::priLev pri ) :
|
||||
cacChannel ( chanIn ),
|
||||
cacChannel ( chanIn ),
|
||||
cacCtx ( cacIn ),
|
||||
piiu ( & iiuIn ),
|
||||
sid ( UINT_MAX ),
|
||||
@@ -57,7 +57,7 @@ nciu::nciu ( cac & cacIn, netiiu & iiuIn, cacChannelNotify & chanIn,
|
||||
if ( nameLengthTmp > MAX_UDP_SEND - sizeof ( caHdr ) || nameLengthTmp > USHRT_MAX ) {
|
||||
throw cacChannel::badString ();
|
||||
}
|
||||
|
||||
|
||||
if ( pri > 0xff ) {
|
||||
throw cacChannel::badPriority ();
|
||||
}
|
||||
@@ -76,26 +76,28 @@ nciu::~nciu ()
|
||||
// channels are created by the user, and only destroyed by the user
|
||||
// using this routine
|
||||
void nciu::destroy (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExcusionGuard )
|
||||
{
|
||||
while ( baseNMIU * pNetIO = this->eventq.first () ) {
|
||||
bool success = this->cacCtx.destroyIO ( guard, pNetIO->getId (), *this );
|
||||
bool success = this->cacCtx.destroyIO ( callbackGuard, mutualExcusionGuard,
|
||||
pNetIO->getId (), *this );
|
||||
assert ( success );
|
||||
}
|
||||
|
||||
|
||||
// if the claim reply has not returned yet then we will issue
|
||||
// the clear channel request to the server when the claim reply
|
||||
// arrives and there is no matching nciu in the client
|
||||
if ( this->channelNode::isInstalledInServer ( guard ) ) {
|
||||
this->getPIIU(guard)->clearChannelRequest (
|
||||
guard, this->sid, this->id );
|
||||
if ( this->channelNode::isInstalledInServer ( mutualExcusionGuard ) ) {
|
||||
this->getPIIU(mutualExcusionGuard)->clearChannelRequest (
|
||||
mutualExcusionGuard, this->sid, this->id );
|
||||
}
|
||||
this->piiu->uninstallChan ( guard, *this );
|
||||
this->cacCtx.destroyChannel ( guard, *this );
|
||||
this->piiu->uninstallChan ( mutualExcusionGuard, *this );
|
||||
this->cacCtx.destroyChannel ( mutualExcusionGuard, *this );
|
||||
}
|
||||
|
||||
void nciu::operator delete ( void * )
|
||||
{
|
||||
{
|
||||
// Visual C++ .net appears to require operator delete if
|
||||
// placement operator delete is defined? I smell a ms rat
|
||||
// because if I declare placement new and delete, but
|
||||
@@ -105,15 +107,15 @@ void nciu::operator delete ( void * )
|
||||
__FILE__, __LINE__ );
|
||||
}
|
||||
|
||||
void nciu::initiateConnect (
|
||||
void nciu::initiateConnect (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
{
|
||||
this->cacCtx.initiateConnect ( guard, *this, this->piiu );
|
||||
}
|
||||
|
||||
void nciu::connect ( unsigned nativeType,
|
||||
unsigned nativeCount, unsigned sidIn,
|
||||
epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
void nciu::connect ( unsigned nativeType,
|
||||
unsigned nativeCount, unsigned sidIn,
|
||||
epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
@@ -127,7 +129,7 @@ void nciu::connect ( unsigned nativeType,
|
||||
|
||||
/*
|
||||
* if less than v4.1 then the server will never
|
||||
* send access rights and there will always be access
|
||||
* send access rights and there will always be access
|
||||
*/
|
||||
bool v41Ok = this->piiu->ca_v41_ok ( guard );
|
||||
if ( ! v41Ok ) {
|
||||
@@ -138,49 +140,49 @@ void nciu::connect ( unsigned nativeType,
|
||||
/*
|
||||
* if less than v4.1 then the server will never
|
||||
* send access rights and we know that there
|
||||
* will always be access and also need to call
|
||||
* will always be access and also need to call
|
||||
* their call back here
|
||||
*/
|
||||
if ( ! v41Ok ) {
|
||||
this->notify().accessRightsNotify (
|
||||
this->notify().accessRightsNotify (
|
||||
guard, this->accessRightState );
|
||||
}
|
||||
|
||||
// channel uninstal routine grabs the callback lock so
|
||||
// a channel will not be deleted while a call back is
|
||||
// a channel will not be deleted while a call back is
|
||||
// in progress
|
||||
//
|
||||
// the callback lock is also taken when a channel
|
||||
// disconnects to prevent a race condition with the
|
||||
// the callback lock is also taken when a channel
|
||||
// disconnects to prevent a race condition with the
|
||||
// code below - ie we hold the callback lock here
|
||||
// so a chanel cant be destroyed out from under us.
|
||||
this->notify().connectNotify ( guard );
|
||||
}
|
||||
|
||||
void nciu::unresponsiveCircuitNotify (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void nciu::unresponsiveCircuitNotify (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
ioid tmpId = this->getId ();
|
||||
cac & caRefTmp = this->cacCtx;
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
this->cacCtx.disconnectAllIO ( cbGuard, guard,
|
||||
this->cacCtx.disconnectAllIO ( cbGuard, guard,
|
||||
*this, this->eventq );
|
||||
this->notify().disconnectNotify ( guard );
|
||||
// if they destroy the channel in their disconnect
|
||||
// if they destroy the channel in their disconnect
|
||||
// handler then we have to be very careful to not
|
||||
// touch this object if it has been destroyed
|
||||
nciu * pChan = caRefTmp.lookupChannel ( guard, tmpId );
|
||||
if ( pChan ) {
|
||||
caAccessRights noRights;
|
||||
pChan->notify().accessRightsNotify ( guard, noRights );
|
||||
// likewise, they might destroy the channel in their access rights
|
||||
// handler so we have to be very careful to not touch this
|
||||
// likewise, they might destroy the channel in their access rights
|
||||
// handler so we have to be very careful to not touch this
|
||||
// object from here on down
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::setServerAddressUnknown ( netiiu & newiiu,
|
||||
void nciu::setServerAddressUnknown ( netiiu & newiiu,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
@@ -193,8 +195,8 @@ void nciu::setServerAddressUnknown ( netiiu & newiiu,
|
||||
this->accessRightState.clrWritePermit();
|
||||
}
|
||||
|
||||
void nciu::accessRightsStateChange (
|
||||
const caAccessRights & arIn, epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
void nciu::accessRightsStateChange (
|
||||
const caAccessRights & arIn, epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
@@ -204,7 +206,7 @@ void nciu::accessRightsStateChange (
|
||||
// the channel delete routine takes the call back lock so
|
||||
// that this will not be called when the channel is being
|
||||
// deleted.
|
||||
//
|
||||
//
|
||||
this->notify().accessRightsNotify ( guard, this->accessRightState );
|
||||
}
|
||||
|
||||
@@ -213,7 +215,7 @@ void nciu::accessRightsStateChange (
|
||||
*/
|
||||
bool nciu::searchMsg ( epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
bool success = this->piiu->searchMsg (
|
||||
bool success = this->piiu->searchMsg (
|
||||
guard, this->getId (), this->pNameStr, this->nameLength );
|
||||
if ( success ) {
|
||||
if ( this->retry < UINT_MAX ) {
|
||||
@@ -256,21 +258,21 @@ unsigned nciu::nameLen (
|
||||
return this->nameLength;
|
||||
}
|
||||
|
||||
unsigned nciu::requestMessageBytesPending (
|
||||
unsigned nciu::requestMessageBytesPending (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
return piiu->requestMessageBytesPending ( guard );
|
||||
}
|
||||
|
||||
void nciu::flush (
|
||||
void nciu::flush (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
piiu->flush ( guard );
|
||||
}
|
||||
|
||||
cacChannel::ioStatus nciu::read (
|
||||
cacChannel::ioStatus nciu::read (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned type, arrayElementCount countIn,
|
||||
unsigned type, arrayElementCount countIn,
|
||||
cacReadNotify ¬ify, ioid *pId )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
@@ -292,7 +294,7 @@ cacChannel::ioStatus nciu::read (
|
||||
throw cacChannel::badType ();
|
||||
}
|
||||
|
||||
netReadNotifyIO & io = this->cacCtx.readNotifyRequest (
|
||||
netReadNotifyIO & io = this->cacCtx.readNotifyRequest (
|
||||
guard, *this, *this, type, countIn, notify );
|
||||
if ( pId ) {
|
||||
*pId = io.getId ();
|
||||
@@ -314,7 +316,7 @@ void nciu::stringVerify ( const char *pStr, const unsigned count )
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::write (
|
||||
void nciu::write (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned type, arrayElementCount countIn, const void * pValue )
|
||||
{
|
||||
@@ -337,8 +339,8 @@ void nciu::write (
|
||||
this->piiu->writeRequest ( guard, *this, type, countIn, pValue );
|
||||
}
|
||||
|
||||
cacChannel::ioStatus nciu::write (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount countIn,
|
||||
cacChannel::ioStatus nciu::write (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount countIn,
|
||||
const void * pValue, cacWriteNotify & notify, ioid * pId )
|
||||
{
|
||||
// make sure that they get this and not "no write access"
|
||||
@@ -356,7 +358,7 @@ cacChannel::ioStatus nciu::write (
|
||||
nciu::stringVerify ( (char *) pValue, countIn );
|
||||
}
|
||||
|
||||
netWriteNotifyIO & io = this->cacCtx.writeNotifyRequest (
|
||||
netWriteNotifyIO & io = this->cacCtx.writeNotifyRequest (
|
||||
guard, *this, *this, type, countIn, pValue, notify );
|
||||
if ( pId ) {
|
||||
*pId = io.getId ();
|
||||
@@ -365,13 +367,13 @@ cacChannel::ioStatus nciu::write (
|
||||
return cacChannel::iosAsynch;
|
||||
}
|
||||
|
||||
void nciu::subscribe (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type,
|
||||
arrayElementCount nElem, unsigned mask,
|
||||
void nciu::subscribe (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type,
|
||||
arrayElementCount nElem, unsigned mask,
|
||||
cacStateNotify & notify, ioid *pId )
|
||||
{
|
||||
netSubscription & io = this->cacCtx.subscriptionRequest (
|
||||
guard, *this, *this, type, nElem, mask, notify,
|
||||
netSubscription & io = this->cacCtx.subscriptionRequest (
|
||||
guard, *this, *this, type, nElem, mask, notify,
|
||||
this->channelNode::isInstalledInServer ( guard ) );
|
||||
this->eventq.add ( io );
|
||||
if ( pId ) {
|
||||
@@ -379,24 +381,27 @@ void nciu::subscribe (
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::ioCancel (
|
||||
epicsGuard < epicsMutex > & guard, const ioid & idIn )
|
||||
void nciu::ioCancel (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard,
|
||||
const ioid & idIn )
|
||||
{
|
||||
this->cacCtx.destroyIO ( guard, idIn, *this );
|
||||
this->cacCtx.destroyIO ( callbackGuard,
|
||||
mutualExclusionGuard, idIn, *this );
|
||||
}
|
||||
|
||||
void nciu::ioShow (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
void nciu::ioShow (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const ioid &idIn, unsigned level ) const
|
||||
{
|
||||
this->cacCtx.ioShow ( guard, idIn, level );
|
||||
}
|
||||
|
||||
unsigned nciu::getHostName (
|
||||
unsigned nciu::getHostName (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
char *pBuf, unsigned bufLength ) const throw ()
|
||||
{
|
||||
return this->piiu->getHostName (
|
||||
{
|
||||
return this->piiu->getHostName (
|
||||
guard, pBuf, bufLength );
|
||||
}
|
||||
|
||||
@@ -424,7 +429,7 @@ short nciu::nativeType (
|
||||
return type;
|
||||
}
|
||||
|
||||
arrayElementCount nciu::nativeElementCount (
|
||||
arrayElementCount nciu::nativeElementCount (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
arrayElementCount countOut = 0ul;
|
||||
@@ -472,20 +477,20 @@ void nciu::show ( unsigned level ) const
|
||||
this->show ( guard, level );
|
||||
}
|
||||
|
||||
void nciu::show (
|
||||
void nciu::show (
|
||||
epicsGuard < epicsMutex > & guard, unsigned level ) const
|
||||
{
|
||||
if ( this->connected ( guard ) ) {
|
||||
char hostNameTmp [256];
|
||||
this->getHostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) );
|
||||
::printf ( "Channel \"%s\", connected to server %s",
|
||||
::printf ( "Channel \"%s\", connected to server %s",
|
||||
this->pNameStr, hostNameTmp );
|
||||
if ( level > 1u ) {
|
||||
int tmpTypeCode = static_cast < int > ( this->typeCode );
|
||||
::printf ( ", native type %s, native element count %u",
|
||||
dbf_type_to_text ( tmpTypeCode ), this->count );
|
||||
::printf ( ", %sread access, %swrite access",
|
||||
this->accessRightState.readPermit() ? "" : "no ",
|
||||
::printf ( ", %sread access, %swrite access",
|
||||
this->accessRightState.readPermit() ? "" : "no ",
|
||||
this->accessRightState.writePermit() ? "" : "no ");
|
||||
}
|
||||
::printf ( "\n" );
|
||||
@@ -495,7 +500,7 @@ void nciu::show (
|
||||
}
|
||||
|
||||
if ( level > 2u ) {
|
||||
::printf ( "\tnetwork IO pointer = %p\n",
|
||||
::printf ( "\tnetwork IO pointer = %p\n",
|
||||
static_cast <void *> ( this->piiu ) );
|
||||
::printf ( "\tserver identifier %u\n", this->sid );
|
||||
::printf ( "\tsearch retry number=%u\n", this->retry );
|
||||
@@ -503,7 +508,7 @@ void nciu::show (
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::ioCompletionNotify (
|
||||
void nciu::ioCompletionNotify (
|
||||
epicsGuard < epicsMutex > &, class baseNMIU & io )
|
||||
{
|
||||
this->eventq.remove ( io );
|
||||
@@ -544,7 +549,7 @@ void nciu::sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & guard )
|
||||
pNetIO->forceSubscriptionUpdate ( guard, *this );
|
||||
}
|
||||
catch ( ... ) {
|
||||
errlogPrintf (
|
||||
errlogPrintf (
|
||||
"CAC: failed to send subscription update request "
|
||||
"during channel connect\n" );
|
||||
}
|
||||
@@ -552,68 +557,68 @@ void nciu::sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & guard )
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::disconnectAllIO (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void nciu::disconnectAllIO (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
this->cacCtx.disconnectAllIO ( cbGuard, guard,
|
||||
this->cacCtx.disconnectAllIO ( cbGuard, guard,
|
||||
*this, this->eventq );
|
||||
}
|
||||
|
||||
void nciu::serviceShutdownNotify (
|
||||
epicsGuard < epicsMutex > & callbackControlGuard,
|
||||
epicsGuard < epicsMutex > & callbackControlGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard )
|
||||
{
|
||||
this->setServerAddressUnknown ( noopIIU, mutualExclusionGuard );
|
||||
this->notify().serviceShutdownNotify ( mutualExclusionGuard );
|
||||
}
|
||||
|
||||
void channelNode::setRespPendingState (
|
||||
epicsGuard < epicsMutex > &, unsigned index )
|
||||
void channelNode::setRespPendingState (
|
||||
epicsGuard < epicsMutex > &, unsigned index )
|
||||
{
|
||||
this->listMember =
|
||||
this->listMember =
|
||||
static_cast < channelNode::channelState >
|
||||
( channelNode::cs_searchRespPending0 + index );
|
||||
if ( this->listMember > cs_searchRespPending17 ) {
|
||||
throw std::runtime_error (
|
||||
throw std::runtime_error (
|
||||
"resp search timer index out of bounds" );
|
||||
}
|
||||
}
|
||||
|
||||
void channelNode::setReqPendingState (
|
||||
epicsGuard < epicsMutex > &, unsigned index )
|
||||
void channelNode::setReqPendingState (
|
||||
epicsGuard < epicsMutex > &, unsigned index )
|
||||
{
|
||||
this->listMember =
|
||||
this->listMember =
|
||||
static_cast < channelNode::channelState >
|
||||
( channelNode::cs_searchReqPending0 + index );
|
||||
if ( this->listMember > cs_searchReqPending17 ) {
|
||||
throw std::runtime_error (
|
||||
throw std::runtime_error (
|
||||
"req search timer index out of bounds" );
|
||||
}
|
||||
}
|
||||
|
||||
unsigned channelNode::getMaxSearchTimerCount ()
|
||||
unsigned channelNode::getMaxSearchTimerCount ()
|
||||
{
|
||||
return epicsMin (
|
||||
return epicsMin (
|
||||
cs_searchReqPending17 - cs_searchReqPending0,
|
||||
cs_searchRespPending17 - cs_searchRespPending0 ) + 1u;
|
||||
}
|
||||
|
||||
unsigned channelNode::getSearchTimerIndex (
|
||||
unsigned channelNode::getSearchTimerIndex (
|
||||
epicsGuard < epicsMutex > & )
|
||||
{
|
||||
channelNode::channelState chanState = this->listMember;
|
||||
unsigned index = 0u;
|
||||
if ( chanState >= cs_searchReqPending0 &&
|
||||
if ( chanState >= cs_searchReqPending0 &&
|
||||
chanState <= cs_searchReqPending17 ) {
|
||||
index = chanState - cs_searchReqPending0;
|
||||
}
|
||||
else if ( chanState >= cs_searchRespPending0 &&
|
||||
else if ( chanState >= cs_searchRespPending0 &&
|
||||
chanState <= cs_searchRespPending17 ) {
|
||||
index = chanState - cs_searchRespPending0;
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error (
|
||||
throw std::runtime_error (
|
||||
"channel was expected to be in a search timer, but wasnt" );;
|
||||
}
|
||||
return index;
|
||||
|
||||
@@ -5,24 +5,24 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
#ifndef nciuh
|
||||
#ifndef nciuh
|
||||
#define nciuh
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
@@ -123,45 +123,45 @@ private:
|
||||
|
||||
class privateInterfaceForIO {
|
||||
public:
|
||||
virtual void ioCompletionNotify (
|
||||
virtual void ioCompletionNotify (
|
||||
epicsGuard < epicsMutex > &, class baseNMIU & ) = 0;
|
||||
virtual arrayElementCount nativeElementCount (
|
||||
virtual arrayElementCount nativeElementCount (
|
||||
epicsGuard < epicsMutex > & ) const = 0;
|
||||
virtual bool connected ( epicsGuard < epicsMutex > & ) const = 0;
|
||||
protected:
|
||||
virtual ~privateInterfaceForIO() {}
|
||||
};
|
||||
|
||||
class nciu :
|
||||
class nciu :
|
||||
public cacChannel,
|
||||
public chronIntIdRes < nciu >,
|
||||
public chronIntIdRes < nciu >,
|
||||
public channelNode,
|
||||
private privateInterfaceForIO {
|
||||
public:
|
||||
nciu ( cac &, netiiu &, cacChannelNotify &,
|
||||
nciu ( cac &, netiiu &, cacChannelNotify &,
|
||||
const char * pNameIn, cacChannel::priLev );
|
||||
~nciu ();
|
||||
void connect ( unsigned nativeType,
|
||||
unsigned nativeCount, unsigned sid,
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void connect ( unsigned nativeType,
|
||||
unsigned nativeCount, unsigned sid,
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void connect ( epicsGuard < epicsMutex > & cbGuard,
|
||||
void connect ( epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void unresponsiveCircuitNotify (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void unresponsiveCircuitNotify (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void circuitHangupNotify ( class udpiiu &,
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void circuitHangupNotify ( class udpiiu &,
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void setServerAddressUnknown (
|
||||
void setServerAddressUnknown (
|
||||
netiiu & newiiu, epicsGuard < epicsMutex > & guard );
|
||||
bool searchMsg (
|
||||
bool searchMsg (
|
||||
epicsGuard < epicsMutex > & );
|
||||
void serviceShutdownNotify (
|
||||
epicsGuard < epicsMutex > & callbackControlGuard,
|
||||
epicsGuard < epicsMutex > & callbackControlGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard );
|
||||
void accessRightsStateChange ( const caAccessRights &,
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
void accessRightsStateChange ( const caAccessRights &,
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
ca_uint32_t getSID (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
@@ -172,12 +172,12 @@ public:
|
||||
const netiiu * getConstPIIU (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
cac & getClient ();
|
||||
void searchReplySetUp ( netiiu &iiu, unsigned sidIn,
|
||||
void searchReplySetUp ( netiiu &iiu, unsigned sidIn,
|
||||
ca_uint16_t typeIn, arrayElementCount countIn,
|
||||
epicsGuard < epicsMutex > & );
|
||||
void show (
|
||||
void show (
|
||||
unsigned level ) const;
|
||||
void show (
|
||||
void show (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned level ) const;
|
||||
unsigned getName (
|
||||
@@ -189,22 +189,22 @@ public:
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
unsigned getHostName (
|
||||
epicsGuard < epicsMutex > &,
|
||||
char * pBuf, unsigned bufLen ) const throw ();
|
||||
void writeException (
|
||||
char * pBuf, unsigned bufLen ) const throw ();
|
||||
void writeException (
|
||||
epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > &,
|
||||
int status, const char *pContext, unsigned type, arrayElementCount count );
|
||||
cacChannel::priLev getPriority (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
void * operator new (
|
||||
void * operator new (
|
||||
size_t size, tsFreeList < class nciu, 1024, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (
|
||||
( void *, tsFreeList < class nciu, 1024, epicsMutexNOOP > & ))
|
||||
//arrayElementCount nativeElementCount ( epicsGuard < epicsMutex > & ) const;
|
||||
void resubscribe ( epicsGuard < epicsMutex > & );
|
||||
void sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & );
|
||||
void disconnectAllIO (
|
||||
void disconnectAllIO (
|
||||
epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > & );
|
||||
bool connected ( epicsGuard < epicsMutex > & ) const;
|
||||
bool connected ( epicsGuard < epicsMutex > & ) const;
|
||||
unsigned getcount() const { return count; }
|
||||
|
||||
private:
|
||||
@@ -218,38 +218,47 @@ private:
|
||||
unsigned retry; // search retry number
|
||||
unsigned short nameLength; // channel name length
|
||||
ca_uint16_t typeCode;
|
||||
ca_uint8_t priority;
|
||||
ca_uint8_t priority;
|
||||
virtual void destroy (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard );
|
||||
void initiateConnect (
|
||||
epicsGuard < epicsMutex > & );
|
||||
unsigned requestMessageBytesPending (
|
||||
unsigned requestMessageBytesPending (
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard );
|
||||
void flush (
|
||||
void flush (
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard );
|
||||
ioStatus read (
|
||||
ioStatus read (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
cacReadNotify &, ioid * );
|
||||
void write (
|
||||
void write (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
const void *pValue );
|
||||
ioStatus write (
|
||||
ioStatus write (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
const void *pValue, cacWriteNotify &, ioid * );
|
||||
void subscribe (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned type, arrayElementCount nElem,
|
||||
void subscribe (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned type, arrayElementCount nElem,
|
||||
unsigned mask, cacStateNotify ¬ify, ioid * );
|
||||
virtual void ioCancel (
|
||||
// The primary mutex must be released when calling the user's
|
||||
// callback, and therefore a finite interval exists when we are
|
||||
// moving forward with the intent to call the users callback
|
||||
// but the users IO could be deleted during this interval.
|
||||
// To prevent the user's callback from being called after
|
||||
// destroying his IO we must past a guard for the callback
|
||||
// mutex here.
|
||||
virtual void ioCancel (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard,
|
||||
const ioid & );
|
||||
void ioShow (
|
||||
void ioShow (
|
||||
epicsGuard < epicsMutex > &,
|
||||
const ioid &, unsigned level ) const;
|
||||
short nativeType (
|
||||
short nativeType (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
caAccessRights accessRights (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
@@ -264,7 +273,7 @@ private:
|
||||
arrayElementCount nativeElementCount (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
static void stringVerify ( const char *pStr, const unsigned count );
|
||||
void ioCompletionNotify (
|
||||
void ioCompletionNotify (
|
||||
epicsGuard < epicsMutex > &, class baseNMIU & );
|
||||
const char * pHostName (
|
||||
epicsGuard < epicsMutex > & guard ) const throw ();
|
||||
@@ -273,16 +282,16 @@ private:
|
||||
void operator delete ( void * );
|
||||
};
|
||||
|
||||
inline void * nciu::operator new ( size_t size,
|
||||
inline void * nciu::operator new ( size_t size,
|
||||
tsFreeList < class nciu, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
inline void nciu::operator delete ( void * pCadaver,
|
||||
tsFreeList < class nciu, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
{
|
||||
freeList.release ( pCadaver, sizeof ( nciu ) );
|
||||
}
|
||||
#endif
|
||||
@@ -300,19 +309,19 @@ inline ca_uint32_t nciu::getCID (
|
||||
}
|
||||
|
||||
// this is to only be used by early protocol revisions
|
||||
inline void nciu::connect ( epicsGuard < epicsMutex > & cbGuard,
|
||||
inline void nciu::connect ( epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
this->connect ( this->typeCode, this->count,
|
||||
this->connect ( this->typeCode, this->count,
|
||||
this->sid, cbGuard, guard );
|
||||
}
|
||||
|
||||
inline void nciu::searchReplySetUp ( netiiu &iiu, unsigned sidIn,
|
||||
inline void nciu::searchReplySetUp ( netiiu &iiu, unsigned sidIn,
|
||||
ca_uint16_t typeIn, arrayElementCount countIn,
|
||||
epicsGuard < epicsMutex > & )
|
||||
{
|
||||
this->piiu = & iiu;
|
||||
this->typeCode = typeIn;
|
||||
this->typeCode = typeIn;
|
||||
this->count = countIn;
|
||||
this->sid = sidIn;
|
||||
}
|
||||
@@ -323,13 +332,13 @@ inline netiiu * nciu::getPIIU (
|
||||
return this->piiu;
|
||||
}
|
||||
|
||||
inline void nciu::writeException (
|
||||
epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
int status, const char * pContext,
|
||||
inline void nciu::writeException (
|
||||
epicsGuard < epicsMutex > & /* cbGuard */,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
int status, const char * pContext,
|
||||
unsigned typeIn, arrayElementCount countIn )
|
||||
{
|
||||
this->notify().writeException ( guard,
|
||||
this->notify().writeException ( guard,
|
||||
status, pContext, typeIn, countIn );
|
||||
}
|
||||
|
||||
@@ -357,15 +366,15 @@ inline channelNode::channelNode () :
|
||||
|
||||
inline bool channelNode::isConnected ( epicsGuard < epicsMutex > & ) const
|
||||
{
|
||||
return
|
||||
this->listMember == cs_connected ||
|
||||
return
|
||||
this->listMember == cs_connected ||
|
||||
this->listMember == cs_subscripReqPend ||
|
||||
this->listMember == cs_subscripUpdateReqPend;
|
||||
}
|
||||
|
||||
inline bool channelNode::isInstalledInServer ( epicsGuard < epicsMutex > & ) const
|
||||
{
|
||||
return
|
||||
return
|
||||
this->listMember == cs_connected ||
|
||||
this->listMember == cs_subscripReqPend ||
|
||||
this->listMember == cs_unrespCircuit ||
|
||||
|
||||
@@ -5,19 +5,19 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
*
|
||||
* Copyright, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
@@ -48,92 +48,94 @@
|
||||
|
||||
struct oldChannelNotify : private cacChannelNotify {
|
||||
public:
|
||||
oldChannelNotify (
|
||||
epicsGuard < epicsMutex > &, struct ca_client_context &,
|
||||
const char * pName, caCh * pConnCallBackIn,
|
||||
oldChannelNotify (
|
||||
epicsGuard < epicsMutex > &, struct ca_client_context &,
|
||||
const char * pName, caCh * pConnCallBackIn,
|
||||
void * pPrivateIn, capri priority );
|
||||
void destructor (
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void destructor (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & mutexGuard );
|
||||
|
||||
// legacy C API
|
||||
friend unsigned epicsShareAPI ca_get_host_name (
|
||||
friend unsigned epicsShareAPI ca_get_host_name (
|
||||
chid pChan, char * pBuf, unsigned bufLength );
|
||||
friend const char * epicsShareAPI ca_host_name (
|
||||
friend const char * epicsShareAPI ca_host_name (
|
||||
chid pChan );
|
||||
friend const char * epicsShareAPI ca_name (
|
||||
friend const char * epicsShareAPI ca_name (
|
||||
chid pChan );
|
||||
friend void epicsShareAPI ca_set_puser (
|
||||
friend void epicsShareAPI ca_set_puser (
|
||||
chid pChan, void * puser );
|
||||
friend void * epicsShareAPI ca_puser (
|
||||
friend void * epicsShareAPI ca_puser (
|
||||
chid pChan );
|
||||
friend int epicsShareAPI ca_change_connection_event (
|
||||
friend int epicsShareAPI ca_change_connection_event (
|
||||
chid pChan, caCh * pfunc );
|
||||
friend int epicsShareAPI ca_replace_access_rights_event (
|
||||
friend int epicsShareAPI ca_replace_access_rights_event (
|
||||
chid pChan, caArh *pfunc );
|
||||
friend int epicsShareAPI ca_array_get ( chtype type,
|
||||
friend int epicsShareAPI ca_array_get ( chtype type,
|
||||
arrayElementCount count, chid pChan, void * pValue );
|
||||
friend int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
friend int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
arrayElementCount count, chid pChan,
|
||||
caEventCallBackFunc *pfunc, void *arg );
|
||||
friend int epicsShareAPI ca_array_put (
|
||||
chtype type, arrayElementCount count,
|
||||
friend int epicsShareAPI ca_array_put (
|
||||
chtype type, arrayElementCount count,
|
||||
chid pChan, const void * pValue );
|
||||
friend int epicsShareAPI ca_array_put_callback (
|
||||
chtype type, arrayElementCount count,
|
||||
chid pChan, const void *pValue,
|
||||
friend int epicsShareAPI ca_array_put_callback (
|
||||
chtype type, arrayElementCount count,
|
||||
chid pChan, const void *pValue,
|
||||
caEventCallBackFunc *pfunc, void *usrarg );
|
||||
friend double epicsShareAPI ca_beacon_period (
|
||||
friend double epicsShareAPI ca_beacon_period (
|
||||
chid pChan );
|
||||
friend unsigned epicsShareAPI ca_search_attempts (
|
||||
friend unsigned epicsShareAPI ca_search_attempts (
|
||||
chid pChan );
|
||||
friend unsigned epicsShareAPI ca_write_access (
|
||||
friend unsigned epicsShareAPI ca_write_access (
|
||||
chid pChan );
|
||||
friend unsigned epicsShareAPI ca_read_access (
|
||||
friend unsigned epicsShareAPI ca_read_access (
|
||||
chid pChan );
|
||||
friend short epicsShareAPI ca_field_type (
|
||||
friend short epicsShareAPI ca_field_type (
|
||||
chid pChan );
|
||||
friend arrayElementCount epicsShareAPI ca_element_count (
|
||||
friend arrayElementCount epicsShareAPI ca_element_count (
|
||||
chid pChan );
|
||||
friend int epicsShareAPI ca_v42_ok (
|
||||
friend int epicsShareAPI ca_v42_ok (
|
||||
chid pChan );
|
||||
friend int epicsShareAPI ca_create_subscription (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
long mask, caEventCallBackFunc * pCallBack,
|
||||
friend int epicsShareAPI ca_create_subscription (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
long mask, caEventCallBackFunc * pCallBack,
|
||||
void * pCallBackArg, evid * monixptr );
|
||||
friend enum channel_state epicsShareAPI ca_state (
|
||||
chid pChan );
|
||||
friend double epicsShareAPI ca_receive_watchdog_delay (
|
||||
friend enum channel_state epicsShareAPI ca_state (
|
||||
chid pChan );
|
||||
friend double epicsShareAPI ca_receive_watchdog_delay (
|
||||
chid pChan );
|
||||
|
||||
unsigned getName (
|
||||
epicsGuard < epicsMutex > &,
|
||||
char * pBuf, unsigned bufLen ) const throw ();
|
||||
void show (
|
||||
void show (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned level ) const;
|
||||
void initiateConnect (
|
||||
epicsGuard < epicsMutex > & );
|
||||
void read (
|
||||
void read (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
cacReadNotify ¬ify, cacChannel::ioid *pId = 0 );
|
||||
void write (
|
||||
void write (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count, const void *pValue,
|
||||
unsigned type, arrayElementCount count, const void *pValue,
|
||||
cacWriteNotify &, cacChannel::ioid *pId = 0 );
|
||||
void ioCancel (
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard,
|
||||
void ioCancel (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard,
|
||||
const cacChannel::ioid & );
|
||||
void ioShow (
|
||||
void ioShow (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const cacChannel::ioid &, unsigned level ) const;
|
||||
ca_client_context & getClientCtx ();
|
||||
void eliminateExcessiveSendBacklog (
|
||||
void eliminateExcessiveSendBacklog (
|
||||
epicsGuard < epicsMutex > & );
|
||||
|
||||
void * operator new ( size_t size,
|
||||
void * operator new ( size_t size,
|
||||
tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void * ,
|
||||
epicsPlacementDeleteOperator (( void * ,
|
||||
tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & ))
|
||||
protected:
|
||||
~oldChannelNotify ();
|
||||
@@ -150,7 +152,7 @@ private:
|
||||
void disconnectNotify ( epicsGuard < epicsMutex > & );
|
||||
void serviceShutdownNotify (
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard );
|
||||
void accessRightsNotify (
|
||||
void accessRightsNotify (
|
||||
epicsGuard < epicsMutex > &, const caAccessRights & );
|
||||
void exception ( epicsGuard < epicsMutex > &,
|
||||
int status, const char * pContext );
|
||||
@@ -160,24 +162,24 @@ private:
|
||||
void writeException ( epicsGuard < epicsMutex > &,
|
||||
int status, const char * pContext,
|
||||
unsigned type, arrayElementCount count );
|
||||
oldChannelNotify ( const oldChannelNotify & );
|
||||
oldChannelNotify & operator = ( const oldChannelNotify & );
|
||||
oldChannelNotify ( const oldChannelNotify & );
|
||||
oldChannelNotify & operator = ( const oldChannelNotify & );
|
||||
void operator delete ( void * );
|
||||
};
|
||||
|
||||
class getCopy : public cacReadNotify {
|
||||
public:
|
||||
getCopy (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
ca_client_context & cacCtx,
|
||||
oldChannelNotify &, unsigned type,
|
||||
getCopy (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
ca_client_context & cacCtx,
|
||||
oldChannelNotify &, unsigned type,
|
||||
arrayElementCount count, void *pValue );
|
||||
~getCopy ();
|
||||
void show ( unsigned level ) const;
|
||||
void cancel ();
|
||||
void * operator new ( size_t size,
|
||||
void * operator new ( size_t size,
|
||||
tsFreeList < class getCopy, 1024, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < class getCopy, 1024, epicsMutexNOOP > & ))
|
||||
private:
|
||||
arrayElementCount count;
|
||||
@@ -187,10 +189,10 @@ private:
|
||||
unsigned ioSeqNo;
|
||||
unsigned type;
|
||||
void completion (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, const void *pData );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char *pContext, unsigned type, arrayElementCount count );
|
||||
getCopy ( const getCopy & );
|
||||
getCopy & operator = ( const getCopy & );
|
||||
@@ -199,23 +201,23 @@ private:
|
||||
|
||||
class getCallback : public cacReadNotify {
|
||||
public:
|
||||
getCallback (
|
||||
oldChannelNotify & chanIn,
|
||||
getCallback (
|
||||
oldChannelNotify & chanIn,
|
||||
caEventCallBackFunc *pFunc, void *pPrivate );
|
||||
~getCallback ();
|
||||
void * operator new ( size_t size,
|
||||
~getCallback ();
|
||||
void * operator new ( size_t size,
|
||||
tsFreeList < class getCallback, 1024, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < class getCallback, 1024, epicsMutexNOOP > & ))
|
||||
private:
|
||||
oldChannelNotify & chan;
|
||||
caEventCallBackFunc * pFunc;
|
||||
void * pPrivate;
|
||||
void completion (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, const void *pData);
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char * pContext, unsigned type, arrayElementCount count );
|
||||
getCallback ( const getCallback & );
|
||||
getCallback & operator = ( const getCallback & );
|
||||
@@ -224,21 +226,21 @@ private:
|
||||
|
||||
class putCallback : public cacWriteNotify {
|
||||
public:
|
||||
putCallback (
|
||||
oldChannelNotify &,
|
||||
putCallback (
|
||||
oldChannelNotify &,
|
||||
caEventCallBackFunc *pFunc, void *pPrivate );
|
||||
~putCallback ();
|
||||
void * operator new ( size_t size,
|
||||
void * operator new ( size_t size,
|
||||
tsFreeList < class putCallback, 1024, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < class putCallback, 1024, epicsMutexNOOP > & ))
|
||||
private:
|
||||
oldChannelNotify & chan;
|
||||
caEventCallBackFunc * pFunc;
|
||||
void *pPrivate;
|
||||
void completion ( epicsGuard < epicsMutex > & );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char *pContext,
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char *pContext,
|
||||
unsigned type, arrayElementCount count );
|
||||
putCallback ( const putCallback & );
|
||||
putCallback & operator = ( const putCallback & );
|
||||
@@ -249,17 +251,25 @@ struct oldSubscription : private cacStateNotify {
|
||||
public:
|
||||
oldSubscription (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
oldChannelNotify & chanIn, cacChannel & io,
|
||||
oldChannelNotify & chanIn, cacChannel & io,
|
||||
unsigned type, arrayElementCount nElem, unsigned mask,
|
||||
caEventCallBackFunc * pFuncIn, void * pPrivateIn,
|
||||
evid * );
|
||||
~oldSubscription ();
|
||||
oldChannelNotify & channel () const;
|
||||
void cancel (
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void * operator new ( size_t size,
|
||||
// The primary mutex must be released when calling the user's
|
||||
// callback, and therefore a finite interval exists when we are
|
||||
// moving forward with the intent to call the users callback
|
||||
// but the users IO could be deleted during this interval.
|
||||
// To prevent the user's callback from being called after
|
||||
// destroying his IO we must past a guard for the callback
|
||||
// mutex here.
|
||||
void cancel (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard );
|
||||
void * operator new ( size_t size,
|
||||
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & ))
|
||||
private:
|
||||
oldChannelNotify & chan;
|
||||
@@ -267,10 +277,10 @@ private:
|
||||
caEventCallBackFunc * pFunc;
|
||||
void * pPrivate;
|
||||
void current (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, const void *pData );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char *pContext, unsigned type, arrayElementCount count );
|
||||
oldSubscription ( const oldSubscription & );
|
||||
oldSubscription & operator = ( const oldSubscription & );
|
||||
@@ -285,16 +295,16 @@ struct ca_client_context : public cacContextNotify
|
||||
public:
|
||||
ca_client_context ( bool enablePreemptiveCallback = false );
|
||||
virtual ~ca_client_context ();
|
||||
void changeExceptionEvent (
|
||||
void changeExceptionEvent (
|
||||
caExceptionHandler * pfunc, void * arg );
|
||||
void registerForFileDescriptorCallBack (
|
||||
void registerForFileDescriptorCallBack (
|
||||
CAFDHANDLER * pFunc, void * pArg );
|
||||
void replaceErrLogHandler ( caPrintfFunc * ca_printf_func );
|
||||
cacChannel & createChannel (
|
||||
epicsGuard < epicsMutex > &, const char * pChannelName,
|
||||
cacChannel & createChannel (
|
||||
epicsGuard < epicsMutex > &, const char * pChannelName,
|
||||
cacChannelNotify &, cacChannel::priLev pri );
|
||||
void flush ( epicsGuard < epicsMutex > & );
|
||||
void eliminateExcessiveSendBacklog (
|
||||
void eliminateExcessiveSendBacklog (
|
||||
epicsGuard < epicsMutex > &, cacChannel & );
|
||||
int pendIO ( const double & timeout );
|
||||
int pendEvent ( const double & timeout );
|
||||
@@ -304,18 +314,18 @@ public:
|
||||
unsigned sequenceNumberOfOutstandingIO (
|
||||
epicsGuard < epicsMutex > & ) const;
|
||||
unsigned beaconAnomaliesSinceProgramStart () const;
|
||||
void incrementOutstandingIO (
|
||||
void incrementOutstandingIO (
|
||||
epicsGuard < epicsMutex > &, unsigned ioSeqNo );
|
||||
void decrementOutstandingIO (
|
||||
void decrementOutstandingIO (
|
||||
epicsGuard < epicsMutex > &, unsigned ioSeqNo );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo );
|
||||
void exception (
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
const char * pFileName, unsigned lineNo );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
unsigned type, arrayElementCount count, unsigned op );
|
||||
void blockForEventAndEnableCallbacks (
|
||||
void blockForEventAndEnableCallbacks (
|
||||
epicsEvent & event, const double & timeout );
|
||||
CASG * lookupCASG ( epicsGuard < epicsMutex > &, unsigned id );
|
||||
static void installDefaultService ( cacService & );
|
||||
@@ -325,9 +335,9 @@ public:
|
||||
// perhaps these should be eliminated in deference to the exception mechanism
|
||||
int printFormated ( const char * pformat, ... ) const;
|
||||
int varArgsPrintFormated ( const char * pformat, va_list args ) const;
|
||||
void signal ( int ca_status, const char * pfilenm,
|
||||
void signal ( int ca_status, const char * pfilenm,
|
||||
int lineno, const char * pFormat, ... );
|
||||
void vSignal ( int ca_status, const char * pfilenm,
|
||||
void vSignal ( int ca_status, const char * pfilenm,
|
||||
int lineno, const char *pFormat, va_list args );
|
||||
bool preemptiveCallbakIsEnabled () const;
|
||||
void destroyGetCopy ( epicsGuard < epicsMutex > &, getCopy & );
|
||||
@@ -336,25 +346,27 @@ public:
|
||||
void destroySubscription ( epicsGuard < epicsMutex > &, oldSubscription & );
|
||||
epicsMutex & mutexRef () const;
|
||||
|
||||
template < class T >
|
||||
void whenThereIsAnExceptionDestroySyncGroupIO ( epicsGuard < epicsMutex > &, T & );
|
||||
|
||||
// legacy C API
|
||||
// legacy C API
|
||||
friend int epicsShareAPI ca_create_channel (
|
||||
const char * name_str, caCh * conn_func, void * puser,
|
||||
capri priority, chid * chanptr );
|
||||
friend int epicsShareAPI ca_clear_channel ( chid pChan );
|
||||
friend int epicsShareAPI ca_array_get ( chtype type,
|
||||
friend int epicsShareAPI ca_array_get ( chtype type,
|
||||
arrayElementCount count, chid pChan, void * pValue );
|
||||
friend int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
friend int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
arrayElementCount count, chid pChan,
|
||||
caEventCallBackFunc *pfunc, void *arg );
|
||||
friend int epicsShareAPI ca_array_put ( chtype type,
|
||||
friend int epicsShareAPI ca_array_put ( chtype type,
|
||||
arrayElementCount count, chid pChan, const void * pValue );
|
||||
friend int epicsShareAPI ca_array_put_callback ( chtype type,
|
||||
arrayElementCount count, chid pChan, const void * pValue,
|
||||
friend int epicsShareAPI ca_array_put_callback ( chtype type,
|
||||
arrayElementCount count, chid pChan, const void * pValue,
|
||||
caEventCallBackFunc *pfunc, void *usrarg );
|
||||
friend int epicsShareAPI ca_create_subscription (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg,
|
||||
friend int epicsShareAPI ca_create_subscription (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg,
|
||||
evid *monixptr );
|
||||
friend int epicsShareAPI ca_flush_io ();
|
||||
friend int epicsShareAPI ca_clear_subscription ( evid pMon );
|
||||
@@ -363,6 +375,17 @@ public:
|
||||
friend int epicsShareAPI ca_sg_block ( const CA_SYNC_GID gid, ca_real timeout );
|
||||
friend int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid );
|
||||
friend int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid );
|
||||
friend int epicsShareAPI ca_sg_array_get ( const CA_SYNC_GID gid,
|
||||
chtype type, arrayElementCount count,
|
||||
chid pChan, void *pValue );
|
||||
friend int epicsShareAPI ca_sg_array_put ( const CA_SYNC_GID gid,
|
||||
chtype type, arrayElementCount count,
|
||||
chid pChan, const void *pValue );
|
||||
friend int ca_sync_group_destroy ( CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
ca_client_context & cac, const CA_SYNC_GID gid );
|
||||
friend void sync_group_reset ( ca_client_context & client,
|
||||
CASG & sg );
|
||||
|
||||
// exceptions
|
||||
class noSocket {};
|
||||
@@ -375,11 +398,11 @@ private:
|
||||
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > subscriptionFreeList;
|
||||
tsFreeList < struct CASG, 128, epicsMutexNOOP > casgFreeList;
|
||||
mutable epicsMutex mutex;
|
||||
mutable epicsMutex cbMutex;
|
||||
mutable epicsMutex cbMutex;
|
||||
epicsEvent ioDone;
|
||||
epicsEvent callbackThreadActivityComplete;
|
||||
epicsThreadId createdByThread;
|
||||
epics_auto_ptr < epicsGuard < epicsMutex > > pCallbackGuard;
|
||||
epics_auto_ptr < CallbackGuard > pCallbackGuard;
|
||||
epics_auto_ptr < cacContext > pServiceContext;
|
||||
caExceptionHandler * ca_exception_func;
|
||||
void * ca_exception_arg;
|
||||
@@ -397,15 +420,15 @@ private:
|
||||
void attachToClientCtx ();
|
||||
void callbackProcessingInitiateNotify ();
|
||||
void callbackProcessingCompleteNotify ();
|
||||
cacContext & createNetworkContext (
|
||||
cacContext & createNetworkContext (
|
||||
epicsMutex & mutualExclusion, epicsMutex & callbackControl );
|
||||
void _sendWakeupMsg ();
|
||||
|
||||
ca_client_context ( const ca_client_context & );
|
||||
ca_client_context & operator = ( const ca_client_context & );
|
||||
|
||||
friend void cacOnceFunc ( void * );
|
||||
friend void cacExitHandler ( void *);
|
||||
ca_client_context ( const ca_client_context & );
|
||||
ca_client_context & operator = ( const ca_client_context & );
|
||||
|
||||
friend void cacOnceFunc ( void * );
|
||||
friend void cacExitHandler ( void *);
|
||||
static cacService * pDefaultService;
|
||||
static epicsMutex * pDefaultServiceInstallMutex;
|
||||
static const unsigned flushBlockThreshold;
|
||||
@@ -425,7 +448,7 @@ inline unsigned oldChannelNotify::getName (
|
||||
return this->io.getName ( guard, pBuf, bufLen );
|
||||
}
|
||||
|
||||
inline void oldChannelNotify::show (
|
||||
inline void oldChannelNotify::show (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned level ) const
|
||||
{
|
||||
@@ -438,58 +461,60 @@ inline void oldChannelNotify::initiateConnect (
|
||||
this->io.initiateConnect ( guard );
|
||||
}
|
||||
|
||||
inline void oldChannelNotify::ioCancel (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
inline void oldChannelNotify::ioCancel (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard,
|
||||
const cacChannel::ioid & id )
|
||||
{
|
||||
this->io.ioCancel ( guard, id );
|
||||
this->io.ioCancel ( callbackGuard, mutualExclusionGuard, id );
|
||||
}
|
||||
|
||||
inline void oldChannelNotify::ioShow (
|
||||
inline void oldChannelNotify::ioShow (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
const cacChannel::ioid & id, unsigned level ) const
|
||||
{
|
||||
this->io.ioShow ( guard, id, level );
|
||||
}
|
||||
|
||||
inline void oldChannelNotify::eliminateExcessiveSendBacklog (
|
||||
inline void oldChannelNotify::eliminateExcessiveSendBacklog (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
this->cacCtx.eliminateExcessiveSendBacklog ( guard, this->io );
|
||||
}
|
||||
|
||||
inline void * oldChannelNotify::operator new ( size_t size,
|
||||
inline void * oldChannelNotify::operator new ( size_t size,
|
||||
tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
inline void oldChannelNotify::operator delete ( void *pCadaver,
|
||||
tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & freeList )
|
||||
inline void oldChannelNotify::operator delete ( void *pCadaver,
|
||||
tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
freeList.release ( pCadaver );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void * oldSubscription::operator new ( size_t size,
|
||||
inline void * oldSubscription::operator new ( size_t size,
|
||||
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
inline void oldSubscription::operator delete ( void *pCadaver,
|
||||
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & freeList )
|
||||
inline void oldSubscription::operator delete ( void *pCadaver,
|
||||
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
freeList.release ( pCadaver );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void oldSubscription::cancel (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
inline void oldSubscription::cancel (
|
||||
CallbackGuard & callbackGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard )
|
||||
{
|
||||
this->chan.ioCancel ( guard, this->id );
|
||||
this->chan.ioCancel ( callbackGuard, mutualExclusionGuard, this->id );
|
||||
}
|
||||
|
||||
inline oldChannelNotify & oldSubscription::channel () const
|
||||
@@ -497,43 +522,43 @@ inline oldChannelNotify & oldSubscription::channel () const
|
||||
return this->chan;
|
||||
}
|
||||
|
||||
inline void * getCopy::operator new ( size_t size,
|
||||
inline void * getCopy::operator new ( size_t size,
|
||||
tsFreeList < class getCopy, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
inline void getCopy::operator delete ( void *pCadaver,
|
||||
tsFreeList < class getCopy, 1024, epicsMutexNOOP > & freeList )
|
||||
inline void getCopy::operator delete ( void *pCadaver,
|
||||
tsFreeList < class getCopy, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
freeList.release ( pCadaver );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void * putCallback::operator new ( size_t size,
|
||||
inline void * putCallback::operator new ( size_t size,
|
||||
tsFreeList < class putCallback, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
inline void putCallback::operator delete ( void * pCadaver,
|
||||
tsFreeList < class putCallback, 1024, epicsMutexNOOP > & freeList )
|
||||
inline void putCallback::operator delete ( void * pCadaver,
|
||||
tsFreeList < class putCallback, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
freeList.release ( pCadaver );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void * getCallback::operator new ( size_t size,
|
||||
inline void * getCallback::operator new ( size_t size,
|
||||
tsFreeList < class getCallback, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#ifdef CXX_PLACEMENT_DELETE
|
||||
inline void getCallback::operator delete ( void * pCadaver,
|
||||
tsFreeList < class getCallback, 1024, epicsMutexNOOP > & freeList )
|
||||
inline void getCallback::operator delete ( void * pCadaver,
|
||||
tsFreeList < class getCallback, 1024, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
freeList.release ( pCadaver );
|
||||
}
|
||||
@@ -555,5 +580,32 @@ inline unsigned ca_client_context::sequenceNumberOfOutstandingIO (
|
||||
// perhaps on SMP systems THERE should be lock/unlock around this
|
||||
return this->ioSeqNo;
|
||||
}
|
||||
|
||||
|
||||
template < class T >
|
||||
void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO (
|
||||
epicsGuard < epicsMutex > & guard, T & io )
|
||||
{
|
||||
if ( this->pCallbackGuard.get() &&
|
||||
this->createdByThread == epicsThreadGetIdSelf () ) {
|
||||
io.destroy ( *this->pCallbackGuard.get(), guard );
|
||||
}
|
||||
else {
|
||||
// dont reverse the lock hierarchy
|
||||
epicsGuardRelease < epicsMutex > guardRelease ( guard );
|
||||
{
|
||||
//
|
||||
// we will definately stall out here if all of the
|
||||
// following are true
|
||||
//
|
||||
// o user creates non-preemtive mode client library context
|
||||
// o user doesnt periodically call a ca function
|
||||
// o user calls this function from an auxiillary thread
|
||||
//
|
||||
CallbackGuard cbGuard ( this->cbMutex );
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
io.destroy ( cbGuard, guard );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ifndef oldAccessh
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
@@ -43,13 +43,13 @@ extern "C" void cacNoopAccesRightsHandler ( struct access_rights_handler_args )
|
||||
{
|
||||
}
|
||||
|
||||
oldChannelNotify::oldChannelNotify (
|
||||
epicsGuard < epicsMutex > & guard, ca_client_context & cacIn,
|
||||
const char *pName, caCh * pConnCallBackIn,
|
||||
oldChannelNotify::oldChannelNotify (
|
||||
epicsGuard < epicsMutex > & guard, ca_client_context & cacIn,
|
||||
const char *pName, caCh * pConnCallBackIn,
|
||||
void * pPrivateIn, capri priority ) :
|
||||
cacCtx ( cacIn ),
|
||||
io ( cacIn.createChannel ( guard, pName, *this, priority ) ),
|
||||
pConnCallBack ( pConnCallBackIn ),
|
||||
cacCtx ( cacIn ),
|
||||
io ( cacIn.createChannel ( guard, pName, *this, priority ) ),
|
||||
pConnCallBack ( pConnCallBackIn ),
|
||||
pPrivate ( pPrivateIn ), pAccessRightsFunc ( cacNoopAccesRightsHandler ),
|
||||
ioSeqNo ( 0 ), currentlyConnected ( false ), prevConnected ( false )
|
||||
{
|
||||
@@ -65,19 +65,20 @@ oldChannelNotify::~oldChannelNotify ()
|
||||
}
|
||||
|
||||
void oldChannelNotify::destructor (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & mutexGuard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
this->io.destroy ( guard );
|
||||
mutexGuard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
|
||||
this->io.destroy ( cbGuard, mutexGuard );
|
||||
// no need to worry about a connect preempting here because
|
||||
// the io (the nciu) has been destroyed above
|
||||
if ( this->pConnCallBack == 0 && ! this->currentlyConnected ) {
|
||||
this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo );
|
||||
this->cacCtx.decrementOutstandingIO ( mutexGuard, this->ioSeqNo );
|
||||
}
|
||||
this->~oldChannelNotify ();
|
||||
}
|
||||
|
||||
void oldChannelNotify::connectNotify (
|
||||
void oldChannelNotify::connectNotify (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
this->currentlyConnected = true;
|
||||
@@ -97,7 +98,7 @@ void oldChannelNotify::connectNotify (
|
||||
}
|
||||
}
|
||||
|
||||
void oldChannelNotify::disconnectNotify (
|
||||
void oldChannelNotify::disconnectNotify (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
this->currentlyConnected = false;
|
||||
@@ -112,7 +113,7 @@ void oldChannelNotify::disconnectNotify (
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->cacCtx.incrementOutstandingIO (
|
||||
this->cacCtx.incrementOutstandingIO (
|
||||
guard, this->ioSeqNo );
|
||||
}
|
||||
}
|
||||
@@ -123,7 +124,7 @@ void oldChannelNotify::serviceShutdownNotify (
|
||||
this->disconnectNotify ( guard );
|
||||
}
|
||||
|
||||
void oldChannelNotify::accessRightsNotify (
|
||||
void oldChannelNotify::accessRightsNotify (
|
||||
epicsGuard < epicsMutex > & guard, const caAccessRights & ar )
|
||||
{
|
||||
struct access_rights_handler_args args;
|
||||
@@ -137,25 +138,25 @@ void oldChannelNotify::accessRightsNotify (
|
||||
}
|
||||
}
|
||||
|
||||
void oldChannelNotify::exception (
|
||||
void oldChannelNotify::exception (
|
||||
epicsGuard < epicsMutex > & guard, int status, const char * pContext )
|
||||
{
|
||||
this->cacCtx.exception ( guard, status, pContext, __FILE__, __LINE__ );
|
||||
}
|
||||
|
||||
void oldChannelNotify::readException (
|
||||
void oldChannelNotify::readException (
|
||||
epicsGuard < epicsMutex > & guard, int status, const char *pContext,
|
||||
unsigned type, arrayElementCount count, void * /* pValue */ )
|
||||
{
|
||||
this->cacCtx.exception ( guard, status, pContext,
|
||||
this->cacCtx.exception ( guard, status, pContext,
|
||||
__FILE__, __LINE__, *this, type, count, CA_OP_GET );
|
||||
}
|
||||
|
||||
void oldChannelNotify::writeException (
|
||||
void oldChannelNotify::writeException (
|
||||
epicsGuard < epicsMutex > & guard, int status, const char *pContext,
|
||||
unsigned type, arrayElementCount count )
|
||||
{
|
||||
this->cacCtx.exception ( guard, status, pContext,
|
||||
this->cacCtx.exception ( guard, status, pContext,
|
||||
__FILE__, __LINE__, *this, type, count, CA_OP_PUT );
|
||||
}
|
||||
|
||||
@@ -173,7 +174,7 @@ void oldChannelNotify::operator delete ( void * )
|
||||
/*
|
||||
* ca_get_host_name ()
|
||||
*/
|
||||
unsigned epicsShareAPI ca_get_host_name (
|
||||
unsigned epicsShareAPI ca_get_host_name (
|
||||
chid pChan, char * pBuf, unsigned bufLength )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef() );
|
||||
@@ -186,7 +187,7 @@ unsigned epicsShareAPI ca_get_host_name (
|
||||
* !!!! not thread safe !!!!
|
||||
*
|
||||
*/
|
||||
const char * epicsShareAPI ca_host_name (
|
||||
const char * epicsShareAPI ca_host_name (
|
||||
chid pChan )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
@@ -196,7 +197,7 @@ const char * epicsShareAPI ca_host_name (
|
||||
/*
|
||||
* ca_set_puser ()
|
||||
*/
|
||||
void epicsShareAPI ca_set_puser (
|
||||
void epicsShareAPI ca_set_puser (
|
||||
chid pChan, void * puser )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
@@ -206,7 +207,7 @@ void epicsShareAPI ca_set_puser (
|
||||
/*
|
||||
* ca_get_puser ()
|
||||
*/
|
||||
void * epicsShareAPI ca_puser (
|
||||
void * epicsShareAPI ca_puser (
|
||||
chid pChan )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
@@ -220,7 +221,7 @@ int epicsShareAPI ca_change_connection_event ( chid pChan, caCh * pfunc )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
if ( ! pChan->currentlyConnected ) {
|
||||
if ( pfunc ) {
|
||||
if ( pfunc ) {
|
||||
if ( ! pChan->pConnCallBack ) {
|
||||
pChan->cacCtx.decrementOutstandingIO ( guard, pChan->ioSeqNo );
|
||||
}
|
||||
@@ -238,7 +239,7 @@ int epicsShareAPI ca_change_connection_event ( chid pChan, caCh * pfunc )
|
||||
/*
|
||||
* ca_replace_access_rights_event
|
||||
*/
|
||||
int epicsShareAPI ca_replace_access_rights_event (
|
||||
int epicsShareAPI ca_replace_access_rights_event (
|
||||
chid pChan, caArh *pfunc )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
@@ -246,11 +247,11 @@ int epicsShareAPI ca_replace_access_rights_event (
|
||||
// The order of the following is significant to guarantee that the
|
||||
// access rights handler is always gets called even if the channel connects
|
||||
// while this is running. There is some very small chance that the
|
||||
// handler could be called twice here with the same access rights state, but
|
||||
// handler could be called twice here with the same access rights state, but
|
||||
// that will not upset the application.
|
||||
pChan->pAccessRightsFunc = pfunc ? pfunc : cacNoopAccesRightsHandler;
|
||||
caAccessRights tmp = pChan->io.accessRights ( guard );
|
||||
|
||||
|
||||
if ( pChan->currentlyConnected ) {
|
||||
struct access_rights_handler_args args;
|
||||
args.chid = pChan;
|
||||
@@ -265,7 +266,7 @@ int epicsShareAPI ca_replace_access_rights_event (
|
||||
/*
|
||||
* ca_array_get ()
|
||||
*/
|
||||
int epicsShareAPI ca_array_get ( chtype type,
|
||||
int epicsShareAPI ca_array_get ( chtype type,
|
||||
arrayElementCount count, chid pChan, void *pValue )
|
||||
{
|
||||
int caStatus;
|
||||
@@ -279,10 +280,10 @@ int epicsShareAPI ca_array_get ( chtype type,
|
||||
unsigned tmpType = static_cast < unsigned > ( type );
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
pChan->eliminateExcessiveSendBacklog ( guard );
|
||||
autoPtrFreeList < getCopy, 0x400, epicsMutexNOOP > pNotify
|
||||
autoPtrFreeList < getCopy, 0x400, epicsMutexNOOP > pNotify
|
||||
( pChan->getClientCtx().getCopyFreeList,
|
||||
new ( pChan->getClientCtx().getCopyFreeList )
|
||||
getCopy ( guard, pChan->getClientCtx(), *pChan,
|
||||
new ( pChan->getClientCtx().getCopyFreeList )
|
||||
getCopy ( guard, pChan->getClientCtx(), *pChan,
|
||||
tmpType, count, pValue ) );
|
||||
pChan->io.read ( guard, type, count, *pNotify, 0 );
|
||||
pNotify.release ();
|
||||
@@ -333,7 +334,7 @@ int epicsShareAPI ca_array_get ( chtype type,
|
||||
/*
|
||||
* ca_array_get_callback ()
|
||||
*/
|
||||
int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
arrayElementCount count, chid pChan,
|
||||
caEventCallBackFunc *pfunc, void *arg )
|
||||
{
|
||||
@@ -342,11 +343,14 @@ int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
if ( type < 0 ) {
|
||||
return ECA_BADTYPE;
|
||||
}
|
||||
if ( pfunc == NULL ) {
|
||||
return ECA_BADFUNCPTR;
|
||||
}
|
||||
unsigned tmpType = static_cast < unsigned > ( type );
|
||||
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
pChan->eliminateExcessiveSendBacklog ( guard );
|
||||
autoPtrFreeList < getCallback, 0x400, epicsMutexNOOP > pNotify
|
||||
autoPtrFreeList < getCallback, 0x400, epicsMutexNOOP > pNotify
|
||||
( pChan->getClientCtx().getCallbackFreeList,
|
||||
new ( pChan->getClientCtx().getCallbackFreeList )
|
||||
getCallback ( *pChan, pfunc, arg ) );
|
||||
@@ -396,9 +400,9 @@ int epicsShareAPI ca_array_get_callback ( chtype type,
|
||||
return caStatus;
|
||||
}
|
||||
|
||||
void oldChannelNotify::read (
|
||||
void oldChannelNotify::read (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
unsigned type, arrayElementCount count,
|
||||
unsigned type, arrayElementCount count,
|
||||
cacReadNotify & notify, cacChannel::ioid * pId )
|
||||
{
|
||||
this->io.read ( guard, type, count, notify, pId );
|
||||
@@ -407,7 +411,7 @@ void oldChannelNotify::read (
|
||||
/*
|
||||
* ca_array_put_callback ()
|
||||
*/
|
||||
int epicsShareAPI ca_array_put_callback ( chtype type, arrayElementCount count,
|
||||
int epicsShareAPI ca_array_put_callback ( chtype type, arrayElementCount count,
|
||||
chid pChan, const void *pValue, caEventCallBackFunc *pfunc, void *usrarg )
|
||||
{
|
||||
int caStatus;
|
||||
@@ -415,6 +419,9 @@ int epicsShareAPI ca_array_put_callback ( chtype type, arrayElementCount count,
|
||||
if ( type < 0 ) {
|
||||
return ECA_BADTYPE;
|
||||
}
|
||||
if ( pfunc == NULL ) {
|
||||
return ECA_BADFUNCPTR;
|
||||
}
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
pChan->eliminateExcessiveSendBacklog ( guard );
|
||||
unsigned tmpType = static_cast < unsigned > ( type );
|
||||
@@ -468,7 +475,7 @@ int epicsShareAPI ca_array_put_callback ( chtype type, arrayElementCount count,
|
||||
/*
|
||||
* ca_array_put ()
|
||||
*/
|
||||
int epicsShareAPI ca_array_put ( chtype type, arrayElementCount count,
|
||||
int epicsShareAPI ca_array_put ( chtype type, arrayElementCount count,
|
||||
chid pChan, const void * pValue )
|
||||
{
|
||||
if ( type < 0 ) {
|
||||
@@ -522,9 +529,9 @@ int epicsShareAPI ca_array_put ( chtype type, arrayElementCount count,
|
||||
return caStatus;
|
||||
}
|
||||
|
||||
int epicsShareAPI ca_create_subscription (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg,
|
||||
int epicsShareAPI ca_create_subscription (
|
||||
chtype type, arrayElementCount count, chid pChan,
|
||||
long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg,
|
||||
evid * monixptr )
|
||||
{
|
||||
if ( type < 0 ) {
|
||||
@@ -552,7 +559,7 @@ int epicsShareAPI ca_create_subscription (
|
||||
try {
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
try {
|
||||
// if this stalls out on a live circuit then an exception
|
||||
// if this stalls out on a live circuit then an exception
|
||||
// can be forthcoming which we must ignore (this is a
|
||||
// special case preserving legacy ca_create_subscription
|
||||
// behavior)
|
||||
@@ -562,7 +569,7 @@ int epicsShareAPI ca_create_subscription (
|
||||
// intentionally ignored (its ok to subscribe when not connected)
|
||||
}
|
||||
new ( pChan->getClientCtx().subscriptionFreeList )
|
||||
oldSubscription (
|
||||
oldSubscription (
|
||||
guard, *pChan, pChan->io, tmpType, count, mask,
|
||||
pCallBack, pCallBackArg, monixptr );
|
||||
// dont touch object created after above new because
|
||||
@@ -603,8 +610,8 @@ int epicsShareAPI ca_create_subscription (
|
||||
}
|
||||
}
|
||||
|
||||
void oldChannelNotify::write (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount count,
|
||||
void oldChannelNotify::write (
|
||||
epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount count,
|
||||
const void * pValue, cacWriteNotify & notify, cacChannel::ioid * pId )
|
||||
{
|
||||
this->io.write ( guard, type, count, pValue, notify, pId );
|
||||
@@ -613,7 +620,7 @@ void oldChannelNotify::write (
|
||||
/*
|
||||
* ca_field_type()
|
||||
*/
|
||||
short epicsShareAPI ca_field_type ( chid pChan )
|
||||
short epicsShareAPI ca_field_type ( chid pChan )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
return pChan->io.nativeType ( guard );
|
||||
@@ -622,7 +629,7 @@ short epicsShareAPI ca_field_type ( chid pChan )
|
||||
/*
|
||||
* ca_element_count ()
|
||||
*/
|
||||
arrayElementCount epicsShareAPI ca_element_count ( chid pChan )
|
||||
arrayElementCount epicsShareAPI ca_element_count ( chid pChan )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
return pChan->io.nativeElementCount ( guard );
|
||||
@@ -674,7 +681,7 @@ const char * epicsShareAPI ca_name ( chid pChan )
|
||||
|
||||
unsigned epicsShareAPI ca_search_attempts ( chid pChan )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
|
||||
return pChan->io.searchAttempts ( guard );
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $version = '0.4';
|
||||
my $version = '0.5';
|
||||
|
||||
|
||||
package CA;
|
||||
@@ -507,6 +507,11 @@ class method syntax, e.g. C<< CA->pend_io(10) >>.
|
||||
|
||||
=over 4
|
||||
|
||||
=item version
|
||||
|
||||
Returns the EPICS_VERSION_STRING from the version of EPICS Base this software
|
||||
was built using.
|
||||
|
||||
=item flush_io
|
||||
|
||||
Flush outstanding IO requests to the server. This routine is useful for users
|
||||
@@ -633,7 +638,7 @@ not follow this pattern, but are still printable strings.
|
||||
|
||||
=item [1] R3.14 Channel Access Reference Manual by Jeffrey O. Hill
|
||||
|
||||
L<http://www.aps.anl.gov/epics/base/R3-14/11-docs/CAref.html>
|
||||
L<http://www.aps.anl.gov/epics/base/R3-14/12-docs/CAref.html>
|
||||
|
||||
=back
|
||||
|
||||
@@ -644,7 +649,7 @@ Andrew Johnson, E<lt>anj@aps.anl.govE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2008 UChicago Argonne LLC, as Operator of Argonne National
|
||||
Copyright (C) 2008-2014 UChicago Argonne LLC, as Operator of Argonne National
|
||||
Laboratory.
|
||||
|
||||
This software is distributed under the terms of the EPICS Open License.
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
#include "cadef.h"
|
||||
#include "db_access.h"
|
||||
#include "epicsVersion.h"
|
||||
#include "alarm.h"
|
||||
#include "alarmString.h"
|
||||
|
||||
typedef union {
|
||||
dbr_long_t iv;
|
||||
@@ -1010,6 +1010,12 @@ void CA_flush_io(const char *class) {
|
||||
}
|
||||
|
||||
|
||||
/* CA::version($class) */
|
||||
|
||||
const char * CA_version(const char *class) {
|
||||
return EPICS_VERSION_STRING;
|
||||
}
|
||||
|
||||
/* CA::add_exception_event($class, \&sub) */
|
||||
|
||||
static
|
||||
@@ -1214,6 +1220,15 @@ int CA_write_access(SV *ca_ref) {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* Ensure that the generated boot_Cap5 function is visible
|
||||
* outside of the libCap5.so shared library when compiling
|
||||
* with GCC4+ and -fvisibility=hidden is used.
|
||||
*/
|
||||
#if __GNUC__ >= 4
|
||||
XS(boot_Cap5) __attribute__ ((visibility ("default")));
|
||||
#endif
|
||||
|
||||
|
||||
MODULE = Cap5 PACKAGE = Cap5
|
||||
|
||||
MODULE = Cap5 PACKAGE = CA PREFIX = CA_
|
||||
@@ -1385,6 +1400,10 @@ void
|
||||
CA_flush_io (class)
|
||||
const char * class
|
||||
|
||||
const char *
|
||||
CA_version (class)
|
||||
const char * class
|
||||
|
||||
void
|
||||
CA_add_exception_event (class, sub)
|
||||
const char * class
|
||||
|
||||
@@ -61,10 +61,6 @@ ifdef T_A
|
||||
$(RM) $@ $@_new
|
||||
$(PERL) $(EXTUTILS)/xsubpp -typemap $(EXTUTILS)/typemap $< > $@_new && $(MV) $@_new $@
|
||||
|
||||
%.html: ../%.pm
|
||||
$(RM) $@
|
||||
podchecker $< && pod2html --infile=$< --outfile=$@
|
||||
|
||||
$(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH)/%: %
|
||||
$(ECHO) "Installing loadable shared library $@"
|
||||
@$(INSTALL_LIBRARY) -d -m $(LIB_PERMISSIONS) $< $(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
|
||||
@@ -148,11 +148,11 @@ sub display {
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "\nUsage: caget [options] <PV name> ...\n",
|
||||
print STDERR "\nUsage: caget.pl [options] <PV name> ...\n",
|
||||
"\n",
|
||||
" -h: Help: Print this message\n",
|
||||
"Channel Access options:\n",
|
||||
" -w <sec>: Wait time, specifies longer CA timeout, default is $opt_w second\n",
|
||||
" -w <sec>: Wait time, specifies CA timeout, default is $opt_w second\n",
|
||||
"Format options:\n",
|
||||
" -t: Terse mode - print only value, without name\n",
|
||||
" -a: Wide mode \"name timestamp value stat sevr\" (read PVs as DBR_TIME_xxx)\n",
|
||||
@@ -182,6 +182,7 @@ sub HELP_MESSAGE {
|
||||
" -0b: Print as binary number\n",
|
||||
"Set output field separator:\n",
|
||||
" -F <ofs>: Use <ofs> to separate fields on output\n",
|
||||
"\n";
|
||||
"\n",
|
||||
"Base version: ", CA->version, "\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
|
||||
@@ -52,13 +52,14 @@ sub display {
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "\nUsage: cainfo [options] <PV name> ...\n",
|
||||
print STDERR "\nUsage: cainfo.pl [options] <PV name> ...\n",
|
||||
"\n",
|
||||
" -h: Help: Print this message\n",
|
||||
"Channel Access options:\n",
|
||||
" -w <sec>: Wait time, specifies CA timeout, default is $opt_w second\n",
|
||||
"\n",
|
||||
"Example: cainfo my_channel another_channel\n",
|
||||
"\n";
|
||||
"\n",
|
||||
"Base version: ", CA->version, "\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
|
||||
@@ -109,11 +109,11 @@ sub display {
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "\nUsage: camonitor [options] <PV name> ...\n",
|
||||
print STDERR "\nUsage: camonitor.pl [options] <PV name> ...\n",
|
||||
"\n",
|
||||
" -h: Help: Print this message\n",
|
||||
"Channel Access options:\n",
|
||||
" -w <sec>: Wait time, specifies longer CA timeout, default is $opt_w second\n",
|
||||
" -w <sec>: Wait time, specifies CA timeout, default is $opt_w second\n",
|
||||
" -m <mask>: Specify CA event mask to use, with <mask> being any combination of\n",
|
||||
" 'v' (value), 'a' (alarm), 'l' (log/archive), 'p' (property)",
|
||||
" Default: '$opt_m'\n",
|
||||
@@ -144,6 +144,7 @@ sub HELP_MESSAGE {
|
||||
"\n",
|
||||
"Example: camonitor -f8 my_channel another_channel\n",
|
||||
" (doubles are printed as %f with 8 decimal digits)\n",
|
||||
"\n";
|
||||
"\n",
|
||||
"Base version: ", CA->version, "\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
#!/usr/bin/env perl
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
@@ -401,23 +401,22 @@ sub printRecordList {
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "\n",
|
||||
"Usage: capr.pl -h\n",
|
||||
" capr.pl [-d file.dbd] [-w seconds] -r\n",
|
||||
" capr.pl [-d file.dbd] [-w seconds] -f record_type\n",
|
||||
" capr.pl [-d file.dbd] [-w seconds] record_name [interest]\n",
|
||||
"Description:\n",
|
||||
" Attempts to perform a \"dbpr\" record print via channel access for \n",
|
||||
" record_name at an interest level which defaults to level 0.\n\n",
|
||||
" The -r or -f options cause it to print record type or field lists.\n",
|
||||
" capr.pl [options] -r\n",
|
||||
" capr.pl [options] -f <record type>\n",
|
||||
" capr.pl [options] <record name> [<interest>]\n",
|
||||
"\n",
|
||||
"Options:\n",
|
||||
" -h Prints this help message.\n",
|
||||
" -r Lists all record types in the dbd file.\n",
|
||||
" -f record_type: Lists all fields plus their interest level, data type\n",
|
||||
" and number base for the given record_type.\n",
|
||||
" -d file.dbd: The dbd file containing record type definitions.\n",
|
||||
" This can be set using the EPICS_CAPR_DBD_FILE environment variable.\n",
|
||||
" Currently ", AbsPath($opt_d), "\n",
|
||||
" -w seconds: CA connection timeout, currently $opt_w\n",
|
||||
"\n";
|
||||
" -h Print this help message.\n",
|
||||
"Channel Access options:\n",
|
||||
" -w <sec>: Wait time, specifies CA timeout, default is $opt_w second\n",
|
||||
"Database Definitions:\n",
|
||||
" -d <file.dbd>: The file containing record type definitions.\n",
|
||||
" This can be set using the EPICS_CAPR_DBD_FILE environment variable.\n",
|
||||
" Default: ", AbsPath($opt_d), "\n",
|
||||
"Output Options:\n",
|
||||
" -r Lists all record types in the selected dbd file.\n",
|
||||
" -f <record type>: Lists all fields with their interest level, data type\n",
|
||||
" and number base for the given record_type.\n",
|
||||
"\n",
|
||||
"Base version: ", CA->version, "\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
|
||||
@@ -151,11 +151,11 @@ sub display {
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "\nUsage: caput [options] <PV name> <PV value> ...\n",
|
||||
print STDERR "\nUsage: caput.pl [options] <PV name> <PV value> ...\n",
|
||||
"\n",
|
||||
" -h: Help: Print this message\n",
|
||||
"Channel Access options:\n",
|
||||
" -w <sec>: Wait time, specifies longer CA timeout, default is $opt_w second\n",
|
||||
" -w <sec>: Wait time, specifies CA timeout, default is $opt_w second\n",
|
||||
" -c: Use put_callback to wait for completion\n",
|
||||
"Format options:\n",
|
||||
" -t: Terse mode - print only sucessfully written value, without name\n",
|
||||
@@ -180,7 +180,8 @@ sub HELP_MESSAGE {
|
||||
"Examples:\n",
|
||||
" caput my_channel 1.2\n",
|
||||
" caput my_waveform 1.2 2.4 3.6 4.8 6.0\n",
|
||||
"\n";
|
||||
"\n",
|
||||
"Base version: ", CA->version, "\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# This script is used to extract information about the Perl build
|
||||
# configuration, so the EPICS build system uses the same settings.
|
||||
|
||||
@@ -57,9 +57,9 @@ void putCallback::completion ( epicsGuard < epicsMutex > & guard )
|
||||
// fetch client context and destroy prior to releasing
|
||||
// the lock and calling cb in case they destroy channel there
|
||||
this->chan.getClientCtx().destroyPutCallback ( guard, *this );
|
||||
{
|
||||
if ( pFuncTmp ) {
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
( *pFuncTmp ) ( args );
|
||||
pFuncTmp ( args );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
template < class T >
|
||||
class sgAutoPtr {
|
||||
public:
|
||||
sgAutoPtr ( epicsGuard < epicsMutex > &,
|
||||
struct CASG &, tsDLList < syncGroupNotify > & );
|
||||
sgAutoPtr ( epicsGuard < epicsMutex > &, struct CASG & );
|
||||
~sgAutoPtr ();
|
||||
sgAutoPtr < T > & operator = ( T * );
|
||||
T * operator -> ();
|
||||
@@ -38,18 +37,16 @@ public:
|
||||
T * get ();
|
||||
T * release ();
|
||||
private:
|
||||
tsDLList < syncGroupNotify > & list;
|
||||
T * pNotify;
|
||||
struct CASG & sg;
|
||||
epicsGuard < epicsMutex > & guard;
|
||||
sgAutoPtr & operator = ( const sgAutoPtr & );
|
||||
sgAutoPtr & operator = ( const sgAutoPtr & );
|
||||
};
|
||||
|
||||
template < class T >
|
||||
inline sgAutoPtr < T > :: sgAutoPtr (
|
||||
epicsGuard < epicsMutex > & guardIn,
|
||||
struct CASG & sgIn, tsDLList < syncGroupNotify > & listIn ) :
|
||||
list ( listIn ), pNotify ( 0 ), sg ( sgIn ), guard ( guardIn )
|
||||
epicsGuard < epicsMutex > & guardIn, struct CASG & sgIn ) :
|
||||
pNotify ( 0 ), sg ( sgIn ), guard ( guardIn )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -57,8 +54,9 @@ template < class T >
|
||||
inline sgAutoPtr < T > :: ~sgAutoPtr ()
|
||||
{
|
||||
if ( this->pNotify ) {
|
||||
list.remove ( *this->pNotify );
|
||||
pNotify->destroy ( this->guard, this->sg );
|
||||
this->sg.ioPendingList.remove ( *this->pNotify );
|
||||
this->sg.client.
|
||||
whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,11 +64,12 @@ template < class T >
|
||||
inline sgAutoPtr < T > & sgAutoPtr < T > :: operator = ( T * pNotifyIn )
|
||||
{
|
||||
if ( this->pNotify ) {
|
||||
list.remove ( *this->pNotify );
|
||||
pNotify->destroy ( this->guard, this->sg );
|
||||
this->sg.ioPendingList.remove ( *this->pNotify );
|
||||
this->sg.client.
|
||||
whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify );
|
||||
}
|
||||
this->pNotify = pNotifyIn;
|
||||
list.add ( *this->pNotify );
|
||||
this->sg.ioPendingList.add ( *this->pNotify );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,24 +5,24 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
#ifndef syncGrouph
|
||||
#ifndef syncGrouph
|
||||
#define syncGrouph
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
@@ -46,152 +46,153 @@
|
||||
|
||||
static const unsigned CASG_MAGIC = 0xFAB4CAFE;
|
||||
|
||||
// used to control access to CASG's recycle routines which
|
||||
// should only be indirectly invoked by CASG when its lock
|
||||
// is applied
|
||||
class casgRecycle {
|
||||
public:
|
||||
virtual void recycleSyncGroupWriteNotify (
|
||||
epicsGuard < epicsMutex > &, class syncGroupWriteNotify & io ) = 0;
|
||||
virtual void recycleSyncGroupReadNotify (
|
||||
epicsGuard < epicsMutex > &, class syncGroupReadNotify & io ) = 0;
|
||||
protected:
|
||||
virtual ~casgRecycle ();
|
||||
};
|
||||
|
||||
class syncGroupNotify : public tsDLNode < syncGroupNotify > {
|
||||
public:
|
||||
syncGroupNotify ();
|
||||
virtual void destroy (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
casgRecycle & ) = 0;
|
||||
virtual bool ioPending (
|
||||
virtual void destroy (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard ) = 0;
|
||||
virtual bool ioPending (
|
||||
epicsGuard < epicsMutex > & guard ) = 0;
|
||||
virtual void cancel (
|
||||
epicsGuard < epicsMutex > & guard ) = 0;
|
||||
virtual void show (
|
||||
epicsGuard < epicsMutex > &,
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
|
||||
virtual void show (
|
||||
epicsGuard < epicsMutex > &,
|
||||
unsigned level ) const = 0;
|
||||
protected:
|
||||
virtual ~syncGroupNotify ();
|
||||
syncGroupNotify ( const syncGroupNotify & );
|
||||
syncGroupNotify & operator = ( const syncGroupNotify & );
|
||||
virtual ~syncGroupNotify ();
|
||||
syncGroupNotify ( const syncGroupNotify & );
|
||||
syncGroupNotify & operator = ( const syncGroupNotify & );
|
||||
};
|
||||
|
||||
struct CASG;
|
||||
|
||||
class syncGroupReadNotify : public syncGroupNotify, public cacReadNotify {
|
||||
public:
|
||||
static syncGroupReadNotify * factory (
|
||||
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &,
|
||||
struct CASG &, chid, void *pValueIn );
|
||||
void destroy (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
casgRecycle & );
|
||||
bool ioPending (
|
||||
typedef void ( CASG :: * PRecycleFunc )
|
||||
( epicsGuard < epicsMutex > &, syncGroupReadNotify & );
|
||||
static syncGroupReadNotify * factory (
|
||||
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &,
|
||||
CASG &, PRecycleFunc, chid, void *pValueIn );
|
||||
void destroy (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void begin ( epicsGuard < epicsMutex > &,
|
||||
bool ioPending (
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void begin ( epicsGuard < epicsMutex > &,
|
||||
unsigned type, arrayElementCount count );
|
||||
void cancel (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
|
||||
protected:
|
||||
syncGroupReadNotify ( struct CASG & sgIn, chid, void * pValueIn );
|
||||
syncGroupReadNotify ( CASG & sgIn, PRecycleFunc, chid, void * pValueIn );
|
||||
virtual ~syncGroupReadNotify ();
|
||||
private:
|
||||
chid chan;
|
||||
struct CASG & sg;
|
||||
PRecycleFunc pRecycleFunc;
|
||||
CASG & sg;
|
||||
void * pValue;
|
||||
const unsigned magic;
|
||||
cacChannel::ioid id;
|
||||
bool idIsValid;
|
||||
bool ioComplete;
|
||||
void operator delete ( void * );
|
||||
void * operator new ( size_t,
|
||||
void * operator new ( size_t,
|
||||
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & ))
|
||||
void completion (
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, const void * pData );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
epicsGuard < epicsMutex > &, int status,
|
||||
const char * pContext, unsigned type, arrayElementCount count );
|
||||
syncGroupReadNotify ( const syncGroupReadNotify & );
|
||||
syncGroupReadNotify & operator = ( const syncGroupReadNotify & );
|
||||
syncGroupReadNotify ( const syncGroupReadNotify & );
|
||||
syncGroupReadNotify & operator = ( const syncGroupReadNotify & );
|
||||
};
|
||||
|
||||
class syncGroupWriteNotify : public syncGroupNotify, public cacWriteNotify {
|
||||
public:
|
||||
static syncGroupWriteNotify * factory (
|
||||
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &,
|
||||
struct CASG &, chid );
|
||||
void destroy (
|
||||
epicsGuard < epicsMutex > & guard,
|
||||
casgRecycle & );
|
||||
bool ioPending (
|
||||
typedef void ( CASG :: * PRecycleFunc )
|
||||
( epicsGuard < epicsMutex > &, syncGroupWriteNotify & );
|
||||
static syncGroupWriteNotify * factory (
|
||||
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &,
|
||||
CASG &, PRecycleFunc, chid );
|
||||
void destroy (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void begin ( epicsGuard < epicsMutex > &, unsigned type,
|
||||
bool ioPending (
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void begin ( epicsGuard < epicsMutex > &, unsigned type,
|
||||
arrayElementCount count, const void * pValueIn );
|
||||
void cancel (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
|
||||
protected:
|
||||
syncGroupWriteNotify ( struct CASG &, chid );
|
||||
syncGroupWriteNotify ( struct CASG &, PRecycleFunc, chid );
|
||||
virtual ~syncGroupWriteNotify (); // allocate only from pool
|
||||
private:
|
||||
chid chan;
|
||||
struct CASG & sg;
|
||||
PRecycleFunc pRecycleFunc;
|
||||
CASG & sg;
|
||||
const unsigned magic;
|
||||
cacChannel::ioid id;
|
||||
bool idIsValid;
|
||||
bool ioComplete;
|
||||
void operator delete ( void * );
|
||||
void * operator new ( size_t,
|
||||
void * operator new ( size_t,
|
||||
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & ))
|
||||
void completion ( epicsGuard < epicsMutex > & );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char *pContext,
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char *pContext,
|
||||
unsigned type, arrayElementCount count );
|
||||
syncGroupWriteNotify ( const syncGroupWriteNotify & );
|
||||
syncGroupWriteNotify & operator = ( const syncGroupWriteNotify & );
|
||||
syncGroupWriteNotify ( const syncGroupWriteNotify & );
|
||||
syncGroupWriteNotify & operator = ( const syncGroupWriteNotify & );
|
||||
};
|
||||
|
||||
struct ca_client_context;
|
||||
|
||||
template < class T > class sgAutoPtr;
|
||||
|
||||
struct CASG : public chronIntIdRes < CASG >, private casgRecycle {
|
||||
struct CASG : public chronIntIdRes < CASG > {
|
||||
public:
|
||||
CASG ( epicsGuard < epicsMutex > &, ca_client_context & cacIn );
|
||||
void destructor (
|
||||
void destructor (
|
||||
CallbackGuard &,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
bool ioComplete (
|
||||
bool ioComplete (
|
||||
CallbackGuard &,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
bool verify ( epicsGuard < epicsMutex > & ) const;
|
||||
int block ( epicsGuard < epicsMutex > * pcbGuard,
|
||||
int block ( epicsGuard < epicsMutex > * pcbGuard,
|
||||
epicsGuard < epicsMutex > & guard, double timeout );
|
||||
void reset ( epicsGuard < epicsMutex > & guard );
|
||||
void reset ( CallbackGuard &, epicsGuard < epicsMutex > & );
|
||||
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
|
||||
void show ( unsigned level ) const;
|
||||
void get ( epicsGuard < epicsMutex > &, chid pChan,
|
||||
unsigned type, arrayElementCount count, void * pValue );
|
||||
void put ( epicsGuard < epicsMutex > &, chid pChan,
|
||||
unsigned type, arrayElementCount count, const void * pValue );
|
||||
void completionNotify (
|
||||
void completionNotify (
|
||||
epicsGuard < epicsMutex > &, syncGroupNotify & );
|
||||
int printFormated ( const char * pFormat, ... );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo );
|
||||
void exception (
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
const char * pFileName, unsigned lineNo );
|
||||
void exception (
|
||||
epicsGuard < epicsMutex > &, int status, const char * pContext,
|
||||
const char * pFileName, unsigned lineNo, oldChannelNotify & chan,
|
||||
unsigned type, arrayElementCount count, unsigned op );
|
||||
void * operator new ( size_t size,
|
||||
void * operator new ( size_t size,
|
||||
tsFreeList < struct CASG, 128, epicsMutexNOOP > & );
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
epicsPlacementDeleteOperator (( void *,
|
||||
tsFreeList < struct CASG, 128, epicsMutexNOOP > & ))
|
||||
|
||||
private:
|
||||
tsDLList < syncGroupNotify > ioPendingList;
|
||||
tsDLList < syncGroupNotify > ioCompletedList;
|
||||
@@ -200,18 +201,20 @@ private:
|
||||
unsigned magic;
|
||||
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > freeListReadOP;
|
||||
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > freeListWriteOP;
|
||||
void recycleSyncGroupWriteNotify (
|
||||
epicsGuard < epicsMutex > &, syncGroupWriteNotify & io );
|
||||
void recycleSyncGroupReadNotify (
|
||||
epicsGuard < epicsMutex > &, syncGroupReadNotify & io );
|
||||
|
||||
void destroyPendingIO (
|
||||
void destroyPendingIO (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void destroyCompletedIO (
|
||||
void destroyCompletedIO (
|
||||
CallbackGuard & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard );
|
||||
void recycleReadNotifyIO ( epicsGuard < epicsMutex > &,
|
||||
syncGroupReadNotify & );
|
||||
void recycleWriteNotifyIO ( epicsGuard < epicsMutex > &,
|
||||
syncGroupWriteNotify & );
|
||||
|
||||
CASG ( const CASG & );
|
||||
CASG & operator = ( const CASG & );
|
||||
CASG ( const CASG & );
|
||||
CASG & operator = ( const CASG & );
|
||||
|
||||
void operator delete ( void * );
|
||||
|
||||
@@ -248,27 +251,27 @@ inline void boolFlagManager::release ()
|
||||
this->pBool = 0;
|
||||
}
|
||||
|
||||
inline void * CASG::operator new ( size_t size,
|
||||
inline void * CASG::operator new ( size_t size,
|
||||
tsFreeList < struct CASG, 128, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
return freeList.allocate ( size );
|
||||
}
|
||||
|
||||
#if defined ( CXX_PLACEMENT_DELETE )
|
||||
inline void CASG::operator delete ( void * pCadaver,
|
||||
tsFreeList < struct CASG, 128, epicsMutexNOOP > & freeList )
|
||||
inline void CASG::operator delete ( void * pCadaver,
|
||||
tsFreeList < struct CASG, 128, epicsMutexNOOP > & freeList )
|
||||
{
|
||||
freeList.release ( pCadaver );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool syncGroupWriteNotify::ioPending (
|
||||
inline bool syncGroupWriteNotify::ioPending (
|
||||
epicsGuard < epicsMutex > & /* guard */ )
|
||||
{
|
||||
return ! this->ioComplete;
|
||||
}
|
||||
|
||||
inline bool syncGroupReadNotify::ioPending (
|
||||
inline bool syncGroupReadNotify::ioPending (
|
||||
epicsGuard < epicsMutex > & /* guard */ )
|
||||
{
|
||||
return ! this->ioComplete;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user