ca_context_destroy() slow when circuit unresponsive
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
EPICS Base |
Won't Fix
|
Medium
|
Jeff Hill |
Bug Description
If the application calls ca_context_destroy (or
ca_task_exit) when a TCP circuit is unresponsive,
the library could wait a long time on a clean TCP
shutdown until the TCP circuit is internally aborted
by the IP kernel.
Additional information:
Many thanks to Yevgeny A. Gusev for bringing this
to our attention. He also was kind enough to supply the
following test code that reproduces the problem.
#include <stdio.h>
#include <stdlib.h>
#include <cadef.h>
static const char *progname;
static int disconnected = 0;
static void exception_handler( struct exception_
{
if ( args.chid )
fprintf( stderr, "%s: exception handler for \\"%s\\": %s (%s)\\n",
progname, ca_name( args.chid ), ca_message( args.stat ),
args.ctx );
else
fprintf( stderr, "%s: exception handler message: %s (%s)\\n",
progname, ca_message( args.stat ), args.ctx );
if ( ! ( args.stat & CA_M_SUCCESS ) &&
CA_
ca_signal( args.stat, "CA exception" );
}
static void event_handler( struct event_handler_args args )
{
if ( args.status == ECA_NORMAL )
fprintf( stdout, "%s: event handler called for \\"%s\\"\\n", progname,
ca_name( args.chid ) );
else
fprintf( stderr, "%s: event handler error for \\"%s\\": %s\\n", progname,
ca_name( args.chid ), ca_message( args.status ) );
}
static void connect_handler( struct connection_
{
chid chId = args.chid;
fprintf( stderr, "%s: connection handler for \\"%s\\": %s\\n",
progname, ca_name( chId ), ( ca_state( chId ) == cs_conn ) ?
"CONNECTED" : "DISCONNECTED" );
if ( ca_state( chId ) != cs_conn )
disconnected = 1;
}
int main( int argc, char *argv[] )
{
char *name;
chid chId;
evid evId;
int status;
if ( argc < 2 ) {
fprintf( stdout, "%s: Usage: %s PV-name\\n", argv[0], argv[0] );
exit( 0 );
}
progname = argv[0];
status = ca_context_create( ca_disable_
if ( status != ECA_NORMAL ) {
fprintf( stderr, "%s can't create CA context: %s\\n",
progname, ca_message( status ) );
exit( 0 );
}
status = ca_add_
if ( status != ECA_NORMAL ) {
ca_context_
fprintf( stderr, "%s can't add CA exception handler: %s\\n",
progname, ca_message( status ) );
exit( 0 );
}
name = argv[1];
status = ca_create_channel( name, ( caCh * ) connect_handler, NULL,
( capri ) 50, &chId );
if ( ( status != ECA_NORMAL ) ||
( ( status = ca_pend_io( 5.0 ) ) != ECA_NORMAL ) ) {
fprintf( stderr, "%s can't create channel \\"%s\\": %s\\n",
progname, name, ca_message( status ) );
exit( 0 );
}
status = ca_create_
if ( ( status != ECA_NORMAL ) ||
( ( status = ca_pend_io( 5.0 ) ) != ECA_NORMAL ) ) {
fprintf( stderr, "%s can't add event handler for \\"%s\\": %s\\n",
progname, name, ca_message( status ) );
exit( 0 );
}
while ( 1 ) {
/*
To see how ca_context_
before ca_pend_event() when some network activity probably isn't
completed.
*/
if ( disconnected ) {
fprintf( stdout, "%s: ca_context_destroy start\\n", progname );
ca_
fprintf( stdout, "%s: ca_context_destroy end\\n", progname );
exit( 0 );
}
ca_pend_event( 5.0 );
}
exit( 1 );
}
Original Mantis Bug: mantis-95
http://
summary: |
- hang in ca_context_destroy() when circuit is unresponsive + ca_context_destroy() slow when circuit unresponsive |
Changed in epics-base: | |
status: | Incomplete → Confirmed |
importance: | Wishlist → Medium |
fixed the following problems: destroy( ) attempting a destroy( ) attempting a
o application could hang for too long in ca_context_
clean shutdown if circuit is known to be unresponsive
o application could hang for too long in ca_context_
clean shutdown if circuit is not known to be unresponsive, but is
o unexpected errno from recv diagnostic was improperrly supressed
for locally initiated circuit abort