UCS Functions

This chapter describes the functions used in UCS.

1. Overview

The following describes the functions used in UCS programs.

  • Server/Client Functions

    Function Description

    tppost

    Generates a specific event from a server or client and delivers a message.

    tpsetfd

    Registers a socket FD in an external socket scheduler of a UCS process.

    tpsubscribe

    Subscribes to a specific event or set of events.

    tpunsubscribe

    Removes an event subscription or a set of event subscriptions.

  • Server Functions

    Function Description

    tpclrfd

    Turns off a socket FD in an internal fdset of a UCS-type process.

    tpissetfd

    Checks if data is received in a socket FD in a UCS process.

    tpregcb

    Sets a routine that receives a response for an asynchronous request of a UCS from a server.

    tprelay

    Forwards a service request to another service routine that contains the information of a client that has requested the service.

    tpsavectx

    Manages client information in a UCS process.

    tpschedule

    Waits for data to be received in a UCS-type server process.

    tpsendtocli

    Sends an unrequested message to a specified client.

    tpsvctimeout

    Call a routine when a service timeout occurs.

    tpsvrdown

    Terminates the UCS-type server process normally.

    tpunregb

    Resets a routine that receives a response for an asynchronous request.

  • Client Functions

    Function Description

    tpgetunsol

    Processes unrequested messages.

    tpsetunsol

    Sets a routine that processes unrequested and received messages.

    tpsetunsol_flag

    Sets a notification message reception flag.

2. Server/Client Functions

2.1. tppost

The tppost function generates a specific event from a server or client and delivers a message. tppost() notifies the occurrence of an event to all clients and server processes that have been registered for the event with the eventname through tpsubscribe(). If required, a message can be delivered.

  • Prototype

    # include <tmaxapi.h>
    int tppost(char *eventname, char *data, long len, long flags)
  • Parameter

    Parameter Description

    eventname

    A NULL-terminated string of up to 15 characters. Wildcards and partial matching are not supported.

    data

    A pointer to the message buffer, which must be allocated in advance using tpalloc().

    len

    The length of the message buffer to send.

    If data indicates a buffer that does not require a specified length, the len will be ignored (0 is used by default). If data indicates a buffer that requires a specified length, the len must not be 0. If data is NULL, the len will be ignored.

    flags

    Only TPNOTIME is used.

  • Return Value

    Value Description

    Positive

    The function call succeeded.

    Negative

    The function call failed, and an error code is set in tperrno.

  • Errors

    If tppost() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. For clients, this is most typically a network error.

    [TPEOS]

    An error occurred in the operating system. This is typically a memory allocation issue.

    [TPEINVAL]

    An incorrect parameter was used.

    [TPENOENT]

    For tpsubscribe(), the qname in the TPEVCTL structure, or the RQ or server specified by the svc, does not exist.

    [TPEPROTO]

    A protocol error occurred. This happens if tpsubscribe() is executed from the client with ctl not set to NULL, or from the server with ctl set to NULL.

    [TPETIME]

    A timeout occurred.

  • Related functions

    tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()

2.2. tpsetfd

The tpsetfd function registers a socket file descriptor (fd) in the external socket scheduler of a UCS process. It is used when a UCS-type process manages user-defined sockets.

A UCS scheduler monitors both messages received on a socket fd and messages from TMM and CLH. If a message is received on a user-defined socket, tpschedule() returns a normal result (UCS_USER_MSG) without requiring an additional process. To determine which socket received the message, tpistfd() must be used.

  • Prototype

    #include <ucs.h>
    int  tpsetfd (int  fd)
  • Parameter

    Parameter Description

    fd

    The socket fd to register.

  • Return Value

    Value Description

    1

    The function call succeeded.

    -1

    The function call failed, and an error code is set in tperrno.

  • Errors

    If tpsetfd() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

  • Example

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ...
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){
            error processing
        }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){
            error processing
        }
    
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
    
        if (inaddr != -1){
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
        }
        ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
        if (ret == -1){
            error processing
        }
        ret = listen(listen_fd, 5);
        if (ret == -1){
            error processing
        }
    
        ret = tpsetfd(listen_fd);
        if (ret == -1){
            error processing
        }
        ...
    
        while(1) {
            n = tpschedule(10);
            ...
            if (n == UCS_USER_MSG){
                if (tpissetfd(listen_fd)) {
                    child_len = sizeof(child_addr);
                    newfd = accept(listen_fd, &child_addr, &child_len);
                    if (newfd == -1){
                        error processing
                    }
    
                ret = tpsetfd(newfd);
                if (ret == -1){
                    error processing
                }
            }
    
            if (tpissetfd(newfd)){
                /* Read the buffer from the socket */
                fd_read(newfd, buf, 1024);
                ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,
                               (long *)&rlen, TPNOFLAGS);
                if (ret == -1){
                    error processing
                }
                ...
                tpclrfd(newfd);
                close(newfd);
            }
            ...
        }
        return 1;
    }
  • Related functions

    tpclrfd(), tpissetfd()

