Ingres CL GC

From Ingres Community Wiki

Jump to: navigation, search

Ingres Compatability Library
Architecture - Overview - Suggestions - GL: BA - BT - ERGL - handy - HSH - LC - LL - MEGL - MM - MO - MU - PM - SP - TMGL - CL: CI - CK - CM - CP - CS - CSMT - CV - CX - DI - DL - DS - ER - ERold - EX - FP - GC - GV - handy - ID - JF - LG - LK - LO - ME - MH - NM - OL - PC - PE - QU - SA - SI - SR - ST - TC - TE - TH - TM - TR - UT

Contents

Compatibility Library Specification - GC

Abstract

This is the specification of the GC facility provided by the compatibility library for local and network inter-process communication.

Revision: 3.0, 8-Dec-98

Document History

  • Revision 3.0, 8-Dec-98.
    • Removed GCsendpeer, GCrecvpeer, and GCA specific data structures.

Specification

Overview

This section specifies the CL routines which are part of the General Communication Facility (GCF).

GCF has three components: GCA is the Application Program Interface (API), GCN is the Name Translation Service (Name Server), and GCC is the Communication Service (Comm Server). GCN is fundamental to the functioning of GCA, and together they provide support of local homogeneous API communications. The GCC component provides the ability to bridge two dissimilar local API communications environments via separate heterogeneous communications conducted between them.

The CL routines described in this chapter fall into two separate categories: those associated with GCA local API communications, and those associated with GCC remote heterogeneous communications. They are known as the GCA CL and the GCC CL, respectively, and collectively as the GC CL. They are the means by which the components of GCF interface to a particular execution environment. The GCA CL and the GCC CL are specified separately.

In contrast to other CL modules, the GC CL routines provide two different header files: <gc.h> and <gcccl.h>. These files are constant across all implementations of the same release level.

In this introduction, we first describe the features of the GCA CL and then the features of the GCC CL. Terms explained for the GCA CL are not explained again for the GCC CL.


Library

CL

GCA CL

The GCA CL contains two types of routines: housekeeping routines and the IPC (interprocess communication) support. The housekeeping routines are described only in the interface section below.

The IPC support provides an interface between GCA and the preferred IPC mechanism supported by the OS. The interface to the local IPC is some dozen routines, most of which take a single parameter list (called SVC_PARMS).

Intended Uses

The GCA CL routines are intended for use only by the GCA and GCN components of GCF. They provide functional support for the various aspects of managing interprocess communication. They are not intended for use outside of GCF.

Connection oriented

The GCA CL provides a connection oriented, intra-host, reliable IPC (interprocess communication) mechanism, presumably built upon an IPC mechanism provided by the operating system.

The mechanism is said to be connection oriented because it establishes a connection, or "association," between two peer processes. The peer processes send and receive data over this association until it is dismantled. Data sent by one process is reliably received by the other. The initiator of the connection is known as the client process and the responder is known as the server process (even though a server process may be an initiator on one association and a responder on another). The initiator makes a connection request with GCrequest; the responder receives a connection indication with GClisten. These connections are called "GCA" connections.

When a process establishes an association, the GCA CL identifies the association with a pointer to the GCA CL's local control block (GCCB) for the association. GCA passes that GCCB pointer to all GCA CL routines for the operations it requests on that association, but does not itself dereference the GCCB. A process may have multiple, concurrent GCA associations, and they should not interfere. The maximum number of concurrent associations is determined only by what the GCA CL can (and will) bear.

Since an association is connection oriented, the GCA CL must have connection awareness; that is it must be able to determine if its partner has exited, abruptly or otherwise, and cause to fail any pending or future I/O requests made on that association.

The GCA CL IPC mechanism is said to be intra-host because it is only required to build associations between processes on the same host. The GCA CL may optionally support cross-host connections when the capability is provided by the IPC mechanism. Cross-host connections are not required to support heterogenous environments.

The mechanism is said to be reliable because either a requested data transfer succeeds or an (unrecoverable) error is reported to both parties. Additionally, data are presented to the receiver in the same order they are sent by the sender.

It is recommended that the GCA CL be built upon a connection oriented OS IPC mechanism rather than, say, mailboxes. If the GCA CL uses a connection-less IPC mechanism, it will have to provide (usually at no small cost) connection control.

Listen ID

Server processes are identified through their Listen ID. A Listen ID is generated by the GCA CL when GCA calls GCregister. GCA then normally registers this Listen ID with the Name Server. The Listen ID of the target server process is the addressing information GCA passes GCrequest on connection initiation.

Since the Name Server relies on detecting defunct Listen ID's to unregister servers which have exited, it is important that Listen ID's not be immediately reused when one server exits and another starts. "Immediately" here means 5 minutes, since that is the (current) interval at which the Name Server checks its registries.

Byte stream

A GCA CL association is a full duplex, two channel, mostly byte-stream oriented connection.

As a GCA CL association is full duplex, it must permit simultaneous data transmission in both directions.

A GCA CL association must support two subchannels: NORMAL and EXPEDITED. A send of data on one channel can only be received by the peer process issuing a receive on that same channel. The name "EXPEDITED" does not necessarily imply more rapid travel than NORMAL data, but only that EXPEDITED data must not lag NORMAL data. That is, EXPEDITED data sent before NORMAL data must be guaranteed to arrive before that NORMAL data. If the OS IPC can not support a separate subchannel for EXPEDITED data or the above rules cannot be guaranteed, the GCA CL must multiplex NORMAL and EXPEDITED data. This can cause the EXPEDITED data to be flow-controlled with the NORMAL data by the underlying IPC, somewhat defeating the purpose of EXPEDITED data, but that is deemed to be acceptable.

Each of the two subchannels of a GCA CL association is byte-stream oriented, which means that although data must arrive at the receiver in the same order as it was sent, the size of the buffer sent need not be preserved on receipt. For example, the GCsend routine may be asked to send 100 bytes, after which the peer's GCreceive may return with the first 75 bytes on one invocation and then the remaining 25 on the next invocation.

For compatibility reasons, the GCA CL must support synchronization marks on the NORMAL subchannel. These are called "chop marks" and are generated by the GCpurge routine. A chop mark flows in-order on the NORMAL subchannel, is distinguishable by the GCA CL from other data, and causes the partner's NORMAL GCreceive to return with a "new chop" indicator (a flag in the parameter list). The transmission of a chop mark implies that NORMAL data sent before the chop mark can be discarded (purged), but in practice it is difficult to guarantee the ordering of NORMAL and EXPEDITED data if a chop mark purges the NORMAL channel.

Both the multiplexing of NORMAL and EXPEDITED data as well as the requirement for chop marks will complicate the implementation of the GCA CL. In particular, even though the GCA CL presents a byte stream interface and the OS IPC mechanism might be byte stream oriented, the GCA CL implementation cannot simply be pass-through. The GCA CL will have to bundle the data into messages with headers indicating the subchannel and chop mark presence.

Asynchronous Interface

All I/O operations of the GCA CL must function asynchronously; that is, return without blocking and signal completion by calling a "callback" routine. Under this scheme, GCA makes a request by calling a GCA CL routine, passing it a parameter block containing (among other things) the parameters of the operation and the address of a callback routine. When the operation completes within the CL, the GCA CL calls the callback routine, passing it the parameter block.

An I/O event handling mechanism specific to the CL or OS is responsible for carrying the operation between request and callback.

The GCA CL may signal completion by driving its callback asynchronously at any time, but a callback may not be interrupted by (e.g. in timeslicing servers) or run concurrenly with (e.g. in multiprocessing servers) any other GCA activity on the same connection, either driven by callback or by GCA user request. This is a restriction in GCA which it must impose on the GCA CL.

