web analytics
Bea Tuxedo Application-to-Transaction Monitor Interface (ATMI) In C/C++ Options
codeling
Posted: Wednesday, April 6, 2016 3:48:25 PM

Rank:Advanced Member
Groups: Member
Joined: 12/11/2015
Posts: 938
Points: 3945

Buffer Management

Initially, a process has no buffers. Before sending a message, a buffer must be allocated using tpalloc(). The sender's data can then be placed in the buffer and sent. This buffer has a specific structure. The particular structure is denoted by the type argument to the tpalloc() function. Since some structures can need further classification, a subtype can also be given (for example, a particular type of C structure).

When receiving a message, a buffer is required into which application data can be received. This buffer must be one originally gotten from tpalloc(). Note that a BEA Tuxedo ATMI system server, in its main, allocates a buffer whose address is passed to a request/response or conversational service upon invoking the service. (See tpservice(3c) for details on how this buffer is treated.)

Buffers used for receiving messages are treated slightly differently than those used for sending: the size and address usually change upon receipt of a message, since the system internally swaps the buffer passed into the receive call with internal buffers it used to process the buffer. A buffer may grow or shrink when it receives data. Whether it grows or shrinks depends on the amount of data sent by the sender, and the internal data flow needed to get the data from sender to receiver. Many factors can affect the buffer size, including compression, receiving a message from a different type of machine, and the action of the postrecv() function for the type of buffer being used (see buffer(3c)). The buffer sizes in Workstation clients are usually different from those in native clients.

It is best to think of the receive buffer as a placeholder, rather than the actual container that will receive the message. The system sometimes uses the size of the buffer you pass as a hint, so it does help if it is big enough to hold the expected reply.

On the sending side, buffer types that might be filled to less than their allocated capacity (for example, FML or STRING buffers) send only the amount used. A 100K FML32 buffer with one integer field in it is sent as a much smaller buffer, containing only that integer.

This means that the receiver will receive a buffer smaller than what was originally allocated by the sender, yet larger than the data that was sent. For example, if a STRING buffer of 10K bytes is allocated, and the string "HELLO" is copied into it, only the six bytes are sent, and the receiver will probably end up with a buffer that is around 1K or 4K bytes. (It may be larger or smaller, depending on other factors.) The BEA Tuxedo ATMI system guarantees only that a received message will contain all of the data that was sent; it does not guarantee that the message will contain all the free space it originally contained.

The process receiving the reply is responsible for noting size changes in the buffer (using tptypes()) and reallocating the buffer if necessary. All BEA Tuxedo ATMI functions change a receiver's buffer return information about the amount of data in the buffer, so it should become standard practice to check the buffer size every time a reply is received.

One can send and receive messages using the same data buffer. Alternatively, a different data buffer can be allocated for each message. It is usually the responsibility of the calling process to free its buffers by invoking tpfree(). However, in limited cases, the BEA Tuxedo ATMI system frees the caller's buffer. For more information about buffer usage, see the descriptions of communication functions such as tpfree().

Sponsor
Posted: Wednesday, April 6, 2016 3:48:25 PM
codeling
Posted: Wednesday, April 6, 2016 4:03:43 PM

Rank:Advanced Member
Groups: Member
Joined: 12/11/2015
Posts: 938
Points: 3945

Buffer Type Switch

The tmtype_sw_t structure provides the description required when adding new buffer types to tm_typesw(), the buffer type switch for a process. The switch elements are defined in typesw(5). The function names used in this entry are templates for the actual function names defined by the BEA Tuxedo ATMI system or by applications in which custom buffer types are created. These function names can be mapped easily to switch elements: to create a template name simply add the prefix _tm to the element name of a function pointer. For example, the template name for the element initbuf is _tminitbuf.

The type element must be non-NULL and at most 8 characters in length. If this element is not unique in the switch, then subtype() must be non-NULL.

The subtype() element can be NULL, a string of at most 16 characters, or * (the wildcard character). The combination of type() and subtype() must uniquely identify an element in the switch.

A given type can have multiple subtypes. If all subtypes are to be treated the same for a given type, then the wildcard character, "*", can be used. Note that the tptypes() function can be used to determine a buffer's type and subtype if subtypes need to be distinguished. If some subset of the subtypes within a particular type are to be treated individually, and the rest are to be treated identically, then those that are to be singled out with specific subtype values should appear in the switch before the subtype designated with the wildcard. Thus, searching for types and subtypes in the switch is done from top to bottom, and the wildcard subtype entry accepts any "leftover" type matches.