2.3. tpsubscribe

The tpsubscribe function subscribes to a specific event or a set of events identified by eventname. It allows the caller to receive a notification whenever the specified event occurs. This function is available on both servers and clients.

  • Prototype

    # include <tmaxapi.h>
    long tpsubscribe(char *eventname, char *filter, TPEVCTL *ctl, long flags)
  • Parameter

    Parameter Description

    eventname

    A NULL-terminated string with a maximum length of 15 characters. Wildcards or partial matches are not supported; only the exact name can be registered.

    filter

    Reserved for future-use. This parameter must be set to NULL.

    ctl

    A structure that receives a message when an event occurs. Its behavior depends on the caller: if a client uses tpsubscribe(), ctl must be NULL. The message will then be delivered as unsolicited data, which the client can handle using tpsubscribe() or tpgetunsol().

    flags

    Only TPNOTIME is used.

    When tpsubscribe() is executed from a server, ctl must be NULL and configured as follows:

    struct tpevctl {
        long ctl_flags;
        long post_flags;
        char svc[XATMI_SERVICE_NAME_LENGTH];
        char qname[RQ_NAME_LENGTH];
    };
    typedef struct tpevctl TPEVCTL;
    Member Description

    ctl_flags

    Reserved for future-use and not currently supported. Set to 0.

    post_flags

    Reserved for future-use and not currently supported. Set to 0.

    svc[XATMI_SERVICE_NAME_LENGTH]

    When using svc, the message is sent to the server in a manner similar to tpacall (svc, data, len, TPNOREPLY), and the server’s return value is ignored. Use only one of qname or svc.

    qname[RQ_NAME_LENGTH]

    When using qname, the message is stored in the RQ through tpenq (qname, NULL, data, len, TPNOFLAGS).

  • Return Value

    Value Description

    descriptor

    The function call succeeded and returns the descriptor to be used when calling tpunsubscribe().

    -1

    The function call failed, and an error code is set in tperrno.

  • Errors

    If tpsubscribe() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. For clients, this is most often a network error.

    [TPEOS]

    An error occurred in the operating system. This is typically a memory allocation issue.

    [TPEINVAL]

    An incorrect parameter was used.

    [TPENOENT]

    The qname specified for the TPEVCTL struct, or the RQ or server specified by svc does not exist.

    [TPEPROTO]

    CTL is not NULL in the client and server.

    [TPETIME]

    A timeout occurred.

  • Related functions

    tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()

2.4. tpunsubscribe

The tpunsubscribe function unsubscribes a specific event subscribed through tpsubscribe(). When all requests for unsubsription are completed, the event’s table is deleted by the Tmax system. This function is available on both servers and clients.

  • Prototype

    # include <tmaxapi.h>
    int tpunsubscribe(long sd, long flags)
  • Parameter

    Parameter Description

    sd

    The return value retrieved by tpsubscribe().

    flags

    Only TPNOTIME is used.

  • Return Value

    Value Description

    Positive

    The function call succeeded.

    Negative

    The function call failed, and an error code is set in tperrno.

  • Errors

    If tpunsubscribe() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. For clients, this is most often a network error.

    [TPEOS]

    An error occurred in the operating system. This is typically a memory allocation issue.

    [TPEINVAL]

    An incorrect parameter was used.

    [TPETIME]

    A timeout occurred.

  • Related functions

    tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()

3. Server Functions

3.1. tpclrfd

The tpclrfd function turns off a socket fd in an internal fdset of a UCS-type process. It is used for scheduling an external socket in a UCS-type server process.

  • Prototype

    #include <ucs.h>
    int  tpclrfd (int fd)
  • Parameter

    Parameter Description

    fd

    The socket of an internal fdset to be turned off.

  • Return Value

    Return Value Description

    1

    The function call succeeded.

    -1

    The function call failed. An error code is set in tperrno.

  • Error

    If tpclrfd() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

  • Example

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ….
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){ error processing }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){ error processing }
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
        if (inaddr != -1){
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
        }
    
        ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
        if (ret == -1){ error processing }
        ret = listen(listen_fd, 5);
        if (ret == -1){ error processing }
    
        tpsetfd(listen_fd);
        ...
        while(1) {
            n = tpschedule(10);
            ...
            if (n == UCS_USER_MSG){
            if (tpissetfd(listen_fd)) {
                child_len = sizeof(child_addr);
                newfd = accept(listen_fd, &child_addr, &child_len);
                if (newfd == -1){ error processing }
                tpsetfd(newfd);
            }
    
            if (tpissetfd(newfd)){
                /* Read the buffer from the socket */
                fd_read(newfd, buf, 1024);
                ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,
                             (long *)&rlen, TPNOFLAGS);
                if (ret == -1){ error processing }
                    ...
                ret = tpclrfd(newfd);
                if (ret == -1){ error processing }
                close(newfd);
            }
            ...
       }
       return 1;
    }
  • Related function

    tpissetfd()

