Merge lp:~ralph-lange/epics-base/ca-over-tcp into lp:~epics-core/epics-base/3.14
- ca-over-tcp
- Merge into 3.14
Status: | Merged |
---|---|
Merged at revision: | 12092 |
Proposed branch: | lp:~ralph-lange/epics-base/ca-over-tcp |
Merge into: | lp:~epics-core/epics-base/3.14 |
Diff against target: |
3727 lines (+1333/-650) 23 files modified
src/ca/CASG.cpp (+8/-12) src/ca/CAref.html (+168/-155) src/ca/SearchDest.h (+39/-0) src/ca/caProto.h (+4/-1) src/ca/ca_client_context.cpp (+8/-7) src/ca/cac.cpp (+126/-60) src/ca/cac.h (+34/-18) src/ca/iocinf.cpp (+8/-7) src/ca/nciu.h (+1/-1) src/ca/tcpiiu.cpp (+128/-40) src/ca/udpiiu.cpp (+213/-85) src/ca/udpiiu.h (+37/-10) src/ca/virtualCircuit.h (+48/-13) src/cas/generic/caHdrLargeArray.h (+1/-1) src/cas/generic/casStrmClient.cc (+256/-41) src/cas/generic/casStrmClient.h (+77/-71) src/cas/io/bsdSocket/casIntfIO.cc (+33/-34) src/cas/io/bsdSocket/casStreamIO.cc (+20/-25) src/cas/io/bsdSocket/casStreamIO.h (+24/-32) src/libCom/env/envDefs.h (+1/-0) src/rsrv/camessage.c (+74/-15) src/rsrv/caservertask.c (+14/-10) src/rsrv/server.h (+11/-12) |
To merge this branch: | bzr merge lp:~ralph-lange/epics-base/ca-over-tcp |
Related bugs: | |
Related blueprints: |
CA on TCP only connections
(Medium)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrew Johnson | Approve | ||
Jeff Hill | Approve | ||
Review via email: mp+23505@code.launchpad.net |
Commit message
Description of the change
Feature: Run CA over TCP only, so that it can be used through a single TCP tunnel (e.g. an SSH tunnel).
At the Codeathon 2008, Jeff and I were adding the necessary features to the CVS trunk (aka 3.15).
I pulled the changes into a feature branch against 3.14/trunk, so that they can be reviewed and (hopefully) merged into 3.14 soon - Andrew was suggesting this to be a topic at the Codeathon 2010.
I also did some more testing, finding and fixing two issues (bugs) in the 2008 changes.
Ralph Lange (ralph-lange) wrote : | # |
Thanks, Jeff.
I did some testing with a setup of two soft IOCs and the example name
server (that's actually how I found the two issues that were not working
in the 2008 Codeathon version), focussing on how the new feature behaves
in different situations ( IOCs and/or name servers going away and coming
back). I was also running the integration tests all ways (old client -
new server, new client - old server, new client - new server) to make
sure it did't obviously break existing behavior. Admittedly I did not
add any new tests to the test suite, as I found it hard to think of a
reasonable test. Do you have an idea?
If your IMHO remark refers to the bug fixes in the reference manual:
first I was reluctant, but then decided as these were fixing bugs in the
documentation only, it was not worth creating a new branch for that.
If you refer to adding a new feature to the 3.14 series: as I told you,
Andrew wants to discuss at the Codeathon which release this branch
should be merged to. Note that to escape the large number of meaningless
"sync" commit comments in the main CVS trunk, we decided a few months
ago that 3.15 should be developed from forking off the existing 3.14
branch (that has meaningful commit messages). To make this possible,
3.15 only changes in the CVS trunk have to be pulled out into
feature-branches against the 3.14 release - which is exactly what I was
doing with the "ca-over-tcp" feature. Now we can decide if that branch
should be part of 3.14 (before the split) or 3.15 (after the split).
I removed the comment in udpiiu.cpp as you suggested and pushed the
change onto LP.
Cheers,
Ralph
On Fri 14 May 2010 1:34:29 Jeff Hill wrote:
> Review: Approve
>
> Looks fine, but its hard to catch everything with a source code review so testing is important. IMHO its important to keep bug fix changes and new features in different release series, and we seem to be slipping a bit on that level of discipline.
>
> udpiiu.cpp comment on line 278 prob no-longer applies and can be removed
>
- 12053. By Ralph Lange <rlange@nsls2rlange>
-
Removed comment about ellfree @Windows in udpiiu.cpp (suggested by Jeff).
Jeff Hill (johill-lanl) wrote : | # |
Hi Ralph,
Sorry about the "sync" commits on the main trunk. Certainly this is in retrospect a bit lazy on my part and I will need to be better in the future. However in my defense, the vast majority of the "sync" commits were for new code - the new server and the atomic primitives in libCom. The vast majority of the rest of them were related to epics mutex name space changes in src/ca.
I was writing code quickly and using the SCC system to transfer back and forth from my home to my workplace. For that type of development when the commit is occurring only to transfer the code between my house and my workplace the minutia comments are less beneficial (it can be hard to come up with insightful comments when you are tired, and leaving late). Note that this was work on new features and not patches. We definitely need the SCC comments for tracking patches. I do see that doing such developments on branches works better. I anticipate that the merge is going to take some extra work however.
The changes to the reference manual are fine. My concern is about maintaining quality in the production system, and from my perspective that can only be achieved if we make major releases on a slower schedule and then keep patching them until they are nearly perfect. My concern is that adding features to a patch series introduces quality control risk.
Thanks,
Jeff
> Thanks, Jeff.
>
> I did some testing with a setup of two soft IOCs and the example name
> server (that's actually how I found the two issues that were not working
> in the 2008 Codeathon version), focussing on how the new feature behaves
> in different situations ( IOCs and/or name servers going away and coming
> back). I was also running the integration tests all ways (old client -
> new server, new client - old server, new client - new server) to make
> sure it did't obviously break existing behavior. Admittedly I did not
> add any new tests to the test suite, as I found it hard to think of a
> reasonable test. Do you have an idea?
>
> If your IMHO remark refers to the bug fixes in the reference manual:
> first I was reluctant, but then decided as these were fixing bugs in the
> documentation only, it was not worth creating a new branch for that.
>
> If you refer to adding a new feature to the 3.14 series: as I told you,
> Andrew wants to discuss at the Codeathon which release this branch
> should be merged to. Note that to escape the large number of meaningless
> "sync" commit comments in the main CVS trunk, we decided a few months
> ago that 3.15 should be developed from forking off the existing 3.14
> branch (that has meaningful commit messages). To make this possible,
> 3.15 only changes in the CVS trunk have to be pulled out into
> feature-branches against the 3.14 release - which is exactly what I was
> doing with the "ca-over-tcp" feature. Now we can decide if that branch
> should be part of 3.14 (before the split) or 3.15 (after the split).
>
> I removed the comment in udpiiu.cpp as you suggested and pushed the
> change onto LP.
>
> Cheers,
> Ralph
>
>
> On Fri 14 May 2010 1:34:29 Jeff Hill wrote:
> > Review: Approve
> >
> > Looks fine, but its hard to catch everything with a sou...
Andrew Johnson (anj) wrote : | # |
Hi Ralph,
I started trying to merge branch this today. I added a default value ("") for EPICS_CA_
I'm getting a compile errors from my vxWorks builds, both 5.5.2 and 6.8. VxWorks 5.5.2 complains about line 613 in cac.cpp:
bool newIIU = findOrCreateVir
guard, addr,
The last argument 'false' should be deleted as the prototype expects a pointer that defaults to 0. I don't know why the other arch's don't object to this, I guess they manage to convert the false into a NULL pointer.
5.5.2 also complains about udpiiu.cpp:
../udpiiu.cpp: In method `void udpiiu:
../udpiiu.h:153: `class epicsMutex & udpiiu::cacMutex' is private
../udpiiu.cpp:919: within this context
../udpiiu.h:160: `SOCKET udpiiu::sock' is private
../udpiiu.cpp:923: within this context
../udpiiu.h:164: `bool udpiiu:
../udpiiu.cpp:936: within this context
../udpiiu.cpp: In method `void udpiiu:
../udpiiu.h:153: `class epicsMutex & udpiiu::cacMutex' is private
../udpiiu.cpp:970: within this context
../udpiiu.cpp: In method `void udpiiu:
../udpiiu.h:162: `ca_uint16_t udpiiu::serverPort' is private
../udpiiu.cpp:1033: within this context
../udpiiu.h:151: `class cac & udpiiu::cacRef' is private
../udpiiu.cpp:1038: within this context
../udpiiu.h:151: `class cac & udpiiu::cacRef' is private
../udpiiu.cpp:1043: within this context
../udpiiu.cpp: In method `void udpiiu:
../udpiiu.h:153: `class epicsMutex & udpiiu::cacMutex' is private
../udpiiu.cpp:1052: within this context
It isn't giving member functions of nested classes access to their parent class private data members, which I can fix by adding a couple of friend definitions to class udpiiu in udpiiu.h:
friend class udpiiu:
friend class udpiiu:
With that change, vxWorks 5.5.2 builds OK.
VxWorks 6.8 also complains about udpiiu.cpp:
../udpiiu.cpp: In member function 'virtual void udpiiu:
../udpiiu.cpp:924: error: invalid conversion from 'const char*' to 'char*'
../udpiiu.cpp:924: error: initializing argument 2 of 'int sendto(int, char*, int, int, sockaddr*, int)'
The relevant code is:
void udpiiu :: SearchDestUDP :: searchRequest (
{
...
int status = sendto ( _udpiiu.sock, pBuf, bufSizeAsInt, 0,
& _destAddr.sa, sizeof ( _destAddr.sa ) );
In vxWorks the second argument to sendto() is not marked as const. Adding a const_cast<char *> around the argument is ugly, but the alternative was requiring changes to too many other files for me to finish exploring it. With that change vxWorks 6.8 finished building OK...
Ralph Lange (ralph-lange) wrote : | # |
Hi Andrew,
these fixes sound fine to me - please go ahead and commit them.
I'm especially sorry about the boolean vs. pointer issue - iirc that was one of my latest prototype changes that I obviously did not apply to all usages.
My test setup was running two standard (base) soft IOCs and the example name server. After starting a camonitor client connecting to one of the IOCs by UDP (through CA_ADDR_LIST) and the other IOC through the name server, you can check the behavior when IOCs and/or name server go down and come back for different combinations of the env variable settings.
Jeff is probably the only one who built this on Windows.
Thanks a lot!
Ralph
Preview Diff
1 | === modified file 'src/ca/CASG.cpp' |
2 | --- src/ca/CASG.cpp 2007-08-23 17:46:28 +0000 |
3 | +++ src/ca/CASG.cpp 2010-05-14 13:38:34 +0000 |
4 | @@ -1,16 +1,15 @@ |
5 | /*************************************************************************\ |
6 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
7 | -* National Laboratory. |
8 | -* Copyright (c) 2002 The Regents of the University of California, as |
9 | -* Operator of Los Alamos National Laboratory. |
10 | -* EPICS BASE Versions 3.13.7 |
11 | -* and higher are distributed subject to a Software License Agreement found |
12 | -* in file LICENSE that is included with this distribution. |
13 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
14 | + * National Laboratory. |
15 | + * Copyright (c) 2002 The Regents of the University of California, as |
16 | + * Operator of Los Alamos National Laboratory. |
17 | + * EPICS BASE Versions 3.13.7 |
18 | + * and higher are distributed subject to a Software License Agreement found |
19 | + * in file LICENSE that is included with this distribution. |
20 | \*************************************************************************/ |
21 | + |
22 | /* |
23 | * Author: Jeffrey O. Hill |
24 | - * hill@luke.lanl.gov |
25 | - * (505) 665 1831 |
26 | */ |
27 | |
28 | #include <string> |
29 | @@ -314,6 +313,3 @@ |
30 | errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", |
31 | __FILE__, __LINE__ ); |
32 | } |
33 | - |
34 | - |
35 | - |
36 | |
37 | === modified file 'src/ca/CAref.html' |
38 | --- src/ca/CAref.html 2009-12-15 22:42:57 +0000 |
39 | +++ src/ca/CAref.html 2010-05-14 13:38:34 +0000 |
40 | @@ -19,25 +19,25 @@ |
41 | |
42 | <h1>EPICS R3.14 Channel Access Reference Manual</h1> |
43 | <address> |
44 | - Jeffrey O. Hill |
45 | + Jeffrey O. Hill |
46 | </address> |
47 | |
48 | <p><span style="font-size: x-small; font-weight:lighter;">Los Alamos National |
49 | Laboratory, SNS Division</span></p> |
50 | <address> |
51 | - Ralph Lange |
52 | + Ralph Lange |
53 | </address> |
54 | |
55 | <p><span style="font-size: x-small; font-weight:lighter;">Helmholtz-Zentrum |
56 | Berlin (BESSY II)</span></p> |
57 | |
58 | -<p><span style="font-size: xx-small; font-weight:lighter;">Copyright © 2009 |
59 | -Helmholtz-Zentrum Berlin für Materialien und Energie GmbH.<br> |
60 | -Copyright © 2002 The University of Chicago, as Operator of Argonne National |
61 | +<p><span style="font-size: xx-small; font-weight:lighter;">Copyright © 2009 |
62 | +Helmholtz-Zentrum Berlin für Materialien und Energie GmbH.<br> |
63 | +Copyright © 2002 The University of Chicago, as Operator of Argonne National |
64 | Laboratory.<br> |
65 | -Copyright © 2002 The Regents of the University of California, as Operator of |
66 | +Copyright © 2002 The Regents of the University of California, as Operator of |
67 | Los Alamos National Laboratory.<br> |
68 | -Copyright © 2002 Berliner Speicherringgesellschaft für Synchrotronstrahlung |
69 | +Copyright © 2002 Berliner Speicherringgesellschaft für Synchrotronstrahlung |
70 | GmbH.</span></p> |
71 | |
72 | <p><span style="font-size: xx-small; font-weight:lighter;">EPICS BASE Versions |
73 | @@ -105,7 +105,7 @@ |
74 | |
75 | <h3><a href="#Troublesho">Troubleshooting</a></h3> |
76 | <ul> |
77 | - <li><a href="#When">When Clients Do Not Connect to Their Server</a> |
78 | + <li><a href="#When">When Clients Do Not Connect to Their Server</a> |
79 | <ul> |
80 | <li><a href="#Broadcast">Client and Server Broadcast Addresses Dont |
81 | Match</a></li> |
82 | @@ -136,7 +136,7 @@ |
83 | <li><a href="#Connection">Connection Management</a></li> |
84 | <li><a href="#Thread">Thread Safety and Preemptive Callback to User |
85 | Code</a></li> |
86 | - <li><a href="#Client2">CA Client Contexts and Application Specific Auxillary |
87 | + <li><a href="#Client2">CA Client Contexts and Application Specific Auxiliary |
88 | Threads</a></li> |
89 | <li><a href="#Polling">Polling the CA Client Library From Single Threaded |
90 | Applications</a></li> |
91 | @@ -148,7 +148,7 @@ |
92 | handlers</a></li> |
93 | </ul> |
94 | |
95 | -<h3>Functionality Index </h3> |
96 | +<h3>Functionality Index</h3> |
97 | <ul> |
98 | <li><a href="#ca_context_create">create CA client context</a></li> |
99 | <li><a href="#ca_context_destroy">terminate CA client context</a></li> |
100 | @@ -158,7 +158,7 @@ |
101 | <li><a href="#ca_put">write to a channel and wait for initiated activities to |
102 | complete</a></li> |
103 | <li><a href="#ca_get">read from a channel</a></li> |
104 | - <li><a href="#ca_add_event">subscribe for state change updates</a></li> |
105 | + <li><a href="#ca_add_event">subscribe for state change updates</a></li> |
106 | <li><a href="#ca_clear_event">cancel a subscription</a></li> |
107 | <li><a href="#ca_pend_io">block for certain requests to complete</a></li> |
108 | <li><a href="#ca_test_io">test to see if certain requests have |
109 | @@ -178,13 +178,13 @@ |
110 | <li><a href="#ca_get">ca_array_get_callback</a></li> |
111 | <li><a href="#ca_put">ca_array_put</a></li> |
112 | <li><a href="#ca_put">ca_array_put_callback</a></li> |
113 | - <li><a href="#ca_attach_context">ca_attach_context </a></li> |
114 | + <li><a href="#ca_attach_context">ca_attach_context</a></li> |
115 | <li><a href="#ca_clear_channel">ca_clear_channel</a></li> |
116 | <li><a href="#ca_clear_event">ca_clear_subscription</a></li> |
117 | <li><a href="#ca_client_status">ca_client_status</a></li> |
118 | <li><a href="#ca_context_create">ca_context_create</a></li> |
119 | <li><a href="#ca_context_destroy">ca_context_destroy</a></li> |
120 | - <li><a href="CAref.html#ca_client_status">ca_context_status</a></li> |
121 | + <li><a href="#ca_client_status">ca_context_status</a></li> |
122 | <li><a href="#ca_create_channel">ca_create_channel</a></li> |
123 | <li><a href="#ca_add_event">ca_create_subscription</a></li> |
124 | <li><a href="#ca_current_context">ca_current_context</a></li> |
125 | @@ -283,6 +283,11 @@ |
126 | <td>YES</td> |
127 | </tr> |
128 | <tr> |
129 | + <td>EPICS_CA_NAME_SERVERS</td> |
130 | + <td>{N.N.N.N N.N.N.N:P ...}</td> |
131 | + <td><none></td> |
132 | + </tr> |
133 | + <tr> |
134 | <td>EPICS_CA_CONN_TMO</td> |
135 | <td>r > 0.1 seconds</td> |
136 | <td>30.0</td> |
137 | @@ -299,7 +304,7 @@ |
138 | </tr> |
139 | <tr> |
140 | <td>EPICS_CA_SERVER_PORT</td> |
141 | - <td>i > 5000</td> |
142 | + <td>i > 5000</td> |
143 | <td>5064</td> |
144 | </tr> |
145 | <tr> |
146 | @@ -327,7 +332,7 @@ |
147 | <tbody> |
148 | <tr> |
149 | <td>C shell</td> |
150 | - <td>setenv EPICS_CA_ADDR_LIST 1.2.3.4</td> |
151 | + <td>setenv EPICS_CA_ADDR_LIST 1.2.3.4</td> |
152 | </tr> |
153 | <tr> |
154 | <td>bash</td> |
155 | @@ -335,7 +340,7 @@ |
156 | </tr> |
157 | <tr> |
158 | <td>vxWorks shell</td> |
159 | - <td>putenv ( "EPICS_CA_ADDR_LIST =1.2.3.4" )</td> |
160 | + <td>putenv ( "EPICS_CA_ADDR_LIST=1.2.3.4" )</td> |
161 | </tr> |
162 | <tr> |
163 | <td>DOS command line</td> |
164 | @@ -352,7 +357,7 @@ |
165 | |
166 | <p>Normally in a local area network (LAN) environment CA discovers the address |
167 | of the host for an EPICS process variable by broadcasting frames containing a |
168 | -list of channel names ( CA search messages ) and waiting for responses from the |
169 | +list of channel names (CA search messages) and waiting for responses from the |
170 | servers that host the channels identified. Likewise CA clients efficiently |
171 | discover that CA servers have recently joined the LAN or disconnected from the |
172 | LAN by monitoring periodically broadcasted beacons sent out by the servers. |
173 | @@ -362,7 +367,7 @@ |
174 | |
175 | <h3><a name="Network">IP Network Administration Background Information</a></h3> |
176 | |
177 | -<p>Channel Access is implemented using internet protocols (IP). IP addresses |
178 | +<p>Channel Access is implemented using internet protocols (IP). IP addresses |
179 | are divided into host and network portions. The boundary between each portion |
180 | is determined by the IP netmask. Portions of the IP address corresponding to |
181 | zeros in the netmask specify the hosts address within an IP subnet. Portions of |
182 | @@ -415,7 +420,7 @@ |
183 | site might set up an operational control system and a test control system on |
184 | the same network. In this situation it is desirable for the test system and the |
185 | operational system to use identical PV names without fear of collision. A site |
186 | -might also configure the CA port numbers because some other facility is already |
187 | +might also configure the CA port numbers because some other facility is already |
188 | using the default port numbers. The default Channel Access port numbers have |
189 | been registered with IANA.</p> |
190 | |
191 | @@ -464,23 +469,31 @@ |
192 | broadcast address of that subnet is added to the list. For each point to point |
193 | interface found, the destination address of that link is added to the list. |
194 | This automatic server address list initialization can be disabled if the EPICS |
195 | -environment variable "EPICS_CA_AUTO_ADDR_LIST" exists and its value is either |
196 | +environment variable EPICS_CA_AUTO_ADDR_LIST exists and its value is either |
197 | of "no" or "NO". The typical default is to enable network interface |
198 | -introspection driven initialization with "EPICS_CA_AUTO_ADDR_LIST" set to "YES" |
199 | +introspection driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES" |
200 | or "yes".</p> |
201 | |
202 | <p>Following network interface introspection, any IP addresses specified in the |
203 | EPICS environment variable EPICS_CA_ADDR_LIST are added to the list of |
204 | destination addresses for CA client name resolution requests. In an EPICS |
205 | system crossing multiple subnets the EPICS_CA_ADDR_LIST must be set so that CA |
206 | -name resolution ( search requests ) frames pass from CA clients to the targeted |
207 | +name resolution (search requests) frames pass from CA clients to the targeted |
208 | CA servers unless a CA proxy (gateway) is installed. The addresses in |
209 | EPICS_CA_ADDR_LIST may be dotted IP addresses or host names if the local OS has |
210 | support for host name to IP address translation. When multiple names are added |
211 | to EPICS_CA_ADDR_LIST they must be separated by white space. There is no |
212 | -requirement that the addresses specified in the EPICS_CA_ADDR_LIST be a |
213 | +requirement that the addresses specified in the EPICS_CA_ADDR_LIST be |
214 | broadcast addresses, but this will often be the most convenient choice.</p> |
215 | |
216 | +<p>For any IP addresses specified in the EPICS environment variable |
217 | +EPICS_CA_NAME_SERVERS, TCP connections are opened and used for CA client name |
218 | +resolution requests. (Thus, broadcast addresses are not allowed in |
219 | +EPICS_CA_NAME_SERVERS.) When used in combination with an empty |
220 | +EPICS_CA_ADDR_LIST and EPICS_CA_AUTO_ADDR_LIST set to "NO", Channel Access can |
221 | +be run without using UDP for name resolution. Such an TCP-only mode allows for |
222 | +Channel Access to work e.g. through SSH tunnels.</p> |
223 | + |
224 | <table border="1"> |
225 | <tbody> |
226 | <tr> |
227 | @@ -716,7 +729,7 @@ |
228 | EPICS_CA_MAX_ARRAY_BYTES determines the size of the largest array that may pass |
229 | through CA. Prior to this version only arrays smaller than 16k bytes could be |
230 | transfered. The CA libraries maintains a free list of 16384 byte network |
231 | -buffers that are used for ordinary communication. If EPICS_CA_MAX_ARRAY_BYTES |
232 | +buffers that are used for ordinary communication. If EPICS_CA_MAX_ARRAY_BYTES |
233 | is larger than 16384 then a second free list of larger data buffers is |
234 | established and used only after a client send its first large array request.</p> |
235 | |
236 | @@ -751,7 +764,7 @@ |
237 | </tr> |
238 | <tr> |
239 | <td>EPICS_CAS_SERVER_PORT</td> |
240 | - <td>i > 5000</td> |
241 | + <td>i > 5000</td> |
242 | <td>EPICS_CA_SERVER_PORT</td> |
243 | </tr> |
244 | <tr> |
245 | @@ -766,12 +779,12 @@ |
246 | </tr> |
247 | <tr> |
248 | <td>EPICS_CAS_BEACON_PERIOD</td> |
249 | - <td>r > 0.1 seconds</td> |
250 | + <td>r > 0.1 seconds</td> |
251 | <td>EPICS_CA_BEACON_PERIOD</td> |
252 | </tr> |
253 | <tr> |
254 | <td>EPICS_CAS_BEACON_PORT</td> |
255 | - <td>i > 5000</td> |
256 | + <td>i > 5000</td> |
257 | <td>EPICS_CA_REPEATER_PORT</td> |
258 | </tr> |
259 | <tr> |
260 | @@ -824,8 +837,8 @@ |
261 | list is not augmented.</p> |
262 | |
263 | <p>The EPICS_CAS_BEACON_PORT parameter specifies the destination port for |
264 | -server beacons. The only exception to this occurs when ports are specified in |
265 | -EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If |
266 | +server beacons. The only exception to this occurs when ports are specified |
267 | +in EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If |
268 | EPICS_CAS_BEACON_PORT is not specified then beacons are sent to the port |
269 | specified in EPICS_CA_REPEATER_PORT.</p> |
270 | |
271 | @@ -846,7 +859,7 @@ |
272 | |
273 | <p>Name resolution requests originating from any of the IP addresses specified |
274 | in the EPICS_CAS_IGNORE_ADDR_LIST parameter are not replied to.<em>In R3.14 and |
275 | -previous releases the CA server employed by iocCore does not implemet this |
276 | +previous releases the CA server employed by iocCore does not implement this |
277 | feature.</em></p> |
278 | |
279 | <h4>Client Configuration that also Applies to Servers</h4> |
280 | @@ -1082,11 +1095,11 @@ |
281 | </tr> |
282 | <tr> |
283 | <td>-w <sec></td> |
284 | - <td>Wait time, specifies CA timeout, default is 1.0 second(s)</td> |
285 | + <td>Wait time, specifies longer CA timeout, default is 1.0 second</td> |
286 | </tr> |
287 | <tr> |
288 | <td>-c</td> |
289 | - <td>Asynchronous get (use ca_get_callback and wait for completion)</td> |
290 | + <td>Asynchronous get (use ca_get_callback instead of ca_get)</td> |
291 | </tr> |
292 | <tr> |
293 | <td>-p <prio></td> |
294 | @@ -1115,7 +1128,7 @@ |
295 | </tr> |
296 | <tr> |
297 | <td>-d <type></td> |
298 | - <td>Request specific dbr type; use string (DBR_ prefix may be omitted) |
299 | + <td>Request specific dbr type; use string (DBR_ prefix may be omitted) |
300 | |
301 | <p>or number of one of the following types:</p> |
302 | |
303 | @@ -1341,7 +1354,7 @@ |
304 | </tr> |
305 | <tr> |
306 | <td>-w <sec></td> |
307 | - <td>Wait time, specifies CA timeout, default is 1.0 second(s)</td> |
308 | + <td>Wait time, specifies longer CA timeout, default is 1.0 second</td> |
309 | </tr> |
310 | <tr> |
311 | <td>-m <mask></td> |
312 | @@ -1495,7 +1508,7 @@ |
313 | </tr> |
314 | <tr> |
315 | <td>-w <sec></td> |
316 | - <td>Wait time, specifies CA timeout, default is 1.0 second(s)</td> |
317 | + <td>Wait time, specifies longer CA timeout, default is 1.0 second</td> |
318 | </tr> |
319 | <tr> |
320 | <td>-c</td> |
321 | @@ -1583,7 +1596,7 @@ |
322 | </tr> |
323 | <tr> |
324 | <td>-w <sec></td> |
325 | - <td>Wait time, specifies CA timeout, default is 1.0 second(s)</td> |
326 | + <td>Wait time, specifies longer CA timeout, default is 1.0 second</td> |
327 | </tr> |
328 | <tr> |
329 | <td>-s <level></td> |
330 | @@ -1973,8 +1986,8 @@ |
331 | <p>If the subscription update producer in the server produces subscription |
332 | updates faster than the subscription update consumer in the client consumes |
333 | them, then events have to be discarded if the buffering in the server |
334 | -isn’t allowed to grow to an infinite size. This is a law of nature |
335 | -– based on queuing theory of course.</p> |
336 | +isn't allowed to grow to an infinite size. This is a law of nature |
337 | +- based on queuing theory of course.</p> |
338 | |
339 | <p>What is done depends on the version of the CA server. All server versions |
340 | place quotas on the maximum number of subscription updates allowed on the |
341 | @@ -1996,10 +2009,10 @@ |
342 | getting time warped, but also guarantees that intervening events are discarded |
343 | until the slow client catches up.</p> |
344 | |
345 | -<p>There is currently no message on the IOC’s console when a particular |
346 | -client is slow on the uptake. A message of this type used to exist many years |
347 | -ago, but it was a source of confusion (and what we will call message noise) so |
348 | -it was removed. </p> |
349 | +<p>There is currently no message on the IOC's console when a |
350 | +particular client is slow on the uptake. A message of this type used to exist |
351 | +many years ago, but it was a source of confusion (and what we will call |
352 | +message noise) so it was removed. </p> |
353 | |
354 | <p>There is unfortunately no field in the protocol allowing the server to |
355 | indicate that an intervening subscription update was discarded. We should |
356 | @@ -2212,7 +2225,7 @@ |
357 | #include "cadef.h" |
358 | |
359 | int main ( int argc, char ** argv ) |
360 | -{ |
361 | +{ |
362 | struct dbr_time_double * pTD; |
363 | const dbr_double_t * pValue; |
364 | unsigned nBytes; |
365 | @@ -2222,12 +2235,12 @@ |
366 | chid chan; |
367 | double sum; |
368 | int status; |
369 | - |
370 | + |
371 | if ( argc != 2 ) { |
372 | fprintf ( stderr, "usage: %s <channel name>", argv[0] ); |
373 | return -1; |
374 | } |
375 | - |
376 | + |
377 | status = ca_create_channel ( argv[1], 0, 0, 0, & chan ); |
378 | SEVCHK ( status, "ca_create_channel()" ); |
379 | status = ca_pend_io ( 15.0 ); |
380 | @@ -2243,7 +2256,7 @@ |
381 | fprintf ( stderr, "insufficient memory to complete request\n" ); |
382 | return -1; |
383 | } |
384 | - |
385 | + |
386 | status = ca_array_get ( DBR_TIME_DOUBLE, elementCount, chan, pTD ); |
387 | SEVCHK ( status, "ca_array_get()" ); |
388 | status = ca_pend_io ( 15.0 ); |
389 | @@ -2251,23 +2264,23 @@ |
390 | fprintf ( stderr, "\"%s\" didnt return a value.\n", argv[1] ); |
391 | return -1; |
392 | } |
393 | - |
394 | - pValue = & pTD->value; |
395 | - sum = 0.0; |
396 | - for ( i = 0; i < elementCount; i++ ) { |
397 | - sum += pValue[i]; |
398 | + |
399 | + pValue = & pTD->value; |
400 | + sum = 0.0; |
401 | + for ( i = 0; i < elementCount; i++ ) { |
402 | + sum += pValue[i]; |
403 | } |
404 | - |
405 | + |
406 | epicsTimeToStrftime ( timeString, sizeof ( timeString ), |
407 | "%a %b %d %Y %H:%M:%S.%f", & pTD->stamp ); |
408 | |
409 | printf ( "The sum of elements in %s at %s was %f\n", |
410 | argv[1], timeString, sum ); |
411 | - |
412 | + |
413 | ca_clear_channel ( chan ); |
414 | ca_task_exit (); |
415 | free ( pTD ); |
416 | - |
417 | + |
418 | return 0; |
419 | }</code></pre> |
420 | |
421 | @@ -2310,7 +2323,7 @@ |
422 | <h3><a name="Channel1">Channel Access Exceptions</a></h3> |
423 | |
424 | <p>When the server detects a failure, and there is no client call back function |
425 | -attached to the request, then an exception handler is executed in the client. |
426 | +attached to the request, an exception handler is executed in the client. |
427 | The default exception handler prints a message on the console and exits if the |
428 | exception condition is severe. Certain internal exceptions within the CA client |
429 | library, and failures detected by the SEVCHK macro may also cause the exception |
430 | @@ -2332,8 +2345,8 @@ |
431 | <h3><a name="Arrays">Arrays</a></h3> |
432 | |
433 | <p>For routines that require an argument specifying the number of array |
434 | -elements, no more than the process variable's maximum native element count may |
435 | -be requested. The process variable's maximum native element count is available |
436 | +elements, no more than the process variable's maximum native element count may |
437 | +be requested. The process variable's maximum native element count is available |
438 | from ca_element_count() when the channel is connected. If less elements than |
439 | the process variable's native element count are requested the requested values |
440 | will be fetched beginning at element zero. By default CA limits the number of |
441 | @@ -2376,19 +2389,19 @@ |
442 | |
443 | <p>Starting with EPICS R3.14 the CA client libraries are fully thread safe on |
444 | all OS (in past releases the library was thread safe only on vxWorks). When the |
445 | -client library is initialized the programmer may specify if preemptive call |
446 | -back is enabled. Preemptive call back is disabled by default. If preemptive |
447 | -call back is enabled then the user's call back functions might be called by |
448 | +client library is initialized the programmer may specify if preemptive callback |
449 | +is to be enabled. Preemptive callback is disabled by default. If preemptive |
450 | +callback is enabled, then the user's callback functions might be called by |
451 | CA's auxiliary threads when the main initiating channel access thread is not |
452 | inside of a function in the channel access client library. Otherwise, the |
453 | -user's call back functions will be called only when the main initiating channel |
454 | +user's callback functions will be called only when the main initiating channel |
455 | access thread is executing inside of the CA client library. When the CA client |
456 | -library invokes a user's call back function it will always wait for the current |
457 | -callback to complete prior to executing another call back function. Programmers |
458 | +library invokes a user's callback function, it will always wait for the current |
459 | +callback to complete prior to executing another callback function. Programmers |
460 | enabling preemptive callback should be familiar with using mutex locks to |
461 | create a reliable multi-threaded program.</p> |
462 | |
463 | -<p>To set up a traditional single threaded client you will need code like this |
464 | +<p>To set up a traditional single threaded client, you will need code like this |
465 | (see <a href="#ca_context_create">ca_context_create</a> and <a |
466 | href="#Client2">CA Client Contexts and Application Specific Auxiliary |
467 | Threads</a>) .</p> |
468 | @@ -2412,7 +2425,7 @@ |
469 | database CA links and the sequencer are designed to not use the same CA client |
470 | library threads, network circuits, and data structures. Each thread that calls |
471 | <a href="#ca_context_create">ca_context_create()</a> for the first time either |
472 | -directly, or implicitly when calling any CA library function for the first |
473 | +directly or implicitly when calling any CA library function for the first |
474 | time, creates a CA client library context. A CA client library context contains |
475 | all of the threads, network circuits, and data structures required to connect |
476 | and communicate with the channels that a CA client application has created. The |
477 | @@ -2432,6 +2445,7 @@ |
478 | with a CA context it need only make ordinary ca_xxxx() library calls to use the |
479 | context.</p> |
480 | |
481 | + |
482 | <p>A CA client library context can be shut down and cleaned up, after |
483 | destroying any channels or application specific threads that are attached to |
484 | it, by calling <a href="#ca_context_destroy">ca_context_destroy()</a>. The |
485 | @@ -2484,9 +2498,9 @@ |
486 | <ul> |
487 | <li>The vxWorks shell thread runs at the very highest priority in the system |
488 | and therefore socket calls are made at a priority that is above the |
489 | - priority of tNetTask − a practice that has caused the WRS IP kernel |
490 | + priority of tNetTask - a practice that has caused the WRS IP kernel |
491 | to get sick in the past. That symptom was observed some time ago, but we |
492 | - don’t know if WRS has fixed the problem.</li> |
493 | + don't know if WRS has fixed the problem.</li> |
494 | </ul> |
495 | <ul> |
496 | <li>The vxWorks shell thread runs at the very highest priority in the system |
497 | @@ -2501,7 +2515,7 @@ |
498 | <ul> |
499 | <li>In EPICS R3.13 the CA client library installed vxWorks task exit handlers |
500 | behaved strangely if CA functions were called from the vxWorks shell, |
501 | - ca_task_exit() wasn’t called, and the vxWorks shell restarted. In |
502 | + ca_task_exit() wasn't called, and the vxWorks shell restarted. In |
503 | EPICS R3.14 vxWorks task exit handlers are not installed and therefore |
504 | cleanup is solely the responsibility of the user. With EPICS R3.14 the user |
505 | must call ca_context_destroy or ca_task_exit to clean up on vxWorks. This |
506 | @@ -2584,7 +2598,7 @@ |
507 | |
508 | <h4>Description</h4> |
509 | |
510 | -<p>Shut down the calling thread's channel access client context and free any |
511 | +<p>Shut down the calling thread's channel access client context and free any |
512 | resources allocated. Detach the calling thread from any CA client context.</p> |
513 | |
514 | <p>Any user-created threads that have attached themselves to the CA context |
515 | @@ -2637,8 +2651,8 @@ |
516 | on a channel.</p> |
517 | |
518 | <p>The circuit may be initially connected or disconnected depending on the |
519 | -state of the network and the location of the channel. A channel will only enter |
520 | -a connected state after server's address is determined, and only if channel |
521 | +state of the network and the location of the channel. A channel will only enter |
522 | +a connected state after server's address is determined, and only if channel |
523 | access successfully establishes a virtual circuit through the network to the |
524 | server. Channel access routines that send a request to a server will return |
525 | ECA_DISCONNCHID if the channel is currently disconnected.</p> |
526 | @@ -2676,7 +2690,7 @@ |
527 | <dd>A nil terminated process variable name string. EPICS process control |
528 | function block database variable names are of the form "<record |
529 | name>.<field name>". If the field name and the period separator |
530 | - are omitted then the "VAL" field is implicit. For example "RFHV01" and |
531 | + are omitted then the "VAL" field is implicit. For example "RFHV01" and |
532 | "RFHV01.VAL" reference the same EPICS process control function block |
533 | database variable.</dd> |
534 | </dl> |
535 | @@ -2685,7 +2699,7 @@ |
536 | <dd>Optional address of the user's call back function to be run when the |
537 | connection state changes. Casual users of channel access may decide to |
538 | set this field to nil or 0 if they do not need to have a call back |
539 | - function run in response to each connection state change event. |
540 | + function run in response to each connection state change event. |
541 | <p>The following structure is passed <em>by value </em>to the user's |
542 | connection connection callback function. The <code>op</code> field will |
543 | be set by the CA client library to <code>CA_OP_CONN_UP</code> when the |
544 | @@ -2701,8 +2715,8 @@ |
545 | </dl> |
546 | <dl> |
547 | <dt><code>PUSER</code></dt> |
548 | - <dd>The value of this void pointer argument is retained in |
549 | - storage associated with the specified channel. See the MACROS manual page |
550 | + <dd>The value of this void pointer argument is retained in |
551 | + storage associated with the specified channel. See the MACROS manual page |
552 | for reading and writing this field. Casual users of channel access may |
553 | wish to set this field to nil or 0.</dd> |
554 | </dl> |
555 | @@ -2743,7 +2757,7 @@ |
556 | |
557 | <h4>Description</h4> |
558 | |
559 | -<p>Shutdown and reclaim resources associated with a channel created by |
560 | +<p>Shutdown and reclaim resources associated with a channel created by |
561 | ca_create_channel().</p> |
562 | |
563 | <p>All remote operation requests such as the above are accumulated (buffered) |
564 | @@ -2753,7 +2767,7 @@ |
565 | |
566 | <p>Clearing a channel does not cause its disconnect handler to be called, but |
567 | clearing a channel does shutdown and reclaim any channel state change event |
568 | -subscriptions (monitors) registered with the channel.</p> |
569 | +subscriptions (monitors) registered with the channel.</p> |
570 | |
571 | <h4>Arguments</h4> |
572 | <dl> |
573 | @@ -2787,13 +2801,13 @@ |
574 | |
575 | <p>Write a scalar or array value to a process variable.</p> |
576 | |
577 | -<p>When ca_array_put or ca_put are invoked the client will receive no response |
578 | +<p>When ca_array_put or ca_put are invoked the client will receive no response |
579 | unless the request can not be fulfilled in the server. If unsuccessful an |
580 | -exception handler is run on the client side. </p> |
581 | +exception handler is run on the client side.</p> |
582 | |
583 | <p>When ca_array_put_callback are invoked the user supplied asynchronous call |
584 | -back is called only after the initiated write operation, and all actions |
585 | -resulting from the initiating write operation, complete.</p> |
586 | +back is called only after the initiated write operation, and all actions |
587 | +resulting from the initiating write operation, complete.</p> |
588 | |
589 | <p>If unsuccessful the call back function is invoked indicating failure status. |
590 | </p> |
591 | @@ -2802,7 +2816,7 @@ |
592 | then the client's call back function is called with failure status, but this |
593 | does not guarantee that the server did not receive and process the request |
594 | before the disconnect. If a connection is lost and then resumed outstanding ca |
595 | -put requests are not automatically reissued following reconnect.</p> |
596 | +put requests are not automatically reissued following reconnect.</p> |
597 | |
598 | <p>All of these functions return ECA_DISCONN if the channel is currently |
599 | disconnected.</p> |
600 | @@ -2860,7 +2874,7 @@ |
601 | </dl> |
602 | <dl> |
603 | <dt><code>PFUNC</code></dt> |
604 | - <dd>address of <a href="#User">user supplied callback function</a> to be |
605 | + <dd>address of <a href="#User">user supplied callback function</a> to be |
606 | run when the requested operation completes</dd> |
607 | </dl> |
608 | <dl> |
609 | @@ -2888,7 +2902,7 @@ |
610 | <p>ECA_DISCONN - Channel is disconnected</p> |
611 | |
612 | <h4>See Also</h4> |
613 | -ca_flush_io() |
614 | +ca_flush_io() |
615 | |
616 | <p>ca_pend_event()</p> |
617 | |
618 | @@ -2915,12 +2929,13 @@ |
619 | assumed to be stable in the application supplied buffer until after ECA_NORMAL |
620 | is returned from ca_pend_io. If a connection is lost outstanding ca get |
621 | requests are not automatically reissued following reconnect.</p> |
622 | -When ca_get_callback or ca_array_get_callback are invoked a value is read |
623 | -from the channel and then the user's callback is invoked with a pointer to the |
624 | + |
625 | +<p>When ca_get_callback or ca_array_get_callback are invoked a value is read |
626 | +from the channel and then the user's callback is invoked with a pointer to the |
627 | retrieved value. Note that ca_pend_io will not block for the delivery of values |
628 | requested by ca_get_callback. If the channel disconnects before a ca get |
629 | callback request can be completed, then the clients call back function is |
630 | -called with failure status. |
631 | +called with failure status.</p> |
632 | |
633 | <p>All of these functions return ECA_DISCONN if the channel is currently |
634 | disconnected.</p> |
635 | @@ -2992,7 +3007,7 @@ |
636 | <p>ECA_DISCONN - Channel is disconnected</p> |
637 | |
638 | <h4>See Also</h4> |
639 | -ca_pend_io() |
640 | +ca_pend_io() |
641 | |
642 | <p>ca_pend_event()</p> |
643 | |
644 | @@ -3010,7 +3025,7 @@ |
645 | <h4>Description</h4> |
646 | |
647 | <p>Register a state change subscription and specify a call back function to be |
648 | -invoked whenever the process variable undergoes significant state changes. A |
649 | +invoked whenever the process variable undergoes significant state changes. A |
650 | significant change can be a change in the process variable's value, alarm |
651 | status, or alarm severity. In the process control function block database the |
652 | deadband field determines the magnitude of a significant change for for the |
653 | @@ -3018,7 +3033,7 @@ |
654 | client library and potentially a CA server until one of ca_clear_channel or |
655 | ca_clear_event is called.</p> |
656 | |
657 | -<p>Subscriptions may be installed or canceled against both connected and |
658 | +<p>Subscriptions may be installed or canceled against both connected and |
659 | disconnected channels. The specified USERFUNC is called once immediately after |
660 | the subscription is installed with the process variable's current state if the |
661 | process variable is connected. Otherwise, the specified USERFUNC is called |
662 | @@ -3027,7 +3042,7 @@ |
663 | variable's current state from within ca_add_event() if the client and the |
664 | process variable share the same address space.</p> |
665 | |
666 | -<p>If a subscription is installed on a channel in a disconnected state then the |
667 | +<p>If a subscription is installed on a channel in a disconnected state then the |
668 | requested count will be set to the native maximum element count of the channel |
669 | if the requested count is larger.</p> |
670 | |
671 | @@ -3038,8 +3053,8 @@ |
672 | |
673 | <p>If at any time after subscribing, read access to the specified process |
674 | variable is lost, then the call back will be invoked immediately indicating |
675 | -that read access was lost via the status argument. When read access is restored |
676 | -normal event processing will resume starting always with at least one update |
677 | +that read access was lost via the status argument. When read access is restored |
678 | +normal event processing will resume starting always with at least one update |
679 | indicating the current state of the channel.</p> |
680 | |
681 | <p>A better name for this function might have been ca_subscribe.</p> |
682 | @@ -3066,7 +3081,7 @@ |
683 | </dl> |
684 | <dl> |
685 | <dt><code>USRERFUNC</code></dt> |
686 | - <dd>The address of <a href="#User">user supplied callback function</a> to |
687 | + <dd>The address of <a href="#User">user supplied callback function</a> to |
688 | be invoked with each subscription update.</dd> |
689 | </dl> |
690 | <dl> |
691 | @@ -3082,7 +3097,7 @@ |
692 | <dt><code>PEVID</code></dt> |
693 | <dd>This is a pointer to user supplied event id which is overwritten if |
694 | successful. This event id can later be used to clear a specific |
695 | - event. This option may may be omitted by passing a nil pointer.</dd> |
696 | + event. This option may may be omitted by passing a nil pointer.</dd> |
697 | </dl> |
698 | <dl> |
699 | <dt><code>MASK</code></dt> |
700 | @@ -3117,7 +3132,7 @@ |
701 | <p>ECA_ADDFAIL - A local database event add failed</p> |
702 | |
703 | <h4>See Also</h4> |
704 | -ca_pend_event() |
705 | +ca_pend_event() |
706 | |
707 | <p>ca_flush_io()</p> |
708 | |
709 | @@ -3130,7 +3145,7 @@ |
710 | <p>Cancel a subscription.</p> |
711 | |
712 | <p>All ca_clear_event() requests such as the above are accumulated (buffered) |
713 | -and not forwarded to the server until one of ca_flush_io, ca_pend_io, |
714 | +and not forwarded to the server until one of ca_flush_io, ca_pend_io, |
715 | ca_pend_event, or ca_sg_pend are called. This allows several requests to be |
716 | efficiently sent together in one message.</p> |
717 | |
718 | @@ -3167,7 +3182,7 @@ |
719 | </ul> |
720 | |
721 | <p>If ECA_TIMEOUT is returned then get requests may be reissued followed by a |
722 | -subsequent call to ca_pend_io(). Specifically, the function will block only for |
723 | +subsequent call to ca_pend_io(). Specifically, the function will block only for |
724 | outstanding <a href="#ca_get">ca_get</a> requests issued, and also any channels |
725 | created specifying a nill connection handler function pointer, after the last |
726 | call to ca_pend_io() or ca client context creation whichever is later. Note |
727 | @@ -3177,7 +3192,7 @@ |
728 | |
729 | <p>If no <a href="#ca_get">ca_get</a> or connection state change events are |
730 | outstanding then ca_pend_io() will flush the send buffer and return immediately |
731 | -<em>without processing any outstanding channel access background |
732 | +<em>without processing any outstanding channel access background |
733 | activities</em>.</p> |
734 | |
735 | <p>The delay specified to ca_pend_io() should take into account worst case |
736 | @@ -3192,7 +3207,7 @@ |
737 | <dl> |
738 | <dt>TIMEOUT</dt> |
739 | <dd>Specifies the time out interval. A <code>TIMEOUT</code> interval of |
740 | - zero specifies forever.</dd> |
741 | + zero specifies forever.</dd> |
742 | </dl> |
743 | |
744 | <h4>Returns</h4> |
745 | @@ -3205,7 +3220,7 @@ |
746 | <p>ECA_EVDISALLOW - Function inappropriate for use within an event handler</p> |
747 | |
748 | <h4>See Also</h4> |
749 | -<a href="#ca_get">ca_get</a>() |
750 | +<a href="#ca_get">ca_get</a>() |
751 | |
752 | <p><a href="#ca_create_channel">ca_create_channel</a>()</p> |
753 | |
754 | @@ -3217,12 +3232,12 @@ |
755 | |
756 | <h4>Description</h4> |
757 | |
758 | -<p>This function tests to see if all <a href="#ca_get">ca_get</a> requests are |
759 | +<p>This function tests to see if all <a href="#ca_get">ca_get</a> requests are |
760 | complete and channels created specifying a nill connection callback function |
761 | pointer are connected. It will report the status of outstanding <a |
762 | href="#ca_get">ca_get</a> requests issued, and channels created specifying a |
763 | nill connection callback function pointer, after the last call to ca_pend_io() |
764 | -or CA context initialization whichever is later.</p> |
765 | +or CA context initialization whichever is later.</p> |
766 | |
767 | <h4>Returns</h4> |
768 | |
769 | @@ -3280,8 +3295,8 @@ |
770 | |
771 | <h4>Description</h4> |
772 | |
773 | -<p>Flush outstanding IO requests to the server. This routine might be useful |
774 | -to users who need to flush requests prior to performing client side labor in |
775 | +<p>Flush outstanding IO requests to the server. This routine might be useful |
776 | +to users who need to flush requests prior to performing client side labor in |
777 | parallel with labor performed in the server.</p> |
778 | |
779 | <p>Outstanding requests are also sent whenever the buffer which holds them |
780 | @@ -3324,7 +3339,7 @@ |
781 | </dl> |
782 | <dl> |
783 | <dt><code>CONTEXT_STRING</code></dt> |
784 | - <dd>A null terminated character string to supply as error context to |
785 | + <dd>A null terminated character string to supply as error context to |
786 | diagnostics.</dd> |
787 | </dl> |
788 | |
789 | @@ -3345,9 +3360,9 @@ |
790 | |
791 | <p>When an error occurs in the server asynchronous to the clients thread then |
792 | information about this type of error is passed from the server to the client in |
793 | -an exception message. When the client receives this exception message an |
794 | +an exception message. When the client receives this exception message an |
795 | exception handler callback is called.The default exception handler prints a |
796 | -diagnostic message on the client's standard out and terminates execution if the |
797 | +diagnostic message on the client's standard out and terminates execution if the |
798 | error condition is severe.</p> |
799 | |
800 | <p>Note that certain fields in "struct exception_handler_args" are not |
801 | @@ -3364,7 +3379,7 @@ |
802 | reinstalled. The following structure is passed by value to the user's |
803 | callback function. Currently, the <code>op </code>field can be one of |
804 | <code>CA_OP_GET, CA_OP_PUT, CA_OP_CREATE_CHANNEL, CA_OP_ADD_EVENT, |
805 | - CA_OP_CLEAR_EVENT, or CA_OP_OTHER.</code> |
806 | + CA_OP_CLEAR_EVENT, or CA_OP_OTHER.</code> |
807 | <pre><code>struct exception_handler_args { |
808 | void *usr; /* user argument supplied when installed */ |
809 | chanId chid; /* channel id (may be nill) */ |
810 | @@ -3387,23 +3402,22 @@ |
811 | |
812 | <h4>Example</h4> |
813 | <pre><code>void ca_exception_handler ( |
814 | - struct exception_handler_args args) |
815 | + struct exception_handler_args args) |
816 | { |
817 | - char buf[512]; |
818 | - char *pName; |
819 | + char buf[512]; |
820 | + char *pName; |
821 | |
822 | - if ( args.chid ) { |
823 | - pName = ca_name ( args.chid ); |
824 | - } |
825 | - else{ |
826 | - pName = "?"; |
827 | - } |
828 | - sprintf ( buf, |
829 | - "%s - with request chan=%s op=%d data type=%s count=%d", |
830 | - args.ctx, pName, args.op, dbr_type_to_text ( args.type ), args.count ); |
831 | - ca_signal ( args.stat, buf ); |
832 | - |
833 | -} |
834 | + if ( args.chid ) { |
835 | + pName = ca_name ( args.chid ); |
836 | + } |
837 | + else { |
838 | + pName = "?"; |
839 | + } |
840 | + sprintf ( buf, |
841 | + "%s - with request chan=%s op=%d data type=%s count=%d", |
842 | + args.ctx, pName, args.op, dbr_type_to_text ( args.type ), args.count ); |
843 | + ca_signal ( args.stat, buf ); |
844 | +} |
845 | ca_add_exception_event ( ca_exception_handler , 0 );</code></pre> |
846 | |
847 | <h4>Returns</h4> |
848 | @@ -3419,7 +3433,7 @@ |
849 | <h4>Description</h4> |
850 | |
851 | <p>For use with the services provided by a file descriptor manager (IO |
852 | -multiplexor) such as ""fdmgr.c". A file descriptor manager is often needed when |
853 | +multiplexor) such as "fdmgr.c". A file descriptor manager is often needed when |
854 | two file descriptor IO intensive libraries such as the EPICS channel access |
855 | client library and the X window system client library must coexist in the same |
856 | UNIX process. This function allows an application code to be notified whenever |
857 | @@ -3535,7 +3549,7 @@ |
858 | <li>whenever the access rights state of a connected channel changes</li> |
859 | </ul> |
860 | |
861 | -<p>When a channel is created no access rights handler is installed.</p> |
862 | +<p>When a channel is created no access rights handler is installed.</p> |
863 | |
864 | <h4>Arguments</h4> |
865 | <dl> |
866 | @@ -3587,7 +3601,7 @@ |
867 | <h4>Returns</h4> |
868 | <dl> |
869 | <dt><code>TYPE</code></dt> |
870 | - <dd>The data type code will be a member of the set of DBF_XXXX in |
871 | + <dd>The data type code will be a member of the set of DBF_XXXX in |
872 | db_access.h. The constant TYPENOTCONN is returned if the channel is |
873 | disconnected.<a name="ca_element_count"></a></dd> |
874 | </dl> |
875 | @@ -3598,7 +3612,7 @@ |
876 | |
877 | <h4>Description</h4> |
878 | |
879 | -<p>Return the maximum array element count in the server for the specified IO |
880 | +<p>Return the maximum array element count in the server for the specified IO |
881 | channel.</p> |
882 | |
883 | <h4>Arguments</h4> |
884 | @@ -3610,7 +3624,7 @@ |
885 | <h4>Returns</h4> |
886 | <dl> |
887 | <dt><code>COUNT</code></dt> |
888 | - <dd>The maximum array element count in the server. An element count of |
889 | + <dd>The maximum array element count in the server. An element count of |
890 | zero is returned if the channel is disconnected.</dd> |
891 | </dl> |
892 | |
893 | @@ -3641,7 +3655,7 @@ |
894 | |
895 | <h4>Description</h4> |
896 | |
897 | -<p>Set a user private void pointer variable retained with each channel for use |
898 | +<p>Set a user private void pointer variable retained with each channel for use |
899 | at the users discretion.</p> |
900 | |
901 | <h4>Arguments</h4> |
902 | @@ -3750,8 +3764,8 @@ |
903 | |
904 | <h4>Description</h4> |
905 | |
906 | -<p>Returns boolean true if the client currently has read access to the |
907 | -specified channel and boolean false otherwise.</p> |
908 | +<p>Returns boolean true if the client currently has read access to the |
909 | +specified channel and boolean false otherwise.</p> |
910 | |
911 | <h4>Arguments</h4> |
912 | <dl> |
913 | @@ -3762,8 +3776,8 @@ |
914 | <h4>Returns</h4> |
915 | <dl> |
916 | <dt><code>STRING</code></dt> |
917 | - <dd>boolean true if the client currently has read access to the specified |
918 | - channel and boolean false otherwise</dd> |
919 | + <dd>boolean true if the client currently has read access to the specified |
920 | + channel and boolean false otherwise</dd> |
921 | </dl> |
922 | |
923 | <h3><code><a name="L6941">ca_write_access()</a></code></h3> |
924 | @@ -3772,8 +3786,8 @@ |
925 | |
926 | <h4>Description</h4> |
927 | |
928 | -<p>Returns boolean true if the client currently has write access to the |
929 | -specified channel and boolean false otherwise.</p> |
930 | +<p>Returns boolean true if the client currently has write access to the |
931 | +specified channel and boolean false otherwise.</p> |
932 | |
933 | <h4>Arguments</h4> |
934 | <dl> |
935 | @@ -3784,8 +3798,8 @@ |
936 | <h4>Returns</h4> |
937 | <dl> |
938 | <dt><code>STRING</code></dt> |
939 | - <dd>boolean true if the client currently has write access to the specified |
940 | - channel and boolean false otherwise</dd> |
941 | + <dd>boolean true if the client currently has write access to the specified |
942 | + channel and boolean false otherwise</dd> |
943 | </dl> |
944 | |
945 | <h3><code><a name="dbr_size[]">dbr_size[]</a></code></h3> |
946 | @@ -3794,12 +3808,12 @@ |
947 | |
948 | <h4>Description</h4> |
949 | |
950 | -<p>An array that returns the size in bytes for a DBR_XXXX type.</p> |
951 | +<p>An array that returns the size in bytes for a DBR_XXXX type.</p> |
952 | |
953 | <h4>Arguments</h4> |
954 | <dl> |
955 | <dt><code>TYPE</code></dt> |
956 | - <dd>The data type code. A member of the set of DBF_XXXX in db_access.h.</dd> |
957 | + <dd>The data type code. A member of the set of DBF_XXXX in db_access.h.</dd> |
958 | </dl> |
959 | |
960 | <h4>Returns</h4> |
961 | @@ -3814,7 +3828,7 @@ |
962 | |
963 | <h4>Description</h4> |
964 | |
965 | -<p>Returns the size in bytes for a DBR_XXXX type with COUNT elements. If the |
966 | +<p>Returns the size in bytes for a DBR_XXXX type with COUNT elements. If the |
967 | DBR type is a structure then the value field is the last field in the |
968 | structure. If COUNT is greater than one then COUNT-1 elements are appended to |
969 | the end of the structure so that they can be addressed as an array through a |
970 | @@ -3850,7 +3864,7 @@ |
971 | <h4>Arguments</h4> |
972 | <dl> |
973 | <dt><code>TYPE</code></dt> |
974 | - <dd>The data type code. A member of the set of DBF_XXXX in db_access.h.</dd> |
975 | + <dd>The data type code. A member of the set of DBF_XXXX in db_access.h.</dd> |
976 | </dl> |
977 | |
978 | <h4>Returns</h4> |
979 | @@ -3872,7 +3886,7 @@ |
980 | <h4>Arguments</h4> |
981 | <dl> |
982 | <dt><code>TYPE</code></dt> |
983 | - <dd>The data type code. A member of the set of DBR_XXXX in db_access.h.</dd> |
984 | + <dd>The data type code. A member of the set of DBR_XXXX in db_access.h.</dd> |
985 | </dl> |
986 | |
987 | <h4>Returns</h4> |
988 | @@ -3937,7 +3951,7 @@ |
989 | <p>ECA_ALLOCMEM - Failed, unable to allocate memory</p> |
990 | |
991 | <h4>See Also</h4> |
992 | -ca_sg_delete() |
993 | +ca_sg_delete() |
994 | |
995 | <p>ca_sg_block()</p> |
996 | |
997 | @@ -3996,7 +4010,7 @@ |
998 | |
999 | <p>Values written into your program's variables by a channel access synchronous |
1000 | group request should not be referenced by your program until ECA_NORMAL has |
1001 | -been received from ca_sg_block(). This routine will process pending channel |
1002 | +been received from ca_sg_block(). This routine will process pending channel |
1003 | access background activity while it is waiting.</p> |
1004 | |
1005 | <h4>Arguments</h4> |
1006 | @@ -4028,7 +4042,7 @@ |
1007 | |
1008 | <h3><code><a name="ca_sg_test">ca_sg_test()</a></code></h3> |
1009 | <pre><code>#include <cadef.h> |
1010 | -int ca_sg_test ( CA_SYNC_GID GID )</code></pre> |
1011 | +int ca_sg_test ( CA_SYNC_GID GID )</code></pre> |
1012 | |
1013 | <h4>Description</h4> |
1014 | |
1015 | @@ -4087,7 +4101,7 @@ |
1016 | int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE, |
1017 | unsigned long COUNT, chid CHID, void *PVALUE );</code></pre> |
1018 | |
1019 | -<p>Write a value, or array of values, to a channel and increment the |
1020 | +<p>Write a value, or array of values, to a channel and increment the |
1021 | outstanding request count of a synchronous group. The ca_sg_array_put |
1022 | functionality is implemented using ca_array_put_callback.</p> |
1023 | |
1024 | @@ -4157,8 +4171,8 @@ |
1025 | ca_array_get_callback.</p> |
1026 | |
1027 | <p>The values written into your program's variables by ca_sg_get should not be |
1028 | -referenced by your program until ECA_NORMAL has been received from ca_sg_block |
1029 | -, or until ca_sg_test returns ECA_IODONE.</p> |
1030 | +referenced by your program until ECA_NORMAL has been received from ca_sg_block, |
1031 | +or until ca_sg_test returns ECA_IODONE.</p> |
1032 | |
1033 | <p>All remote operation requests such as the above are accumulated (buffered) |
1034 | and not forwarded to the server until one of ca_flush_io, ca_pend_io, |
1035 | @@ -4186,7 +4200,7 @@ |
1036 | </dl> |
1037 | <dl> |
1038 | <dt><code>CHID</code></dt> |
1039 | - <dd>channel identifier</dd> |
1040 | + <dd>channel identifier</dd> |
1041 | </dl> |
1042 | <dl> |
1043 | <dt><code>PVALUE</code></dt> |
1044 | @@ -4196,9 +4210,9 @@ |
1045 | |
1046 | <h4>Returns</h4> |
1047 | |
1048 | -<p>ECA_NORMAL - Normal successful completion </p> |
1049 | +<p>ECA_NORMAL - Normal successful completion�</p> |
1050 | |
1051 | -<p>ECA_BADSYNCGRP - Invalid synchronous group </p> |
1052 | +<p>ECA_BADSYNCGRP - Invalid synchronous group�</p> |
1053 | |
1054 | <p>ECA_BADCHID - Corrupted CHID</p> |
1055 | |
1056 | @@ -4224,7 +4238,7 @@ |
1057 | <h4>Description</h4> |
1058 | |
1059 | <p>Prints information about the client context including, at higher interest |
1060 | -levels, status for each channel. Lacking a CA context pointer, |
1061 | +levels, status for each channel. Lacking a CA context pointer, |
1062 | ca_client_status() prints information about the calling threads CA context.</p> |
1063 | |
1064 | <h4>Arguments</h4> |
1065 | @@ -4404,7 +4418,6 @@ |
1066 | bytes</dd> |
1067 | </dl> |
1068 | |
1069 | -<p><small>$Id$ |
1070 | -.</small></p> |
1071 | +<p></p> |
1072 | </body> |
1073 | </html> |
1074 | |
1075 | === added file 'src/ca/SearchDest.h' |
1076 | --- src/ca/SearchDest.h 1970-01-01 00:00:00 +0000 |
1077 | +++ src/ca/SearchDest.h 2010-05-14 13:38:34 +0000 |
1078 | @@ -0,0 +1,39 @@ |
1079 | +/*************************************************************************\ |
1080 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1081 | + * National Laboratory. |
1082 | + * Copyright (c) 2002 The Regents of the University of California, as |
1083 | + * Operator of Los Alamos National Laboratory. |
1084 | + * EPICS BASE Versions 3.13.7 |
1085 | + * and higher are distributed subject to a Software License Agreement found |
1086 | + * in file LICENSE that is included with this distribution. |
1087 | +\*************************************************************************/ |
1088 | + |
1089 | +#ifndef SearchDest_h |
1090 | +#define SearchDest_h |
1091 | + |
1092 | +#include <osiSock.h> |
1093 | +#include <epicsTime.h> |
1094 | +#include <tsDLList.h> |
1095 | +#include "caProto.h" |
1096 | + |
1097 | +class channelNode; |
1098 | +class epicsMutex; |
1099 | +template < class T > class epicsGuard; |
1100 | + |
1101 | +struct SearchDest : |
1102 | + public tsDLNode < SearchDest > { |
1103 | + virtual ~SearchDest () {}; |
1104 | + struct Callback { |
1105 | + virtual ~Callback () {}; |
1106 | + virtual void notify ( |
1107 | + const caHdr & msg, const void * pPayload, |
1108 | + const osiSockAddr & addr, const epicsTime & ) = 0; |
1109 | + virtual void show ( |
1110 | + epicsGuard < epicsMutex > &, unsigned level ) const = 0; |
1111 | + }; |
1112 | + virtual void searchRequest ( epicsGuard < epicsMutex > &, |
1113 | + const char * pbuf, size_t len ) = 0; |
1114 | + virtual void show ( epicsGuard < epicsMutex > &, unsigned level ) const = 0; |
1115 | +}; |
1116 | + |
1117 | +#endif // SearchDest_h |
1118 | |
1119 | === modified file 'src/ca/caProto.h' |
1120 | --- src/ca/caProto.h 2004-10-04 18:55:40 +0000 |
1121 | +++ src/ca/caProto.h 2010-05-14 13:38:34 +0000 |
1122 | @@ -40,6 +40,7 @@ |
1123 | # define CA_V49(MINOR) ((MINOR)>=9u) /* large arrays, dispatch priorities */ |
1124 | # define CA_V410(MINOR) ((MINOR)>=10u) /* beacon counter */ |
1125 | # define CA_V411(MINOR) ((MINOR)>=11u) /* sequence numbers in UDP version command */ |
1126 | +# define CA_V412(MINOR) ((MINOR)>=12u) /* TCP-based search requests */ |
1127 | #elif CA_MAJOR_PROTOCOL_REVISION > 4u |
1128 | # define CA_V41(MINOR) ( 1u ) |
1129 | # define CA_V42(MINOR) ( 1u ) |
1130 | @@ -52,6 +53,7 @@ |
1131 | # define CA_V49(MINOR) ( 1u ) |
1132 | # define CA_V410(MINOR) ( 1u ) |
1133 | # define CA_V411(MINOR) ( 1u ) |
1134 | +# define CA_V412(MINOR) ( 1u ) |
1135 | #else |
1136 | # define CA_V41(MINOR) ( 0u ) |
1137 | # define CA_V42(MINOR) ( 0u ) |
1138 | @@ -64,7 +66,8 @@ |
1139 | # define CA_V49(MINOR) ( 0u ) |
1140 | # define CA_V410(MINOR) ( 0u ) |
1141 | # define CA_V411(MINOR) ( 0u ) |
1142 | -#endif |
1143 | +# define CA_V412(MINOR) ( 0u ) |
1144 | +#endif |
1145 | |
1146 | /* |
1147 | * These port numbers are only used if the CA repeater and |
1148 | |
1149 | === modified file 'src/ca/ca_client_context.cpp' |
1150 | --- src/ca/ca_client_context.cpp 2009-08-21 00:53:55 +0000 |
1151 | +++ src/ca/ca_client_context.cpp 2010-05-14 13:38:34 +0000 |
1152 | @@ -1,12 +1,13 @@ |
1153 | /*************************************************************************\ |
1154 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1155 | -* National Laboratory. |
1156 | -* Copyright (c) 2002 The Regents of the University of California, as |
1157 | -* Operator of Los Alamos National Laboratory. |
1158 | -* EPICS BASE Versions 3.13.7 |
1159 | -* and higher are distributed subject to a Software License Agreement found |
1160 | -* in file LICENSE that is included with this distribution. |
1161 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1162 | + * National Laboratory. |
1163 | + * Copyright (c) 2002 The Regents of the University of California, as |
1164 | + * Operator of Los Alamos National Laboratory. |
1165 | + * EPICS BASE Versions 3.13.7 |
1166 | + * and higher are distributed subject to a Software License Agreement found |
1167 | + * in file LICENSE that is included with this distribution. |
1168 | \*************************************************************************/ |
1169 | + |
1170 | /* |
1171 | * |
1172 | * |
1173 | |
1174 | === modified file 'src/ca/cac.cpp' |
1175 | --- src/ca/cac.cpp 2009-08-14 16:56:31 +0000 |
1176 | +++ src/ca/cac.cpp 2010-05-14 13:38:34 +0000 |
1177 | @@ -1,14 +1,14 @@ |
1178 | /*************************************************************************\ |
1179 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1180 | -* National Laboratory. |
1181 | -* Copyright (c) 2002 The Regents of the University of California, as |
1182 | -* Operator of Los Alamos National Laboratory. |
1183 | -* EPICS BASE Versions 3.13.7 |
1184 | -* and higher are distributed subject to a Software License Agreement found |
1185 | -* in file LICENSE that is included with this distribution. |
1186 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1187 | + * National Laboratory. |
1188 | + * Copyright (c) 2002 The Regents of the University of California, as |
1189 | + * Operator of Los Alamos National Laboratory. |
1190 | + * EPICS BASE Versions 3.13.7 |
1191 | + * and higher are distributed subject to a Software License Agreement found |
1192 | + * in file LICENSE that is included with this distribution. |
1193 | \*************************************************************************/ |
1194 | -/* |
1195 | - * |
1196 | + |
1197 | +/* |
1198 | * L O S A L A M O S |
1199 | * Los Alamos National Laboratory |
1200 | * Los Alamos, New Mexico 87545 |
1201 | @@ -16,6 +16,7 @@ |
1202 | * Copyright, 1986, The Regents of the University of California. |
1203 | * |
1204 | * Author: Jeff Hill |
1205 | + * |
1206 | */ |
1207 | |
1208 | #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" |
1209 | @@ -34,6 +35,7 @@ |
1210 | #include "errlog.h" |
1211 | |
1212 | #define epicsExportSharedSymbols |
1213 | +#include "addrList.h" |
1214 | #include "iocinf.h" |
1215 | #include "cac.h" |
1216 | #include "inetAddrID.h" |
1217 | @@ -62,7 +64,7 @@ |
1218 | &cac::readRespAction, |
1219 | &cac::badTCPRespAction, |
1220 | &cac::badTCPRespAction, |
1221 | - &cac::badTCPRespAction, |
1222 | + &cac::searchRespAction, |
1223 | &cac::badTCPRespAction, |
1224 | &cac::badTCPRespAction, |
1225 | &cac::badTCPRespAction, |
1226 | @@ -177,6 +179,10 @@ |
1227 | strncpy ( this->pUserName, tmp, len ); |
1228 | } |
1229 | |
1230 | + this->_serverPort = |
1231 | + envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT, |
1232 | + static_cast <unsigned short> (CA_SERVER_PORT) ); |
1233 | + |
1234 | status = envGetDoubleConfigParam ( &EPICS_CA_CONN_TMO, &this->connTMO ); |
1235 | if ( status ) { |
1236 | this->connTMO = CA_CONN_VERIFY_PERIOD; |
1237 | @@ -234,6 +240,34 @@ |
1238 | this->timerQueue.release (); |
1239 | throw; |
1240 | } |
1241 | + |
1242 | + /* |
1243 | + * load user configured tcp name server address list, |
1244 | + * create virtual circuits, and add them to server table |
1245 | + */ |
1246 | + ELLLIST dest, tmpList; |
1247 | + |
1248 | + ellInit ( & dest ); |
1249 | + ellInit ( & tmpList ); |
1250 | + |
1251 | + addAddrToChannelAccessAddressList ( &tmpList, &EPICS_CA_NAME_SERVERS, this->_serverPort, false ); |
1252 | + removeDuplicateAddresses ( &dest, &tmpList, 0 ); |
1253 | + |
1254 | + epicsGuard < epicsMutex > guard ( this->mutex ); |
1255 | + |
1256 | + while ( osiSockAddrNode * |
1257 | + pNode = reinterpret_cast < osiSockAddrNode * > ( ellGet ( & dest ) ) ) { |
1258 | + tcpiiu * piiu = NULL; |
1259 | + SearchDestTCP * pdst = new SearchDestTCP ( *this, pNode->addr ); |
1260 | + this->registerSearchDest ( guard, * pdst ); |
1261 | + bool newIIU = findOrCreateVirtCircuit ( |
1262 | + guard, pNode->addr, cacChannel::priorityDefault, |
1263 | + piiu, CA_UKN_MINOR_VERSION, pdst ); |
1264 | + free ( pNode ); |
1265 | + if ( newIIU ) { |
1266 | + piiu->start ( guard ); |
1267 | + } |
1268 | + } |
1269 | } |
1270 | |
1271 | cac::~cac () |
1272 | @@ -468,7 +502,8 @@ |
1273 | if ( ! this->pudpiiu ) { |
1274 | this->pudpiiu = new udpiiu ( |
1275 | guard, this->timerQueue, this->cbMutex, |
1276 | - this->mutex, this->notify, *this ); |
1277 | + this->mutex, this->notify, *this, this->_serverPort, |
1278 | + this->searchDestList ); |
1279 | } |
1280 | |
1281 | nciu * pNetChan = new ( this->channelFreeList ) |
1282 | @@ -477,6 +512,57 @@ |
1283 | return *pNetChan; |
1284 | } |
1285 | |
1286 | +bool cac::findOrCreateVirtCircuit ( |
1287 | + epicsGuard < epicsMutex > & guard, const osiSockAddr & addr, |
1288 | + unsigned priority, tcpiiu *& piiu, unsigned minorVersionNumber, |
1289 | + SearchDestTCP * pSearchDest ) |
1290 | +{ |
1291 | + guard.assertIdenticalMutex ( this->mutex ); |
1292 | + bool newIIU = false; |
1293 | + |
1294 | + if ( piiu ) { |
1295 | + if ( ! piiu->alive ( guard ) ) { |
1296 | + return newIIU; |
1297 | + } |
1298 | + } |
1299 | + else { |
1300 | + try { |
1301 | + autoPtrFreeList < tcpiiu, 32, epicsMutexNOOP > pnewiiu ( |
1302 | + this->freeListVirtualCircuit, |
1303 | + new ( this->freeListVirtualCircuit ) tcpiiu ( |
1304 | + *this, this->mutex, this->cbMutex, this->notify, this->connTMO, |
1305 | + this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber, |
1306 | + this->ipToAEngine, priority, pSearchDest ) ); |
1307 | + |
1308 | + bhe * pBHE = this->beaconTable.lookup ( addr.ia ); |
1309 | + if ( ! pBHE ) { |
1310 | + pBHE = new ( this->bheFreeList ) |
1311 | + bhe ( this->mutex, epicsTime (), 0u, addr.ia ); |
1312 | + if ( this->beaconTable.add ( *pBHE ) < 0 ) { |
1313 | + return newIIU; |
1314 | + } |
1315 | + } |
1316 | + this->serverTable.add ( *pnewiiu ); |
1317 | + this->circuitList.add ( *pnewiiu ); |
1318 | + pBHE->registerIIU ( guard, *pnewiiu ); |
1319 | + piiu = pnewiiu.release (); |
1320 | + newIIU = true; |
1321 | + } |
1322 | + catch ( std :: exception & except ) { |
1323 | + errlogPrintf ( |
1324 | + "CAC: exception during virtual circuit creation \"%s\"\n", |
1325 | + except.what () ); |
1326 | + return newIIU; |
1327 | + } |
1328 | + catch ( ... ) { |
1329 | + errlogPrintf ( |
1330 | + "CAC: Nonstandard exception during virtual circuit creation\n" ); |
1331 | + return newIIU; |
1332 | + } |
1333 | + } |
1334 | + return newIIU; |
1335 | +} |
1336 | + |
1337 | void cac::transferChanToVirtCircuit ( |
1338 | unsigned cid, unsigned sid, // X aCC 431 |
1339 | ca_uint16_t typeCode, arrayElementCount count, |
1340 | @@ -484,7 +570,7 @@ |
1341 | const epicsTime & currentTime ) |
1342 | { |
1343 | if ( addr.sa.sa_family != AF_INET ) { |
1344 | - return ; |
1345 | + return; |
1346 | } |
1347 | |
1348 | epicsGuard < epicsMutex > guard ( this->mutex ); |
1349 | @@ -501,6 +587,7 @@ |
1350 | * Ignore duplicate search replies |
1351 | */ |
1352 | osiSockAddr chanAddr = pChan->getPIIU(guard)->getNetworkAddress (guard); |
1353 | + |
1354 | if ( chanAddr.sa.sa_family != AF_UNSPEC ) { |
1355 | if ( ! sockAddrAreIdentical ( &addr, &chanAddr ) ) { |
1356 | char acc[64]; |
1357 | @@ -519,52 +606,12 @@ |
1358 | return; |
1359 | } |
1360 | |
1361 | - /* |
1362 | - * look for an existing virtual circuit |
1363 | - */ |
1364 | - bool newIIU = false; |
1365 | caServerID servID ( addr.ia, pChan->getPriority(guard) ); |
1366 | tcpiiu * piiu = this->serverTable.lookup ( servID ); |
1367 | - if ( piiu ) { |
1368 | - if ( ! piiu->alive ( guard ) ) { |
1369 | - return; |
1370 | - } |
1371 | - } |
1372 | - else { |
1373 | - try { |
1374 | - autoPtrFreeList < tcpiiu, 32, epicsMutexNOOP > pnewiiu ( |
1375 | - this->freeListVirtualCircuit, |
1376 | - new ( this->freeListVirtualCircuit ) tcpiiu ( |
1377 | - *this, this->mutex, this->cbMutex, this->notify, this->connTMO, |
1378 | - this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber, |
1379 | - this->ipToAEngine, pChan->getPriority(guard) ) ); |
1380 | - bhe * pBHE = this->beaconTable.lookup ( addr.ia ); |
1381 | - if ( ! pBHE ) { |
1382 | - pBHE = new ( this->bheFreeList ) |
1383 | - bhe ( this->mutex, epicsTime (), 0u, addr.ia ); |
1384 | - if ( this->beaconTable.add ( *pBHE ) < 0 ) { |
1385 | - return; |
1386 | - } |
1387 | - } |
1388 | - this->serverTable.add ( *pnewiiu ); |
1389 | - this->circuitList.add ( *pnewiiu ); |
1390 | - this->iiuExistenceCount++; |
1391 | - pBHE->registerIIU ( guard, *pnewiiu ); |
1392 | - piiu = pnewiiu.release (); |
1393 | - newIIU = true; |
1394 | - } |
1395 | - catch ( std :: exception & except ) { |
1396 | - errlogPrintf ( |
1397 | - "CAC: exception during virtual circuit creation \"%s\"\n", |
1398 | - except.what () ); |
1399 | - return; |
1400 | - } |
1401 | - catch ( ... ) { |
1402 | - errlogPrintf ( |
1403 | - "CAC: nonstandard exception during virtual circuit creation\n" ); |
1404 | - return; |
1405 | - } |
1406 | - } |
1407 | + |
1408 | + bool newIIU = findOrCreateVirtCircuit ( |
1409 | + guard, addr, |
1410 | + pChan->getPriority(guard), piiu, minorVersionNumber, false ); |
1411 | |
1412 | // must occur before moving to new iiu |
1413 | pChan->getPIIU(guard)->uninstallChanDueToSuccessfulSearchResponse ( |
1414 | @@ -746,9 +793,10 @@ |
1415 | return *pIO.release (); |
1416 | } |
1417 | |
1418 | -bool cac::versionAction ( callbackManager &, tcpiiu &, |
1419 | - const epicsTime &, const caHdrLargeArray &, void * ) |
1420 | +bool cac::versionAction ( callbackManager &, tcpiiu & iiu, |
1421 | + const epicsTime &, const caHdrLargeArray & msg, void * ) |
1422 | { |
1423 | + iiu.versionRespNotify ( msg ); |
1424 | return true; |
1425 | } |
1426 | |
1427 | @@ -831,6 +879,15 @@ |
1428 | return true; |
1429 | } |
1430 | |
1431 | +bool cac::searchRespAction ( callbackManager &, tcpiiu & iiu, |
1432 | + const epicsTime & currentTime, const caHdrLargeArray & msg, |
1433 | + void * /* pMsgBdy */ ) |
1434 | +{ |
1435 | + assert ( this->pudpiiu ); |
1436 | + iiu.searchRespNotify ( currentTime, msg ); |
1437 | + return true; |
1438 | +} |
1439 | + |
1440 | bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu, |
1441 | const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy ) |
1442 | { |
1443 | @@ -1076,7 +1133,7 @@ |
1444 | } |
1445 | |
1446 | bool cac::verifyAndDisconnectChan ( |
1447 | - callbackManager & mgr, tcpiiu &, |
1448 | + callbackManager & mgr, tcpiiu &, |
1449 | const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ ) |
1450 | { |
1451 | epicsGuard < epicsMutex > guard ( this->mutex ); |
1452 | @@ -1139,6 +1196,7 @@ |
1453 | { |
1454 | callbackManager mgr ( this->notify, this->cbMutex ); |
1455 | epicsGuard < epicsMutex > guard ( this->mutex ); |
1456 | + |
1457 | if ( iiu.channelCount ( guard ) ) { |
1458 | char hostNameTmp[64]; |
1459 | iiu.getHostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); |
1460 | @@ -1166,13 +1224,14 @@ |
1461 | // this waits for send/recv threads to exit |
1462 | // this also uses the cac free lists so cac must wait |
1463 | // for this to finish before it shuts down |
1464 | + |
1465 | iiu.~tcpiiu (); |
1466 | |
1467 | { |
1468 | epicsGuard < epicsMutex > guard ( this->mutex ); |
1469 | this->freeListVirtualCircuit.release ( & iiu ); |
1470 | this->iiuExistenceCount--; |
1471 | - // signal iiu uninstal event so that cac can properly shut down |
1472 | + // signal iiu uninstall event so that cac can properly shut down |
1473 | this->iiuUninstall.signal(); |
1474 | } |
1475 | // do not touch "this" after lock is released above |
1476 | @@ -1230,3 +1289,10 @@ |
1477 | this->mdpvFreeList.release ( & mfmdpv ); |
1478 | } |
1479 | |
1480 | +void cac::registerSearchDest ( |
1481 | + epicsGuard < epicsMutex > & guard, |
1482 | + SearchDest & req ) |
1483 | +{ |
1484 | + guard.assertIdenticalMutex ( this->mutex ); |
1485 | + this->searchDestList.add ( req ); |
1486 | +} |
1487 | |
1488 | === modified file 'src/ca/cac.h' |
1489 | --- src/ca/cac.h 2009-08-13 23:29:02 +0000 |
1490 | +++ src/ca/cac.h 2010-05-14 13:38:34 +0000 |
1491 | @@ -1,25 +1,23 @@ |
1492 | /*************************************************************************\ |
1493 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1494 | -* National Laboratory. |
1495 | -* Copyright (c) 2002 The Regents of the University of California, as |
1496 | -* Operator of Los Alamos National Laboratory. |
1497 | -* EPICS BASE Versions 3.13.7 |
1498 | -* and higher are distributed subject to a Software License Agreement found |
1499 | -* in file LICENSE that is included with this distribution. |
1500 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1501 | + * National Laboratory. |
1502 | + * Copyright (c) 2002 The Regents of the University of California, as |
1503 | + * Operator of Los Alamos National Laboratory. |
1504 | + * EPICS BASE Versions 3.13.7 |
1505 | + * and higher are distributed subject to a Software License Agreement found |
1506 | + * in file LICENSE that is included with this distribution. |
1507 | \*************************************************************************/ |
1508 | -/* |
1509 | - * |
1510 | - * |
1511 | + |
1512 | +/* |
1513 | * L O S A L A M O S |
1514 | * Los Alamos National Laboratory |
1515 | * Los Alamos, New Mexico 87545 |
1516 | - * |
1517 | + * |
1518 | * Copyright, 1986, The Regents of the University of California. |
1519 | - * |
1520 | - * |
1521 | - * Author Jeffrey O. Hill |
1522 | - * johill@lanl.gov |
1523 | - * 505 665 1831 |
1524 | + * |
1525 | + * |
1526 | + * Author: Jeff Hill |
1527 | + * |
1528 | */ |
1529 | |
1530 | #ifndef cach |
1531 | @@ -182,6 +180,13 @@ |
1532 | int status, const char * pContext, |
1533 | const char * pFileName, unsigned lineNo ); |
1534 | |
1535 | + // search destination management |
1536 | + void registerSearchDest ( |
1537 | + epicsGuard < epicsMutex > &, SearchDest & req ); |
1538 | + bool findOrCreateVirtCircuit ( |
1539 | + epicsGuard < epicsMutex > &, const osiSockAddr &, |
1540 | + unsigned, tcpiiu *&, unsigned, SearchDestTCP * pSearchDest = NULL ); |
1541 | + |
1542 | // diagnostics |
1543 | unsigned circuitCount ( epicsGuard < epicsMutex > & ) const; |
1544 | void show ( epicsGuard < epicsMutex > &, unsigned level ) const; |
1545 | @@ -191,6 +196,7 @@ |
1546 | int varArgsPrintFormated ( |
1547 | epicsGuard < epicsMutex > & callbackControl, |
1548 | const char *pformat, va_list args ) const; |
1549 | + double connectionTimeout ( epicsGuard < epicsMutex > & ); |
1550 | |
1551 | // buffer management |
1552 | char * allocateSmallBufferTCP (); |
1553 | @@ -235,6 +241,7 @@ |
1554 | resTable < bhe, inetAddrID > beaconTable; |
1555 | resTable < tcpiiu, caServerID > serverTable; |
1556 | tsDLList < tcpiiu > circuitList; |
1557 | + tsDLList < SearchDest > searchDestList; |
1558 | tsFreeList |
1559 | < class tcpiiu, 32, epicsMutexNOOP > |
1560 | freeListVirtualCircuit; |
1561 | @@ -275,6 +282,7 @@ |
1562 | unsigned maxRecvBytesTCP; |
1563 | unsigned maxContigFrames; |
1564 | unsigned beaconAnomalyCount; |
1565 | + unsigned short _serverPort; |
1566 | unsigned iiuExistenceCount; |
1567 | |
1568 | void recycleReadNotifyIO ( |
1569 | @@ -303,6 +311,8 @@ |
1570 | const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); |
1571 | bool writeNotifyRespAction ( callbackManager &, tcpiiu &, |
1572 | const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); |
1573 | + bool searchRespAction ( callbackManager &, tcpiiu &, |
1574 | + const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); |
1575 | bool readNotifyRespAction ( callbackManager &, tcpiiu &, |
1576 | const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); |
1577 | bool eventRespAction ( callbackManager &, tcpiiu &, |
1578 | @@ -444,11 +454,17 @@ |
1579 | return _refLocalHostName->pointer (); |
1580 | } |
1581 | |
1582 | -inline unsigned cac :: |
1583 | +inline unsigned cac :: |
1584 | maxContiguousFrames ( epicsGuard < epicsMutex > & ) const |
1585 | { |
1586 | return maxContigFrames; |
1587 | +} |
1588 | + |
1589 | +inline double cac :: |
1590 | + connectionTimeout ( epicsGuard < epicsMutex > & guard ) |
1591 | +{ |
1592 | + guard.assertIdenticalMutex ( this->mutex ); |
1593 | + return this->connTMO; |
1594 | } |
1595 | |
1596 | #endif // ifdef cach |
1597 | - |
1598 | |
1599 | === modified file 'src/ca/iocinf.cpp' |
1600 | --- src/ca/iocinf.cpp 2009-08-04 19:10:30 +0000 |
1601 | +++ src/ca/iocinf.cpp 2010-05-14 13:38:34 +0000 |
1602 | @@ -1,12 +1,13 @@ |
1603 | /*************************************************************************\ |
1604 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1605 | -* National Laboratory. |
1606 | -* Copyright (c) 2002 The Regents of the University of California, as |
1607 | -* Operator of Los Alamos National Laboratory. |
1608 | -* EPICS BASE Versions 3.13.7 |
1609 | -* and higher are distributed subject to a Software License Agreement found |
1610 | -* in file LICENSE that is included with this distribution. |
1611 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1612 | + * National Laboratory. |
1613 | + * Copyright (c) 2002 The Regents of the University of California, as |
1614 | + * Operator of Los Alamos National Laboratory. |
1615 | + * EPICS BASE Versions 3.13.7 |
1616 | + * and higher are distributed subject to a Software License Agreement found |
1617 | + * in file LICENSE that is included with this distribution. |
1618 | \*************************************************************************/ |
1619 | + |
1620 | /* |
1621 | * |
1622 | * L O S A L A M O S |
1623 | |
1624 | === modified file 'src/ca/nciu.h' |
1625 | --- src/ca/nciu.h 2008-07-28 16:19:50 +0000 |
1626 | +++ src/ca/nciu.h 2010-05-14 13:38:34 +0000 |
1627 | @@ -41,7 +41,7 @@ |
1628 | # include "shareLib.h" |
1629 | #endif |
1630 | |
1631 | -#define CA_MINOR_PROTOCOL_REVISION 11 |
1632 | +#define CA_MINOR_PROTOCOL_REVISION 12 |
1633 | #include "caProto.h" |
1634 | |
1635 | #include "cacIO.h" |
1636 | |
1637 | === modified file 'src/ca/tcpiiu.cpp' |
1638 | --- src/ca/tcpiiu.cpp 2009-09-11 00:49:02 +0000 |
1639 | +++ src/ca/tcpiiu.cpp 2010-05-14 13:38:34 +0000 |
1640 | @@ -1,16 +1,14 @@ |
1641 | /*************************************************************************\ |
1642 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1643 | -* National Laboratory. |
1644 | -* Copyright (c) 2002 The Regents of the University of California, as |
1645 | -* Operator of Los Alamos National Laboratory. |
1646 | -* EPICS BASE Versions 3.13.7 |
1647 | -* and higher are distributed subject to a Software License Agreement found |
1648 | -* in file LICENSE that is included with this distribution. |
1649 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1650 | + * National Laboratory. |
1651 | + * Copyright (c) 2002 The Regents of the University of California, as |
1652 | + * Operator of Los Alamos National Laboratory. |
1653 | + * EPICS BASE Versions 3.13.7 |
1654 | + * and higher are distributed subject to a Software License Agreement found |
1655 | + * in file LICENSE that is included with this distribution. |
1656 | \*************************************************************************/ |
1657 | |
1658 | - |
1659 | /* |
1660 | - * |
1661 | * L O S A L A M O S |
1662 | * Los Alamos National Laboratory |
1663 | * Los Alamos, New Mexico 87545 |
1664 | @@ -18,6 +16,7 @@ |
1665 | * Copyright, 1986, The Regents of the University of California. |
1666 | * |
1667 | * Author: Jeff Hill |
1668 | + * |
1669 | */ |
1670 | |
1671 | #ifdef _MSC_VER |
1672 | @@ -228,7 +227,6 @@ |
1673 | epicsThreadSleep ( 0.1 ); |
1674 | } |
1675 | } |
1676 | - |
1677 | this->iiu.cacRef.destroyIIU ( this->iiu ); |
1678 | } |
1679 | |
1680 | @@ -236,7 +234,6 @@ |
1681 | unsigned nBytesInBuf, const epicsTime & currentTime ) |
1682 | { |
1683 | unsigned nBytes = 0u; |
1684 | - |
1685 | assert ( nBytesInBuf <= INT_MAX ); |
1686 | |
1687 | this->sendDog.start ( currentTime ); |
1688 | @@ -453,6 +450,10 @@ |
1689 | this->iiu.cacRef.destroyIIU ( this->iiu ); |
1690 | return; |
1691 | } |
1692 | + if ( this->iiu.isNameService () ) { |
1693 | + this->iiu.pSearchDest->setCircuit ( &this->iiu ); |
1694 | + this->iiu.pSearchDest->enable (); |
1695 | + } |
1696 | } |
1697 | |
1698 | this->iiu.sendThread.start (); |
1699 | @@ -477,7 +478,7 @@ |
1700 | pComBuf->fillFromWire ( this->iiu, stat ); |
1701 | |
1702 | epicsTime currentTime = epicsTime::getCurrent (); |
1703 | - |
1704 | + |
1705 | { |
1706 | epicsGuard < epicsMutex > guard ( this->iiu.mutex ); |
1707 | |
1708 | @@ -634,17 +635,27 @@ |
1709 | continue; |
1710 | } |
1711 | else if ( errnoCpy == SOCK_SHUTDOWN ) { |
1712 | - break; |
1713 | + if ( ! this->iiu.isNameService () ) { |
1714 | + break; |
1715 | + } |
1716 | } |
1717 | - else { |
1718 | + else { |
1719 | char sockErrBuf[64]; |
1720 | epicsSocketConvertErrnoToString ( |
1721 | sockErrBuf, sizeof ( sockErrBuf ) ); |
1722 | - errlogPrintf ( "CAC: Unable to connect because \"%s\"\n", |
1723 | + errlogPrintf ( "CAC: Unable to connect because \"%s\"\n", |
1724 | sockErrBuf ); |
1725 | - this->iiu.disconnectNotify ( guard ); |
1726 | - break; |
1727 | - } |
1728 | + if ( ! this->iiu.isNameService () ) { |
1729 | + this->iiu.disconnectNotify ( guard ); |
1730 | + break; |
1731 | + } |
1732 | + } |
1733 | + { |
1734 | + double sleepTime = this->iiu.cacRef.connectionTimeout ( guard ); |
1735 | + epicsGuardRelease < epicsMutex > unguard ( guard ); |
1736 | + epicsThreadSleep ( sleepTime ); |
1737 | + } |
1738 | + continue; |
1739 | } |
1740 | } |
1741 | return; |
1742 | @@ -659,7 +670,8 @@ |
1743 | epicsTimerQueue & timerQueue, const osiSockAddr & addrIn, |
1744 | comBufMemoryManager & comBufMemMgrIn, |
1745 | unsigned minorVersion, ipAddrToAsciiEngine & engineIn, |
1746 | - const cacChannel::priLev & priorityIn ) : |
1747 | + const cacChannel::priLev & priorityIn, |
1748 | + SearchDestTCP * pSearchDestIn ) : |
1749 | caServerID ( addrIn.ia, priorityIn ), |
1750 | hostNameCacheInstance ( addrIn, engineIn ), |
1751 | recvThread ( *this, cbMutexIn, ctxNotifyIn, "CAC-TCP-recv", |
1752 | @@ -680,6 +692,7 @@ |
1753 | comBufMemMgr ( comBufMemMgrIn ), |
1754 | cacRef ( cac ), |
1755 | pCurData ( cac.allocateSmallBufferTCP () ), |
1756 | + pSearchDest ( pSearchDestIn ), |
1757 | mutex ( mutexIn ), |
1758 | cbMutex ( cbMutexIn ), |
1759 | minorProtocolVersion ( minorVersion ), |
1760 | @@ -815,6 +828,10 @@ |
1761 | } |
1762 | # endif |
1763 | |
1764 | + if ( isNameService() ) { |
1765 | + pSearchDest->setCircuit ( this ); |
1766 | + } |
1767 | + |
1768 | memset ( (void *) &this->curMsg, '\0', sizeof ( this->curMsg ) ); |
1769 | } |
1770 | |
1771 | @@ -831,6 +848,7 @@ |
1772 | epicsGuard < epicsMutex > & guard ) |
1773 | { |
1774 | guard.assertIdenticalMutex ( this->mutex ); |
1775 | + |
1776 | if ( this->state == iiucs_connected ) { |
1777 | if ( this->unresponsiveCircuit ) { |
1778 | this->initiateAbortShutdown ( guard ); |
1779 | @@ -1014,8 +1032,12 @@ |
1780 | // |
1781 | // tcpiiu::~tcpiiu () |
1782 | // |
1783 | -tcpiiu::~tcpiiu () |
1784 | +tcpiiu :: ~tcpiiu () |
1785 | { |
1786 | + if ( this->pSearchDest ) { |
1787 | + this->pSearchDest->disable (); |
1788 | + } |
1789 | + |
1790 | this->sendThread.exitWait (); |
1791 | this->recvThread.exitWait (); |
1792 | this->sendDog.cancel (); |
1793 | @@ -1830,7 +1852,9 @@ |
1794 | |
1795 | this->channelCountTot = 0u; |
1796 | |
1797 | - this->initiateCleanShutdown ( guard ); |
1798 | + if ( ! isNameService () ) { |
1799 | + this->initiateCleanShutdown ( guard ); |
1800 | + } |
1801 | } |
1802 | |
1803 | void tcpiiu::unlinkAllChannels ( |
1804 | @@ -1839,7 +1863,7 @@ |
1805 | { |
1806 | cbGuard.assertIdenticalMutex ( this->cbMutex ); |
1807 | guard.assertIdenticalMutex ( this->mutex ); |
1808 | - |
1809 | + |
1810 | while ( nciu * pChan = this->createReqPend.get () ) { |
1811 | pChan->serviceShutdownNotify ( cbGuard, guard ); |
1812 | } |
1813 | @@ -1890,7 +1914,9 @@ |
1814 | |
1815 | this->channelCountTot = 0u; |
1816 | |
1817 | - this->initiateCleanShutdown ( guard ); |
1818 | + if ( ! isNameService () ) { |
1819 | + this->initiateCleanShutdown ( guard ); |
1820 | + } |
1821 | } |
1822 | |
1823 | void tcpiiu::installChannel ( |
1824 | @@ -1909,20 +1935,6 @@ |
1825 | this->sendThreadFlushEvent.signal (); |
1826 | } |
1827 | |
1828 | -void tcpiiu::nameResolutionMsgEndNotify () |
1829 | -{ |
1830 | - bool wakeupNeeded = false; |
1831 | - { |
1832 | - epicsGuard < epicsMutex > autoMutex ( this->mutex ); |
1833 | - if ( this->createReqPend.count () ) { |
1834 | - wakeupNeeded = true; |
1835 | - } |
1836 | - } |
1837 | - if ( wakeupNeeded ) { |
1838 | - this->sendThreadFlushEvent.signal (); |
1839 | - } |
1840 | -} |
1841 | - |
1842 | bool tcpiiu :: connectNotify ( |
1843 | epicsGuard < epicsMutex > & guard, nciu & chan ) |
1844 | { |
1845 | @@ -1980,7 +1992,7 @@ |
1846 | } |
1847 | chan.channelNode::listMember = channelNode::cs_none; |
1848 | this->channelCountTot--; |
1849 | - if ( this->channelCountTot == 0 ) { |
1850 | + if ( this->channelCountTot == 0 && ! this->isNameService() ) { |
1851 | this->initiateCleanShutdown ( guard ); |
1852 | } |
1853 | } |
1854 | @@ -2100,5 +2112,81 @@ |
1855 | guard, id, pName, nameLength ); |
1856 | } |
1857 | |
1858 | - |
1859 | - |
1860 | +SearchDestTCP :: SearchDestTCP ( |
1861 | + cac & cacIn, const osiSockAddr & addrIn ) : |
1862 | + _ptcpiiu ( NULL ), |
1863 | + _cac ( cacIn ), |
1864 | + _addr ( addrIn ), |
1865 | + _active ( false ) |
1866 | +{ |
1867 | +} |
1868 | + |
1869 | +void SearchDestTCP :: disable () |
1870 | +{ |
1871 | + _active = false; |
1872 | + _ptcpiiu = NULL; |
1873 | +} |
1874 | + |
1875 | +void SearchDestTCP :: enable () |
1876 | +{ |
1877 | + _active = true; |
1878 | +} |
1879 | + |
1880 | +void SearchDestTCP :: searchRequest ( |
1881 | + epicsGuard < epicsMutex > & guard, |
1882 | + const char * pBuf, size_t len ) |
1883 | +{ |
1884 | + // restart circuit if it was shut down |
1885 | + if ( ! _ptcpiiu ) { |
1886 | + tcpiiu * piiu = NULL; |
1887 | + bool newIIU = _cac.findOrCreateVirtCircuit ( |
1888 | + guard, _addr, cacChannel::priorityDefault, |
1889 | + piiu, CA_UKN_MINOR_VERSION, this ); |
1890 | + if ( newIIU ) { |
1891 | + piiu->start ( guard ); |
1892 | + } |
1893 | + _ptcpiiu = piiu; |
1894 | + } |
1895 | + |
1896 | + // does this server support TCP-based name resolution? |
1897 | + if ( CA_V412 ( _ptcpiiu->minorProtocolVersion ) ) { |
1898 | + guard.assertIdenticalMutex ( _ptcpiiu->mutex ); |
1899 | + assert ( CA_MESSAGE_ALIGN ( len ) == len ); |
1900 | + comQueSendMsgMinder minder ( _ptcpiiu->sendQue, guard ); |
1901 | + _ptcpiiu->sendQue.pushString ( pBuf, len ); |
1902 | + minder.commit (); |
1903 | + _ptcpiiu->flushRequest ( guard ); |
1904 | + } |
1905 | +} |
1906 | + |
1907 | +void SearchDestTCP :: show ( |
1908 | + epicsGuard < epicsMutex > & guard, unsigned level ) const |
1909 | +{ |
1910 | + :: printf ( "tcpiiu :: SearchDestTCP\n" ); |
1911 | +} |
1912 | + |
1913 | +void tcpiiu :: versionRespNotify ( const caHdrLargeArray & msg ) |
1914 | +{ |
1915 | + this->minorProtocolVersion = msg.m_count; |
1916 | +} |
1917 | + |
1918 | +void tcpiiu :: searchRespNotify ( |
1919 | + const epicsTime & currentTime, const caHdrLargeArray & msg ) |
1920 | +{ |
1921 | + /* |
1922 | + * the type field is abused to carry the port number |
1923 | + * so that we can have multiple servers on one host |
1924 | + */ |
1925 | + osiSockAddr serverAddr; |
1926 | + if ( msg.m_cid != INADDR_BROADCAST ) { |
1927 | + serverAddr.ia.sin_family = AF_INET; |
1928 | + serverAddr.ia.sin_addr.s_addr = htonl ( msg.m_cid ); |
1929 | + serverAddr.ia.sin_port = htons ( msg.m_dataType ); |
1930 | + } |
1931 | + else { |
1932 | + serverAddr = this->address (); |
1933 | + } |
1934 | + cacRef.transferChanToVirtCircuit |
1935 | + ( msg.m_available, msg.m_cid, 0xffff, |
1936 | + 0, minorProtocolVersion, serverAddr, currentTime ); |
1937 | +} |
1938 | |
1939 | === modified file 'src/ca/udpiiu.cpp' |
1940 | --- src/ca/udpiiu.cpp 2009-07-09 17:06:45 +0000 |
1941 | +++ src/ca/udpiiu.cpp 2010-05-14 13:38:34 +0000 |
1942 | @@ -1,12 +1,13 @@ |
1943 | /*************************************************************************\ |
1944 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1945 | -* National Laboratory. |
1946 | -* Copyright (c) 2002 The Regents of the University of California, as |
1947 | -* Operator of Los Alamos National Laboratory. |
1948 | -* EPICS BASE Versions 3.13.7 |
1949 | -* and higher are distributed subject to a Software License Agreement found |
1950 | -* in file LICENSE that is included with this distribution. |
1951 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
1952 | + * National Laboratory. |
1953 | + * Copyright (c) 2002 The Regents of the University of California, as |
1954 | + * Operator of Los Alamos National Laboratory. |
1955 | + * EPICS BASE Versions 3.13.7 |
1956 | + * and higher are distributed subject to a Software License Agreement found |
1957 | + * in file LICENSE that is included with this distribution. |
1958 | \*************************************************************************/ |
1959 | + |
1960 | /* |
1961 | * |
1962 | * L O S A L A M O S |
1963 | @@ -73,7 +74,9 @@ |
1964 | epicsMutex & cbMutexIn, |
1965 | epicsMutex & cacMutexIn, |
1966 | cacContextNotify & ctxNotifyIn, |
1967 | - cac & cac ) : |
1968 | + cac & cac, |
1969 | + unsigned port, |
1970 | + tsDLList < SearchDest > & searchDestListIn ) : |
1971 | recvThread ( *this, ctxNotifyIn, cbMutexIn, "CAC-UDP", |
1972 | epicsThreadGetStackSize ( epicsThreadStackMedium ), |
1973 | cac::lowestPriorityLevelAbove ( |
1974 | @@ -95,7 +98,7 @@ |
1975 | lastReceivedSeqNo ( 0 ), |
1976 | sock ( 0 ), |
1977 | repeaterPort ( 0 ), |
1978 | - serverPort ( 0 ), |
1979 | + serverPort ( port ), |
1980 | localPort ( 0 ), |
1981 | shutdownCmd ( false ), |
1982 | lastReceivedSeqNoIsValid ( false ) |
1983 | @@ -150,10 +153,6 @@ |
1984 | envGetInetPortConfigParam ( &EPICS_CA_REPEATER_PORT, |
1985 | static_cast <unsigned short> (CA_REPEATER_PORT) ); |
1986 | |
1987 | - this->serverPort = |
1988 | - envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT, |
1989 | - static_cast <unsigned short> (CA_SERVER_PORT) ); |
1990 | - |
1991 | this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); |
1992 | if ( this->sock == INVALID_SOCKET ) { |
1993 | char sockErrBuf[64]; |
1994 | @@ -238,8 +237,19 @@ |
1995 | * load user and auto configured |
1996 | * broadcast address list |
1997 | */ |
1998 | - ellInit ( & this->dest ); // X aCC 392 |
1999 | - configureChannelAccessAddressList ( & this->dest, this->sock, this->serverPort ); |
2000 | + ELLLIST dest; |
2001 | + ellInit ( & dest ); |
2002 | + configureChannelAccessAddressList ( & dest, this->sock, this->serverPort ); |
2003 | + while ( osiSockAddrNode * |
2004 | + pNode = reinterpret_cast < osiSockAddrNode * > ( ellGet ( & dest ) ) ) { |
2005 | + SearchDestUDP & searchDest = * |
2006 | + new SearchDestUDP ( pNode->addr, *this ); |
2007 | + _searchDestList.add ( searchDest ); |
2008 | + free ( pNode ); |
2009 | + } |
2010 | + |
2011 | + /* add list of tcp name service addresses */ |
2012 | + _searchDestList.add ( searchDestListIn ); |
2013 | |
2014 | caStartRepeaterIfNotInstalled ( this->repeaterPort ); |
2015 | |
2016 | @@ -265,14 +275,12 @@ |
2017 | this->shutdown ( cbGuard, guard ); |
2018 | } |
2019 | |
2020 | - // avoid use of ellFree because problems on windows occur if the |
2021 | - // free is in a different DLL than the malloc |
2022 | - ELLNODE * nnode = this->dest.node.next; |
2023 | - while ( nnode ) |
2024 | + tsDLIter < SearchDest > iter ( _searchDestList.firstIter () ); |
2025 | + while ( iter.valid () ) |
2026 | { |
2027 | - ELLNODE * pnode = nnode; |
2028 | - nnode = nnode->next; |
2029 | - free ( pnode ); |
2030 | + SearchDest & curr ( *iter ); |
2031 | + iter++; |
2032 | + delete & curr; |
2033 | } |
2034 | |
2035 | epicsSocketDestroy ( this->sock ); |
2036 | @@ -344,7 +352,7 @@ |
2037 | { |
2038 | epicsThreadPrivateSet ( caClientCallbackThreadId, &this->iiu ); |
2039 | |
2040 | - if ( ellCount ( & this->iiu.dest ) == 0 ) { // X aCC 392 |
2041 | + if ( this->iiu._searchDestList.count () == 0 ) { |
2042 | callbackManager mgr ( this->ctxNotify, this->cbMutex ); |
2043 | epicsGuard < epicsMutex > guard ( this->iiu.cacMutex ); |
2044 | genLocalExcep ( mgr.cbGuard, guard, |
2045 | @@ -614,26 +622,31 @@ |
2046 | return true; |
2047 | } |
2048 | |
2049 | -bool udpiiu::searchRespAction ( // X aCC 361 |
2050 | - const caHdr &msg, |
2051 | - const osiSockAddr & addr, const epicsTime & currentTime ) |
2052 | +bool udpiiu :: searchRespAction ( |
2053 | + const caHdr & msg, const osiSockAddr & addr, |
2054 | + const epicsTime & currentTime ) |
2055 | { |
2056 | + /* |
2057 | + * we dont currently know what to do with channel's |
2058 | + * found to be at non-IP type addresses |
2059 | + */ |
2060 | if ( addr.sa.sa_family != AF_INET ) { |
2061 | - return false; |
2062 | + return true; |
2063 | } |
2064 | |
2065 | /* |
2066 | * Starting with CA V4.1 the minor version number |
2067 | - * is appended to the end of each search reply. |
2068 | + * is appended to the end of each UDP search reply. |
2069 | * This value is ignored by earlier clients. |
2070 | */ |
2071 | ca_uint32_t minorVersion; |
2072 | - if ( msg.m_postsize >= sizeof (minorVersion) ){ |
2073 | + if ( msg.m_postsize >= sizeof ( minorVersion ) ){ |
2074 | /* |
2075 | * care is taken here not to break gcc 3.2 aggressive alias |
2076 | * analysis rules |
2077 | */ |
2078 | - ca_uint8_t * pPayLoad = ( ca_uint8_t *) ( &msg + 1 ); |
2079 | + const ca_uint8_t * pPayLoad = |
2080 | + reinterpret_cast < const ca_uint8_t *> ( & msg + 1 ); |
2081 | unsigned byte0 = pPayLoad[0]; |
2082 | unsigned byte1 = pPayLoad[1]; |
2083 | minorVersion = ( byte0 << 8u ) | byte1; |
2084 | @@ -667,12 +680,12 @@ |
2085 | } |
2086 | |
2087 | if ( CA_V42 ( minorVersion ) ) { |
2088 | - this->cacRef.transferChanToVirtCircuit |
2089 | + cacRef.transferChanToVirtCircuit |
2090 | ( msg.m_available, msg.m_cid, 0xffff, |
2091 | 0, minorVersion, serverAddr, currentTime ); |
2092 | } |
2093 | else { |
2094 | - this->cacRef.transferChanToVirtCircuit |
2095 | + cacRef.transferChanToVirtCircuit |
2096 | ( msg.m_available, msg.m_cid, msg.m_dataType, |
2097 | msg.m_count, minorVersion, serverAddr, currentTime ); |
2098 | } |
2099 | @@ -895,62 +908,167 @@ |
2100 | return true; |
2101 | } |
2102 | |
2103 | -bool udpiiu::datagramFlush ( |
2104 | - epicsGuard < epicsMutex > &, const epicsTime & /* currentTime */ ) |
2105 | -{ |
2106 | +udpiiu :: SearchDestUDP :: SearchDestUDP ( |
2107 | + const osiSockAddr & destAddr, udpiiu & udpiiuIn ) : |
2108 | + _destAddr ( destAddr ), _udpiiu ( udpiiuIn ) |
2109 | +{ |
2110 | +} |
2111 | + |
2112 | +void udpiiu :: SearchDestUDP :: searchRequest ( |
2113 | + epicsGuard < epicsMutex > & guard, const char * pBuf, size_t bufSize ) |
2114 | +{ |
2115 | + guard.assertIdenticalMutex ( _udpiiu.cacMutex ); |
2116 | + assert ( bufSize <= INT_MAX ); |
2117 | + int bufSizeAsInt = static_cast < int > ( bufSize ); |
2118 | + while ( true ) { |
2119 | + int status = sendto ( _udpiiu.sock, pBuf, bufSizeAsInt, 0, |
2120 | + & _destAddr.sa, sizeof ( _destAddr.sa ) ); |
2121 | + if ( status == bufSizeAsInt ) { |
2122 | + break; |
2123 | + } |
2124 | + if ( status >= 0 ) { |
2125 | + errlogPrintf ( "CAC: UDP sendto () call returned strange xmit count?\n" ); |
2126 | + break; |
2127 | + } |
2128 | + else { |
2129 | + int localErrno = SOCKERRNO; |
2130 | + |
2131 | + if ( localErrno == SOCK_EINTR ) { |
2132 | + if ( _udpiiu.shutdownCmd ) { |
2133 | + break; |
2134 | + } |
2135 | + else { |
2136 | + continue; |
2137 | + } |
2138 | + } |
2139 | + else if ( localErrno == SOCK_SHUTDOWN ) { |
2140 | + break; |
2141 | + } |
2142 | + else if ( localErrno == SOCK_ENOTSOCK ) { |
2143 | + break; |
2144 | + } |
2145 | + else if ( localErrno == SOCK_EBADF ) { |
2146 | + break; |
2147 | + } |
2148 | + else { |
2149 | + char sockErrBuf[64]; |
2150 | + epicsSocketConvertErrnoToString ( |
2151 | + sockErrBuf, sizeof ( sockErrBuf ) ); |
2152 | + char buf[64]; |
2153 | + sockAddrToDottedIP ( &_destAddr.sa, buf, sizeof ( buf ) ); |
2154 | + errlogPrintf ( |
2155 | + "CAC: error = \"%s\" sending UDP msg to %s\n", |
2156 | + sockErrBuf, buf); |
2157 | + break; |
2158 | + } |
2159 | + } |
2160 | + } |
2161 | +} |
2162 | + |
2163 | +void udpiiu :: SearchDestUDP :: show ( |
2164 | + epicsGuard < epicsMutex > & guard, unsigned level ) const |
2165 | +{ |
2166 | + guard.assertIdenticalMutex ( _udpiiu.cacMutex ); |
2167 | + char buf[64]; |
2168 | + sockAddrToDottedIP ( &_destAddr.sa, buf, sizeof ( buf ) ); |
2169 | + :: printf ( "UDP Search destination \"%s\"\n", buf ); |
2170 | +} |
2171 | + |
2172 | +udpiiu :: SearchRespCallback :: SearchRespCallback ( udpiiu & udpiiuIn ) : |
2173 | + _udpiiu ( udpiiuIn ) |
2174 | +{ |
2175 | +} |
2176 | + |
2177 | +void udpiiu :: SearchRespCallback :: notify ( |
2178 | + const caHdr & msg, const void * pPayloadUntyped, |
2179 | + const osiSockAddr & addr, const epicsTime & currentTime ) |
2180 | +{ |
2181 | + /* |
2182 | + * we dont currently know what to do with channel's |
2183 | + * found to be at non-IP type addresses |
2184 | + */ |
2185 | + if ( addr.sa.sa_family != AF_INET ) { |
2186 | + return; |
2187 | + } |
2188 | + |
2189 | + /* |
2190 | + * Starting with CA V4.1 the minor version number |
2191 | + * is appended to the end of each search reply. |
2192 | + * This value is ignored by earlier clients. |
2193 | + */ |
2194 | + ca_uint32_t minorVersion; |
2195 | + if ( msg.m_postsize >= sizeof ( minorVersion ) ){ |
2196 | + /* |
2197 | + * care is taken here not to break gcc 3.2 aggressive alias |
2198 | + * analysis rules |
2199 | + */ |
2200 | + const ca_uint8_t * pPayLoad = reinterpret_cast < const ca_uint8_t *> ( pPayloadUntyped ); |
2201 | + unsigned byte0 = pPayLoad[0]; |
2202 | + unsigned byte1 = pPayLoad[1]; |
2203 | + minorVersion = ( byte0 << 8u ) | byte1; |
2204 | + } |
2205 | + else { |
2206 | + minorVersion = CA_UKN_MINOR_VERSION; |
2207 | + } |
2208 | + |
2209 | + /* |
2210 | + * the type field is abused to carry the port number |
2211 | + * so that we can have multiple servers on one host |
2212 | + */ |
2213 | + osiSockAddr serverAddr; |
2214 | + serverAddr.ia.sin_family = AF_INET; |
2215 | + if ( CA_V48 ( minorVersion ) ) { |
2216 | + if ( msg.m_cid != INADDR_BROADCAST ) { |
2217 | + serverAddr.ia.sin_addr.s_addr = htonl ( msg.m_cid ); |
2218 | + } |
2219 | + else { |
2220 | + serverAddr.ia.sin_addr = addr.ia.sin_addr; |
2221 | + } |
2222 | + serverAddr.ia.sin_port = htons ( msg.m_dataType ); |
2223 | + } |
2224 | + else if ( CA_V45 (minorVersion) ) { |
2225 | + serverAddr.ia.sin_port = htons ( msg.m_dataType ); |
2226 | + serverAddr.ia.sin_addr = addr.ia.sin_addr; |
2227 | + } |
2228 | + else { |
2229 | + serverAddr.ia.sin_port = htons ( _udpiiu.serverPort ); |
2230 | + serverAddr.ia.sin_addr = addr.ia.sin_addr; |
2231 | + } |
2232 | + |
2233 | + if ( CA_V42 ( minorVersion ) ) { |
2234 | + _udpiiu.cacRef.transferChanToVirtCircuit |
2235 | + ( msg.m_available, msg.m_cid, 0xffff, |
2236 | + 0, minorVersion, serverAddr, currentTime ); |
2237 | + } |
2238 | + else { |
2239 | + _udpiiu.cacRef.transferChanToVirtCircuit |
2240 | + ( msg.m_available, msg.m_cid, msg.m_dataType, |
2241 | + msg.m_count, minorVersion, serverAddr, currentTime ); |
2242 | + } |
2243 | +} |
2244 | + |
2245 | +void udpiiu :: SearchRespCallback :: show ( |
2246 | + epicsGuard < epicsMutex > & guard, unsigned level ) const |
2247 | +{ |
2248 | + guard.assertIdenticalMutex ( _udpiiu.cacMutex ); |
2249 | + ::printf ( "udpiiu :: SearchRespCallback\n" ); |
2250 | +} |
2251 | + |
2252 | +bool udpiiu :: datagramFlush ( |
2253 | + epicsGuard < epicsMutex > & guard, const epicsTime & currentTime ) |
2254 | +{ |
2255 | + guard.assertIdenticalMutex ( cacMutex ); |
2256 | + |
2257 | // dont send the version header by itself |
2258 | if ( this->nBytesInXmitBuf <= sizeof ( caHdr ) ) { |
2259 | return false; |
2260 | } |
2261 | |
2262 | - osiSockAddrNode *pNode = ( osiSockAddrNode * ) // X aCC 749 |
2263 | - ellFirst ( & this->dest ); |
2264 | - while ( pNode ) { |
2265 | - int status; |
2266 | - |
2267 | - assert ( this->nBytesInXmitBuf <= INT_MAX ); |
2268 | - status = sendto ( this->sock, this->xmitBuf, |
2269 | - (int) this->nBytesInXmitBuf, 0, |
2270 | - &pNode->addr.sa, sizeof ( pNode->addr.sa ) ); |
2271 | - if ( status != (int) this->nBytesInXmitBuf ) { |
2272 | - if ( status >= 0 ) { |
2273 | - errlogPrintf ( "CAC: UDP sendto () call returned strange xmit count?\n" ); |
2274 | - break; |
2275 | - } |
2276 | - else { |
2277 | - int localErrno = SOCKERRNO; |
2278 | - |
2279 | - if ( localErrno == SOCK_EINTR ) { |
2280 | - if ( this->shutdownCmd ) { |
2281 | - break; |
2282 | - } |
2283 | - else { |
2284 | - continue; |
2285 | - } |
2286 | - } |
2287 | - else if ( localErrno == SOCK_SHUTDOWN ) { |
2288 | - break; |
2289 | - } |
2290 | - else if ( localErrno == SOCK_ENOTSOCK ) { |
2291 | - break; |
2292 | - } |
2293 | - else if ( localErrno == SOCK_EBADF ) { |
2294 | - break; |
2295 | - } |
2296 | - else { |
2297 | - char sockErrBuf[64]; |
2298 | - epicsSocketConvertErrnoToString ( |
2299 | - sockErrBuf, sizeof ( sockErrBuf ) ); |
2300 | - char buf[64]; |
2301 | - sockAddrToDottedIP ( &pNode->addr.sa, buf, sizeof ( buf ) ); |
2302 | - errlogPrintf ( |
2303 | - "CAC: error = \"%s\" sending UDP msg to %s\n", |
2304 | - sockErrBuf, buf); |
2305 | - break; |
2306 | - } |
2307 | - } |
2308 | - } |
2309 | - pNode = (osiSockAddrNode *) ellNext ( &pNode->node ); // X aCC 749 |
2310 | + tsDLIter < SearchDest > iter ( _searchDestList.firstIter () ); |
2311 | + while ( iter.valid () ) |
2312 | + { |
2313 | + iter->searchRequest ( guard, this->xmitBuf, this->nBytesInXmitBuf ); |
2314 | + iter++; |
2315 | } |
2316 | |
2317 | this->nBytesInXmitBuf = 0u; |
2318 | @@ -960,7 +1078,7 @@ |
2319 | return true; |
2320 | } |
2321 | |
2322 | -void udpiiu::show ( unsigned level ) const |
2323 | +void udpiiu :: show ( unsigned level ) const |
2324 | { |
2325 | epicsGuard < epicsMutex > guard ( this->cacMutex ); |
2326 | |
2327 | @@ -968,7 +1086,17 @@ |
2328 | if ( level > 1u ) { |
2329 | ::printf ("\trepeater port %u\n", this->repeaterPort ); |
2330 | ::printf ("\tdefault server port %u\n", this->serverPort ); |
2331 | - printChannelAccessAddressList ( & this->dest ); |
2332 | + ::printf ( "Search Destination List with %u items\n", |
2333 | + _searchDestList.count () ); |
2334 | + if ( level > 2u ) { |
2335 | + tsDLIterConst < SearchDest > iter ( |
2336 | + _searchDestList.firstIter () ); |
2337 | + while ( iter.valid () ) |
2338 | + { |
2339 | + iter->show ( guard, level - 2 ); |
2340 | + iter++; |
2341 | + } |
2342 | + } |
2343 | } |
2344 | if ( level > 2u ) { |
2345 | ::printf ("\tsocket identifier %d\n", this->sock ); |
2346 | |
2347 | === modified file 'src/ca/udpiiu.h' |
2348 | --- src/ca/udpiiu.h 2007-08-23 17:46:28 +0000 |
2349 | +++ src/ca/udpiiu.h 2010-05-14 13:38:34 +0000 |
2350 | @@ -1,11 +1,11 @@ |
2351 | /*************************************************************************\ |
2352 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2353 | -* National Laboratory. |
2354 | -* Copyright (c) 2002 The Regents of the University of California, as |
2355 | -* Operator of Los Alamos National Laboratory. |
2356 | -* EPICS BASE Versions 3.13.7 |
2357 | -* and higher are distributed subject to a Software License Agreement found |
2358 | -* in file LICENSE that is included with this distribution. |
2359 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2360 | + * National Laboratory. |
2361 | + * Copyright (c) 2002 The Regents of the University of California, as |
2362 | + * Operator of Los Alamos National Laboratory. |
2363 | + * EPICS BASE Versions 3.13.7 |
2364 | + * and higher are distributed subject to a Software License Agreement found |
2365 | + * in file LICENSE that is included with this distribution. |
2366 | \*************************************************************************/ |
2367 | |
2368 | /* |
2369 | @@ -47,6 +47,7 @@ |
2370 | #include "searchTimer.h" |
2371 | #include "disconnectGovernorTimer.h" |
2372 | #include "repeaterSubscribeTimer.h" |
2373 | +#include "SearchDest.h" |
2374 | |
2375 | extern "C" void cacRecvThreadUDP ( void *pParam ); |
2376 | |
2377 | @@ -97,7 +98,9 @@ |
2378 | epicsMutex & callbackControl, |
2379 | epicsMutex & mutualExclusion, |
2380 | cacContextNotify &, |
2381 | - class cac & ); |
2382 | + class cac &, |
2383 | + unsigned port, |
2384 | + tsDLList < SearchDest > & ); |
2385 | virtual ~udpiiu (); |
2386 | void installNewChannel ( |
2387 | epicsGuard < epicsMutex > &, nciu &, netiiu * & ); |
2388 | @@ -108,17 +111,41 @@ |
2389 | void shutdown ( epicsGuard < epicsMutex > & cbGuard, |
2390 | epicsGuard < epicsMutex > & guard ); |
2391 | void show ( unsigned level ) const; |
2392 | - |
2393 | + |
2394 | // exceptions |
2395 | class noSocket {}; |
2396 | |
2397 | private: |
2398 | + class SearchDestUDP : |
2399 | + public SearchDest { |
2400 | + public: |
2401 | + SearchDestUDP ( const osiSockAddr &, udpiiu & ); |
2402 | + void searchRequest ( |
2403 | + epicsGuard < epicsMutex > &, const char * pBuf, size_t bufLen ); |
2404 | + void show ( |
2405 | + epicsGuard < epicsMutex > &, unsigned level ) const; |
2406 | + private: |
2407 | + osiSockAddr _destAddr; |
2408 | + udpiiu & _udpiiu; |
2409 | + }; |
2410 | + class SearchRespCallback : |
2411 | + public SearchDest :: Callback { |
2412 | + public: |
2413 | + SearchRespCallback ( udpiiu & ); |
2414 | + void notify ( |
2415 | + const caHdr &, const void * pPayload, |
2416 | + const osiSockAddr &, const epicsTime & ); |
2417 | + void show ( |
2418 | + epicsGuard < epicsMutex > &, unsigned level ) const; |
2419 | + private: |
2420 | + udpiiu & _udpiiu; |
2421 | + }; |
2422 | char xmitBuf [MAX_UDP_SEND]; |
2423 | char recvBuf [MAX_UDP_RECV]; |
2424 | udpRecvThread recvThread; |
2425 | repeaterSubscribeTimer repeaterSubscribeTmr; |
2426 | disconnectGovernorTimer govTmr; |
2427 | - ELLLIST dest; |
2428 | + tsDLList < SearchDest > _searchDestList; |
2429 | double maxPeriod; |
2430 | double rtteMean; |
2431 | double rtteMeanDev; |
2432 | |
2433 | === modified file 'src/ca/virtualCircuit.h' |
2434 | --- src/ca/virtualCircuit.h 2009-07-14 22:39:41 +0000 |
2435 | +++ src/ca/virtualCircuit.h 2010-05-14 13:38:34 +0000 |
2436 | @@ -1,12 +1,13 @@ |
2437 | /*************************************************************************\ |
2438 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2439 | -* National Laboratory. |
2440 | -* Copyright (c) 2002 The Regents of the University of California, as |
2441 | -* Operator of Los Alamos National Laboratory. |
2442 | -* EPICS BASE Versions 3.13.7 |
2443 | -* and higher are distributed subject to a Software License Agreement found |
2444 | -* in file LICENSE that is included with this distribution. |
2445 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2446 | + * National Laboratory. |
2447 | + * Copyright (c) 2002 The Regents of the University of California, as |
2448 | + * Operator of Los Alamos National Laboratory. |
2449 | + * EPICS BASE Versions 3.13.7 |
2450 | + * and higher are distributed subject to a Software License Agreement found |
2451 | + * in file LICENSE that is included with this distribution. |
2452 | \*************************************************************************/ |
2453 | + |
2454 | /* |
2455 | * |
2456 | * |
2457 | @@ -37,6 +38,7 @@ |
2458 | #include "tcpRecvWatchdog.h" |
2459 | #include "tcpSendWatchdog.h" |
2460 | #include "hostNameCache.h" |
2461 | +#include "SearchDest.h" |
2462 | #include "compilerDependencies.h" |
2463 | |
2464 | class callbackManager; |
2465 | @@ -93,15 +95,34 @@ |
2466 | void run (); |
2467 | }; |
2468 | |
2469 | -class tcpiiu : |
2470 | +class SearchDestTCP : public SearchDest { |
2471 | +public: |
2472 | + SearchDestTCP ( cac &, const osiSockAddr & ); |
2473 | + void searchRequest ( epicsGuard < epicsMutex > & guard, |
2474 | + const char * pbuf, size_t len ); |
2475 | + void show ( epicsGuard < epicsMutex > & guard, unsigned level ) const; |
2476 | + void setCircuit ( tcpiiu * ); |
2477 | + void disable (); |
2478 | + void enable (); |
2479 | +private: |
2480 | + tcpiiu * _ptcpiiu; |
2481 | + cac & _cac; |
2482 | + const osiSockAddr _addr; |
2483 | + bool _active; |
2484 | +}; |
2485 | + |
2486 | +class tcpiiu : |
2487 | public netiiu, public tsDLNode < tcpiiu >, |
2488 | public tsSLNode < tcpiiu >, public caServerID, |
2489 | private wireSendAdapter, private wireRecvAdapter { |
2490 | + friend void SearchDestTCP::searchRequest ( epicsGuard < epicsMutex > & guard, |
2491 | + const char * pbuf, size_t len ); |
2492 | public: |
2493 | tcpiiu ( cac & cac, epicsMutex & mutualExclusion, epicsMutex & callbackControl, |
2494 | cacContextNotify &, double connectionTimeout, epicsTimerQueue & timerQueue, |
2495 | const osiSockAddr & addrIn, comBufMemoryManager &, unsigned minorVersion, |
2496 | - ipAddrToAsciiEngine & engineIn, const cacChannel::priLev & priorityIn ); |
2497 | + ipAddrToAsciiEngine & engineIn, const cacChannel::priLev & priorityIn, |
2498 | + SearchDestTCP * pSearchDestIn = NULL); |
2499 | ~tcpiiu (); |
2500 | void start ( |
2501 | epicsGuard < epicsMutex > & ); |
2502 | @@ -175,12 +196,15 @@ |
2503 | epicsGuard < epicsMutex > & guard, nciu & chan ); |
2504 | bool connectNotify ( |
2505 | epicsGuard < epicsMutex > &, nciu & chan ); |
2506 | - void nameResolutionMsgEndNotify (); |
2507 | + |
2508 | + void searchRespNotify ( |
2509 | + const epicsTime &, const caHdrLargeArray & ); |
2510 | + void versionRespNotify ( const caHdrLargeArray & ); |
2511 | |
2512 | void * operator new ( size_t size, |
2513 | tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & ); |
2514 | - epicsPlacementDeleteOperator (( void *, |
2515 | - tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & )) |
2516 | + epicsPlacementDeleteOperator (( void *, |
2517 | + tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & )); |
2518 | |
2519 | private: |
2520 | hostNameCache hostNameCacheInstance; |
2521 | @@ -205,6 +229,7 @@ |
2522 | comBufMemoryManager & comBufMemMgr; |
2523 | cac & cacRef; |
2524 | char * pCurData; |
2525 | + SearchDestTCP * pSearchDest; |
2526 | epicsMutex & mutex; |
2527 | epicsMutex & cbMutex; |
2528 | unsigned minorProtocolVersion; |
2529 | @@ -257,6 +282,7 @@ |
2530 | bool bytesArePendingInOS () const; |
2531 | void decrementBlockingForFlushCount ( |
2532 | epicsGuard < epicsMutex > & guard ); |
2533 | + bool isNameService () const; |
2534 | |
2535 | // send protocol stubs |
2536 | void echoRequest ( |
2537 | @@ -386,5 +412,14 @@ |
2538 | this->recvDog.probeResponseNotify ( cbGuard ); |
2539 | } |
2540 | |
2541 | +inline bool tcpiiu::isNameService () const |
2542 | +{ |
2543 | + return ( this->pSearchDest != NULL ); |
2544 | +} |
2545 | + |
2546 | +inline void SearchDestTCP::setCircuit ( tcpiiu * piiu ) |
2547 | +{ |
2548 | + _ptcpiiu = piiu; |
2549 | +} |
2550 | + |
2551 | #endif // ifdef virtualCircuith |
2552 | - |
2553 | |
2554 | === modified file 'src/cas/generic/caHdrLargeArray.h' |
2555 | --- src/cas/generic/caHdrLargeArray.h 2003-02-12 19:11:43 +0000 |
2556 | +++ src/cas/generic/caHdrLargeArray.h 2010-05-14 13:38:34 +0000 |
2557 | @@ -32,7 +32,7 @@ |
2558 | # include "shareLib.h" |
2559 | #endif |
2560 | |
2561 | -static const unsigned char CA_MINOR_PROTOCOL_REVISION = 11; |
2562 | +static const unsigned char CA_MINOR_PROTOCOL_REVISION = 12; |
2563 | |
2564 | typedef ca_uint32_t caResId; |
2565 | |
2566 | |
2567 | === modified file 'src/cas/generic/casStrmClient.cc' |
2568 | --- src/cas/generic/casStrmClient.cc 2009-08-18 00:36:22 +0000 |
2569 | +++ src/cas/generic/casStrmClient.cc 2010-05-14 13:38:34 +0000 |
2570 | @@ -1,29 +1,27 @@ |
2571 | /*************************************************************************\ |
2572 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2573 | -* National Laboratory. |
2574 | -* Copyright (c) 2002 The Regents of the University of California, as |
2575 | -* Operator of Los Alamos National Laboratory. |
2576 | -* EPICS BASE Versions 3.13.7 |
2577 | -* and higher are distributed subject to a Software License Agreement found |
2578 | -* in file LICENSE that is included with this distribution. |
2579 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2580 | + * National Laboratory. |
2581 | + * Copyright (c) 2002 The Regents of the University of California, as |
2582 | + * Operator of Los Alamos National Laboratory. |
2583 | + * EPICS BASE Versions 3.13.7 |
2584 | + * and higher are distributed subject to a Software License Agreement found |
2585 | + * in file LICENSE that is included with this distribution. |
2586 | \*************************************************************************/ |
2587 | + |
2588 | /* |
2589 | - * $Id$ |
2590 | - * |
2591 | * Author Jeffrey O. Hill |
2592 | - * johill@lanl.gov |
2593 | - * 505 665 1831 |
2594 | */ |
2595 | |
2596 | // *must* be defined before including net_convert.h |
2597 | typedef unsigned long arrayElementCount; |
2598 | |
2599 | #include "osiWireFormat.h" |
2600 | -#include "net_convert.h" // byte order conversion from libca |
2601 | -#include "dbMapper.h" // ait to dbr types |
2602 | +#include "net_convert.h" // byte order conversion from libca |
2603 | +#include "dbMapper.h" // ait to dbr types |
2604 | #include "gddAppTable.h" // EPICS application type table |
2605 | -#include "gddApps.h" // gdd predefined application type codes |
2606 | +#include "gddApps.h" // gdd predefined application type codes |
2607 | #include "errlog.h" |
2608 | +#include "osiPoolStatus.h" // is there sufficent space in pool |
2609 | |
2610 | #define epicsExportSharedSymbols |
2611 | #include "casStrmClient.h" |
2612 | @@ -47,7 +45,7 @@ |
2613 | & casStrmClient::readAction, |
2614 | & casStrmClient::writeAction, |
2615 | & casStrmClient::uknownMessageAction, |
2616 | - & casStrmClient::uknownMessageAction, |
2617 | + & casStrmClient::searchAction, |
2618 | & casStrmClient::uknownMessageAction, |
2619 | & casStrmClient::eventsOffAction, |
2620 | & casStrmClient::eventsOnAction, |
2621 | @@ -74,10 +72,13 @@ |
2622 | // |
2623 | // casStrmClient::casStrmClient() |
2624 | // |
2625 | -casStrmClient::casStrmClient ( caServerI & cas, clientBufMemoryManager & mgrIn ) : |
2626 | +casStrmClient::casStrmClient ( |
2627 | + caServerI & cas, clientBufMemoryManager & mgrIn, |
2628 | + const caNetAddr & clientAddr ) : |
2629 | casCoreClient ( cas ), |
2630 | in ( *this, mgrIn, 1 ), |
2631 | out ( *this, mgrIn ), |
2632 | + _clientAddr ( clientAddr ), |
2633 | pUserName ( 0 ), |
2634 | pHostName ( 0 ), |
2635 | incommingBytesToDrain ( 0 ), |
2636 | @@ -141,7 +142,7 @@ |
2637 | this->incommingBytesToDrain = 0u; |
2638 | } |
2639 | } |
2640 | - |
2641 | + |
2642 | // |
2643 | // process any messages in the in buffer |
2644 | // |
2645 | @@ -618,30 +619,30 @@ |
2646 | } |
2647 | |
2648 | { |
2649 | - caStatus servStat = this->read (); |
2650 | - if ( servStat == S_casApp_success ) { |
2651 | + caStatus servStat = this->read (); |
2652 | + if ( servStat == S_casApp_success ) { |
2653 | assert ( pValueRead.valid () ); |
2654 | caStatus status = this->readNotifyResponse ( |
2655 | guard, pChan, *mp, |
2656 | *pValueRead, servStat ); |
2657 | this->responseIsPending = ( status != S_cas_success ); |
2658 | return status; |
2659 | - } |
2660 | - else if ( servStat == S_casApp_asyncCompletion ) { |
2661 | - return S_cas_success; |
2662 | - } |
2663 | - else if ( servStat == S_casApp_postponeAsyncIO ) { |
2664 | + } |
2665 | + else if ( servStat == S_casApp_asyncCompletion ) { |
2666 | + return S_cas_success; |
2667 | + } |
2668 | + else if ( servStat == S_casApp_postponeAsyncIO ) { |
2669 | return S_casApp_postponeAsyncIO; |
2670 | - } |
2671 | - else { |
2672 | - caStatus status = this->readNotifyFailureResponse ( |
2673 | - guard, *mp, ECA_GETFAIL ); |
2674 | + } |
2675 | + else { |
2676 | + caStatus status = this->readNotifyFailureResponse ( |
2677 | + guard, *mp, ECA_GETFAIL ); |
2678 | if ( status != S_cas_success ) { |
2679 | this->pendingResponseStatus = servStat; |
2680 | - this->responseIsPending = true; |
2681 | - } |
2682 | + this->responseIsPending = true; |
2683 | + } |
2684 | return status; |
2685 | - } |
2686 | + } |
2687 | } |
2688 | } |
2689 | |
2690 | @@ -1025,23 +1026,23 @@ |
2691 | // |
2692 | { |
2693 | caStatus servStat = this->write ( & casChannelI :: write ); |
2694 | - if ( servStat == S_casApp_success || |
2695 | + if ( servStat == S_casApp_success || |
2696 | servStat == S_casApp_asyncCompletion ) { |
2697 | return S_cas_success; |
2698 | - } |
2699 | - else if ( servStat == S_casApp_postponeAsyncIO ) { |
2700 | + } |
2701 | + else if ( servStat == S_casApp_postponeAsyncIO ) { |
2702 | return S_casApp_postponeAsyncIO; |
2703 | - } |
2704 | - else { |
2705 | + } |
2706 | + else { |
2707 | caStatus status = |
2708 | this->writeActionSendFailureStatus ( guard, *mp, |
2709 | pChan->getCID(), servStat ); |
2710 | if ( status != S_cas_success ) { |
2711 | this->pendingResponseStatus = servStat; |
2712 | this->responseIsPending = true; |
2713 | - } |
2714 | + } |
2715 | return status; |
2716 | - } |
2717 | + } |
2718 | } |
2719 | |
2720 | // |
2721 | @@ -1194,6 +1195,221 @@ |
2722 | return status; |
2723 | } |
2724 | |
2725 | +// |
2726 | +// casStrmClient :: asyncSearchResp() |
2727 | +// |
2728 | +caStatus casStrmClient :: asyncSearchResponse ( |
2729 | + epicsGuard < casClientMutex > & guard, const caNetAddr & /* outAddr */, |
2730 | + const caHdrLargeArray & msg, const pvExistReturn & retVal, |
2731 | + ca_uint16_t /* protocolRevision */, ca_uint32_t /* sequenceNumber */ ) |
2732 | +{ |
2733 | + return this->searchResponse ( guard, msg, retVal ); |
2734 | +} |
2735 | + |
2736 | +// casStrmClient :: hostName() |
2737 | +void casStrmClient :: hostName ( char * pInBuf, unsigned bufSizeIn ) const |
2738 | +{ |
2739 | + _clientAddr.stringConvert ( pInBuf, bufSizeIn ); |
2740 | +} |
2741 | + |
2742 | +// |
2743 | +// caStatus casStrmClient :: searchResponse() |
2744 | +// |
2745 | +caStatus casStrmClient :: searchResponse ( |
2746 | + epicsGuard < casClientMutex > & guard, |
2747 | + const caHdrLargeArray & msg, |
2748 | + const pvExistReturn & retVal ) |
2749 | +{ |
2750 | + if ( retVal.getStatus() != pverExistsHere ) { |
2751 | + return S_cas_success; |
2752 | + } |
2753 | + |
2754 | + // |
2755 | + // starting with V4.1 the count field is used (abused) |
2756 | + // by the client to store the minor version number of |
2757 | + // the client. |
2758 | + // |
2759 | + // Old versions expect alloc of channel in response |
2760 | + // to a search request. This is no longer supported. |
2761 | + // |
2762 | + if ( !CA_V44( msg.m_count ) ) { |
2763 | + errlogPrintf ( |
2764 | + "client \"%s\" using EPICS R3.11 CA " |
2765 | + "connect protocol was ignored\n", |
2766 | + pHostName ); |
2767 | + // |
2768 | + // old connect protocol was dropped when the |
2769 | + // new API was added to the server (they must |
2770 | + // now use clients at EPICS 3.12 or higher) |
2771 | + // |
2772 | + caStatus status = this->sendErr ( |
2773 | + guard, & msg, invalidResID, ECA_DEFUNCT, |
2774 | + "R3.11 connect sequence from old client was ignored" ); |
2775 | + return status; |
2776 | + } |
2777 | + |
2778 | + // |
2779 | + // cid field is abused to carry the IP |
2780 | + // address in CA_V48 or higher |
2781 | + // (this allows a CA servers to serve |
2782 | + // as a directory service) |
2783 | + // |
2784 | + // data type field is abused to carry the IP |
2785 | + // port number here CA_V44 or higher |
2786 | + // (this allows multiple CA servers on one |
2787 | + // host) |
2788 | + // |
2789 | + ca_uint32_t serverAddr; |
2790 | + ca_uint16_t serverPort; |
2791 | + if ( CA_V48( msg.m_count ) ) { |
2792 | + struct sockaddr_in ina; |
2793 | + if ( retVal.addrIsValid() ) { |
2794 | + caNetAddr addr = retVal.getAddr(); |
2795 | + ina = addr.getSockIP(); |
2796 | + // |
2797 | + // If they dont specify a port number then the default |
2798 | + // CA server port is assumed when it it is a server |
2799 | + // address redirect (it is never correct to use this |
2800 | + // server's port when it is a redirect). |
2801 | + // |
2802 | + if ( ina.sin_port == 0u ) { |
2803 | + ina.sin_port = htons ( CA_SERVER_PORT ); |
2804 | + } |
2805 | + } |
2806 | + else { |
2807 | + // |
2808 | + // We dont fill in the servers address here because |
2809 | + // the client has a tcp circuit to us and he knows |
2810 | + // our address |
2811 | + // |
2812 | + ina.sin_addr.s_addr = htonl ( ~0U ); |
2813 | + ina.sin_port = htons ( 0 ); |
2814 | + } |
2815 | + serverAddr = ntohl ( ina.sin_addr.s_addr ); |
2816 | + serverPort = ntohs ( ina.sin_port ); |
2817 | + } |
2818 | + else { |
2819 | + serverAddr = ntohl ( ~0U ); |
2820 | + serverPort = ntohs ( 0 ); |
2821 | + } |
2822 | + |
2823 | + caStatus status = this->out.copyInHeader ( CA_PROTO_SEARCH, |
2824 | + 0, serverPort, 0, serverAddr, msg.m_available, 0 ); |
2825 | + // |
2826 | + // Starting with CA V4.1 the minor version number |
2827 | + // is appended to the end of each search reply. |
2828 | + // This value is ignored by earlier clients. |
2829 | + // |
2830 | + if ( status == S_cas_success ) { |
2831 | + this->out.commitMsg (); |
2832 | + } |
2833 | + |
2834 | + return status; |
2835 | +} |
2836 | + |
2837 | +// |
2838 | +// casStrmClient :: searchAction() |
2839 | +// |
2840 | +caStatus casStrmClient :: searchAction ( epicsGuard < casClientMutex > & guard ) |
2841 | +{ |
2842 | + const caHdrLargeArray *mp = this->ctx.getMsg(); |
2843 | + const char *pChanName = static_cast <char * > ( this->ctx.getData() ); |
2844 | + caStatus status; |
2845 | + |
2846 | + // |
2847 | + // check the sanity of the message |
2848 | + // |
2849 | + if ( mp->m_postsize <= 1 ) { |
2850 | + caServerI::dumpMsg ( this->pHostName, "?", mp, this->ctx.getData(), |
2851 | + "empty PV name extension in TCP search request?\n" ); |
2852 | + return S_cas_success; |
2853 | + } |
2854 | + |
2855 | + if ( pChanName[0] == '\0' ) { |
2856 | + caServerI::dumpMsg ( this->pHostName, "?", mp, this->ctx.getData(), |
2857 | + "zero length PV name in UDP search request?\n" ); |
2858 | + return S_cas_success; |
2859 | + } |
2860 | + |
2861 | + // check for an unterminated string before calling server tool |
2862 | + // by searching backwards through the string (some early versions |
2863 | + // of the client library might not be setting the pad bytes to nill) |
2864 | + for ( unsigned i = mp->m_postsize-1; pChanName[i] != '\0'; i-- ) { |
2865 | + if ( i <= 1 ) { |
2866 | + caServerI::dumpMsg ( pHostName, "?", mp, this->ctx.getData(), |
2867 | + "unterminated PV name in UDP search request?\n" ); |
2868 | + return S_cas_success; |
2869 | + } |
2870 | + } |
2871 | + |
2872 | + if ( this->getCAS().getDebugLevel() > 6u ) { |
2873 | + this->hostName ( this->pHostName, sizeof ( pHostName ) ); |
2874 | + printf ( "\"%s\" is searching for \"%s\"\n", |
2875 | + pHostName, pChanName ); |
2876 | + } |
2877 | + |
2878 | + // |
2879 | + // verify that we have sufficent memory for a PV and a |
2880 | + // monitor prior to calling PV exist test so that when |
2881 | + // the server runs out of memory we dont reply to |
2882 | + // search requests, and therefore dont thrash through |
2883 | + // caServer::pvExistTest() and casCreatePV::pvAttach() |
2884 | + // |
2885 | + if ( ! osiSufficentSpaceInPool ( 0 ) ) { |
2886 | + return S_cas_success; |
2887 | + } |
2888 | + |
2889 | + // |
2890 | + // ask the server tool if this PV exists |
2891 | + // |
2892 | + this->userStartedAsyncIO = false; |
2893 | + pvExistReturn pver = |
2894 | + this->getCAS()->pvExistTest ( |
2895 | + this->ctx, _clientAddr, pChanName ); |
2896 | + |
2897 | + // |
2898 | + // prevent problems when they initiate |
2899 | + // async IO but dont return status |
2900 | + // indicating so (and vise versa) |
2901 | + // |
2902 | + if ( this->userStartedAsyncIO ) { |
2903 | + if ( pver.getStatus() != pverAsyncCompletion ) { |
2904 | + errMessage ( S_cas_badParameter, |
2905 | + "- assuming asynch IO status from caServer::pvExistTest()"); |
2906 | + } |
2907 | + status = S_cas_success; |
2908 | + } |
2909 | + else { |
2910 | + // |
2911 | + // otherwise we assume sync IO operation was initiated |
2912 | + // |
2913 | + switch ( pver.getStatus() ) { |
2914 | + case pverExistsHere: |
2915 | + status = this->searchResponse ( guard, *mp, pver ); |
2916 | + break; |
2917 | + |
2918 | + case pverDoesNotExistHere: |
2919 | + status = S_cas_success; |
2920 | + break; |
2921 | + |
2922 | + case pverAsyncCompletion: |
2923 | + errMessage ( S_cas_badParameter, |
2924 | + "- unexpected asynch IO status from " |
2925 | + "caServer::pvExistTest() ignored"); |
2926 | + status = S_cas_success; |
2927 | + break; |
2928 | + |
2929 | + default: |
2930 | + errMessage ( S_cas_badParameter, |
2931 | + "- invalid return from " |
2932 | + "caServer::pvExistTest() ignored"); |
2933 | + status = S_cas_success; |
2934 | + break; |
2935 | + } |
2936 | + } |
2937 | + return status; |
2938 | +} |
2939 | + |
2940 | /* |
2941 | * casStrmClient::hostNameAction() |
2942 | */ |
2943 | @@ -2610,9 +2826,8 @@ |
2944 | epicsGuard < epicsMutex > guard ( this->mutex ); |
2945 | return this->in.fill (); |
2946 | } |
2947 | - |
2948 | -bufSizeT casStrmClient :: |
2949 | - inBufBytesPending () const |
2950 | + |
2951 | +bufSizeT casStrmClient :: inBufBytesPending () const |
2952 | { |
2953 | epicsGuard < epicsMutex > guard ( this->mutex ); |
2954 | return this->in.bytesPresent (); |
2955 | |
2956 | === modified file 'src/cas/generic/casStrmClient.h' |
2957 | --- src/cas/generic/casStrmClient.h 2009-08-05 23:58:40 +0000 |
2958 | +++ src/cas/generic/casStrmClient.h 2010-05-14 13:38:34 +0000 |
2959 | @@ -1,12 +1,11 @@ |
2960 | - |
2961 | /*************************************************************************\ |
2962 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2963 | -* National Laboratory. |
2964 | -* Copyright (c) 2002 The Regents of the University of California, as |
2965 | -* Operator of Los Alamos National Laboratory. |
2966 | -* EPICS BASE Versions 3.13.7 |
2967 | -* and higher are distributed subject to a Software License Agreement found |
2968 | -* in file LICENSE that is included with this distribution. |
2969 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
2970 | + * National Laboratory. |
2971 | + * Copyright (c) 2002 The Regents of the University of California, as |
2972 | + * Operator of Los Alamos National Laboratory. |
2973 | + * EPICS BASE Versions 3.13.7 |
2974 | + * and higher are distributed subject to a Software License Agreement found |
2975 | + * in file LICENSE that is included with this distribution. |
2976 | \*************************************************************************/ |
2977 | |
2978 | #ifndef casStrmClienth |
2979 | @@ -37,43 +36,44 @@ |
2980 | public casCoreClient, public outBufClient, |
2981 | public inBufClient, public tsDLNode < casStrmClient > { |
2982 | public: |
2983 | - casStrmClient ( caServerI &, clientBufMemoryManager & ); |
2984 | - virtual ~casStrmClient(); |
2985 | - void show ( unsigned level ) const; |
2986 | + casStrmClient ( caServerI &, clientBufMemoryManager &, const caNetAddr & clientAddr ); |
2987 | + virtual ~casStrmClient(); |
2988 | + void show ( unsigned level ) const; |
2989 | outBufClient::flushCondition flush (); |
2990 | - unsigned getDebugLevel () const; |
2991 | - virtual void hostName ( char * pBuf, unsigned bufSize ) const = 0; |
2992 | - void userName ( char * pBuf, unsigned bufSize ) const; |
2993 | - ca_uint16_t protocolRevision () const; |
2994 | + unsigned getDebugLevel () const; |
2995 | + void hostName ( char * pBuf, unsigned bufSize ) const; |
2996 | + void userName ( char * pBuf, unsigned bufSize ) const; |
2997 | + ca_uint16_t protocolRevision () const; |
2998 | void sendVersion (); |
2999 | protected: |
3000 | - caStatus processMsg (); |
3001 | + caStatus processMsg (); |
3002 | bool inBufFull () const; |
3003 | inBufClient::fillCondition inBufFill (); |
3004 | bufSizeT inBufBytesPending () const; |
3005 | bufSizeT outBufBytesPending () const; |
3006 | private: |
3007 | - char hostNameStr [32]; |
3008 | + //char hostNameStr [32]; |
3009 | inBuf in; |
3010 | outBuf out; |
3011 | - chronIntIdResTable < casChannelI > chanTable; |
3012 | - tsDLList < casChannelI > chanList; |
3013 | - epicsTime lastSendTS; |
3014 | - epicsTime lastRecvTS; |
3015 | - char * pUserName; |
3016 | - char * pHostName; |
3017 | + chronIntIdResTable < casChannelI > chanTable; |
3018 | + tsDLList < casChannelI > chanList; |
3019 | + epicsTime lastSendTS; |
3020 | + epicsTime lastRecvTS; |
3021 | + caNetAddr _clientAddr; |
3022 | + char * pUserName; |
3023 | + char * pHostName; |
3024 | smartGDDPointer pValueRead; |
3025 | unsigned incommingBytesToDrain; |
3026 | caStatus pendingResponseStatus; |
3027 | - ca_uint16_t minor_version_number; |
3028 | + ca_uint16_t minor_version_number; |
3029 | bool reqPayloadNeedsByteSwap; |
3030 | bool responseIsPending; |
3031 | |
3032 | - caStatus createChannel ( const char * pName ); |
3033 | - caStatus verifyRequest ( casChannelI * & pChan ); |
3034 | + caStatus createChannel ( const char * pName ); |
3035 | + caStatus verifyRequest ( casChannelI * & pChan ); |
3036 | typedef caStatus ( casStrmClient :: * pCASMsgHandler ) |
3037 | - ( epicsGuard < casClientMutex > & ); |
3038 | - static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u]; |
3039 | + ( epicsGuard < casClientMutex > & ); |
3040 | + static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u]; |
3041 | |
3042 | // |
3043 | // one function for each CA request type |
3044 | @@ -82,19 +82,20 @@ |
3045 | caStatus ignoreMsgAction ( epicsGuard < casClientMutex > & ); |
3046 | caStatus versionAction ( epicsGuard < casClientMutex > & ); |
3047 | caStatus echoAction ( epicsGuard < casClientMutex > & ); |
3048 | - caStatus eventAddAction ( epicsGuard < casClientMutex > & ); |
3049 | - caStatus eventCancelAction ( epicsGuard < casClientMutex > & ); |
3050 | - caStatus readAction ( epicsGuard < casClientMutex > & ); |
3051 | - caStatus readNotifyAction ( epicsGuard < casClientMutex > & ); |
3052 | - caStatus writeAction ( epicsGuard < casClientMutex > & ); |
3053 | - caStatus eventsOffAction ( epicsGuard < casClientMutex > & ); |
3054 | - caStatus eventsOnAction ( epicsGuard < casClientMutex > & ); |
3055 | - caStatus readSyncAction ( epicsGuard < casClientMutex > & ); |
3056 | - caStatus clearChannelAction ( epicsGuard < casClientMutex > & ); |
3057 | - caStatus claimChannelAction ( epicsGuard < casClientMutex > & ); |
3058 | - caStatus writeNotifyAction ( epicsGuard < casClientMutex > & ); |
3059 | - caStatus clientNameAction ( epicsGuard < casClientMutex > & ); |
3060 | - caStatus hostNameAction ( epicsGuard < casClientMutex > & ); |
3061 | + caStatus eventAddAction ( epicsGuard < casClientMutex > & ); |
3062 | + caStatus eventCancelAction ( epicsGuard < casClientMutex > & ); |
3063 | + caStatus readAction ( epicsGuard < casClientMutex > & ); |
3064 | + caStatus readNotifyAction ( epicsGuard < casClientMutex > & ); |
3065 | + caStatus writeAction ( epicsGuard < casClientMutex > & ); |
3066 | + caStatus eventsOffAction ( epicsGuard < casClientMutex > & ); |
3067 | + caStatus eventsOnAction ( epicsGuard < casClientMutex > & ); |
3068 | + caStatus readSyncAction ( epicsGuard < casClientMutex > & ); |
3069 | + caStatus clearChannelAction ( epicsGuard < casClientMutex > & ); |
3070 | + caStatus claimChannelAction ( epicsGuard < casClientMutex > & ); |
3071 | + caStatus writeNotifyAction ( epicsGuard < casClientMutex > & ); |
3072 | + caStatus clientNameAction ( epicsGuard < casClientMutex > & ); |
3073 | + caStatus hostNameAction ( epicsGuard < casClientMutex > & ); |
3074 | + caStatus searchAction ( epicsGuard < casClientMutex > & ); |
3075 | caStatus sendErr ( epicsGuard < casClientMutex > &, |
3076 | const caHdrLargeArray *curp, ca_uint32_t cid, |
3077 | const int reportedStatus, const char * pformat, ... ); |
3078 | @@ -114,34 +115,40 @@ |
3079 | // one function for each CA request type that has |
3080 | // asynchronous completion |
3081 | // |
3082 | - caStatus createChanResponse ( epicsGuard < casClientMutex > &, |
3083 | - casCtx &, const pvAttachReturn & ); |
3084 | - caStatus readResponse ( epicsGuard < casClientMutex > &, |
3085 | - casChannelI * pChan, const caHdrLargeArray & msg, |
3086 | - const gdd & desc, const caStatus status ); |
3087 | - caStatus readNotifyResponse ( epicsGuard < casClientMutex > &, |
3088 | + caStatus createChanResponse ( epicsGuard < casClientMutex > &, |
3089 | + casCtx &, const pvAttachReturn & ); |
3090 | + caStatus readResponse ( epicsGuard < casClientMutex > &, |
3091 | + casChannelI * pChan, const caHdrLargeArray & msg, |
3092 | + const gdd & desc, const caStatus status ); |
3093 | + caStatus readNotifyResponse ( epicsGuard < casClientMutex > &, |
3094 | casChannelI *pChan, const caHdrLargeArray & msg, |
3095 | - const gdd & desc, const caStatus status ); |
3096 | - caStatus writeResponse ( epicsGuard < casClientMutex > &, casChannelI &, |
3097 | - const caHdrLargeArray & msg, const caStatus status ); |
3098 | - caStatus writeNotifyResponse ( epicsGuard < casClientMutex > &, casChannelI &, |
3099 | - const caHdrLargeArray &, const caStatus status ); |
3100 | - caStatus monitorResponse ( epicsGuard < casClientMutex > &, |
3101 | + const gdd & desc, const caStatus status ); |
3102 | + caStatus writeResponse ( epicsGuard < casClientMutex > &, casChannelI &, |
3103 | + const caHdrLargeArray & msg, const caStatus status ); |
3104 | + caStatus writeNotifyResponse ( epicsGuard < casClientMutex > &, casChannelI &, |
3105 | + const caHdrLargeArray &, const caStatus status ); |
3106 | + caStatus monitorResponse ( epicsGuard < casClientMutex > &, |
3107 | casChannelI & chan, const caHdrLargeArray & msg, |
3108 | - const gdd &, const caStatus status ); |
3109 | + const gdd & desc, const caStatus status ); |
3110 | caStatus enumPostponedCreateChanResponse ( epicsGuard < casClientMutex > &, |
3111 | casChannelI & chan, const caHdrLargeArray & hdr ); |
3112 | caStatus privateCreateChanResponse ( epicsGuard < casClientMutex > &, |
3113 | casChannelI & chan, const caHdrLargeArray & hdr, unsigned dbrType ); |
3114 | - caStatus channelCreateFailedResp ( epicsGuard < casClientMutex > &, |
3115 | + caStatus channelCreateFailedResp ( epicsGuard < casClientMutex > &, |
3116 | const caHdrLargeArray &, const caStatus createStatus ); |
3117 | caStatus channelDestroyEventNotify ( |
3118 | epicsGuard < casClientMutex > & guard, |
3119 | casChannelI * const pChan, ca_uint32_t sid ); |
3120 | - caStatus accessRightsResponse ( |
3121 | + caStatus accessRightsResponse ( |
3122 | casChannelI * pciu ); |
3123 | - caStatus accessRightsResponse ( |
3124 | + caStatus accessRightsResponse ( |
3125 | epicsGuard < casClientMutex > &, casChannelI * pciu ); |
3126 | + caStatus searchResponse ( |
3127 | + epicsGuard < casClientMutex > &, const caHdrLargeArray &, const pvExistReturn & ); |
3128 | + caStatus asyncSearchResponse ( |
3129 | + epicsGuard < casClientMutex > &, const caNetAddr & outAddr, |
3130 | + const caHdrLargeArray & msg, const pvExistReturn & retVal, |
3131 | + ca_uint16_t protocolRevision, ca_uint32_t sequenceNumber ); |
3132 | |
3133 | |
3134 | typedef caStatus ( casChannelI :: * PWriteMethod ) ( |
3135 | @@ -152,29 +159,29 @@ |
3136 | caStatus writeScalarData( PWriteMethod ); |
3137 | |
3138 | outBufClient::flushCondition xSend ( char * pBuf, bufSizeT nBytesToSend, |
3139 | - bufSizeT & nBytesSent ); |
3140 | + bufSizeT & nBytesSent ); |
3141 | inBufClient::fillCondition xRecv ( char * pBuf, bufSizeT nBytesToRecv, |
3142 | - inBufClient::fillParameter parm, bufSizeT & nByesRecv ); |
3143 | - |
3144 | - virtual xBlockingStatus blockingState () const = 0; |
3145 | - |
3146 | - virtual outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, |
3147 | - bufSizeT & nBytesActual ) = 0; |
3148 | - virtual inBufClient::fillCondition osdRecv ( char *pBuf, bufSizeT nBytesReq, |
3149 | - bufSizeT &nBytesActual ) = 0; |
3150 | + inBufClient::fillParameter parm, bufSizeT & nByesRecv ); |
3151 | + |
3152 | + virtual xBlockingStatus blockingState () const = 0; |
3153 | + |
3154 | + virtual outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, |
3155 | + bufSizeT & nBytesActual ) = 0; |
3156 | + virtual inBufClient::fillCondition osdRecv ( char *pBuf, bufSizeT nBytesReq, |
3157 | + bufSizeT &nBytesActual ) = 0; |
3158 | virtual void forceDisconnect () = 0; |
3159 | - caStatus casMonitorCallBack ( |
3160 | + caStatus casMonitorCallBack ( |
3161 | epicsGuard < casClientMutex > &, casMonitor &, const gdd & ); |
3162 | caStatus logBadIdWithFileAndLineno ( |
3163 | epicsGuard < casClientMutex > & guard, const caHdrLargeArray * mp, |
3164 | - const void * dp, const int cacStatus, const char * pFileName, |
3165 | + const void * dp, const int cacStatus, const char * pFileName, |
3166 | const unsigned lineno, const unsigned idIn ); |
3167 | void casChannelDestroyFromInterfaceNotify ( casChannelI & chan, |
3168 | bool immediatedSestroyNeeded ); |
3169 | static void issuePosponeWhenNonePendingWarning ( const char * pReqTypeStr ); |
3170 | |
3171 | - casStrmClient ( const casStrmClient & ); |
3172 | - casStrmClient & operator = ( const casStrmClient & ); |
3173 | + casStrmClient ( const casStrmClient & ); |
3174 | + casStrmClient & operator = ( const casStrmClient & ); |
3175 | }; |
3176 | |
3177 | #define logBadId(GUARD, MP, DP, CACSTAT, RESID) \ |
3178 | @@ -188,4 +195,3 @@ |
3179 | } |
3180 | |
3181 | #endif // casStrmClienth |
3182 | - |
3183 | |
3184 | === modified file 'src/cas/io/bsdSocket/casIntfIO.cc' |
3185 | --- src/cas/io/bsdSocket/casIntfIO.cc 2009-07-25 01:04:14 +0000 |
3186 | +++ src/cas/io/bsdSocket/casIntfIO.cc 2010-05-14 13:38:34 +0000 |
3187 | @@ -1,16 +1,15 @@ |
3188 | /*************************************************************************\ |
3189 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3190 | -* National Laboratory. |
3191 | -* Copyright (c) 2002 The Regents of the University of California, as |
3192 | -* Operator of Los Alamos National Laboratory. |
3193 | -* EPICS BASE Versions 3.13.7 |
3194 | -* and higher are distributed subject to a Software License Agreement found |
3195 | -* in file LICENSE that is included with this distribution. |
3196 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3197 | + * National Laboratory. |
3198 | + * Copyright (c) 2002 The Regents of the University of California, as |
3199 | + * Operator of Los Alamos National Laboratory. |
3200 | + * EPICS BASE Versions 3.13.7 |
3201 | + * and higher are distributed subject to a Software License Agreement found |
3202 | + * in file LICENSE that is included with this distribution. |
3203 | \*************************************************************************/ |
3204 | -// |
3205 | -// $Id$ |
3206 | -// |
3207 | -// Author Jeff Hill |
3208 | + |
3209 | +// |
3210 | +// Author: Jeff Hill |
3211 | // |
3212 | |
3213 | #include <stdio.h> |
3214 | @@ -35,11 +34,11 @@ |
3215 | // casIntfIO::casIntfIO() |
3216 | // |
3217 | casIntfIO::casIntfIO ( const caNetAddr & addrIn ) : |
3218 | - sock ( INVALID_SOCKET ), |
3219 | + sock ( INVALID_SOCKET ), |
3220 | addr ( addrIn.getSockIP() ) |
3221 | { |
3222 | - int status; |
3223 | - osiSocklen_t addrSize; |
3224 | + int status; |
3225 | + osiSocklen_t addrSize; |
3226 | bool portChange; |
3227 | |
3228 | if ( ! osiSockAttach () ) { |
3229 | @@ -152,9 +151,9 @@ |
3230 | { |
3231 | static bool oneMsgFlag = false; |
3232 | |
3233 | - struct sockaddr newAddr; |
3234 | - osiSocklen_t length = ( osiSocklen_t ) sizeof ( newAddr ); |
3235 | - SOCKET newSock = epicsSocketAccept ( this->sock, & newAddr, & length ); |
3236 | + struct sockaddr newClientAddr; |
3237 | + osiSocklen_t length = ( osiSocklen_t ) sizeof ( newClientAddr ); |
3238 | + SOCKET newSock = epicsSocketAccept ( this->sock, & newClientAddr, & length ); |
3239 | if ( newSock == INVALID_SOCKET ) { |
3240 | int errnoCpy = SOCKERRNO; |
3241 | if ( errnoCpy != SOCK_EWOULDBLOCK && ! oneMsgFlag ) { |
3242 | @@ -166,14 +165,14 @@ |
3243 | } |
3244 | return NULL; |
3245 | } |
3246 | - else if ( sizeof ( newAddr ) > (size_t) length ) { |
3247 | + else if ( sizeof ( newClientAddr ) > (size_t) length ) { |
3248 | epicsSocketDestroy ( newSock ); |
3249 | errlogPrintf ( "CAS: accept returned bad address len?\n" ); |
3250 | return NULL; |
3251 | } |
3252 | oneMsgFlag = false; |
3253 | ioArgsToNewStreamIO args; |
3254 | - args.addr = newAddr; |
3255 | + args.clientAddr = newClientAddr; |
3256 | args.sock = newSock; |
3257 | casStreamOS * pOS = new casStreamOS ( cas, bufMgr, args ); |
3258 | if ( ! pOS ) { |
3259 | @@ -197,25 +196,25 @@ |
3260 | // |
3261 | void casIntfIO::setNonBlocking() |
3262 | { |
3263 | - int status; |
3264 | - osiSockIoctl_t yes = true; |
3265 | + int status; |
3266 | + osiSockIoctl_t yes = true; |
3267 | |
3268 | - status = socket_ioctl(this->sock, FIONBIO, &yes); // X aCC 392 |
3269 | - if ( status < 0 ) { |
3270 | - char sockErrBuf[64]; |
3271 | - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); |
3272 | - errlogPrintf ( |
3273 | - "%s:CAS: server non blocking IO set fail because \"%s\"\n", |
3274 | - __FILE__, sockErrBuf ); |
3275 | - } |
3276 | + status = socket_ioctl(this->sock, FIONBIO, &yes); // X aCC 392 |
3277 | + if ( status < 0 ) { |
3278 | + char sockErrBuf[64]; |
3279 | + epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); |
3280 | + errlogPrintf ( |
3281 | + "%s:CAS: server non blocking IO set fail because \"%s\"\n", |
3282 | + __FILE__, sockErrBuf ); |
3283 | + } |
3284 | } |
3285 | - |
3286 | + |
3287 | // |
3288 | // casIntfIO::getFD() |
3289 | // |
3290 | int casIntfIO::getFD() const |
3291 | { |
3292 | - return this->sock; |
3293 | + return this->sock; |
3294 | } |
3295 | |
3296 | // |
3297 | @@ -223,9 +222,9 @@ |
3298 | // |
3299 | void casIntfIO::show(unsigned level) const |
3300 | { |
3301 | - if (level>2u) { |
3302 | - printf(" casIntfIO::sock = %d\n", this->sock); |
3303 | - } |
3304 | + if (level>2u) { |
3305 | + printf(" casIntfIO::sock = %d\n", this->sock); |
3306 | + } |
3307 | } |
3308 | |
3309 | // |
3310 | |
3311 | === modified file 'src/cas/io/bsdSocket/casStreamIO.cc' |
3312 | --- src/cas/io/bsdSocket/casStreamIO.cc 2009-07-30 23:51:48 +0000 |
3313 | +++ src/cas/io/bsdSocket/casStreamIO.cc 2010-05-14 13:38:34 +0000 |
3314 | @@ -1,13 +1,14 @@ |
3315 | /*************************************************************************\ |
3316 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3317 | -* National Laboratory. |
3318 | -* Copyright (c) 2002 The Regents of the University of California, as |
3319 | -* Operator of Los Alamos National Laboratory. |
3320 | -* EPICS BASE is distributed subject to a Software License Agreement found |
3321 | -* in file LICENSE that is included with this distribution. |
3322 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3323 | + * National Laboratory. |
3324 | + * Copyright (c) 2002 The Regents of the University of California, as |
3325 | + * Operator of Los Alamos National Laboratory. |
3326 | + * EPICS BASE is distributed subject to a Software License Agreement found |
3327 | + * in file LICENSE that is included with this distribution. |
3328 | \*************************************************************************/ |
3329 | + |
3330 | // |
3331 | -// $Id$ |
3332 | +// Author: Jeff Hill |
3333 | // |
3334 | |
3335 | #include "errlog.h" |
3336 | @@ -17,11 +18,13 @@ |
3337 | |
3338 | // casStreamIO::casStreamIO() |
3339 | casStreamIO::casStreamIO ( caServerI & cas, clientBufMemoryManager & bufMgr, |
3340 | - const ioArgsToNewStreamIO & args ) : |
3341 | - casStrmClient ( cas, bufMgr ), sock ( args.sock ), addr ( args.addr), |
3342 | - _osSendBufferSize ( MAX_TCP ), blockingFlag ( xIsBlocking ), |
3343 | - sockHasBeenShutdown ( false ) |
3344 | - { |
3345 | + const ioArgsToNewStreamIO & args ) : |
3346 | + casStrmClient ( cas, bufMgr, args.clientAddr ), |
3347 | + sock ( args.sock ), |
3348 | + _osSendBufferSize ( MAX_TCP ), |
3349 | + blockingFlag ( xIsBlocking ), |
3350 | + sockHasBeenShutdown ( false ) |
3351 | +{ |
3352 | assert ( sock >= 0 ); |
3353 | int yes = true; |
3354 | int status; |
3355 | @@ -152,7 +155,7 @@ |
3356 | char sockErrBuf[64]; |
3357 | epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); |
3358 | char buf[64]; |
3359 | - ipAddrToA (&this->addr, buf, sizeof(buf)); |
3360 | + this->hostName ( buf, sizeof ( buf ) ); |
3361 | errlogPrintf ( |
3362 | "CAS: TCP socket send to \"%s\" failed because \"%s\"\n", |
3363 | buf, sockErrBuf ); |
3364 | @@ -197,7 +200,7 @@ |
3365 | myerrno != SOCK_ETIMEDOUT ) { |
3366 | char sockErrBuf[64]; |
3367 | epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); |
3368 | - ipAddrToA (&this->addr, buf, sizeof(buf)); |
3369 | + this->hostName ( buf, sizeof ( buf ) ); |
3370 | errlogPrintf( |
3371 | "CAS: client %s disconnected because \"%s\"\n", |
3372 | buf, sockErrBuf ); |
3373 | @@ -236,10 +239,8 @@ |
3374 | static_cast <const void *> ( this ) ); |
3375 | if (level>1u) { |
3376 | char buf[64]; |
3377 | - ipAddrToA(&this->addr, buf, sizeof(buf)); |
3378 | - printf ( |
3379 | - "client=%s, port=%x\n", |
3380 | - buf, ntohs(this->addr.sin_port)); |
3381 | + this->hostName ( buf, sizeof ( buf ) ); |
3382 | + printf ( "client = \"%s\"\n", buf ); |
3383 | } |
3384 | } |
3385 | |
3386 | @@ -286,7 +287,7 @@ |
3387 | char sockErrBuf[64]; |
3388 | epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); |
3389 | char buf[64]; |
3390 | - ipAddrToA ( &this->addr, buf, sizeof(buf) ); |
3391 | + this->hostName ( buf, sizeof ( buf ) ); |
3392 | errlogPrintf ("CAS: FIONREAD for %s failed because \"%s\"\n", |
3393 | buf, sockErrBuf ); |
3394 | } |
3395 | @@ -300,12 +301,6 @@ |
3396 | } |
3397 | } |
3398 | |
3399 | -// casStreamIO::hostName() |
3400 | -void casStreamIO::hostName ( char * pInBuf, unsigned bufSizeIn ) const |
3401 | -{ |
3402 | - ipAddrToA ( & this->addr, pInBuf, bufSizeIn ); |
3403 | -} |
3404 | - |
3405 | // casStreamIO :: osSendBufferSize () |
3406 | bufSizeT casStreamIO :: osSendBufferSize () const |
3407 | { |
3408 | |
3409 | === modified file 'src/cas/io/bsdSocket/casStreamIO.h' |
3410 | --- src/cas/io/bsdSocket/casStreamIO.h 2009-07-30 23:51:48 +0000 |
3411 | +++ src/cas/io/bsdSocket/casStreamIO.h 2010-05-14 13:38:34 +0000 |
3412 | @@ -1,13 +1,13 @@ |
3413 | - |
3414 | /*************************************************************************\ |
3415 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3416 | -* National Laboratory. |
3417 | -* Copyright (c) 2002 The Regents of the University of California, as |
3418 | -* Operator of Los Alamos National Laboratory. |
3419 | -* EPICS BASE Versions 3.13.7 |
3420 | -* and higher are distributed subject to a Software License Agreement found |
3421 | -* in file LICENSE that is included with this distribution. |
3422 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3423 | + * National Laboratory. |
3424 | + * Copyright (c) 2002 The Regents of the University of California, as |
3425 | + * Operator of Los Alamos National Laboratory. |
3426 | + * EPICS BASE Versions 3.13.7 |
3427 | + * and higher are distributed subject to a Software License Agreement found |
3428 | + * in file LICENSE that is included with this distribution. |
3429 | \*************************************************************************/ |
3430 | + |
3431 | // |
3432 | // $Id$ |
3433 | // |
3434 | @@ -18,42 +18,34 @@ |
3435 | #include "casStrmClient.h" |
3436 | |
3437 | struct ioArgsToNewStreamIO { |
3438 | - caNetAddr addr; |
3439 | - SOCKET sock; |
3440 | + caNetAddr clientAddr; |
3441 | + SOCKET sock; |
3442 | }; |
3443 | |
3444 | class casStreamIO : public casStrmClient { |
3445 | public: |
3446 | - casStreamIO ( caServerI &, clientBufMemoryManager &, |
3447 | + casStreamIO ( caServerI &, clientBufMemoryManager &, |
3448 | const ioArgsToNewStreamIO & ); |
3449 | - ~casStreamIO (); |
3450 | - int getFD () const; |
3451 | - void xSetNonBlocking (); |
3452 | - const caNetAddr getAddr() const; |
3453 | - void hostName ( char *pBuf, unsigned bufSize ) const; |
3454 | + ~casStreamIO (); |
3455 | + int getFD () const; |
3456 | + void xSetNonBlocking (); |
3457 | bufSizeT inCircuitBytesPending () const; |
3458 | bufSizeT osSendBufferSize () const; |
3459 | private: |
3460 | - SOCKET sock; |
3461 | - struct sockaddr_in addr; |
3462 | + SOCKET sock; |
3463 | bufSizeT _osSendBufferSize; |
3464 | - xBlockingStatus blockingFlag; |
3465 | + xBlockingStatus blockingFlag; |
3466 | |
3467 | bool sockHasBeenShutdown; |
3468 | - xBlockingStatus blockingState() const; |
3469 | - void osdShow ( unsigned level ) const; |
3470 | - outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, |
3471 | - bufSizeT & nBytesActual ); |
3472 | - inBufClient::fillCondition osdRecv ( char *pBuf, bufSizeT nBytesReq, |
3473 | - bufSizeT & nBytesActual ); |
3474 | + xBlockingStatus blockingState() const; |
3475 | + void osdShow ( unsigned level ) const; |
3476 | + outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, |
3477 | + bufSizeT & nBytesActual ); |
3478 | + inBufClient::fillCondition osdRecv ( char *pBuf, bufSizeT nBytesReq, |
3479 | + bufSizeT & nBytesActual ); |
3480 | void forceDisconnect (); |
3481 | - casStreamIO ( const casStreamIO & ); |
3482 | - casStreamIO & operator = ( const casStreamIO & ); |
3483 | + casStreamIO ( const casStreamIO & ); |
3484 | + casStreamIO & operator = ( const casStreamIO & ); |
3485 | }; |
3486 | |
3487 | -inline const caNetAddr casStreamIO::getAddr() const |
3488 | -{ |
3489 | - return caNetAddr ( this->addr ); |
3490 | -} |
3491 | - |
3492 | #endif // casStreamIOh |
3493 | |
3494 | === modified file 'src/libCom/env/envDefs.h' |
3495 | --- src/libCom/env/envDefs.h 2009-06-05 19:56:33 +0000 |
3496 | +++ src/libCom/env/envDefs.h 2010-05-14 13:38:34 +0000 |
3497 | @@ -49,6 +49,7 @@ |
3498 | epicsShareExtern const ENV_PARAM EPICS_CA_SERVER_PORT; |
3499 | epicsShareExtern const ENV_PARAM EPICS_CA_MAX_ARRAY_BYTES; |
3500 | epicsShareExtern const ENV_PARAM EPICS_CA_MAX_SEARCH_PERIOD; |
3501 | +epicsShareExtern const ENV_PARAM EPICS_CA_NAME_SERVERS; |
3502 | epicsShareExtern const ENV_PARAM EPICS_CAS_INTF_ADDR_LIST; |
3503 | epicsShareExtern const ENV_PARAM EPICS_CAS_IGNORE_ADDR_LIST; |
3504 | epicsShareExtern const ENV_PARAM EPICS_CAS_AUTO_BEACON_ADDR_LIST; |
3505 | |
3506 | === modified file 'src/rsrv/camessage.c' |
3507 | --- src/rsrv/camessage.c 2009-07-09 16:37:24 +0000 |
3508 | +++ src/rsrv/camessage.c 2010-05-14 13:38:34 +0000 |
3509 | @@ -1,17 +1,16 @@ |
3510 | /*************************************************************************\ |
3511 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3512 | -* National Laboratory. |
3513 | -* Copyright (c) 2002 The Regents of the University of California, as |
3514 | -* Operator of Los Alamos National Laboratory. |
3515 | -* EPICS BASE Versions 3.13.7 |
3516 | -* and higher are distributed subject to a Software License Agreement found |
3517 | -* in file LICENSE that is included with this distribution. |
3518 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3519 | + * National Laboratory. |
3520 | + * Copyright (c) 2002 The Regents of the University of California, as |
3521 | + * Operator of Los Alamos National Laboratory. |
3522 | + * EPICS BASE Versions 3.13.7 |
3523 | + * and higher are distributed subject to a Software License Agreement found |
3524 | + * in file LICENSE that is included with this distribution. |
3525 | \*************************************************************************/ |
3526 | -/* |
3527 | + |
3528 | +/* |
3529 | * Author: Jeffrey O. Hill |
3530 | - * hill@luke.lanl.gov |
3531 | - * (505) 665 1831 |
3532 | - * Date: 5-88 |
3533 | + * |
3534 | */ |
3535 | |
3536 | #include <stddef.h> |
3537 | @@ -2190,9 +2189,9 @@ |
3538 | } |
3539 | |
3540 | /* |
3541 | - * search_reply() |
3542 | + * search_reply_udp () |
3543 | */ |
3544 | -static int search_reply ( caHdrLargeArray *mp, void *pPayload, struct client *client ) |
3545 | +static int search_reply_udp ( caHdrLargeArray *mp, void *pPayload, struct client *client ) |
3546 | { |
3547 | struct dbAddr tmp_addr; |
3548 | ca_uint16_t *pMinorVersion; |
3549 | @@ -2299,6 +2298,66 @@ |
3550 | return RSRV_OK; |
3551 | } |
3552 | |
3553 | +/* |
3554 | + * search_reply_tcp () |
3555 | + */ |
3556 | +static int search_reply_tcp ( |
3557 | + caHdrLargeArray *mp, void *pPayload, struct client *client ) |
3558 | +{ |
3559 | + struct dbAddr tmp_addr; |
3560 | + char *pName = (char *) pPayload; |
3561 | + int status; |
3562 | + int spaceAvailOnFreeList; |
3563 | + size_t spaceNeeded; |
3564 | + size_t reasonableMonitorSpace = 10; |
3565 | + |
3566 | + /* |
3567 | + * check the sanity of the message |
3568 | + */ |
3569 | + if (mp->m_postsize<=1) { |
3570 | + log_header ("empty PV name in UDP search request?", |
3571 | + client, mp, pPayload, 0); |
3572 | + return RSRV_OK; |
3573 | + } |
3574 | + pName[mp->m_postsize-1] = '\0'; |
3575 | + |
3576 | + /* Exit quickly if channel not on this node */ |
3577 | + status = db_name_to_addr (pName, &tmp_addr); |
3578 | + if (status) { |
3579 | + DLOG ( 2, ( "CAS: Lookup for channel \"%s\" failed\n", pPayLoad ) ); |
3580 | + if (mp->m_dataType == DOREPLY) |
3581 | + search_fail_reply ( mp, pPayload, client ); |
3582 | + return RSRV_OK; |
3583 | + } |
3584 | + |
3585 | + /* |
3586 | + * stop further use of server if memory becomes scarse |
3587 | + */ |
3588 | + spaceAvailOnFreeList = freeListItemsAvail ( rsrvChanFreeList ) > 0 |
3589 | + && freeListItemsAvail ( rsrvEventFreeList ) > reasonableMonitorSpace; |
3590 | + spaceNeeded = sizeof (struct channel_in_use) + |
3591 | + reasonableMonitorSpace * sizeof (struct event_ext); |
3592 | + if ( ! ( osiSufficentSpaceInPool(spaceNeeded) || spaceAvailOnFreeList ) ) { |
3593 | + SEND_LOCK(client); |
3594 | + send_err ( mp, ECA_ALLOCMEM, client, "Server memory exhausted" ); |
3595 | + SEND_UNLOCK(client); |
3596 | + return RSRV_OK; |
3597 | + } |
3598 | + |
3599 | + SEND_LOCK ( client ); |
3600 | + status = cas_copy_in_header ( client, CA_PROTO_SEARCH, |
3601 | + 0, ca_server_port, 0, ~0U, mp->m_available, 0 ); |
3602 | + if ( status != ECA_NORMAL ) { |
3603 | + SEND_UNLOCK ( client ); |
3604 | + return RSRV_ERROR; |
3605 | + } |
3606 | + |
3607 | + cas_commit_msg ( client, 0 ); |
3608 | + SEND_UNLOCK ( client ); |
3609 | + |
3610 | + return RSRV_OK; |
3611 | +} |
3612 | + |
3613 | typedef int (*pProtoStubTCP) (caHdrLargeArray *mp, void *pPayload, struct client *client); |
3614 | |
3615 | /* |
3616 | @@ -2312,7 +2371,7 @@ |
3617 | read_action, |
3618 | write_action, |
3619 | bad_tcp_cmd_action, |
3620 | - bad_tcp_cmd_action, |
3621 | + search_reply_tcp, |
3622 | bad_tcp_cmd_action, |
3623 | events_off_action, |
3624 | events_on_action, |
3625 | @@ -2348,7 +2407,7 @@ |
3626 | bad_udp_cmd_action, |
3627 | bad_udp_cmd_action, |
3628 | bad_udp_cmd_action, |
3629 | - search_reply, |
3630 | + search_reply_udp, |
3631 | bad_udp_cmd_action, |
3632 | bad_udp_cmd_action, |
3633 | bad_udp_cmd_action, |
3634 | |
3635 | === modified file 'src/rsrv/caservertask.c' |
3636 | --- src/rsrv/caservertask.c 2009-07-09 16:37:24 +0000 |
3637 | +++ src/rsrv/caservertask.c 2010-05-14 13:38:34 +0000 |
3638 | @@ -1,19 +1,18 @@ |
3639 | /*************************************************************************\ |
3640 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3641 | -* National Laboratory. |
3642 | -* Copyright (c) 2002 The Regents of the University of California, as |
3643 | -* Operator of Los Alamos National Laboratory. |
3644 | -* EPICS BASE Versions 3.13.7 |
3645 | -* and higher are distributed subject to a Software License Agreement found |
3646 | -* in file LICENSE that is included with this distribution. |
3647 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3648 | + * National Laboratory. |
3649 | + * Copyright (c) 2002 The Regents of the University of California, as |
3650 | + * Operator of Los Alamos National Laboratory. |
3651 | + * EPICS BASE Versions 3.13.7 |
3652 | + * and higher are distributed subject to a Software License Agreement found |
3653 | + * in file LICENSE that is included with this distribution. |
3654 | \*************************************************************************/ |
3655 | + |
3656 | /* |
3657 | * $Id$ |
3658 | * |
3659 | * Author: Jeffrey O. Hill |
3660 | - * hill@luke.lanl.gov |
3661 | - * (505) 665 1831 |
3662 | - * Date: 5-88 |
3663 | + * |
3664 | */ |
3665 | |
3666 | #include <stddef.h> |
3667 | @@ -938,6 +937,11 @@ |
3668 | return NULL; |
3669 | } |
3670 | |
3671 | + /* |
3672 | + * add first version message should it be needed |
3673 | + */ |
3674 | + rsrv_version_reply ( client ); |
3675 | + |
3676 | if ( CASDEBUG > 0 ) { |
3677 | char buf[64]; |
3678 | ipAddrToDottedIP ( &client->addr, buf, sizeof(buf) ); |
3679 | |
3680 | === modified file 'src/rsrv/server.h' |
3681 | --- src/rsrv/server.h 2009-07-09 16:37:24 +0000 |
3682 | +++ src/rsrv/server.h 2010-05-14 13:38:34 +0000 |
3683 | @@ -1,17 +1,16 @@ |
3684 | /*************************************************************************\ |
3685 | -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3686 | -* National Laboratory. |
3687 | -* Copyright (c) 2002 The Regents of the University of California, as |
3688 | -* Operator of Los Alamos National Laboratory. |
3689 | -* EPICS BASE Versions 3.13.7 |
3690 | -* and higher are distributed subject to a Software License Agreement found |
3691 | -* in file LICENSE that is included with this distribution. |
3692 | + * Copyright (c) 2002 The University of Chicago, as Operator of Argonne |
3693 | + * National Laboratory. |
3694 | + * Copyright (c) 2002 The Regents of the University of California, as |
3695 | + * Operator of Los Alamos National Laboratory. |
3696 | + * EPICS BASE Versions 3.13.7 |
3697 | + * and higher are distributed subject to a Software License Agreement found |
3698 | + * in file LICENSE that is included with this distribution. |
3699 | \*************************************************************************/ |
3700 | + |
3701 | /* |
3702 | * Author: Jeffrey O. Hill |
3703 | - * hill@luke.lanl.gov |
3704 | - * (505) 665 1831 |
3705 | - * Date: 5-88 |
3706 | + * |
3707 | */ |
3708 | |
3709 | #ifndef INCLserverh |
3710 | @@ -29,7 +28,7 @@ |
3711 | #include "asLib.h" |
3712 | #include "dbAddr.h" |
3713 | #include "dbNotify.h" |
3714 | -#define CA_MINOR_PROTOCOL_REVISION 11 |
3715 | +#define CA_MINOR_PROTOCOL_REVISION 12 |
3716 | #include "caProto.h" |
3717 | #include "ellLib.h" |
3718 | #include "epicsTime.h" |
3719 | @@ -47,7 +46,7 @@ |
3720 | ca_uint32_t m_available; /* protocol stub dependent */ |
3721 | ca_uint16_t m_dataType; /* operation data type */ |
3722 | ca_uint16_t m_cmmd; /* operation to be performed */ |
3723 | -}caHdrLargeArray; |
3724 | +} caHdrLargeArray; |
3725 | |
3726 | /* |
3727 | * !! buf must be the first item in this structure !! |
Looks fine, but its hard to catch everything with a source code review so testing is important. IMHO its important to keep bug fix changes and new features in different release series, and we seem to be slipping a bit on that level of discipline.
udpiiu.cpp comment on line 278 prob no-longer applies and can be removed