To facilitate CL's where flow of control must pass to the event handling mechanism for it to drive its events (i.e. the OS does not deliver software interrupts when events complete), GCA will call the event handling mechanism in a manner dependent (unfortunately) on the application. Three different execution environments must be supported by the GC CL:

  • Applications: GCsync is called to wait for outstanding operations to complete. Event completion callbacks may only be made from GC routines which support callbacks, most notably GCsend, GCreceive and GCsync (preferably just GCsync). Since the CL provides only limited external support for multi-threading outside of CS (semaphores in MU, thread-local storage in ME), the following restrictions apply when the CL internally supports OS multi-threading: event completion callbacks must be made in the same thread context as the original request, GCsync may only block the calling thread, and GCsync must support simultaneous calls from different threads.
  • Single-threaded Servers: GCexec is called after process initialization and the first GC requests have been posted. GCexec is expected to loop driving those requests, the callbacks of which will post further requests. GCexec continues until GCshut is called. Event completion callbacks may be made from GC routines which support callbacks, most notably GCsend and GCreceive, but should be limited to GCexec if possible.
  • Multi-threaded Servers: The CS CL provides multi-threading and event handling services. The GCA CL must operate in cooperation with CS to provide request processing and completion callbacks according to the rules imposed by CS on its clients. Note that the GCA CL must not require CS to operate since CS will not be available in client applications.

Implementation of the GCA CL is directed by its asynchronous callback interface:

  • The CL routines must return instead of blocking, leaving information with the event mechanism about how to carry on the operation. Work is split between the request side of the operation and the completion side of the operation. The completion side of the operation may involve intermediate callbacks from the underlying IPC mechanism, terminated finally by driving the GCA CL user's callback.
  • Because the CL routines return before completing, state information cannot be left on the stack in automatic variables. All information associated with the operation must either be placed in the parameter list by GCA or in the control block for the association by the GCA CL.
  • Because the callback routine may post other requests to the CL, even a request to terminate the assocation, once the CL completes and calls its callback routine it should no longer access the parameter list or the control block.
  • Since status is not returned when an asynchronous request is posted, the callback must always be driven, for success or failure. It is an unrecoverable program error to call the GCA CL without providing a usable parameter list and callback routine.
  • Some GCA CL routines retain a synchronous interface. The method by which these pass status to their callers varies.
Memory Allocator

