callers of ca_add_fd_registration might not always receive select wakeup
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
EPICS Base |
Fix Released
|
Medium
|
Jeff Hill |
Bug Description
During regression testing against an asynchronous variable in the portable server I noticed that the test hung in the fdManagerVerify. There is an esoteric feature in ca client library where the application can watch the ca client librarys file descriptors and call ca_poll (ca_pend_event) when there is activity in the client librarys sockets. The following scenario wasnt working if the service was slower than usual completing the connect sequence for a channel.
Additional information:
status = ca_add_
assert ( status == ECA_NORMAL );
status = ca_create_channel ( pName, 0, 0, 0, & newChan );
assert ( status == ECA_NORMAL );
while ( ca_state ( newChan ) != cs_conn ) {
tmo.tv_sec = 6000;
tmo.tv_usec = 0;
status = fdmgr_pend_event ( mgrCtx, & tmo );
assert ( status >= 0 );
}
Original Mantis Bug: mantis-361
http://
committed this fix
cvs diff -wb (in directory C:\hill\ R3.14.dll_ hell_fix\ epics\base\ src\ca\ ) context. cpp ======= ======= ======= ======= ======= ======= ======= ======= ==== epicsmgr/ cvsroot/ epics/base/ src/ca/ ca_client_ context. cpp,v context. cpp context. cpp 23 Aug 2007 17:46:22 -0000 1.9.2.23 context. cpp 21 Aug 2009 00:46:12 -0000 >fdRegFunc = pFunc; >fdRegFuncNeeds ToBeCalled = true; sendWakeupMsg ();
? Edit1.TXT
? RCa01512
? tst.cpp
Index: ca_client_
=======
RCS file: /net/phoebus/
retrieving revision 1.9.2.23
diff -u -b -w -b -r1.9.2.23 ca_client_
--- ca_client_
+++ ca_client_
@@ -253,6 +253,11 @@
this-
this->fdRegArg = pArg;
this-
+ if ( pFunc ) {
+ // the receive thread might already be blocking
+ // w/o having sent the wakeup message
+ this->_
+ }
// should block here until releated callback in progress completes
}
@@ -557,11 +562,11 @@
0, & tmpAddr.sa, & addrSize ); incePend = true; hreadsPending > 0 ) {
epicsGuar dRelease < epicsMutex > unguard ( guard );
this- >callbackThread ActivityComplet e.wait ( 30.0 ); incePend = true;
} while ( status > 0 );
}
- this->noWakeupS
while ( this->callbackT
}
+ this->noWakeupS
}
double elapsed = epicsTime: :getCurrent( ) - current;
osiSockAd dr tmpAddr;
0, & tmpAddr.sa, sizeof ( tmpAddr.sa ) );
@@ -613,6 +618,13 @@
}
}
if ( sendNeeded ) {
+ _sendWakeupMsg ();
+ }
+ }
+}
+
+void ca_client_context :: _sendWakeupMsg ()
+{
// send short udp message to wake up a file descriptor manager
// when a message arrives
@@ -623,8 +635,6 @@
sendto ( this->sock, & buf, sizeof ( buf ),
}
- }
-}
void ca_client_ context: :callbackProces singCompleteNot ify () ======= ======= ======= ======= ======= ======= ======= ======= ==== epicsmgr/ cvsroot/ epics/base/ src/ca/ oldAccess. h,v ingCompleteNoti fy (); ntext (
{
Index: oldAccess.h
=======
RCS file: /net/phoebus/
retrieving revision 1.47.2.17
diff -u -b -w -b -r1.47.2.17 oldAccess.h
--- oldAccess.h 23 Aug 2007 17:46:24 -0000 1.47.2.17
+++ oldAccess.h 21 Aug 2009 00:46:12 -0000
@@ -404,6 +404,7 @@
void callbackProcess
cacContext & createNetworkCo
epicsMutex & mutualExclusion, epicsMutex & callbackControl );
+ void _sendWakeupMsg ();
ca_client_context ( const ca_client_context & );
ca_client_context & operator = ( const ca_client_context & );
***** CVS exited normally with code 1 *****