3.2. tpissetfd

The tpissetfd function checks whether data has arrived on a socket FD from a UCS process in a server. It is used to schedule external sockets in UCS-type server processes.

  • Prototype

    #include <ucs.h>
    int  tpissetfd (int fd)
  • Parameter

    Parameter Description

    fd

    The FD in the fdset to test.

  • Return Value

    Return Value Description

    Positive value

    The message arrived.

    0

    No message arrived.

    -1

    The function call failed. An error code is set in tperrno.

  • Error

    If tpissetfd() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

  • Example

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ...
    
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
    
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){ error processing }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
    
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){ error processing }
    
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
        if (inaddr != -1)
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
    
            ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
            if (ret == -1){ error processing }
            ret = listen(listen_fd, 5);
            if (ret == -1){ error processing }
    
            tpsetfd(listen_fd);
            ...
            while(1) {
                n = tpschedule(10);
                ...
                if (n == UCS_USER_MSG){
                    if (tpissetfd(listen_fd)) {
                        child_len = sizeof(child_addr);
                        newfd = accept(listen_fd, &child_addr, &child_len);
                        if (newfd == -1){ error processing }
                        tpsetfd(newfd);
                }
                if (tpissetfd(newfd)){
                    /* Read the buffer from the socket */
                    fd_read(newfd, buf, 1024);
                    ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,
                                  (long *)&rlen, TPNOFLAGS);
                    if (ret == -1){ error processing }
                    ...
                    tpclrfd(newfd);
                    close(newfd);
                }
            ...
            }
        }
        return 1;
    }
  • Related functions

    tpissetfd(), tpsetfd()

3.3. tpregcb

The tpregcb function sets a routine that receives a response for an asynchronous UCS request from a server. This routine is used when a UCS type process receives a response from a server program. It is used instead of tpgetrply() in a UCS-type server process.

  • Prototype

    # include <ucs.h>
    int  tpregcb (UcsCallback)
  • Parameter

    Parameter Description

    UcsCallback

    The callback function that handles a response for an asynchronous request in a UCS.

    The UCSMSGINFO structure contains the response message information used to process asynchronous responses in UCS-type servers. The callback routine registered in the tpregcb() function receives this structure as the argument, and executes the response handling logic.

    The response message contains the user response code, error code, message type, connection descriptor, and the length of the response data and the pointer to the response data itself. The UCSMSGINFO structure is defined in the header file <ucs.h> with the following items:

    typedef struct {
            long    urcode;     /* user response code */
            int     errcode;    /* response error code */
            int     msgtype;    /* message type (used as internal identifier) */
            int     cd;         /* connection descriptor */
            int     len;        /* length of response data */
            char    *data;      /* pointer to the response data */
    } UCSMSGINFO;
    Field Description

    urcode

    The user-defined code in the response message.

    errcode

    The error code for the response.

    msgtype

    The message type identifier that is internally used.

    cd

    The connection descriptor for the response.

    len

    The actual length of the response data.

    data

    The pointer to the response data.

  • Return Value

    Return Value Description

    1

    The function call succeeded.

    -1

    The function call failed. An error code is set in tperrno.

  • Error

    If tpregcb() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

  • Example

    ...
    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    
    void reply_receive(UCSMSGINFO *reply);
    DUMMY(TPSVCINFO *msg)
    {
        data process ….
    }
    
    int usermain(int argc, char *argv[])
    {
        int ret;
        char *buf
    
        ret = tpregcb(reply_receive);
        if (ret == -1){ error processing }
        buf=tpalloc(“STRING”, NULL, 0);
        if (buf==NULL) { error processing }
        data process…
        while(1)
        {
            ...
            tpschedule(3);
            cd = tpacall(“SERVICE”, buf, strlen(buf), TPNOFLAGS);
            if (cd < 0) { error processing }
            ...
        }
    }
    
    void reply_receive(UCSMSGINFO *reply)
    {
        rtcd = reply->errcode;
    
        if(rtcd != 0)
        {
             printf("[tperrno(%d) : %s]\n", rtcd,tpstrerror(rtcd));
             /* Error handling code */
        }
    
        printf(“data....%s\n”, reply->data);
    }
  • Related function

    tpunregcb()

3.4. tprelay