The GCA CL must try to use the GCA allocator provided when GCA calls GCinitiate. This allocator has the following semantics:

  • It relies on the GCA CL routine [[Ingres_CL_GC#GCrelease - Release buffers allocated during connection.|GCrelease] to free memory which the GCA CL allocated for a particular association. The allocator does not automatically free any memory.
  • It relies on the GCA CL routine GCterminate to free any remaining memory allocated by the GCA CL since GCinitiate was called.
  • It is not preemptable. If callback routines may preempt non-callback code in an environment, then the allocator (alloc or free) cannot be called by callback routines, and all memory needed for a GCA CL operation must be allocated when the request is made.

The following routines may be invoked by GCA during a callback, and they may therefore neither allocate nor free memory.

GC CL that may not call the allocator
GCdisconn
GCpurge
GCreceive
GCsend
GCusrpwd


The remaining routines are not invoked during callbacks, and may use the allocator.

GC CL that may call the allocator
GCexec
GChostname
GCinitiate
GClisten
GCnsid
GCregister
GCrelease
GCrequest
GCrestore
GCsave
GCshut
GCsync
GCterminate
Timeouts

Most connection related routines take a timeout parameter. A timeout of -1 means wait forever if necessary; a timeout of 0 indicates the operation should fail if it can't be completed without blocking, and a positive timeout indicates the number of milliseconds to allow the operation to block before failing.

If an operation blocks multiple times before completing the timeout applies to the cumulative time while blocked and (if possible to compute) while running. The exception is GCsend : once a single byte of data is sent no timeout should be allowed to occur.

The only (non -1) timeouts that the CL must support are a 0 timeout for GCreceive and GCsync (to effect a poll). The CL may optionally support a positive timeout for GClisten, GCrequest , GCreceive and GCsync to allow for connection timeout, and a 0 or positive timeout for GCdisconn to indicate an abortive release. (Other timeouts are currently unused.)

Buffer Size

GCrequest and GClisten, the GCA CL routines which establish associations, may indicate to GCA a preferred buffer size for use in sending and/or receiving messages. This buffer size need NOT be the same for the two partners in an association. It also need NOT be the same for different associations maintained by the same process.

Save/Restore

The GCA CL must provide a means, through the routines GCsave and GCrestore, to pass an existing association from a parent process to a child process.

Security

The GCA CL has the responsibility for enforcing certain aspects of Ingres security. In particular it must:

  • Supply in GClisten the OS user name of the process which made the initiating GCrequest. This name is trusted by the server; local security is only as strong as GClisten's ability to authenticate the user.
  • Supply in GClisten the access point identifier (terminal name) of the process which made the initiating GCrequest. This identifier is not validated: it is only displayed by monitor programs.
  • Validate user/password pairs against the OS password file. If the GCA CL treats all user/password pairs as valid, potentially forged connection requests from remote hosts will all be trusted.
  • Recognise in GClisten connections from trusted local peers and indicate that fact (c.f. GClisten).
Status Mapping

Currently, GCA requires that the internal GCA CL status codes map one-to-one with the GCA client status codes defined in <gca.h>. CL implementors should be aware of these and should exercise caution when assigning values to <gc.h> status values.

Interversion interoperability

As much as possible, GC routines should be able to interoperate with both older and newer versions of the same routines. GC routines must be upwardly compatibly with previous versions wherever possible, to minimize the need for customers to have to relink and rebuild their applications when moving between Ingres releases.


GCC CL

The GCC CL contains two types of routines: housekeeping routines and protocol drivers. The housekeeping routines are described only in the interface section below.

The protocol drivers provide an interface between GCC and the network protocols supported by the OS. Each protocol driver has the same interface: a single routine taking a parameter list and operation code. Multiple protocol drivers may be linked within a single GCC. The service that a protocol driver provides is described below.

Intended Uses

The GCC CL routines are intended for use only by the GCC component of GCF.

Connection oriented

The GCC CL provides a connection oriented, inter-host, reliable, messaging mechanism.

The initiating GCC makes a connection request with the GCC_CONNECT operation; the responding GCC receives a connection with the GCC_LISTEN operation.

When GCC establishes an association, the GCC CL identifies the association with a pointer to the GCC CL's protocol control block (PCB) for the association. GCC passes that PCB pointer to all GCC CL routines for the operations it requests on that association. GCC may have multiple, concurrent GCC associations, and they should not interfere. These associations may, in turn, be supported by multiple protocol drivers. The maximum number of concurrent associations is determined only by what the GCC CL can (and will) bear.

Listen ID

GCC initializes a protocol driver with the GCC_OPEN operation, at which point the protocol driver determines its Listen ID. The Listen ID, coupled with the host name, is the addressing information a GCC passes its protocol driver on connection initiation.

Message Based

A GCC CL association is a full duplex, reliable message oriented connection which transmits blocks of octets (8 bit bytes).

A GCC CL association is message oriented, data sent with the GCC_SEND operation must be returned in whole by the peer's GCC_READ.

Protocol drivers built upon stream oriented IPC mechanisms must prepend a header indicating the length of the packet, including the size of the prepended header.

Asynchronous Interface

All operations of a protocol driver must function asynchronously.

The same I/O event handling mechanism described for the GCA CL must drive protocol drivers as well.

Heterogeneous interoperability

A protocol driver must interoperate with drivers for that protocol written for other OS's.

If a protocol driver is built upon a connection oriented message based IPC mechanism, the protocol driver need only pass the data through unaffected.

If a protocol driver is built upon a stream IPC mechanism (e.g. TCP), it must use the following message protocol to preserve the message boundaries:

<l1><l2><data>

Where <l1> is the low 8 bits of a 16 bit unsigned integer representing the length of <data>, <l2> is the high 8 bits of the length, and <data> is packet of data to be transmitted. The length must include the two bytes of the length description.

If a protocol driver is built upon a connectionless or other esoteric service, you had best talk to the GCF group.

Header File <gc.h>

The GCA CL interface is defined in the GL file <gc.h>. It does not change from system to system.

GC Miscellaneous Constants

This constant defines the amount of space reserved by GCA preceding the send and receive buffers for GCA CL use.

# define	GCA_CL_HDR_SZ	    16	/* CL area before send and  */
				/* receive buffers */

This constant defines the size of the buffer handed to GCsave.

# define    GCA_CL_MAX_SAVE_SIZE    1024    /* size of buffer handed to */
				    /* GCsave - it can be increased. */
GCnsid Flag Values

GCnsid(), described below, takes a flag indicating its action. The flag's value is defined as:

# define GC_CLEAR_NSID 3
# define GC_RESV_NSID 2
# define GC_SET_NSID 1
# define GC_FIND_NSID 0
GCA CL Interface Structures

Data structures defined by the GCA CL.

SVC_PARMS - GCA service parameter list

This structure provides a means of passing parameters from GCA to the GCA CL routines.

typedef struct SVC_PARMS
{
   PTR	    	*gc_cb;			/* GCA CL control block */
   STATUS	status;			/* return status from CL */
   CL_ERR_DESC	*sys_err;		/* for stuffing CL errors */
   i4     	time_out;		/* timeout in ms, 0 = poll, -1 = forever */
   PTR		closure;		/* Parameter for callback function */
   VOID	(*gca_cl_completion)();	/* Completion callback function */

   struct
   {
	bool            new_chop;	/* Got new chop mark on recieve	*/
	bool            flow_indicator; /* flow for send/receive */

# define	GC_NORMAL	    0	/* Normal data flow indicator */
# define	GC_EXPEDITED	    1	/* Expedited data flow indicator */

	bool            trusted;        /* GClisten says peer is same uid */

	bool            run_sync;   	/* Deprecated! */

   } flags;

   /* GCregister parameters */

   i4		num_connected;		/* for GCregister */
   i4		num_active;		/* for GCregister */
   char	*svr_class;		/* for GCregister */
   char	*listen_id;		/* from GCregister */

   /* GClisten parameters */

   char	*user_name;		/* filled in by GClisten */
   char	*account_name;			/* " */
   char	*access_point_identifier;	/* " */
   i4		size_advise;			/* " */
   char	*sec_label;     	/* filled in by GClisten, will */
                               	/* be zero in non-B1 systems. */

   /* GCrequest parameters */

   char	*partner_host;		/* to GCrequest, may be NULL */
   char	*partner_name;		/* to GCrequest */


   /* GCsend, GCreceive, GCsave, GCrestore parameters */

   PTR		svc_buffer;		/* send/receive buffer */
   i4		svc_send_length;	/* send buffer size */
   i4		reqd_amount;		/* receive buffer size */
   i4		rcv_data_length;	/* actual data received */
    
};
GC_OLD_PEER

This structure is provided solely for backward compatibility purposes. The GCA CL used to be permitted to combined any initial connection establishment info it required with that provided by GCA through the functions GCsendpeer and GCrecvpeer. The GCA CL must now exchange any initial info as a part of GCrequest and GClisten processing. The GCA CL may use the following structure to support old client applications which still use GCsendpeer. The structure provides no semantic information and may only be used to determine the size of the GCA peer information provided by the client application. GCA guarantees that the first send and receive operations on an association will be for peer info so that GClisten, GCreceive, and GCsend can coordinate their operations to support old client applications.

typedef struct GC_OLD_PEER
{
   i4          old1[5];
   i4          old2;
   char        old3[96];
   u_i4        old4;
   i4          old5;
   char        old6[304];
};

Header file <gcccv.h>

This file provides a macro interface to network datatype conversion. These macros convert various atomic datatypes (int & float) from the local syntax to the network transfer syntax (NTS) and back.

It also contains the constants which identify the datatype format id for each processor.

Notation

The byte ordering is as they appear on the wire, left to right. To improve readability, the bit ordering within each byte is what is natural for the processor's native byte ordering: LSB->MSB on VAX and their ilk; MSB->LSB on 68000 and the like. The actual bit ordering on the wire depends on the specification of the data-link layer, not on the CV conversion macros or the processor's native bit ordering.

The following notation is used:

s sign bit
eX-Y exponent, bits X to Y
mX-Y mantissa, bits X to Y

where bit 0 is the LSB.

Network Transfer syntax (NTS) for integers and floating point types

The network transfer syntax (NTS) for I1, I2, and I4 is a VAX int of the same size (lo-hi byte order).

NTS for NAT and LONG is the same as for the I4. Truncation may occur on 16 bit int or 64 bit long machines.

NTS for F4 and F8 is given as:

	F4: e0-7 e8-15s m16-23 m24-31 m0-7 m8-15 
	F8: e0-7 e8-15s m48-55 m56-63 m32-39 m40-47 m16-23 m24-31 m0-7 m8-15

Exponent is excess 16382.

Pictorially:


            -----------------
            |     exp(7:0)  |       lowest-address byte
            | S | exp(14:8) |
            |   mant(55:48) |
            |   mant(63:56) |       highest-address byte
            |   mant(39:32) |
            |   mant(47:40) |
    ------------------------------- (f8 rep. only below this line)
            |   mant(23:16) |
            |   mant(31:24) |
            |   mant(7:0)   |
            |   mant(15:8)  |
            -----------------

Where S is the sign bit; if S is set, the represented number is negative. The f4 representation has 32 bits of mantissa, and is a total of 6 bytes long. The f8 representation has 64 bits of mantissa, and is a total of 10 bytes long. "Exp" is in excess-16382 (!) representation: i.e., "exp" values of 1 through 32767 represent true binary exponents of -16381 through 16385. An "exp" value of 0, together with a sign bit of 0, represents 0. "mant" is a fraction normalized to the range 0.5..1.0, with the redundant most significant bit not represented.

Note the odd byte ordering of the mantissa: each 2-byte chunk is in lohi (VAX-like) order, but the 2-byte chunks are in hilo order. A similar eccentricity is found on the VAX; we emulate it.

All zeros mean zero.

Local floating point formats

The following section gives a byte per byte description of each of the currently recognised floating point formats.

Exponents are invariably (so far) unsigned and with an offset called the excess. Subtract the excess to get the actual exponent.

Mantissas are usually normalized with the leading 1 hidden.

CV_VAX_FLT

LSB->MSB processor.

	F4: m16-22e0 e1-7s m0-7 m8-15 
	F8: m48-54e0 e1-7s m32-39 m40-47 m16-23 m24-31 m0-7 m8-15 

Exponent is excess 128

CV_LH_FLT

LSB->MSB processor.

	F4: m0-7 m8-15 m16-22e0 e1-8s
	F8: m0-7 m8-15 m16-23 m24-31 m32-39 m40-47 m48-54e0 e1-8s

Exponent is excess 126 (F4) 1022 (F8)

CV_HL_FLT

MSB->LSB processor.

	F4: se8-1 e0m22-16 m15-8 m7-0 
	F8: se10-4 e3-0m51-48 m47-40 m39-32 m31-24 m23-16 m15-8 m7-0 

Exponent is excess 126 (F4) 1022 (F8)

CV_CONVEX_FLT
	F4: se8-1 e0m22-16 m15-8 m7-0 
	F8: se10-4 e3-0m51-48 m47-40 m39-32 m31-24 m23-16 m15-8 m7-0 

Exponent is excess 127 (F4) 1023 (F8)

CV_DRS_FLT
	F4: se8-1 e0m22-16 m15-8 m7-0 
	F8: se8-1 e0m54-48 m47-40 m39-32 m31-24 m23-16 m15-8 m7-0 

Exponent is excess 128

CV_IBM_FLT
	F4: se7-0 m23-16 m15-8 m7-0 
	F8: se7-0 m55-48 m47-40 m39-32 m31-24 m23-16 m15-8 m7-0 

Exponent is excess 64, hexadecimal (i.e. exponent shifts mantissa 4 bits at a time) mantissa is normalized with leading 1111 hidden. n.b. IBM mis-numbers their bits 0-63 (left to right). They should be 63-0 (left to right). We use the proper numbering where bit 0 is LSB.

Sizes of network types

These are the constant sizes of data on the network, which do not change.

# define CV_N_I1_SZ		1
# define CV_N_I2_SZ		2
# define CV_N_I4_SZ		4
# define CV_N_F4_SZ		6
# define CV_N_F8_SZ		10
# define CV_N_CHAR_SZ		1
# define CV_N_PTR_SZ		4
# define CV_N_NAT_SZ		4
# define CV_N_LONG_SZ		4

Sizes of local types

These are the sizes of local types, which are specific to the system as defined below.

# define CV_L_I1_SZ		sizeof( i1 )
# define CV_L_I2_SZ		sizeof( i2 )
# define CV_L_I4_SZ		sizeof( i4 )
# define CV_L_F4_SZ		sizeof( f4 )
# define CV_L_F8_SZ		sizeof( f8 )
# define CV_L_CHAR_SZ		sizeof( char )
# define CV_L_PTR_SZ		sizeof( PTR )
# define CV_L_NAT_SZ		sizeof( nat )
# define CV_L_LONG_SZ		sizeof( longnat )

CV_xxxx_yyy - local syntax ids for atomic datatypes

These defines enumerate the various processor specific formats for ints and floats and the platform specific character sets. These we call the local syntax ids. New representations should be given names and ids (0<=id<=127).

When two IIGCC's establish a connection, they compare the datatype ids of the processors at each end of the connection. If the ids for a datatype are different, all datatypes undergo conversion when traveling through the IIGCC. The id -1 matches no other ids, and forces conversion.

Note that a single id represents the size and byte ordering of both ints and longs. A single id represents the size and bit patterns for both a float and a double.

The character sets listed are a subset of those found in the file common!gcf!files!gcccset.nam, and the character set selected should correspond to the transliteration table compiled into common!gcf!gcc!gccgblro.roc and the character set attribute table defined in cl!clf!cm!cmtype.roc. New character sets should no longer be added here; use the 6.4 feature of loadable character sets.

These constants should not change; new ones may be added upon approval from the CL committee.

# define CV_HET_TYPE	-1	 Forces het conversion 
# define CV_LH3232_INT	0	 VAX - lo to hi - 32bit int, long 
# define CV_HL3232_INT	1	 SUN - hi to lo - 32bit int, long 
# define CV_VAX_FLT	0	 VAX floats 
# define CV_HL_FLT	1	 IEEE floats - hi to lo 
# define CV_DRS_FLT	2	 DRS 500 floating point 
# define CV_LH_FLT	3	 IEEE floats - lo to hi 
# define CV_CONVEX_FLT	4	 Convext floats 
# define CV_IBM_FLT	5	 IBM 360/370 floats 

# define CV_ASCII_NCSJ  0x00     ASCII 
# define CV_ASCII_NCSN  0x00

# define CV_8859_NCSJ   0x00     ISO_8859_1 
# define CV_8859_NCSN   0x01

# define CV_PC_NCSJ     0x00     ASCII_IBMPC 
# define CV_PC_NCSN     0x10

# define CV_EBCDIC_NCSJ 0x01     EBCDIC_C 
# define CV_EBCDIC_NCSN 0x00

# define CV_EBCICL_NCSJ 0x01     EBCDIC_ICL 
# define CV_EBCICL_NCSN 0x01

CV_xxx_TYPE - syntax of local types

These symbols are defined to be the correct local syntax ids of the local data types on the system. They often contained within target system specific ifdefs.

CV_INT_TYPE local syntax of integers
CV_FLT_TYPE local syntax of floats & doubles
CV_NCSJ_TYPE major local character set selector
CV_NCSN_TYPE minor local character set selector
# ifdef sun_u42

# define CV_INT_TYPE	CV_HL3232_INT
# define CV_FLT_TYPE	CV_HL_FLT
# define CV_NCSJ_TYPE	CV_ASCII_NCSJ
# define CV_NCSN_TYPE	CV_ASCII_NCSN	

# endif

CV2x_yy_MACRO - convert datatype from local to NTS and back

These macros convert local data syntax to and from the NTS. Note there are no PTR conversion macros - they are skipped over in the data stream because nothing examines the contents of a transmitted PTR.

The caller should set the status variable that is passed by reference to a known state before invoking these macros.

Performance of these macros is critical, as every single byte moved between an application and a server will be converted on each end of the connection.


CV2N_I1_MACRO convert i1 to NTS
CV2N_I2_MACRO convert i2 to NTS
CV2N_I4_MACRO convert i4 to NTS
CV2N_NAT_MACRO convert nat to NTS
CV2N_LONG_MACRO convert longnat to NTS
CV2N_F4_MACRO convert f4 to NTS
CV2N_F8_MACRO convert f8 to NTS
CV2L_I1_MACRO convert i1 to local
CV2L_I2_MACRO convert i2 to local
CV2L_I4_MACRO convert i4 to local
CV2L_NAT_MACRO convert nat to local
CV2L_LONG_MACRO convert longnat to local
CV2L_F4_MACRO convert f4 to local
CV2L_F8_MACRO convert f8 to local

Inputs:

src pointer to source data; element may be unaligned
dst pointer to target area; element may be unaligned

Outputs:

status pointer to status; set only upon error, otherwise untouched.

Returns:

None.

Definitions:

# define CV2L_I1_MACRO( src, dst, status ) ...
# define CV2L_I2_MACRO( src, dst, status ) ...
# define CV2L_I4_MACRO( src, dst, status ) ...
# define CV2L_NAT_MACRO( src, dst, status ) ...
# define CV2L_LONG_MACRO( src, dst, status ) ...
# define CV2L_F4_MACRO( src, dst, status ) ...
# define CV2L_F8_MACRO( src, dst, status ) ...


# define CV2N_I1_MACRO( src, dst, status ) ...
# define CV2N_I2_MACRO( src, dst, status ) ...
# define CV2N_I4_MACRO( src, dst, status ) ...
# define CV2N_NAT_MACRO( src, dst, status ) ...
# define CV2N_LONG_MACRO( src, dst, status ) ...
# define CV2N_F4_MACRO( src, dst, status ) ...
# define CV2N_F8_MACRO( src, dst, status ) ...

Executable Interface: GCA CL Calls - Housekeeping Routines

GCinitiate - Initialize static elements within GCA CL

This routine is called by GCA_INITIATE to pass certain variables to the CL. Currently, these are the addresses of the memory allocation and deallocation routines to be used. Any other system-specific initiation functions may be performed here.

See the comments under Memory Allocator in the GCA CL introduction for restrictions on use the allocator. The allocator's calling interface is:

	PTR	(*alloc)( i4 size )

	VOID	(*free)( PTR ptr )

GCinitiate may use the allocator it is provided.

GCinitiate is synchronous: it completes before returning. It returns its status.

Inputs:

alloc Pointer to memory allocation routine
free Pointer to memory deallocation routine

Outputs:

None

Returns:

OK if operation succeeded, otherwise system specific error status.

Definition:

STATUS
GCinitiate(alloc, free)
PTR         (*alloc)();
VOID        (*free)();

GCterminate - Perform local system-dependent termination functions

GCterminate is invoked by mainline code as the last operation done as a GCA process is terminating its connection with GCA. It may be used to perform any final system-dependent functions which may be required, such as cancelling system functions which are still in process, etc.

GCterminate frees any memory still allocated to the GCA CL. GCterminate may use the allocator provided to GCinitiate.

GCterminate is synchronous: it completes before returning. It returns status in the SVC_PARMS.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements...

Inputs:

None

Outputs:

svc_parms.status if operation succeeded, otherwise system specific error status.
sys_err system specific error data.

Returns:

None

Definition:

VOID
GCterminate(svc_parms)
SVC_PARMS       *svc_parms;

Executable Interface: GCA CL Calls - Connection Establishment & Closing

GCregister - Server start-up notification

This routine is called by GCA_REGISTER on server start-up. It is used to notify the GCA CL that a server has been started.

GCregister establishes an IPC connection endpoint, from which GCA may pick up incoming connections by calling GClisten.

GCregister assigns the Listen ID, or name of the connection endpoint. This is done by a system-specific mechanism that ensures the assignment of a unique name. This is the public external name which would be specified to GCrequest to initiate an association with the server. This is returned to the invoker for its information, by passing a pointer to a character string. This string is allocated by GCregister and must remain (at least) until GCterminate is called.

GCregister may use the allocator provided to GCinitiate.

GCregister is synchronous: it completes before returning. It returns status in the SVC_PARMS.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

char *svr_class Name of type of server registering.

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err OS specific error data.
listen_id Assigned listen address.

Returns:

None

Definition:

VOID
GCregister(svc_parms)
SVC_PARMS          *svc_parms;

GClisten - Establish a server connection with a client

This routine is, by definition, a server-only function.

GClisten receives an incoming connection indication on the IPC endpoint previously set up by GCregister. When GClisten completes, a connection has been established (or has failed to be established) with a requesting client.

GClisten must place a GC Control Block (GCCB) pointer, which identifies the connection, into the SVC_PARMS structure (svc_parms->gc_cb). The GCCB is meaningful only to the GCA CL; GCA does not dereference it.

GCA_LISTEN guarantees that if GClisten fails, it will subsequently call GCdisconn and GCrelease to close the failed connection. Since GCA_LISTEN cannot know how far the connection had progressed when it failed, GCdisconn and GCrelease should make use of information stored in the local control block to choose the proper actions.

The transmission buffer/segment size is set here. The size_advise parameter is set in the svc_parms parm list to specify the optimum buffer size to use if so desired. A value of 0 leaves the client to pick a preferred buffer size.

GClisten returns the user name, account name, terminal name, and security label (all where appropriate) of the user initiating the connection with GCrequest. GClisten does this by returning pointers to character strings. These strings are allocated by GClisten and must remain allocated until GCrelease is called.

GCA_LISTEN alters its authentication protocol if the local peer is trusted, namely if it is a process with as much security privilege as the current process. GClisten must recognise connections from trusted local peers, and for these connections set the "trusted" flag in the svc_parms flags section. A simple method is to trust processes with the same user id as the current process. Environments without the notion of process privileges (such as the PC) can ignore this flag.

When invoked, GClisten may use the allocator provided to GCinitiate. Since the allocator does not allow preemption, if GClisten callback routines can potentially interrupt or run concurrently with non-callback code, then the callbacks of GClisten may not use the allocator.

GClisten is potentially asynchronous: it may return before an incoming association is accepted, and should not block waiting. It signals completion by setting the status in the SVC_PARMS and driving the callback listed in the SVC_PARMS as gca_cl_completion. The call is (*(svc_parms->gca_cl_completion))( svc_parms->closure ).

GClisten should honor the SVC_PARMS time_out, which indicates how long to allow for the indication of a connection. If the listen does not complete within the alloted time, it completes with a status of GC_TIME_OUT. A value of -1 instructs GClisten to wait forever; a value of 0 instructs GClisten to fail if no connection is immediately available; a value greater than 0 instruct GClisten to wait that many milliseconds for a connection before failing. Implementation of timeouts for GClisten, though optional, is highly recommended for efficient operation of the Name Server.

For backward compatibility, GCA_LISTEN guarantees that if GClisten succeeds, the subsequent calls to GCreceive and GCsend will be for the exchange of peer information. Originally, GCA sent a fixed size peer info data block using GCsendpeer and GCrecvpeer and the GCA CL was permitted to bundle its own peer info data with that of GCA. GCA now sends a variable size peer info data block using GCsend and GCreceive and the GCA CL must exchange its own peer info data within the processing of GCrequest and GClisten. GCA CL implementations which must support old clients which still use GCsendpeer may use the structure GC_OLD_PEER as a reference for detecting and processing the old fixed length peer info data block. GClisten should save the peer info data block and return it to GCA on the first call to GCreceive. GCA will subsequently respond with a matching fixed length peer info data block on the first call to GCsend.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

time_out Timeout in ms, 0=poll, -1=no timeout.
closure Parameter for completion routine.
(*gca_cl_completion)(svc_parms->closure) Routine to call on completion.

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err system specific error data.
gc_cb Set to GC control block.
flags.trusted TRUE if peer is a trusted process.
user_name Peer entity's user name.
sec_label B1 security label for peer. Set to 0 for non-B1 secure systems.
account_name Peer entity's account name.
access_point_identifier Peer entity's terminal name.
size_advise Optimum size for communication. Must be multiple of sizeof(ALIGN_RESTRICT).

Returns:

None

Definition:

VOID
GClisten(svc_parms)
SVC_PARMS          *svc_parms;

GCusrpwd - Validate a username/password

GCusrpwd takes the given user name and password and validates them against the system password file. If both the user name is valid and the password is correct for the user, GCusrpwd returns OK; otherwise, GCusrpwd returns a descriptive error number.

The user name is not necessarily the same as the one returned by GClisten. GClisten returns the local peer's user name; GCusrpwd validates the user name for a aliased local and remote connections.

Since GCusrpwd is invoked during a callback of GClisten, GCusrpwd may not use the memory allocator provided to GCinitiate.

GCusrpwd is synchronous: it completes before returning. It returns its status.

Inputs:

username user name to validate
password password to validate

Outputs:

sys_err for CL failures
None

Returns:

OK user and password valid, otherwise system specific error status.
GC_LOGIN_FAIL user or password not valid
or another system specific error status.

Definition:

STATUS
GCusrpwd( username, password, sys_err )
char		*username;
char		*password;
CL_ERR_DESC	*sys_err;

GCrequest - Build connection to peer entity

This routine builds a system-dependent IPC connection to a server which has issued a GClisten. Generally, the target server will reside on the same system as the client. GCA may request a remote connection through the GCA CL using the GClisten partner_host parameter. If network connections are not supported by the IPC mechanism used by a GCA CL implementation, an error should be generated if the partner_host parameter is not NULL and is different than the value returned by GChostname.

GCrequest must place a GC Control Block (GCCB) pointer, which identifies the connection, into the SVC_PARMS structure (svc_parms->gc_cb). The GCCB is meaningful only to the GCA CL; GCA does not dereference it.

GCA_REQUEST guarantees that if GCrequest fails, it will subsequently call GCdisconn and GCrelease to close the failed connection. Since GCA_REQUEST cannot know how far the connection had progressed when it failed, GCdisconn and GCrelease should make use of information stored in the local control block to choose the proper actions.

The transmission buffer/segment size is set here. The size_advise parameter is set in the svc_parms parm list to specify the optimum buffer size to use if so desired. A value of 0 leaves the client to pick a preferred buffer size.

When invoked, GCrequest may use the allocator provided to GCinitiate. Since the allocator does not allow preemption, if GCrequest callback routines can potentially interrupt or run concurrently with non-callback code, then the callbacks of GCrequest may not use the allocator.

GCrequest is potentially asynchronous: it may return before the outgoing association is complete, and should not block waiting. It signals completion by setting the status in the SVC_PARMS and driving the callback listed in the SVC_PARMS as gca_cl_completion. The call is (*(svc_parms->gca_cl_completion))( svc_parms->closure ).

GCrequest should honor the SVC_PARMS time_out, which indicates how long to allow to make the connection. If the request does not complete within the alloted time, it completes with a status of GC_TIME_OUT. A value of -1 instructs GCrequest to wait forever; a value of 0 instructs GCrequest to fail if no connection is immediately available; a value greater than 0 instruct GCrequest to wait that many milliseconds for a connection before failing. Implementation of timeouts for GCrequest is optional.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

time_out Timeout in ms, 0=poll, -1=no timeout.
closure Parameter to completion routine.
(*gca_cl_completion)(svc_parms->closure) Routine to call on completion.
partner_host Host name where target server resides, NULL value for local host.
partner_name Listen ID of target server.

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err system specific error data.
gc_cb Set to GC control block.
size_advise Optimum size for communication. Must be multiple of sizeof(ALIGN_RESTRICT).

Returns:

None

Definition:

VOID
GCrequest( svc_parms )
SVC_PARMS	*svc_parms;

GCdisconn - Complete outstanding requests and close assocation.

GCdisconn performs any I/O necessary to close the association. If the GCA CL has buffered data from completed send operations, GCdisconn flushes those buffers to the OS.

GCdisconn forces completion of any outstanding GCsend or GCreceive requests on the specified association. It does so by setting the status in each request's SVC_PARMS to GC_ASSN_RLSED, and then calling (*(svc_parms->gca_cl_completion))( svc_parms->closure ). These are "orphan" requests resulting from an unexpected failure of the association, or from normal release of an association which still has requests outstanding.

If there are incomplete GCsend requests, i.e. calls to GCsend which have yet to signal completion by driving their callbacks, GCdisconn need not attempt to flush buffered send data: calling GCdisconn while send requests are outstanding implies that GCA wishes to abort the association.

GCdisconn is potentially asynchronous: it may return before the association is closed, and should not block waiting. It signals completion by setting the status in the SVC_PARMS and driving the callback listed in the SVC_PARMS as gca_cl_completion. The call is (*(svc_parms->gca_cl_completion))( svc_parms->closure ).

GCdisconn honors the SVC_PARMS time_out parameter: the timeout specifies how long in milliseconds GCdisconn is to attempt to flush buffered data before closing the association. A timeout of -1 indicates GCdisconn should not time out, and not complete until the buffers are flushed. A timeout of 0 indicates an abortive release: GCdisconn should close the connection immediately, losing any buffered data. If the implementation of the GCA CL does not buffer, the timeout may be ignored.

There is no deallocation of association resources (freeing of memory). That is the job of GCrelease. Since GCdisconn may be invoked during a callback, GCdisconn may not use the memory allocator provided to GCinitiate.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

gc_cb GC control block
time_out Timeout in ms, 0=abort, -1=no timeout.
closure Parameter for completion routine.
(*gca_cl_completion)(svc_parms->closure) Routine to call on completion.

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err system specific error data.

Returns:

None

Side Effects:

Association flushed and closed.

Definition:

VOID
GCdisconn(svc_parms)
SVC_PARMS          *svc_parms;

GCrelease - Release buffers allocated during connection.

Release system specific resources assigned to the association, including the GC control block.

GCrelease may use the allocator provided to GCinitiate.

GCrelease is synchronous: it completes before returning. It returns status in the SVC_PARMS.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

gc_cb GC control block

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err system specific error data.

Returns:

None

Side Effects:

Deallocator called.

Definition:

VOID
GCrelease(svc_parms)
SVC_PARMS          *svc_parms;

Executable Interface: GCA CL Calls - Connection I/O

GCreceive - Receive data on an association

The user of this routine has requested at most svc_parms->reqd_amount bytes of data from the incoming message stream. The data read from the incoming messages is placed at the address starting at svc_parms->svc_buffer.

GCreceive completes when any data are received. GCreceive may successfully complete with less data than requested. It places the amount of data actually received into svc_parms->rcv_data_length.

If GCreceive receives a "chop mark" generated by the peer calling GCpurge, it sets the svc_parms->flags.new_chop flag before completing. If this flag is set, the svc_parms->rcv_data_length is not important.

The flags.flow_indicator element of svc_parms specifies whether the receive function is to be issued on the normal or expedited flow channel: 0 is NORMAL flow, 1 is EXPEDITED flow.

GCreceive is potentially asynchronous: it may return before the buffer is filled, and should not block waiting. It signals completion by setting the status in the SVC_PARMS and driving the callback listed in the SVC_PARMS as gca_cl_completion. The call is (*(svc_parms->gca_cl_completion))( svc_parms->closure ).

GCreceive should honor the SVC_PARMS time_out, which indicates how long to allow for data to arrive. If any data arrives before the alloted time, GCreceive completes with that data as normal. If not, it completes with a status of GC_TIME_OUT. A value of -1 instructs GCreceive to wait forever; a value of 0 instructs GCreceive to fail if no data is immediately available; a value greater than 0 instruct GCreceive to wait that many milliseconds for data before failing. All implementations of GCreceive must support a timeout of -1 and 0. GCreceive may optionally treat a positive timeout as -1.

Possible error conditions are as follows: If the connection to the partner is unexpectedly gone, a status of GC_ASSOC_FAIL is returned. If the connection has been terminated locally, by the GCdisconn routine, a status of GC_ASSN_RLSED is returned. The ability to detect these two modes of disconnection is system dependent. If the distinction cannot be made in a particular implementation, a status of GC_ASSOC_FAIL is the default. GC_ASSOC_FAIL normally covers network errors from which recovery is impossible. Other CL specific errors are possible.

Since GCreceive may be invoked during a callback, GCreceive may not use the memory allocator provided to GCinitiate.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

gc_cb GC control block
time_out Timeout in ms, 0=poll, -1=no timeout.
closure Parameter for completion routine.
(*gca_cl_completion)(svc_parms->closure) Routine to call on completion.
svc_buffer Receive buffer.
reqd_amount Receive buffer size.
flags.flow_indicator 0=normal, 1=expedited flow.

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err system specific error data.
rcv_data_length Amount of data received.
flags.new_chop 0 = no chop mark received
1 = chop mark received

Returns:

None

Definition:

VOID
GCreceive(svc_parms)
SVC_PARMS          *svc_parms;

GCsend - Send data on an association

Send data to the other party in the connection. This routine simulates byte-stream I/O, and utilizes the system-specific IPC mechanism in whatever way is necessary to create this illusion.

The user of this routine has requested svc_parms->svc_send_length bytes of data to be sent on the outgoing message stream. This is to be done in a single operation from the caller's point of view; i.e., the operation is not complete until the caller's entire buffer has been sent. The exact meaning of "sent" is implementation specific, but the data in the caller's buffer must be in a safe harbor, and the caller must be able to re-use the buffer. The data sent as the outgoing message stream is read from the address starting at svc_parms->svc_buffer.

The flags.flow_indicator element of svc_parms specifies whether the send function is to be issued on the normal or expedited flow channel. The expedited flow channel supports at least 64 bytes in a single send. Sends on the normal channel may be of unlimited size.

GCsend is potentially asynchronous: it may return before the data can be copied from the client buffer, and should not block waiting. It signals completion by setting the status in the SVC_PARMS and driving the callback listed as gca_cl_completion. The call is (*(svc_parms->gca_cl_completion))(svc_parms->closure). The invocation of this exit implies to the mainline that the send buffer may now be reused.

GCsend should honor the SVC_PARMS time_out, which indicates how long to allow for the first byte of data to be sent. If the send does not start within the alloted time, it completes with a status of GC_TIME_OUT. Once the send starts (i.e. sends a single byte of data), it does not time out. A value of -1 instructs GCsend to wait forever; a value of 0 instructs GCsend to fail if data cannot be sent immediately; a value greater than 0 instruct GCsend to wait that many milliseconds to be able to send data before failing. Implementation of timeouts for GCsend is optional; it may treat all timeouts as -1.

Possible error conditions are as follows: If the connection to the partner is unexpectedly gone, a status of GC_ASSOC_FAIL is returned. If the connection has been terminated locally, by the GCdisconn routine, a status of GC_ASSN_RLSED is returned. The ability to detect these two modes of disconnection is system dependent. If the distinction cannot be made in a particular implementation, a status of GC_ASSOC_FAIL is the default. GC_ASSOC_FAIL normally covers network errors from which recovery is impossible. Other CL specific errors are possible.

Since GCsend may be invoked during a callback, GCsend may not use the memory allocator provided to GCinitiate.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

gc_cb GC control block
time_out Timeout in ms, 0=poll, -1=no timeout.
closure Parameter for completion routine.
(*gca_cl_completion)(svc_parms->closure) Routine to call on completion.
svc_buffer Send buffer
svc_send_length Send buffer size.
flags.flow_indicator 0=normal, 1=expedited flow.

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err system specific error data.

Returns:

None

Definition:

VOID
GCsend(svc_parms)
SVC_PARMS          *svc_parms;

GCpurge - Purge normal flow send channel.

GCpurge places a synchronization mark ("chop mark") into the normal flow channel. The chop mark flows with the normal data, and causes the peer's GCreceive to return with the svc_parms->flags.new_chop indicator on receipt.

GCpurge may optionally discard normal data sent with GCsend before sending the chop mark, but guarantees a) no data from previous invocations of GCsend will follow the chop mark and b) the chop mark will not arrive earlier than previously sent expedited data. Note that the order of data flow depends on when GCsend and GCpurge are invoked - not when they complete.

