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