The tprelay function is available only in a UCS server process. It can be used in multiple nodes. When a client requests a service, this function requests another service with information about the client. Since the service called by the function notices that it was called by the client, not the function, it returns the result to the client.

A service execution result can be sent to a client that called for a request, so a fast response can be induced with a simple structure in a UCS process. In general, this function is useful when processing a service, because it is integrated with an external application which is a program routine that can obtain results after calling a service two or three times.

If a server process is terminated after saving client information using tpsavcctx() or tpgetctx() but before a request is sent to another service using tprelay(), an error response will be sent to the service caller automatically. For more information about error responses, refer to the CTX_EREPLY option in the SERVER section of the environment configuration. These operations are supported for Tmax versions 5 SP2 or later. In earlier versions, an error response will not be sent to the service caller.

  • Prototype

    #include <ucs.h>
    int  tprelay(char *svc, char *data, long len, long flags, CTX_T *ctxp);
  • Parameter

    Parameter Description

    svc

    The service name registered in the Tmax configuration file.

    data

    The data to be sent when the service is called. If not NULL, must use a buffer allocated by tpalloc().

    len

    The length of the data to be sent. For CARRAY and X_OCTET structure array types, this parameter must be specified.

    flags

    Not currently supported. Set to TPNOFLAGS.

    ctxp

    The information structure retrieved by tpgetctx() or tpsavectx().

  • Return Value

    Return Value Description

    1

    The function call succeeded.

    -1

    The function call failed. An error code is set in tperrno.

  • Error

    If tprelay() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPEINVAL]

    The parameter is invalid. For example, ctxp is NULL, or an incorrect buffer is used.

    [TPESYSTEM]

    An error occurred in the Tmax system.

  • Example

    ...
    #include <stdio.h>
    #include <usrinc/ucs.h>
    CTX_T *ctx = NULL;
    
    DUMMY(TPSVCINFO *msg)
    {
        data process ...
    }
    
    usermain(int argc, char *argv[])
    {
        int ret, i;
        char *rcvbuf, *sndbuf;
        long sndlen;
    
        rcvbuf = (char *)tpalloc(“CARRAY”,NULL, 1024);
        if (rcvbuf == NULL){ error processing }
        i = 0;
    
        while(1) {
            tpschedule(1);
            if (ctx != NULL)
            {
                i++;
                if ((sndbuf = (char *)tpalloc(“CARRAY”,NULL, 1024)) == NULL)
                { error processing }
                else
                {
                     ...
                     ret = tprelay(“TPRETURN”, sndbuf, sndlen, 0, ctx);
                     if (ret==-1) { error processing }
                     data process...
                     ctx = NULL;
                     tpfree(sndbuf);
                 }
            }
        }
    }
    
    int RELAY(TPSVCINFO *rqst)
    {
       ...
       ctx = tpsavectx();
       tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);
    }
  • Related functions

    tpreturn(), tpforward()

3.5. tpsavectx

The tpsavectx function manages client information in a UCS process. This function is used along with tprelay(), which forwards a request to another service. It works in the same way as a general service program, which calls for other services as a tpforward(). Consequently, a called service sends a processing result to the client.

The tpsavectx() function can be used to communicate with an external process that has heterogeneous protocols that are time-consuming and can block channels.

The function can be used in the following format:

Client → svc1 → svc2(service, tpsavectx) → External channel
Client ← svc3 ← svc2(usermain, tprelay) ← External channel
  1. The client sends a service request to svc1.

  2. svc1 calls svc2 using tpforward (...TPNOREPLY).

  3. svc2 is a service which runs in a UCS process, and it calls tpsavectx() in a service routine to save the client information to communicate with an external system.

  4. The result is sent to a usermain and forwarded to svc3 via tprelay(). svc3 considers that svc2 has called it via tpforward(), so it finally sends the result to the client.