GCpurge is synchronous: it completes before returning. Although GCpurge has a synchronous interface, it does not block. Somehow the GCA CL provides for this.

Since GCpurge may be invoked during a callback, GCpurge may not use the memory allocator provided to GCinitiate.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

gc_cb GC control block

Outputs:

status
OK if operation succeeded, otherwise system specific error status.
sys_err system specific error data.

Returns:

None

Definition:

VOID
GCpurge( svc_parms )
SVC_PARMS	*svc_parms;

Executable interface: GCA CL Calls - Saving & Restoring Connections

GCsave - Save data for process switch

GCsave fills a buffer with enough CL private infomation so that the association can be recovered by a child process calling GCrestore. GCA mainline transports the buffer of data and its length from the GCsave call in the parent process to the GCrestore call in the child process.

Changes to the format of this buffer should maintain compatibility with previous versions of the system. As a last resort, GCrestore should recognise an incompatible buffer format and fail appropriately.

It is never the case that both parent and child use the association simultaneously.

There is currently no mechanism for handing an association back to the parent process. It is assumed that once the child process exits, the parent process may then continue using the association.

GCsave may use the allocator provided to GCinitiate.

GCsave is synchronous: it completes before returning.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

gc_cb GC control block
svc_buffer Buffer to fill
reqd_amount Size of svc_buffer as defined by GCA_CL_MAX_SAVE_SIZE in <gc.h>

