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 | 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 |
<== Date ==> | <== Thread ==> |
---|
Subject: | RE: Channel Access Portable Server, passing by pointer in read/write methods |
From: | "Jeff Hill" <[email protected]> |
To: | "'Malitsky, Nikolay D'" <[email protected]>, <[email protected]> |
Date: | Fri, 26 Jun 2009 09:41:18 -0600 |
Nikolay, For the write implementation what
you have will work but you are allowing the client to change the GDD primitive
type and application type structure of your service’s representation –
which may or may not be appropriate in your situation. You end up with an un-typed
service which could cause less predictable behavior. The client could for
example change, using one write, a double value surrounded by lots of meta data
into the string value “off” with no metadata for example. For your read implementation the
primary concern might be that the service wouldn’t be looking at some of
the details of the read request from the client. In particular, the destination
GDD comes preformatted with all of the application types that the client is
fetching (i.e. all of the GDD application types in a CA DBR_XXXX – say DBR_GRAPHIC_DOUBLE),
but your code snippet is substituting instead what the service is storing.
Maybe this is ok as long as a superset of all of the application types is
always provided (where the superset is modal depending on the DBR_XXXX data
model for the value type of string, float, or enum). The client’s request
would be rejected for example if the destination value has primitive type
double and the substituted value is a string with value “off”. What
you have suggested might be ok as long as you don’t mind leaving the
error checking to the server. The server does do the necessary primitive type
conversion checking of the response. If any of the application types are
missing for the clients DBR_XXX type then the client’s read request is
rejected. The code in base/src/makeBaseApp/templates/caServerApp/exPV.cc
shows another way to implement a read using a dispatch table for each of the
applications types. I don’t claim that it’s the proper way to
structure a service, but perhaps it can provide some contrast. The GDD library also as I recall
supports GDD container to GDD container assignment which would be another way
to implement the read. Jeff From:
[email protected] [mailto:[email protected]] On
Behalf Of Malitsky, Nikolay D Hello, I am considering the Channel Access Portable Server for supporting the
C++ middle layer servers. The associated PVs will maintain one-dimensional arrays of characters.
Their lengths can be significant. So, passing by pointer in read/write methods would
be a preferable way. The ‘write’ case looks straightforward (as described in the tutorial, p.35): class my PV : public casPV { …. gdd* pValue; }; caStatus myPV::write(const casCtx& ctx, gdd &value){ … pValue->unreference(); pValue = &value; pValue->reference(); … } The ‘read’ case looks trickier (Probably, because it is not
explained). In short, CORBA addresses such case by using the additional wrappers,
e.g. gdd_var objects, in the ‘read’ method. However, the signature of this method
is already defined by the basis class casPV. Fortunately, it seems we can still use the gdd-based
approach using another mechanism, the pv-associated destructor, e.g. myPVReadDestructor: caStatus myPV::read(const casCtx& ctx, gdd &value){ … value.putRef(pValue->dataPointer(), new myPVReadDestructor(pValue)); pValue->reference(); } where : myPVReadDestructor::run(…){ pValue->unreference(); } Any comments and suggestions about a better solution. Thank you, Nikolay |