In this process, because svc1 calls a service via tpforward with the TPNOREPLY flag, it can prevent channel congestion. This enables a large numbers of clients to be handled with a small number of processes. Additionally, a single UCS process can act as both the sending and receiving processes. It can organize a relatively simple system with efficient system management.

  • Prototype

    #include <ucs.h>
    CTX_T * tpsavectx(void)
  • Return Value

    Return Value Description

    CTX_T

    The function call succeeded.

    NULL

    The function call failed. An error code is set in tperrno.

  • Error

    If tpsavectx() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPEPROTO]

    The tpsavectx() function must be used within a service routine. If it is used outside a service routine, a TPEPROTO error occurs. It cannot be used in tpsvrinit() or tpsvrdone().

    [TPESYSTEM]

    A memory allocation error occurred.

  • Example

    ...
    #include <stdio.h>
    #include <usrinc/ucs.h>
    
    CTX_T *ctx = NULL;
    
    usermain(int argc, char *argv[])
    {
        int ret, i;
        char *rcvbuf, *sndbuf;
        long sndlen;
    
        rcvbuf = (char *)tpalloc(“CARRAY”,NULL, 1024);
        if (rcvbuf == NULL){ error processing }
    
        i = 0;
        while(1) {
            tpschedule(1);
            if (ctx != NULL)
            {
                i++;
                if ((sndbuf = (char *)tpalloc(“CARRAY”,NULL, 1024)) == NULL)
                { error processing }
                else
                {
                    ...
                    ret = tprelay(“TPRETURN”, sndbuf, sndlen, 0, ctx);
                    if (ret==-1) { error processing }
                    data process...
                    ctx = NULL;
                    tpfree(sndbuf);
                }
            }
        }
    }
    
    int RELAY(TPSVCINFO *rqst)
    {
        ...
        ctx = tpsavectx();
        tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);
    }
  • Related functions

    tpreturn(), tpforward(), tprelay()

3.6. tpschedule

The tpschedule function waits for data sent from a UCS server process. It is available only in UCS-type server processes. The function sleeps for up to the specified maximum timeout period, and if data arrives within this period, it returns immediately.

tpschedule() returns after the service corresponding to the received data has been automatically executed. Therefore, the user must not execute the service manually after the data arrival.

Services are always executed by the system. Keep this in mind, even when running a UCS-type service program.

  • Prototype

    #include <ucs.h>
    int  tpschedule(int timeout)
  • Parameter

    Parameter Description

    timeout

    The amount of time to wait in seconds.

    • -1 : Only checks for data arrival and immediately returns.

    • 0 : Waits indefinitely for data to be arrived.

  • Return Value

    Return Value Description

    Positive integer

    The function call succeeded and data arrived.

    -1

    An error occurred because no data arrived within the timeout period or the function call failed. If no data arrives within the timeout period, -1 is returned and tperrno is set to 13 (TPETIME). In other cases, different error codes are set.

  • Error

    If tpschedule() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

    [TPETIME]

    No data arrived until the timeout period expired.

    [TPEPROTO]

    The function was called under an inappropriate condition. For example, it was called from within a service.

  • Example

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    int usermain(int argc, char *argv[])
    {
        ...
        while(1)
        {
            ...
            tpschedule(3);
            ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf,
                          (long *)&rlen, TPNOFLAGS);
            if (ret == -1) { error processing}
            ...
        }
    }
  • Related functions

    tpsleep(), tp_sleep(), tp_usleep()

3.7. tpsendtocli

The tpsendtocli function sends an unrequested message to a specified client. It is available only on servers. If tpbroadcast() sends an unsolicited message to any client connected to the Tmax systems, tpsendtocli() sends a message only to a client that has requested the service provided by the server process.

  • Prototype

    # include <tmaxapi.h>
    int  tpsendtocli (int  clid,  char  *data,  long  len,  long  flags)
  • Parameter

    Parameter Description

    clid

    A unique client number retrieved with tpgetclid().

    data

    A buffer allocated by tpalloc(). If data points to a buffer that does not require a specified length, the len value is ignored and 0 is used by default. If data points to a buffer that requires a specified length, len cannot be 0. If data is NULL, len is ignored.

    len

    The length of the buffer to be sent.

    flags

    Determines the function behavior.

    The following flags are available.

    • TPNOFLAG(0)

      Messages must be received by the client. However, if the client cannot process messages quickly enough, it may take a long time to receive the requested result.

    • TPUDP

      This flag does not indicate that communication with the client uses the UDP protocol. If a caller transmits data while the internal buffer (used for message transfer) is full, the data may be discarded. In other words, this flag allows data to be lost in situations similar to UDP communication.

    • TPFLOWCONTROL

      Checks the status of the client to determine whether another request message can be sent. If too many messages are accumulated, tpsendtocli() returns -1, and tperrno is set to TPEQFULL. This flag helps reduce the load on the Tmax system.

  • Return Value

    Return Value Description

    1

    The function call succeeded.

    -1

    The function call failed. An error code is set in tperrno.

  • Error

    If tpsendcli() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPEBADDESC]

    The clid is invalid.

    [TPEPROTO]

    tpsendtocli() was called under an inappropriate condition.

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

    [TPEQFULL]

    A duplicate message exists.

  • Example

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/tmaxapi.h>
    
    SERVICE(TPSVCINFO *msg)
    {
        int ret, clid;
        char *buf;
    
        buf = (char *)tpalloc(“STRING”, NULL, 0);
        if (buf==NULL) { error processing }
        strcpy(buf, msg->data);
        data process….
        clid = tpgetclid();
        if (clid==-1) { error processing }
    
        ret=tpsendtocli(clid, (char *)buf, 0, 0);
        if (ret==-1) { error processing }
        tpreturn(TPSUCCESS, 0, 0, 0);
    }
  • Related function

    tpbroadcast()