Outputs:

status OK if operation succeeded, otherwise system specific error status.
sys_err System specific error data.
rcv_data_length Amount of svc_buffer used.

Definition:

VOID
GCsave( svc_parms )
SVC_PARMS	*svc_parms;

GCrestore - Restore data following process switch

GCrestore recovers an association in a child process, whose data was saved by GCsave in the parent process. GCrestore (re)creates the GC Control Block (GCCB) and places the GCCB pointer, which identifies the connection, into the SVC_PARMS (svc_parms->gc_cb).

GCrestore may use the allocator provided to GCinitiate.

GCrestore is synchronous: it completes before returning.

All parameters (both input and output) are handled via a pointer to SVC_PARMS structure containing the following elements ...

Inputs:

svc_buffer Buffer from GCsave
svc_send_length Size of saved buffer: returned by GCsave as rcv_data_length

Outputs:

status OK if operation succeeded, otherwise system specific error status.
sys_err System specific error data.
gc_cb Set to GC control block.

Definition:

VOID
GCrestore( svc_parms )
SVC_PARMS	*svc_parms;

Executable Interface: GCA CL Calls - Event Mechanism

GCexec - Drive Asynchronous Events

GCexec drives the event handling mechanism in several GCA applications. The application typically posts a few initial asynchronous GCA CL requests (and in the case of the Comm Server, a few initial GCC CL requests), and then passes control to GCexec. GCexec then allows asynchronous completion of events to occur, calling the callback routines listed for the asynchronous requests; these callback routines typically post more asynchronous requests. This continues until one of the callback routines calls GCshut.

