Hello,
I
am running EPICS R3.14.9 on a Solaris 10 machine, and am having difficulties
implementing a multithreaded event monitoring application. The goal is for the
main thread to open channel connections, and wait for user commands to perform
other tasks. An auxiliary thread would be responsible for processing channel
events as they occur.
I
have read in the 3.14 users manual that when the context is created using
ca_enable_preemptive_callback, the CA library will spawn auxiliary threads that
will automatically execute event callbacks. I use the following code to open a
channel and set a callback (error handling removed for brevity):
void
connect_handler(struct connection_handler_args connect_args)
{
// Handle connection
events.
}
void
event_handler(struct event_handler_args event_args)
{
// Print data.
}
int
main(…) {
chid chId;
int stat;
stat = ca_context_create(ca_enable_preemptive_callback);
stat= ca_create_channel(argv[1], connect_handler, argv[1], 49, &chId);
// Give the connect request time to process
ca_pend_event(0.05);
stat=ca_add_event(DBR_DOUBLE, chId, event_handler, NULL, NULL);
sleep(10.0);
}
Based
on what I’ve read, I would expect that while the main thread is sleeping, the
CA auxiliary threads would be finding events and executing the callback,
however it never does (the actual database value is update at 2 Hz). Is my
understanding or setup of the CA connections incorrect for this usage?
As
a fix, I acquire the ca_context right after I create it, and attach an
application thread to the context which is responsible for executing periodic
polling (again, error checking removed for brevity):
struct
ca_client_context* caContext = NULL;
void*
dispatcher(void* ctx)
{
stat = ca_attach_context(caContext);
while(1) {
ca_pend_event(0.0001);
sleep(0.5);
}
return NULL;
}
int
main(…)
{
…
stat = ca_context_create(ca_enable_preemptive_callback);
caContext = ca_current_context();
…
pthread_create(&dispatchThread, NULL, dispatcher, NULL);
sleep(10.0);
}
Using
this setup I successfully get callback events. Did I misunderstand the
documentation when it said the CA Library would create its own event processing
threads, and that the second method I emply is actually the correct method?
Final
question: When using preemptive callbacks, performing a select on the file
descriptors created by channel connections no longer see any change on the
sockets. Why is this (what is the motivation)?
Any
help would be greatly appreciated.
Douglas A. T. Morrison
Software Engineer
C.A.R.A - W. M. Keck Observatory
65-1120 Mamalahoa Hwy.
Kamuela, HI. 96743
Office: (808)881-3539
Cell: (808)937-0998