gv_util - EPOCH Global Variable Utilities

The GV utilities provide a C language, client interface to EPOCH global variables.

The EPOCH C++ implementation of a client interface accesses global variables directly out of shared memory, thus requiring that an EPOCH global server be running on the client's host. When a client needs to access global variables residing on another machine, the local global server communicates with the remote global server in order to provide a mirror image of the remote machine's shared memory segment.

The GV_UTIL package takes a different approach: rather than requiring a local global server and shared memory, the GV utilities communicate directly with the home global server of the target global segment in order to get information about the variables and to retrieve or store the values of variables.

Before accessing individual variables, an application must first initialize access to the global segment(s) containing the variables:

    #include  <stdio.h>				-- Standard I/O definitions.
    #include  "gv_util.h"			-- EPOCH global variables.
    GlobSeg  segment ;
    gvsCreate (NULL, "stream[@host]", &segment) ;

A network connection is established with the home global server for the stream's segment and a list of the variables in the segment is downloaded and saved by the GV_UTIL package.

After the global segment is created, gvsPoll() must be called periodically or as necessary in order to receive and process messages from the segment's global server. gvsPoll() waits for and reads a single batch of incoming messages; a timeout may be specified to limit how long gvsPoll() waits for input:

    for ( ; ; ) {
        gvsPoll (segment, 5.0) ;		-- Wait 5 seconds.
        ... do something else ...

In event-driven applications (e.g., those based on the X Toolkit or the IOX dispatcher), the socket connection to the global server, returned by gvsFd(), can be monitored for input by your event dispatcher. The input callback, when invoked, should call gvsPoll() with a 0.0-second timeout to read and process the waiting messages.

A specific variable can be looked up by name:

    GlobVar  global ;
    global = gvsFind (segment, "name") ;

or the entire list of variables can be scanned by index:

    for (i = 0 ;  i < gvsCount (segment) ;  i++) {
        global = gvsGet (segment, i) ;
        if (global == NULL)  continue ;

(Because there may be gaps in indices caused by temporary variables, gvsGet() may return NULL for a seemingly valid index.)

Before retrieving the value of a global variable, you must initiate updates to the variable's value. Binding an update callback to the global variable:

    extern  GvUpdateCB  updateCB ;		-- Callback function.
    gvBind (global, updateCB) ;

results in a request for updates being sent to the segment's global server, which immediately sends the current value of the variable. When this and subsequent update messages for the variable are received from the global server, the application's update callback function is automatically invoked by gvsPoll() after the variable's value has been updated.

Finally, to terminate access to a global segment, call gvsDestroy():

    gvsDestroy (segment) ;

There is no need (and no way) to explicitly terminate access to a specific global variable, although a callback on a global variable can be cancelled by calling gvCancel():

    GvCallback  callback = gvBind (global, updateCB) ;
    gvCancel (callback) ;

The following simple client requests updates for all the variables in a segment; as each update is received, it is written to standard output as:

timestamp flags (segment) variable = value

Here is some actual output:

    1997-336-19:48:45.099 00000000 (e3_nml@claudius) ETRG_PITCMD = 0
    1997-336-19:48:45.099 00000000 (e3_nml@claudius) ETRG_ROLCMD = 0
    1997-336-19:48:45.099 00000000 (e3_nml@claudius) ETRG_YAWCMD = 0

and here is the actual code (the first argument on the command should be the segment name, "stream[@host]"):

    #include  <stdio.h>				-- Standard I/O definitions.
    #include  "gv_util.h"			-- EPOCH global variables.
    #include  "tv_util.h"			-- "timeval" utilities.

    int  updateCB (GlobSeg segment, GlobVar global, GvCallback callback,
                   GvCondition condition, void  *clientData)
        long  flags ;
        struct  timeval  timestamp ;
        NamedVariable  variable ;

        if (condition != GvUpdated)  return (0) ;
        variable = gvValue (global, &flags, &timestamp) ;
        printf ("%s %08lX (%s) %s = %s\n",
                tvShow (timestamp, 0, NULL), flags, gvsName (segment),
                gvName (global), nvrString (variable)) ;
        return (0) ;

    main (int argc, char *argv[])
        GlobSeg  segment ;
        GlobVar  global ;
        int  i ;
						-- Create the segment.
        gvsCreate (NULL, argv[1], &segment) ;
						-- Request updates on all.
        for (i = 0 ;  i < gvsCount (segment) ;  i++) {
            global = gvsGet (segment, i) ;
            if (global != NULL)  gvBind (global, updateCB, NULL) ;
						-- Listen for updates.
        for ( ; ; ) {
            if (gvsPoll (segment, -1.0))  break ;
						-- Delete the segment.
        gvsDestroy (segment) ;


Public Procedures

gvsBind() - binds a callback to a global segment.
gvsCount() - returns the maximum number of variables in a global segment.
gvsCreate() - creates a global segment.
gvsDestroy() - deletes a global segment.
gvsFd() - returns a global segment's socket number.
gvsFind() - looks up a variable by name in a global segment.
gvsGet() - looks up a variable by index in a global segment.
gvsIsUp() - checks if a global segment is active.
gvsName() - returns a global segment's name.
gvsPoll() - process pending updates to a global segment.

gvBind() - binds a callback to a global variable.
gvCancel() - cancels a callback.
gvName() - returns a global variable's name.
gvSegment() - returns a global variable's segment.
gvValue() - returns a global variable's current value.

Source Files


Alex Measday  /  E-mail