If the OS provides the event handling mechanism, GCexec presumably needs only to enable asynchronous callbacks and then block until GCshut is called. If the CL must implement the event handling mechanism, then GCexec is the entry point to its main loop.

The event mechanism under GCexec must not allow a callback to be preempted by any other GCA activity on the same connection, either by another callback or through a GCA user request. For single processor environments, this can be satifisfied by serializing the callbacks. For multiprocessing servers, the GCA CL may need semaphore support.

GCexec may use the allocator provided to GCinitiate.

Inputs:

None

Outputs:

None

Returns:

None

Side Effects:

All events driven.

Definition:

VOID
GCexec()

GCshut - Stop GCexec

GCshut causes GCexec to return. When an application uses GCexec to drive callbacks of asynchronous GCA CL and GCC CL requests, it terminates asynchronous activity by calling GCshut. When control returns to GCexec, it itself returns. The application then presumably exits.

If the application calls GCshut before passing control to GCexec, GCexec should return immediately. This can occur if the completion of asynchronous requests occurs before the application calls GCexec.

GCshut may use the allocator provided to GCinitiate.

Inputs:

None

Outputs:

None

Returns:

None

Side Effects:

GCexec returns.

Definition:

VOID
GCshut()

GCsync - Drive Asynchronous Events and wait for Interrupt

