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