3.8. tpsvctimeout

The tpsvctimeout() function is called when a service timeout occurs. When a timeout happens, the server program automatically invokes tpsvctimeout(). If the user redefines this function, the redefined version will be called instead.

When executing tx_commit() or tx_rollback() during a service, if a timeout occurs during the internal steps of xa_commit() or xa_rollback(), tperrno is set to TPETRAN to indicate this, allowing tpsvctimeout() to distinguish internal references.

A built-in tpsvctimeout() is included in the libsvr.so library. By default, this function returns with tpreturn(TPFAIL). If the user redefines tpsvctimeout(), the redefined object file must be linked before the libsvr.so library, ensuring the custom function is correctly called at runtime.

If TPRETURN is configured in the SERVER section, any call to tpreturn() within tpsvctimeout() due to a service timeout will ignore the arguments specified in the source code. Instead, the values defined in the configuration file are forcibly used.

  • Prototype

    # include <tmaxapi.h>
    void  tpsvctimeout(TPSVCINFO *msg)
  • Parameter

    Parameter Description

    msg

    The message used when the timed-out service was called.

  • Return Value

    Since tpsvctimeout() is used by the developer to perform necessary operations when a service timeout occurs, it does not return a value and does not produce an error.

  • Example

    #include <stdio.h>
    #include <usrinc/atmi.h>
    SERVICE(TPSVCINFO *msg)
    {
        ...
        tpreturn(TPSUCCESS,0,(char *)msg->data, 0,TPNOFLAGS);
    }
    
    void tpsvctimeout(TPSVCINFO *msg)
    {
        ...
        tpreturn(TPFAIL, TPETIME, (char *)buf, sizeof(buf), TPNOFLAGS);
    }

3.9. tpsvrdone

The tpsvrdone() function sets a routine to be executed when a server process is terminated. The Tmax application server’s main program (i.e., the main() provided by the Tmax system) calls tpsvrdone() before ending the process, after handling all service requests. When this routine is executed, the server process remains part of Tmax but no longer provides services. Within the tpsvrdone() routine, it is possible to perform Tmax communication or define a transaction.

If tpsvrdone() is executed while keeping an interactive connection, waiting for asynchronous replies, or during a transaction, Tmax will disconnect the interactive connection, ignore any pending asynchronous replies, and stop the transaction. The server will then be terminated immediately.

If a program does not define a tpsvrdone() routine, a default routine provided by Tmax is used. For servers that belong to a server group handling transactions, the default routine calls tx_close() and userlog() to indicate that the server is terminating. If tpreturn() or tpforward() are called within tpsvrdone(), the routine simply returns without performing any operations.

  • Prototype

    # include <tmaxapi.h>
    int tpsvrdone(void)
  • Return Value

    Since tpsvrdone() is written by the developer to perform necessary operations before terminating a server process, it does not return a value and does not produce an error.

  • Example

    #include <stdio.h>
    #include <usrinc/atmi.h>
    
    EXEC SQL INCLUDE sqlca.h;
    
    SERVICE(TPSVCINFO *msg)
    {
        int ret, cd;
        char *buf;
    
        EXEC SQL begin declare section;
        ….
        EXEC SQL end declare section;
        EXEC SQL CONNECT : scott IDENTIFIED BY : tiger;
        buf=tpalloc(“STRING”, NULL, 0);
        if (buf==NULL) { error processing }
        data process….
    
        cd=tpgetclid();
        if (cd==-1) { error processing }
        ret=tpsendtocli(cd, buf, 0, TPNOFLAGS);
        if (ret==-1) { error processing }
        data process....
    
        tpreturn(TPSUCCESS,0,buf, strlen(buf), 0);
    }
    
    int tpsvrdone()
    {
        printf(“ Sevice end\n”);
    }
  • Related functions

    tx_close(), tpsvrinit()

3.10. tpsvrdown

The tpsvrdown function properly terminates a UCS-type server process. UCS-type server processes are generally used for communication with external systems, most commonly banking systems. If an error prevents the external system from processing a service request, a countermeasure is needed. tpsvrdown() terminates the UCS-type server process so that no further service calls are sent to the failing external system. This helps prevent unnecessary resource usage and reduces the risk of overloading the external system.

  • Prototype

    #include <ucs.h>
    int  tpsvrdown(void)
  • Return Value

    Since tpsvrdown() is used by the developer to perform necessary operations before terminating a server process, it does not return a value and does not produce an error.

  • Example

    ...
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    int usermain(int argc, char *argv[])
    {
        count=0;
        ...
        while(1)
        {
            ...
            tpschedule(3);
            cd = tpacall(“SERVICE”, buf, strlen(buf), TPNOREPLY);
            if (cd < 0) { error processing }
            ...
            if (count == 10) tpsvrdown();
        }
    }
    
    void reply_receive(UCSMSGINFO *reply)
    {
        printf(“data....%s\n”, reply->data);
    }
  • Related functions

    tpsvrinit(), tpsvrdone()