GCsync drives the event handling mechanism in synchronous GCA applications. For each requested GCA operation, GCA posts one or more asynchronous GCA CL requests and then passes control to GCsync.

GCsync drives asynchronous event completion as GCexec does, but must return once all outstanding requests have completed. GCsync may return prematurely; GCA will simply reinvoke it.

When invoked in a multi-threaded environment, GCsync will only drive event completions and/or block for GCA requests made by the calling thread. Simultaneous calls to GCsync by multiple threads are permitted. GCsync may not be called during an event completion callback (recursive calls are not permitted).

GCsync is called after inhibiting delivery of keyboard signals (^C) with EXinterrupt( EX_OFF ), to protect GCA CL and mainline code from being interrupted. While blocked, but not while completions are being driven, GCsync should allow keyboard signals to be delivered.

GCsync may use the allocator provided to GCinitiate.

Inputs:

timeout Timeout in ms, 0=poll -1=no timeout

Outputs:

None

Returns:

None

Side Effects:

Events driven.

Definition:

VOID
GCsync( timeout )
longnat timeout;

Executable Interface: GCA CL Calls - Name Server Support

GCnsid - Establish the identification of the local Name Server

GCnsid is invoked to establish and to obtain the identity of the Name Server in a system-dependent way. This routine provides the "bootstrapping" capability required to allow the GCA_REQUEST service to establish an association with the Name Server.

GCnsid provides four operations: RESV, SET, CLEAR, and FIND. The Name Server uses RESV, SET, and CLEAR to make its listen address public on startup and to remove its listen address on shutdown. FIND is used to retrieve this listen address by GCA clients wishing to connect to the Name Server.

RESV and CLEAR form a primitive mechanism to prevent two Name Servers from running simultaneouly. They may always return OK.

The exact syntax of the Listen ID may be system dependent: it is understood only by the GCA CL. The identifiier consists of a null-terminated character string.

Inputs:

flag Operations code
GC_RESV_NSID Called before GC_SET_NSID.
GC_SET_NSID Establish a globally accessible identifier for the Name Server.
GC_CLEAR_NSID Clear the Name Server identifier, so any subsequent FIND_NSID will fail.
GC_FIND_NSID Retrieve the identifier of the Name Server in the local node.
listen_id Source buffer for SET operation.
length The maximum length of listen_id for the SET or FIND operations.

Outputs:

listen_id Target buffer for FIND operation.
GCA_FIND_NSID only
sys_err system specific error info.

Returns:

OK if operation succeeded, otherwise system specific error status.
GC_NM_SRVR_ID_ERR Unable to get/set ND id.

Definition:

STATUS
GCnsid(flag, listen_id, length, sys_err)
i4     	flag;
char    	*listen_id;
i4     	length;
CL_ERR_DESC	*sys_err;

GChostname - Request the local host name.

Attempts to find the local host name as appropriate for a given implementation. The only requirement for the local host name is that it be unique among hosts using shared disks to access a common Ingres installation.

Inputs:

hostlen maximum length of ourhost string
extra characters should be truncated

Outputs:

ourhost the local hostname buffer string

Returns:

None

Definition:

VOID
GChostname(ourhost, hostlen)
char *ourhost;
i4   hostlen;

Header File <gcccl.h>

The GCC CL interface control structures are defined in the GL file <gcccl.h>. It does not change from system to system.

Protocol Identifiers

The GCC_PCE pce_pid identifies a protocol by its name. New values may be defined as necessary. Their current values are listed here. (NB: the practice of naming protocols after their interfaces should not be continued. To the user, TCP/IP is TCP/IP regardless of whether it is accessed via VMS Wollongong, Berkeley sockets, etc. )

# define		DECNET		    "DECNET"
# define		SNA_LU0		    "SNA_LU0"
# define		SNA_LU2		    "SNA_LU2"
# define		SNA_62		    "SNA_62"
# define		TCP_UNIX            "TCP_IP"
# define		TCP_DEC		    "TCP_DEC"
# define		TCP_WOLLONGONG	    "TCP_WOL"
# define		TCP_IP		    "TCP_IP"

