|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||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|
|<== Date ==>||<== Thread ==>|
|Subject:||Re: Race conditions in SNL programs|
|From:||Dirk Zimoch <email@example.com>|
|To:||Benjamin Franksen <firstname.lastname@example.org>|
|Date:||Fri, 21 May 2010 14:40:58 +0200|
Best regards, Dirk
On Friday 21 May 2010, Andrew Johnson wrote:On Thursday 20 May 2010 17:53:04 Benjamin Franksen wrote:This bug must have been in the sequencer for a long, long time, probably right from the beginning.I'm not convinced it's quite as bad as you think; I suspect it derives from R3.14.x when Jeff introduced the ca_enable_preemptive_callback option. Before this time the CA library never got a chance to process network messages unless you called it using ca_pend_event() or ca_pend_io() so the callbacks would only run when the thread was inside the CA library.
Unfortunately, pre-3.14 versions are affected, too, see below.
Hmm, that doesn't necessarily work with multiple state sets though, I
wonder if CA supported sharing CA contexts back then?
It did, this is what the ca_import routine was for.
You are right that if you use one single task and ca_disable_preemptive_callback (or, equivalently, the old ca_task_initialize), then there is no problem. However, even the old 1.9.x sequencer releases use an extra auxiliary task to initialize CA, and a separate task for each state set taht calls ca_import. The auxiliary task is the only place where ca_pend_event is called. This means all callbacks will be executed in the task context of the auxiliary task, and (I checked it) there are no locks taken when the callback copies the data into the program variable.
So, the only difference is that in the old versions it is the sequencer's own task, while in later versions it is a (hidden) CA internal task.