3.11. tpunregcb

The tpunregcb function resets a routine that receives the response to an asynchronous request. It is used in UCS-type server processes.

  • Prototype

    #include <ucs.h>
    int  tpunregcb (void)
  • Return Value

    Return Value Description

    1

    The function call succeeded.

    -1

    The function call failed. An error code is set in tperrno.

  • Error

    If tpunregcb() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

  • Example

    ...
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    void reply_receive(UCSMSGINFO *reply);
    
    int usermain(int argc, char *argv[])
    {
        ...
        ret = tpregcb(reply_receive);
        if (ret == -1){ error processing  }
    
        ret = tpunregcb();
        if (ret == -1){  error processing  }
        while(1)
        {
            ...
            tpschedule(3);
            cd = tpacall(“SERVICE”, buf, strlen(buf), TPNOFLAGS);
            if (cd < 0) { error processing  }
            ...
        }
    }
    
    void reply_receive(UCSMSGINFO *reply)
    {
        printf(“first reply receive\n”);
        printf(“data....%s\n”, reply->data);
    }
  • Related function

    tpregcb()

4. Client Functions

4.1. tpgetunsol

The tpgetunsol() function handles unsolicited messages, which are sent unilaterally without a client request. These messages can be sent via tpbroadcast(), tpsendtoci(), or tppost() executed by the sender.

Any unsolicited messages sent before tpgetunsol() is executed are ignored. To receive unsolicited messages through tpgetunsol(), the TPUNSOL_POLL or TPUNSOL_HND flag must be set when connecting to the Tmax system via tpstart(). When tpgetunsol() is called, even if the tpstart() flag is set to TPUNSOL_IGN, it internally defaults to TPUNSOL_POLL, enabling reception of unsolicited messages from the server.

  • Prototype

    #include <tmaxapi.h>
    int  tpgetunsol (int type, char **data, long *len, long flags)
  • Parameter

    Parameter Description

    type

    The type of the message sent by the server. One of UNSOL_TPPOST, UNSOL_TPBROADCAST, or UNSOL_TPSENDTOCLI.

    data

    A pointer to the received message. It may be an unknown buffer type or subtype, in the case of which the data cannot be sent.

    len

    The total length of the message.

    flags

    Option to enable blocking.

    The following flags are available:

    • TPBLOCK

      Waits for unsolicited messages in block state when calling tpgetunsol().

    • TPNOCHANGE

      If the received response buffer does not match the buffer pointed to by *data, the pointer will be updated to reference the received buffer, within the allowable range recognized by the receiver.

      If this flag is set, the type of the buffer pointed to by *data cannot be changed. The type and subtype of the received response buffer must match those of the buffer pointed to by *data.

    • TPNOTIME

      The caller waits for the response indefinitely, ignoring the block timeout. If tpgetrply() is executed in transaction mode, the transaction timeout still applies.

    • TPSIGRSTRT

      Allows signal interrupts. When a system function call is interrupted, the call is automatically retried. If a signal interrupt occurs while this flag is not set, the function call fails and tperrno is set to TPGOTSIG.

    • TPGETANY

      Returns the first available response, ignoring the input call descriptor (cd). The returned response’s call descriptor is assigned to cd. If no response is available, tpgetrply() continues to wait by default.

  • Return Value

    Return Value Description

    1

    The function call succeeded.

    -1

    The function call failed. An error code is set in tperrno.

  • Error

    If tpgetunsol() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPEPROTO]

    tpgetunsol() was called under an inappropriate condition. tpstart() was not executed and the TMAX_ACTIVATE_AUTO_TPSTART=N option was set.

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

  • Example

    #include <stdio.h>
    #include <string.h>
    #include <usrinc/tmaxapi.h>
    
    void main(int argc, char *argv[])
    {
        int ret;
        char *buf;
        long len;
    
        ret=tpstart((TPSTART_T *)NULL);
        if (ret==-1) { error processing }
    
        buf=tpalloc(“STRING”, NULL, 0);
        if (buf==NULL) { error processing }
        data process....
    
        while(1)
        {
            ret=tp_sleep(2);
            if (ret==-1) { error processing }
    
            if (ret==0)
                printf(“nothing happened\n”);
            else {
                ret=tpgetunsol(UNSOL_TPSENDTOCLI, (char **)&buf, &len, TPNOCHANGE);
                if (ret==-1) { error processing }
                printf(“received data : %s\n”, buf);
            }
    
            data process....
            if (strncmp(buf, “end”, 3)==0) break;
        }
    
        data process....
        tpfree(buf);
        tpend();
    }
  • Related functions

    tpbroadcast(), tpsetunsol(), tpstart(), tpend()