GCpdrvr() Function Codes

A GCC protocol driver, described below, takes a function code directing its action. The functions codes are defined as follows:

#define                 GCC_OPEN	 1
#define                 GCC_LISTEN       2
#define                 GCC_CONNECT      3
#define                 GCC_SEND         4
#define                 GCC_RECEIVE      5
#define                 GCC_DISCONNECT   6

GCC_PCT - Protocol Control Table

The GCC_PCT contains an array of Protocol Control Entries (GCC_PCE), one for each supported protocol. There are at most GCC_L_PCT entries.

# define    GCC_L_PCT		3	/* Number of entries in the PCT */

typedef struct _GCC_PCT
{
    i4              pct_n_entries;		/* Number of table entries */
    GCC_PCE         pct_pce[GCC_L_PCT];		/* Protocol control entry */
};

GCC_PCE - Protocol Control Entry

# define    GCC_L_PROTOCOL  	16	/* Length of a protocol ID */
# define    GCC_L_NODE		64	/* Length of a node name */
# define    GCC_L_PORT		64	/* Length of a port name */


typedef struct _GCC_PCE
{
   char		pce_pid[GCC_L_PROTOCOL];
				/* Protocol ID
				A null-terminated string corresponding
				to the "protocol" component of the
				"protocol, host, port" triple entered
				for a vnode via NETU.  See Protocol
				Identifiers listed above. */


   char		pce_port[GCC_L_PORT];
				/* Default Port ID
				GCC hands this value to the protocol
				driver as the port_id parameter to
				GCC_OPEN if no port is configured. */


   STATUS		(*pce_protocol_rtne)();
				/* Protocol driver entry point. */


   i4  		pce_pkt_sz;
				/* Packet size
				This size should be the maximum (or
				optimal) protocol message size, minus
				the size of the NPCI (protocol specific
				header). */


   i4  		pce_exp_pkt_sz;
				/* Packet size for expedited data.
				Unsupported. */


   u_i4		pce_options;
				/* Flagword for protocol options. */

#define			PCT_VAR_PKT_SZ	    0x0001  /* Per conn packet size */


   u_i4 		pce_flags;
				/* Flagword for runtime state: */


				/* GCC CL Interface Flags */


#define			PCT_NO_PORT	    0x0001  /* No listen port */
#define			PCT_NO_OUT	    0x0002  /* No outbound conn's */


				/* GCC Private Flags. */


#define			PCT_OPN_FAIL	    0x0004  /* Open failed */
#define			PCT_OPEN	    0x0008  /* Open successful */


   PTR			pce_driver;
				/* driver specific (private to driver) */


   PTR			pce_dcb;
				/* driver control block (private to driver) */
} GCC_PCE;

The pce_protocol_rtne has the following calling interface (see GCpdrvr below):

STATUS 
(*pce_protocol_rnte)( func_code, parms ) 
i4  func_code; 
GCC_P_PLIST *parms;

GCC_P_PLIST - Protocol Parameter List

All protocol drivers have an identical interface, taking a function code and parameter list (GCC_P_PLIST) as arguments. The GCC_P_PLIST contains all the input and output parameters for the protocol driver, and slots for some data private to the protocol driver.

typedef struct _GCC_P_PLIST
{
   PTR             pcb;		/* Protocol control block:
					** Unused for GCC_OPEN;
					** Output for GCC_CONNECT, GCC_LISTEN;
					** Input for other operations */


   GCC_PCE	    *pce;		/* Protocol control entry */
   VOID            (*compl_exit)();    /* Routine to call on completion */
   PTR             compl_id;           /* Argument to completion routine */
   u_i4            options;            /* Flagword for operation options */


# define	GCC_EXP_DATA	    0x01	/* Indicates Expedited data;
						** unused and unsupported */
# define	GCC_FLUSH_DATA	    0x02	/* Flush any buffered send data */


   i4  	    function_invoked;	/* Protocol function code:
					** Duplicates function_code arg to
					** GCpdrvr routine. */


   i4		    state;		/* State of the current operation;
					** private to the protocol driver */


   char	    *buffer_ptr;	/* data area */
   i4  	    buffer_lng;		/* data area length */


   union	/* per function parameters */
   {
	struct	/* GCC_OPEN */
	{
	    char	*port_id;		/* Specified listen port */
	    char	*lsn_port;		/* Actual listen port */
	} open;


	struct	/* GCC_CONNECT */
	{
	    char	*port_id;		/* "Port" w/in target node */
	    char	*node_id;		/* Target node identifier */
	    i4		pkt_sz;			/* unused */
	} connect;


	struct	/* GCC_LISTEN */
	{
	    char	*port_id;		/* Specified listen port
						** Same as open.port_id */
	    i4		pkt_sz;			/* unused */
	    char	*node_id;		/* Optional: remote node ID */
	} listen;


   } function_parms;


   STATUS          generic_status;     /* Status of operation execution */
   CL_SYS_ERR      system_status;      /* System-specific status code */
};

The calling interface of compl_exit is:

VOID (*compl_exit)( compl_id );

Executable Interface: GCC CL Calls - Housekeeping

GCcinit - Communication Server initialization routine

This routine is called before any other Communication Server CL routine. It performs all required system-specific initialization functions, including such things as disabling interrupts if necessary or appropriate in the particular environment during the initialization process. Any mechanisms for dealing with asynchronous events may be prepared or set up here.

Inputs:

None

Outputs:

generic_status STATUS for failures.
system_status system specific status of failures.

Returns:

OK if operation succeeded, otherwise system specific error status.

Definition:

STATUS
GCcinit( generic_status, system_status )
STATUS              *generic_status;
CL_ERR_DESC         *system_status;

GCcterm - Communication Server termination function

This routine is normally called just prior to Communication Server termination. It is not guaranteed to be called: There may be server terminations which do not permit an orderly shutdown. If it is invoked, it is after GCexec returns to its caller.

Inputs:

None

Outputs:

generic_status Pointer to an element of type STATUS.
system_status Pointer to an element of type CL_ERR_DESC.

Returns:

OK if operation succeeded, otherwise system specific error status.

Definition:

STATUS
GCcterm( generic_status, system_status )
STATUS              *generic_status;
CL_ERR_DESC         *system_status;

GCpinit - Protocol initialization routine

This routine is called during the communication server initialization process. It is guaranteed to be called before any protocol driver routines are invoked. It is responsible for returning a pointer to the Protocol Control Table (GCC_PCT), and for performing any other initialization which may be required in a specific environment.

The protocol's use can be inhibited by setting both the PCT_NO_PORT and PCT_NO_OUT flags in the pce_flags word.

Protocol driver routines are not referenced directly by the GCC, but rather are invoked by pointer reference through the PCT.

A single protocol driver may support multiple protocols, by having multiple GCC_PCE entries with the same pce_protocol_rtne value. The pce_port should be used to distinguish the protocols.

Inputs:

None

Outputs:

pct Pointer to an allocated and filled-in Protocol Control Table (PCT).
generic_status System-independent status
system_status Environment-specific status

Returns:

OK if operation succeeded, otherwise system specific error status.

Definition:

STATUS
GCpinit(pct, generic_status, system_status)
GCC_PCT         **pct;
STATUS          *generic_status;
CL_ERR_DESC     *system_status;

GCpterm - Protocol termination routine

This routine is called during the communication server termination process. It is guaranteed that no other protocol driver routines will be invoked subsequently. It is responsible for deallocating the Protocol Control Table (PCT), and for performing any other termination functions associated with protocol handling which may be required in a specific environment, such as closing connections to the local system-provided protocol interface.

Inputs:

pct Pointer to the PCT.

Outputs:

generic_status System-independent status
system_status Environment-specific status

Returns:

OK if operation succeeded, otherwise system specific error status.

Definition:

STATUS
GCpterm(pct, generic_status, system_status)
GCC_PCT         *pct;
STATUS          *generic_status;
CL_ERR_DESC     *system_status;