I've finally isolated the issue when calling ca_context_create(1) late ... and it's something to do with how the zero count is handled in ca_array_get_callback -- to be precise, when calling
ca_array_get_callback(dbrcode, 0, channel, callback, context)
the size of the returned array differs, depending on whether ca_context_create(1) was called before or after iocInit! Note that this problem only occurs with internal PVs, for external PVs the correct count is returned in both cases.
I've attached a complete example IOC -- just compile it and run `test` or `test 1` in the root. Running `test` will call ca_context_create(1) late and will print out 'count = 0'; running `test 1` calls ca_context_create(1) early and prints out 'count = 1'. I've tested this with both 3.14.11 and 3.14.12.3.
I can't find documentation for the expected behaviour of calling ca_array_get_callback() with a zero count, but I've never encountered problems with this before: up to now I've expected to get the "natural" record size. Note that if the PV being fetched is an external PV then 'count = 1' is printed as expected.
Note, by the way, that my earlier diagnosis (that something else was also calling ca_context_create() and conflicting) appears to have been completely wrong. Sorry about the red herring.
Here's the core of the IOC:
test.c
======
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <cadef.h>
#include <iocsh.h>
static chid pv_channel;
static void on_get(struct event_handler_args args)
{
printf("on get\n");
printf("count = %ld\n", args.count);
}
static void on_ca_connect(struct connection_handler_args args)
{
printf("on connect\n");
ca_array_get_callback(3, 0, pv_channel, on_get, NULL);
}
int main(int argc, char **argv)
{
bool early_create = argc > 1 && *argv[1] == '1';
printf("Creating CA context %s\n", early_create ? "early" : "late");
if (early_create)
ca_context_create(1);
iocsh("TEST.cmd");
if (!early_create)
ca_context_create(1);
ca_create_channel("TESTPV", on_ca_connect, NULL, 0, &pv_channel);
sleep(1);
return 0;
}
TEST.cmd
========
dbLoadDatabase("dbd/TEST.dbd", NULL, NULL)
TEST_registerRecordDeviceDriver(pdbbase)
dbLoadRecords("TEST.db", NULL)
iocInit()
TEST.db
=======
record(bo, "TESTPV")
{
}
Attachment:
test-ioc.tgz
Description: test-ioc.tgz
- Replies:
- Re: Calling ca_context_create(1) too late Andrew Johnson
- References:
- Calling ca_context_create(1) too late michael.abbott
- Re: Calling ca_context_create(1) too late Andrew Johnson
- Navigate by Date:
- Prev:
RE: caget delays tom.cobb
- Next:
FW: Calling ca_context_create(1) too late michael.abbott
- 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
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: Calling ca_context_create(1) too late michael.abbott
- Next:
Re: Calling ca_context_create(1) too late Andrew Johnson
- 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
2020
2021
2022
2023
2024
|