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