The dfltsize() element is used when allocating or reallocating a buffer. The semantics of tpalloc() and tprealloc() are such that the larger of the following two values is used to create or reallocate a buffer: the value of dfltsize() or the value of the size parameter for the tpalloc() and tprealloc() functions. For some types of structures, such as a fixed-sized C structure, the buffer size should equal the size of the structure. If dfltsize() is set to this value, then the caller may not need to specify the buffer's length to routines in which a buffer is passed. dfltsize() can be 0 or less. However, if tpalloc() or tprealloc() is called and the size parameter for the function being called is also less than or equal to 0, then the routine will fail. We recommend setting dfltsize() to a value greater than 0.

The BEA Tuxedo ATMI system provides five basic buffer types:

CARRAY—a character array, possibly containing NULL characters, which is neither encoded nor decoded during transmission

STRING—a NULL-terminated character array

FML—fielded buffers (FML or FML32)

XML—XML document or datagram buffer

VIEW—simple C structures (VIEW or VIEW32); all views are handled by the same set of routines. The name of a particular view is its subtype name.

Two of these buffer types have synonyms: X_OCTET is a synonym for CARRAY, and both X_C_TYPE and X_COMMON are synonyms for VIEW. X_C_TYPE supports all the same elements as VIEW, whereas X_COMMON supports only longs, shorts, and characters. X_COMMON should be used when both C and COBOL programs are communicating.

An application wishing to supply its own buffer type can do so by adding an instance to the tm_typesw() array. Whenever adding or deleting a buffer type, be careful to leave a NULL entry at the end of the array. Note that a buffer type with a NULL name is not permitted. An application client or server is linked with the new buffer type switch by explicitly specifying the name of the source or object file on the buildserver() or buildclient() command line using the -f option.

codeling
Posted: Wednesday, April 6, 2016 4:04:51 PM

Rank:Advanced Member
Groups: Member
Joined: 12/11/2015
Posts: 938
Points: 3945

Unsolicited Notification

There are two methods for sending messages to application clients outside the boundaries of the client/server interaction defined above. The first is the broadcast mechanism supported by tpbroadcast(). This function allows application clients, servers, and administrators to broadcast typed buffer messages to a set of clients selected on the basis of the names assigned to them. The names assigned to clients are determined in part by the application (specifically, by the information passed in the TPINIT typed buffer at tpinit() time) and in part by the system (based on the processor through which the client accesses the application).

The second method is the notification of a particular client as identified from an earlier or current service request. Each service request contains a unique client identifier that identifies the originating client for the service request. Calls to the tpcall() and tpforward() functions from within a service routine do not change the originating client for that chain of service requests. Client identifiers can be saved and passed between application servers. The tpnotify() function is used to notify clients identified in this manner.

codeling
Posted: Wednesday, April 6, 2016 4:08:36 PM

Rank:Advanced Member
Groups: Member
Joined: 12/11/2015
Posts: 938
Points: 3945

C Language ATMI Return Codes and Other Definitions

