1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 <2014> 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 | Index | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 <2014> 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | multiple threads and ca_attach_context |
From: | Al Honey <[email protected]> |
To: | "'[email protected]'" <[email protected]> |
Date: | Wed, 23 Apr 2014 00:14:32 +0000 |
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 ) 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 |