issues surrounding manipulation of CA contexts

Bug #541219 reported by Jeff Hill
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
EPICS Base
Fix Released
Wishlist
Jeff Hill

Bug Description

These requests originate from Ben Franksen:

As far as I can see after studying the CA Client Library documentation,
it is currently not possible to detach (un-attach) a context from a
task without destroying the context.

OTOH, I also gather from the docs that ca_attach_context fails if the
thread already has a context attached (return value is not ECA_SUCCESS
but ECA_ISATTACHED). This makes re-attaching a different context to a
thread impossible without destroying the context, which may not be what
the user wants, because there may be other threads attached to that
context that should continue to run.

What do you think about adding some

void ca_context_detach()

which set the thread's internal (hidden) context to null without
destroying the context (so other threads are not affected).

A client thread could then perform a sequence like

- use ca_current_context
- save the returned context
- detach the old context
- attach a new context
- some time later re-attach the original (saved) context.

This would be a *very* helpful tool for library writers who want to give
users a more idiot proof API.

On a related note, it would be useful if a variant of ca_context_destroy
existed, that gets the context as parameter, instead of destroying the
current context. An application could then keep track of all active
contexts and destroy them when they are no longer used This could be
done by some independent thread. Of course one could fake this by first
attaching to the context and then calling the existing
ca_context_destroy but this seems a little awkward to do.

And while we're at it, maybe some kind of warning should be added to the
docs, that calling ca_context_destroy has a global effect on *all*
threads attached to the current context.

Original Mantis Bug: mantis-161
    http://www.aps.anl.gov/epics/mantis/view_bug_page.php?f_id=161

Tags: ca 3.14
Revision history for this message
Jeff Hill (johill-lanl) wrote :

From Andrei Liyua:

 If I am not mistaken there are not couple features in current CA
function interface.
 I can suppose that when you came to multithread CA you added
get_current_context and attach functions. But there is not similar
mechanism for ca_context_destoy.
 So I open first thread, create CA context, create first CA
channel. Then I open second thread, attach to current CA context, create
second CA channel. ... Then I decide to close first CA channel and
close context (???!!!). What is behavior CA library? I suppose second CA
channel will be closed without normal procedure of closing second
channel + its monitor?
 But I don't like to close second channel and CA context! Then I
should check is that channel latest? I couldn't find suitable function
in CA function API. Maybe get_current_context has something. But it is
very deep.
 I have once way - hold tracks of my CA channels (minimum is
global counter). Usually it could be done. But if program is mixture of
different libraries and each library comes to CA library then it becomes
impossible.

Revision history for this message
Jeff Hill (johill-lanl) wrote :

More from Ben:

I asked Jeff a similar thing a while ago. Specifically, I asked for a feature
ca_detach_context that would be the opposite of ca_attach_context (and could
also be used to detach the thread that created the context in the first
place[*]). He seemed to be open to the suggestion but I don't know if it is
planned to be included in the next epics release.

[*] ca_create_context in fact does two separate things: It creates a context
and then attaches the calling thread to it; whereas ca_destroy_context first
detaches context from the caling thread, then destroyes the context.

Revision history for this message
Jeff Hill (johill-lanl) wrote :

> So I open first thread, create CA context, create first CA
> channel. Then I open second thread, attach to current CA
> context, create second CA channel. ... Then I decide to
> close first CA channel and close context (???!!!). What
> is behavior CA library? I suppose second CA channel will
> be closed without normal procedure of closing
> second channel + its monitor?

The 2nd channel's subscription (monitor) is removed from the IOC, the channel is removed from the IOC, the circuit to the IOC is disconnected, and the channel is attached to a NOOP CA service.

> But I don't like to close second channel and CA context!
> Then I should check is that channel latest (is the
> last channel)? I couldn't find suitable function in CA
> function API.

There isn’t, currently, an interface for this information in the library.

> I have once way - hold tracks of my CA channels (minimum
> is global counter). Usually it could be done. But if program
> is mixture of different libraries and each library comes to
> CA library then it becomes impossible.

No such interfaces (for attaching and incrementing an in use count and detaching and decrementing an in use count) currently exist. I will add your ideas to Mantis entry 161 (initiated on behalf of Ben) for further consideration.

> But if program is mixture of different libraries and
> each library comes to CA library then it becomes impossible.

One would need to carefully consider if these independent libraries should share a CA context. If so, perhaps you might pass a CA context identifier to these libraries when they initialize.

Revision history for this message
Jeff Hill (johill-lanl) wrote :

I added a new function to the source code and the manual as follows.

void epicsShareAPI ca_detach_context ()
{
    if ( caClientContextId ) {
        epicsThreadPrivateSet ( caClientContextId, 0 );
    }
}

I added additional entry under ca_attach_context() specifying that (and why) ECA_ISATTACHED might be returned.

I added this warning to the ca_context_destroy() doc:

Be advised that any user created threads that might have attached themselves to the CA context must of course stop using it prior to its being destroyed.

I did *not* yet convince myself that there should be a variant of ca_destroy_context() specifying other than the current thread's
context because:

A) This functionality *is* available with a combination of ca_context_attach() and ca_destroy_context()

B) In almost all cases the user should request that the subsystem and any auxiliary threads shut themselves down prior to destroying any ca context that they might have created. Therefore, it seems that the auxiliary thread should call ca_context_destroy, and that adding a special ca_destroy_context() specifying other than the current thread's context is actually helping the user to do something that is ordinarily ill advised.

edited on: 2005-11-14 16:19

Revision history for this message
Jeff Hill (johill-lanl) wrote :

fixed in R3.14.8

Revision history for this message
Andrew Johnson (anj) wrote :

R3.14.8 Release.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.