The following return code and flag definitions are used by the ATMI routines. For an application to work with different transaction monitors without change or recompilation, each system must define its flags and return codes as follows:

 /*
  * The following definitions must be included in atmi.h
  */
 
 
 
 /* Flags to service routines */
 
  #define TPNOBLOCK     0x00000001 /* non-blocking send/rcv */
  #define TPSIGRSTRT    0x00000002 /* restart rcv on interrupt */
  #define TPNOREPLY     0x00000004 /* no reply expected */
  #define TPNOTRAN      0x00000008 /* not sent in transaction mode */
  #define TPTRAN        0x00000010 /* sent in transaction mode */
  #define TPNOTIME      0x00000020 /* no timeout */
  #define TPABSOLUTE    0x00000040 /* absolute value on tmsetprio */
  #define TPGETANY      0x00000080 /* get any valid reply */
  #define TPNOCHANGE    0x00000100 /* force incoming buffer to match */
  #define RESERVED_BIT1 0x00000200 /* reserved for future use */
  #define TPCONV        0x00000400 /* conversational service */
  #define TPSENDONLY    0x00000800 /* send-only mode */
  #define TPRECVONLY    0x00001000 /* recv-only mode */
  #define TPACK         0x00002000 /* */
 
 /* Flags to tpreturn - also defined in xa.h */
  #define TPFAIL        0x20000000 /* service FAILURE for tpreturn */
  #define TPEXIT        0x08000000 /* service FAILURE with server exit */
  #define TPSUCCESS     0x04000000 /* service SUCCESS for tpreturn */
 
 /* Flags to tpscmt - Valid TP_COMMIT_CONTROL
  * characteristic values
  */
  #define TP_CMT_LOGGED 0x01       /* return after commit
                                    * decision is logged */
  #define TP_CMT_COMPLETE 0x02     /* return after commit has
                                    * completed */
 
 
 
 /* client identifier structure */
  struct clientid_t {
  long clientdata[4];              /* reserved for internal use */
  }
  typedef struct clientid_t CLIENTID;
  /* context identifier structure */
  typedef long TPCONTEXT_T;
  /* interface to service routines */
  struct tpsvcinfo {
  name[32];
  long flags;                      /* describes service attributes */
  char *data;                      /* pointer to data */
  long len;                        /* request data length */
  int cd;                          /* connection descriptor
  * if (flags  TPCONV) true */
  long appkey;                     /* application authentication client
  * key */
  CLIENTID cltid;                  /* client identifier for originating
   * client */
  };
 
 typedef struct tpsvcinfo TPSVCINFO;
 
 /* tpinit(3c) interface structure */
  #define MAXTIDENT                30
 
 struct tpinfo_t {
  char usrname[MAXTIDENT+2];       /* client user name */
  char cltname[MAXTIDENT+2];       /* app client name */
  char passwd[MAXTIDENT+2];        /* application password */
  long flags;                      /* initialization flags */
  long datalen;                    /* length of app specific data */
  long data;                       /* placeholder for app data */
  };
  typedef struct tpinfo_t TPINIT;
 
 /* The transactionID structure passed to tpsuspend(3c) and tpresume(3c) */
  struct tp_tranid_t {
  long info[6];                    /* Internally defined */
  };
 
 typedef struct tp_tranid_t TPTRANID;
 
 /* Flags for TPINIT */
  #define TPU_MASK                 0x00000007     /* unsolicited notification
                                                   * mask */
  #define TPU_SIG                  0x00000001     /* signal based
                                    * notification */
  #define TPU_DIP                  0x00000002     /* dip-in based
                                    * notification */
  #define TPU_IGN                  0x00000004     /* ignore unsolicited
                                                   * messages */
  #define TPU_THREAD               0x00000040     /* THREAD notification */
  #define TPSA_FASTPATH            0x00000008     /* System access ==
                                                   * fastpath */
  #define TPSA_PROTECTED           0x00000010     /* System access ==
                                                   * protected */
  #define TPMULTICONTEXTS          0x00000020     /* multiple context associa-
                                                   * tions per process */
  /*  /Q tpqctl_t data structure                  */
  #define TMQNAMELEN               15
  #define TMMSGIDLEN               32
  #define TMCORRIDLEN              32
 
 struct tpqctl_t {                 /* control parameters to queue primitives */
  long flags;                      /* indicates which values are set */
  long deq_time;                   /* absolute/relative time for dequeuing */
  long priority;                   /* enqueue priority */
  long diagnostic;                 /* indicates reason for failure */
  char msgid[TMMSGIDLEN];          /* ID of message before which to queue */
  char corrid[TMCORRIDLEN];        /* correlation ID used to identify message */
  char replyqueue[TMQNAMELEN+1];   /* queue name for reply message */
  char failurequeue[TMQNAMELEN+1]; /* queue name for failure message */
  CLIENTID cltid;                  /* client identifier for */
                                   /* originating client */
  long urcode;                     /* application user-return code */
  long appkey;                     /* application authentication client key */
  long delivery_qos;               /* delivery quality of service */
  long reply_qos;                  /* reply message quality of service */
  long exp_time                    /* expiration time */
  };
  typedef struct tpqctl_t TPQCTL;
 
 /* /Q structure elements that are valid - set in flags */
  #ifndef TPNOFLAGS
  #define TPNOFLAGS                0x00000    /* no flags set -- no get */
  #endif
  #define TPQCORRID                0x00001    /* set/get correlation ID */
  #define TPQFAILUREQ              0x00002    /* set/get failure queue */
  #define TPQBEFOREMSGID           0x00004    /* enqueue before message ID */
  #define TPQGETBYMSGIDOLD         0x00008    /* deprecated */
  #define TPQMSGID                 0x00010    /* get msgid of enq/deq message */
  #define TPQPRIORITY              0x00020    /* set/get message priority */
  #define TPQTOP                   0x00040    /* enqueue at queue top */
  #define TPQWAIT                  0x00080    /* wait for dequeuing */
  #define TPQREPLYQ                0x00100    /* set/get reply queue */
  #define TPQTIME_ABS              0x00200    /* set absolute time */
  #define TPQTIME_REL              0x00400    /* set relative time */
  #define TPQGETBYCORRIDOLD        0x00800    /* deprecated */
  #define TPQPEEK                  0x01000    /* non-destructive dequeue */
  #define TPQDELIVERYQOS           0x02000    /* delivery quality of service */
  #define TPQREPLYQOS              0x04000    /* reply msg quality of service*/
  #define TPQEXPTIME_ABS           0x08000    /* absolute expiration time */
  #define TPQEXPTIME_REL           0x10000    /* relative expiration time */
  #define TPQEXPTIME_NONE          0x20000    /* never expire */
  #define TPQGETBYMSGID            0x40008    /* dequeue by msgid */
  #define TPQGETBYCORRID           0x80800    /* dequeue by corrid */

 /* Valid flags for the quality of service fields in the TPQCTL structure */
  #define TPQQOSDEFAULTPERSIST     0x00001    /* queue's default persistence */
                                              /* policy */
  #define TPQQOSPERSISTENT         0x00002    /* disk message */
  #define TPQQOSNONPERSISTENT      0x00004    /* memory message */

 /* error return codes */
  extern int tperrno;
  extern long tpurcode;
 
 /* tperrno values - error codes */
  * The reference pages explain the context in which the following
  * error codes can return.
  */
 
  #define TPMINVAL                 0          /* minimum error message */
  #define TPEABORT                 1
  #define TPEBADDESC               2
  #define TPEBLOCK                 3
  #define TPEINVAL                 4
  #define TPELIMIT                 5
  #define TPENOENT                 6
  #define TPEOS                    7
  #define TPEPERM                  8
  #define TPEPROTO                 9
  #define TPESVCERR                10
  #define TPESVCFAIL               11
  #define TPESYSTEM                12
  #define TPETIME                  13
  #define TPETRAN                  14
  #define TPGOTSIG                 15
  #define TPERMERR                 16
  #define TPEITYPE                 17
  #define TPEOTYPE                 18
  #define TPERELEASE               19
  #define TPEHAZARD                20
  #define TPEHEURISTIC             21
  #define TPEEVENT                 22
  #define TPEMATCH                 23
  #define TPEDIAGNOSTIC            24
  #define TPEMIB                   25
  #define TPMAXVAL                 26         /* maximum error message */
 
 /* conversations - events */
  #define TPEV_DISCONIMM           0x0001
  #define TPEV_SVCERR              0x0002
  #define TPEV_SVCFAIL             0x0004
  #define TPEV_SVCSUCC             0x0008
  #define TPEV_SENDONLY            0x0020
 
 /* /Q diagnostic codes            */
  #define QMEINVAL                 -1
  #define QMEBADRMID               -2
  #define QMENOTOPEN               -3
  #define QMETRAN                  -4
  #define QMEBADMSGID              -5
  #define QMESYSTEM                -6
  #define QMEOS                    -7
  #define QMEABORTED               -8
  #define QMENOTA                  QMEABORTED
  #define QMEPROTO                 -9
  #define QMEBADQUEUE              -10
  #define QMENOMSG                 -11
  #define QMEINUSE                 -12
  #define QMENOSPACE               -13
  #define QMERELEASE               -14
  #define QMEINVHANDLE             -15
  #define QMESHARE                 -16

 /* EventBroker Messages */
  #define TPEVSERVICE              0x00000001
  #define TPEVQUEUE                0x00000002
  #define TPEVTRAN                 0x00000004
  #define TPEVPERSIST              0x00000008
 
 /* Subscription Control Structure */
  struct tpevctl_t {
      long flags;
      char name1[XATMI_SERVICE_NAME_LENGTH];
      char name2[XATMI_SERVICE_NAME_LENGTH];
      TPQCTL qctl;
  };
  typedef struct tpevctl_t TPEVCTL;
Users browsing this topic
Guest

Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.


© 2018 Digcode.com. All rights reserved.