EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: multiple threads and ca_attach_context
From: "Hill, Jeff" <[email protected]>
To: Al Honey <[email protected]>, "'[email protected]'" <[email protected]>
Date: Wed, 23 Apr 2014 00:55:57 +0000

Aloha Alan,

 

I thought it was my job to jump directly to the source code :-)

 

There are two types of get in CA

1)      A set of ordinary get requests followed by the pend_io call to synchronize completion

2)      get callback

 

The 1st scenario is applicable only to single threaded (i.e. not in preemptive callback mode) applications. Each pend IO call is like the rubber bar at the grocery checkout. It separates one set of groceries from another (one set of gets which might have timed out from a subsequent set which have a new chance for success). This type of synchronization is only applicable in a single threaded execution model.

 

The 2nd scenario works equally well in the single-thread (non-preemptive callback) and preemptive callback modes but does require more effort in the client side application.

 

In preemptive callback mode the callbacks are fully asynchronous, coming from independent threads for each circuit, so be careful to protect your data structures using a mutex as appropriate.

 

Jeff

 

From: [email protected] [mailto:[email protected]] On Behalf Of Al Honey
Sent: Tuesday, April 22, 2014 6:15 PM
To: '[email protected]'
Subject: multiple threads and ca_attach_context

 

Hi

I am unable to determine how to successfully use ca_attach_context, with the creation of multiple threads to read CA channels.

I suspect I have missed a step but do not find any relevant documentation.

This is all pertinent to EPICS R3.14.9

 

Any help would be appreciated.

 

Two scenarios:

1.     Open a connection, via caRepeater, and periodically read the same channel (no problems)

2.     Open a connection, via caRepeater, and periodically launch a posix thread to read the same channel (does not work). Each thread exits after getting a CA channel value.

 

Starting the connection  to caRepeater.

(code snippets are paraphrased somewhat):

 

      static  struct ca_client_context *ca_context = NULL;

 

      stat  = ca_context_create(ca_enable_preemptive_callback);

 

      ca_context = ca_current_context();

 

      stat = ca_add_exception_event( exception_callback, NULL );

 

      stat = ca_add_fd_registration( fdReg, NULL);

 

Now launch threads to obtain channel values, in my failure scenario each thread is accessing the same channel. The following occurs for the first thread.

 

// The following is done for both scenarios.

// Find the info for the specific channel – details not shown, but essentially an element in an array of structures.

 

If ( info->channelId == NULL ) {

   stat = ca_create_channel( ch_name, changeConnection_callback, info, 20, &info->channelId);

 

  // Do the following as ca_pend_io() returns immediately because a callback was registered with the channel creation.

   while ( ca_stateinfo->channelId) != cs_conn ) {  <a delay with overall timeout> }   // Completes without timeout.

}

 

The following is done for each thread (the non-threaded scenario effectively falls thru).

If ( ca_context == NULL )
  ca_context = ca_current_context();            
// This never occurs, as expected, because ca_context was previously setup

else {

  my_context = ca_current_context();

  if ( my_context != ca_context ) {                   // my_context is always nil for each thread and equality for the non=threaded scenario

    stat = ca_attach_context( ca_context );  // This completes without error for each thread

  }

 

The following is done whether or not threads are created (both scenarios):

 

stat = ca_get( info->getType, info->channelId, buff );  // This fails with ECA_DISCONN error status in the threaded scenario only.

 

Even with a 3 second delay after ca_get and then retrying ca_get, it fails with disconnected status, in the threaded scenario.

 

If a thread is not created then the above completes successfully (the ca_attach_context logic does not occur in that scenario).

 

 

Thanks,

Allan

 

 

 

 

 


References:
multiple threads and ca_attach_context Al Honey

Navigate by Date:
Prev: multiple threads and ca_attach_context Al Honey
Next: asyn/stream hang on (very long email, sorry in advance) Mauro Giacchini
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: multiple threads and ca_attach_context Al Honey
Next: asyn/stream hang on (very long email, sorry in advance) Mauro Giacchini
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 17 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·