4.2. tpsetunsol

The tpsetunsol function configures a routine to handle unsolicited messages. It is used on the client-side. How unsolicited messages are handled is determined by the application and can be customized by each client.

Before tpsetunsol() is called for the first time, any unsolicited messages received by the Tmax library are ignored. A call to tpsetunsol() with a NULL parameter pointer is also ignored. The function pointer passed must conform to the required parameter definition.

  • Prototype

    # include  <atmi.h>
    Unsolfunc *tpsetunsol (void ( *disp ) ( char  *data,  long  len,  long  flags ) )
  • Parameter

    Parameter Description

    data

    Points to a received type buffer. If there is no data, it can be NULL. If the buffer type or subtype for data is unknown to the client, data cannot be recognized. The application cannot delete data, but the system can delete it and nullify the data area to return.

    len

    The length of the data.

    flags

    Currently not used.

  • Return Value

    Return Value Description

    Pointer / NULL

    The function call succeeded.

    • Pointer : Returns the existing pointer to the unsolicited message handling routine.

    • NULL : Indicates that no handling function has been configured. This is also considered a successful return.

    TPUNSOLERR

    The function call failed. An error code is set in tperrno.

  • Error

    If tpsetunsol() fails, one of the following codes is set in tperrno.

    Error Code Description

    [TPEPROTO]

    tpsetunsol() was called under an inappropriate condition.

    [TPESYSTEM]

    An error occurred in the Tmax system. Detailed information is recorded in the log file.

    [TPEOS]

    An error occurred in the operating system.

  • Example

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include “../sdl/demo.s”
    
    void get_unsol(char *data, long len, long flags)
    {
        printf(“get unsolicited data = %s\n”, data);
        data process....
    }
    
    void main(int argc, char *argv[])
    {
        int ret;
        char *buf;
        long len;
    
        ret=tpstart((TPSTART_T *)NULL);
        if (ret==-1) { error processing }
        ret=tpsetupsol_flag(TPUNSOL_HND);
        if (ret==-1) { error processing }
    
        ret=tpsetunsol(get_unsol);
        if (ret==TPUNSOLERR) { error processing }
    
        buf = (char *)tpalloc(“CARRAY”, NULL, 20);
        if (buf==NULL) {error processing };
        data process...
    
        ret=tpcall(“SERVICE”, buf, 20, (char **)&buf, &len, TPNOFLAGS);
        if (ret==-1) { error processing }
        data process...
    
        tpfree((char *)buf);
        tpend();
    }
  • Related functions

    tpstart(), tpend(), tpgetunsol()

4.3. tpsetunsol_flag

The tpsetunsol_flag function changes the flag setting for receiving unsolicited messages. It is used on the client side. It resets the flag values used when the client connects to the Tmax system using tpstart().

  • Prototype

    # include <atmi.h>
    int  tpsetunsol_flag  (int  flag)
  • Parameter

    Parameter Description

    flag

    Resets the flag setting for receiving unsolicited messages.

    One of the following values is used:

    • TPUNSOL_IGN : Does not receive unsolicited messages.

    • TPUNSOL_HND, TPUNSOL_POLL : Receives unsolicited messages.

  • Return Value

    Return Value Description

    1

    The function call succeeded.

    -1

    The function call failed. An invalid flag was set. Even if an error occurs, no error code is set in tperrno.

  • Example

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include “../sdl/demo.s”
    
    void get_unsol(char *, long, long);
    void main(int argc, char *argv[])
    {
        int ret;
        char *buf;
        long len;
    
        ret=tpstart((TPSTART_T *)NULL);
        if (ret==-1) { error processing }
        ret=tpsetupsol_flag(TPUNSOL_HND);
        if (ret==-1) { error processing }
    
        ret=tpsetunsol(get_unsol);
        if (ret==TPUNSOLERR) { error processing }
        buf = (char *)tpalloc(“CARRAY”, NULL, 20);
        if (buf==NULL) {error processing };
        data process...
    
        ret=tpcall(“SERVICE”, buf, 20, &buf, &len, TPNOFLAGS);
        if (ret==-1) { error processing }
        data process...
    
        tpfree((char *)buf);
        tpend();
    }
    
    void get_unsol(char *, long, long);
    {
        printf(“get unsolicited data.\n”);
        data process....
    }
  • Related function

    tpstart()