This chapter describes functions that are used in a Tmax server and functions that are required to write a server program in ATMI. A server can act as a client, so functions that are used in a client also can be used.
The following describe the functions that are used in a TCS type server program.
Service completion functions
tpreturn() sends a response to a client. tpforward() forwards a request to another server and ends the service.
Server initialization and termination functions
Opens or closes a database that is connected to the application, and provides a function to process command line options. This subroutine is provided by default.
Multithread/Multicontext
Function | Description |
---|---|
tpsvrthrinit | Provides an initialization function to each thread when a service thread is created in a STD_MT type server. Supported in Tmax v5.0 SP2 and later. |
tpsvrthrdone | Called when a service thread is terminated in a STD_MT type server. Supported in Tmax v5.0 SP2 and later. |
tpgetctxt | Returns the currently set context ID as the first parameter of the thread that called this function. |
tpsetctxt | Sets the context of the thread that called this function as the ID of the first parameter. |
Unrequested message functions
A server can send unrequested messages to clients unilaterally in Tmax. This feature is used when there is information that all clients connected to Tmax must be notified of. The clients that can receive the unrequested message must be connected to Tmax with flags set.
Function | Description |
---|---|
tpsendtocli | A server sends a message, which was registered in advance by clients, to the clients automatically without client request. |
tpgetclid | Returns the ID of the client that is connected to the Tmax system. The ID is used for tpsendtocil(). |
tpchkclid | Checks if the client that corresponds to the client ID of the node where the server process resides is connected. |
For more information about each function, refer to "Tmax Reference Guide".
A server program consists of main(), which is provided by Tmax, and service routines. main() consists of routines that process database connections, disconnections, and command line options. Service routines receive and process requests from a client.
The server main() receives a request from a client and calls the corresponding service routine with a TPSVCINFO structure to process the request. The TPSVCINFO structure has data to be processed and information about the client that sent the request.
The TPSVCINFO structure is defined in the atmi.h header file. The following are the components of the TPSVCINFO structure.
#define XATMI_SERVICE_NAME_LENGTH 16 struct tpsvcinfo { char name[XATMI_SERVICE_NAME_LENGTH]; /* Requested service name */ char *data; /* Request data */ long len; /* Request data length */ long flags; /* Service property */ Int cd; /* Connection descriptor */ }; typedef struct tpsvcinfo TPSVCINFO
Member | Description |
---|---|
name | Name of the service routine requested by a client. |
data | Buffer to receive requested data from a client. This is allocated in advance with tpalloc() in the server main(). |
len | Length of the requested data. |
flags | Notifies a service if it is in a transaction state or the caller requires a response. For example, if flags is TPTRAN, the service is in transaction mode. If flags is TPNOTRAN, the service can participate in the current transaction. |
cd | Connection Descriptor. Sets the clients the response must be sent to. The server allocates the buffer in advance in main() to process the service requested by a client. It is recommended to use data in TPSVCINFO when communicating through tpreturn() or tpforward(). When accessing data in TPSVCINFO, the buffer types of the server program and the client program must be the same. |
Client Program
The following is an example client program.
#include <usrinc/atmi.h> . . . main() { struct strdata *cltdata; if ((cltdata = (strcut strdata *)tpalloc(“STRUCT”, “strdata”, sizeof(struct strdata)) ) == NULL){ error processing routine } . . . if ((tpcall (“SEL_SVC”, cltdata, 0, (char **)&cltdata, &len, TPNOFLAGS))== -1){ error processing routine } . . . }
Server Program
The following is an example service routine. main() is provided by Tmax.
#include <usrinc/atmi.h> . . . SEL_SVC(TPSVCINFO *msg) /* A structure that contains client information and client request*/ { struct strdata *svcdata; /* Change the data type to match the buffer type */ svcdata = (struct strdata *)msg->data; . . . svcdata->ip = sip; strcpy(msg ->data, svcdata); tpreturn(TPSUCCESS, 0, msg->data, sizeof(struct strdata), TPNOFLAGS); };
The tpreturn function means the completion of a service routine. It works the same as a return sentence in the C language. When a tpreturn() is called, a service routine is returned to a Tmax system. To return a service routine correctly to a Tmax system, call a tpreturn() within a service routine.
A tpreturn() function sends a reply message for a service. If a program to receive a reply is waiting with a tpcall(), tpgetrply(),or tprecv(), the reply will be transferred through a receiver's buffer after a tpreturn() is successfully called.
A tpreturn() also allows interactive services to terminate interactive communication. A service routine cannot call a tpdiscon() directly. To ensure a correct result, a program connected to an interactive service should not to call a tpdiscon(). Rather, it must wait for a completion notification from an interactive service, for example, an event like a TPEV_SVCSUCC or a TPEV_SVCFAIL transmitting with a tpreturn().
If a service routine is in a transaction mode, and a client or service that called a service does not start a transaction explicitly (if tx_begin is not used), then a tpreturn will be committed or rolled back as a part of a transaction when tpreturn is TPSUCCESS. A service can be called to multiply as a part of a same transaction (global transaction), therefore, it is will not be completely committed or rolled back until a transaction beginner calls either a tx_commit or a tx_rollback to complete a transaction.
A tpreturn() function must be called after all replies are received from services requested by a service routine. Otherwise, a [TPESVCERR] error or a TPEV_SVCERR event will be returned to the program that communicated with a service routine that depended on the service characteristics. Replies that are not received are automatically ignored by a Tmax system. In addition, the descriptors used for these replies will also be invalidated.
A tpreturn() function must be called after all connections that began from a service used for interactive communication are ended. Otherwise, either a [TPESVCERR] error or a TPEV_SVCERR event will be returned to the program that communicated with a service routine that depended on the service characteristics. In addition, a forcible disconnection event, such as a TPEV_DISCONIMM, will be transferred to a service and all items that are connected to the service.
In an interactive communication, if a service routine does not have communication control when it calls a tpreturn(), two results may happen:
If a service routine calls a tpreturn() with a rval of a TPFAIL and data is NULL, a TPEV_SVCFAIL event will be transferred to a communication starter.
When a tpreturn() is called in other ways, a TPEV_SVCERR event will be transferred to a communication starter. Because an interactive service must have only one interactive communication that does not start from a service, a Tmax system knows the descriptor to which data or an event that is to be transmitted. For this reason, a descriptor is not transferred to a tpreturn() as a parameter.
Prototype
# include <atmi.h> void tpreturn (int rval, long rcode, char *data, long len, long flags)
Parameter
Parameter | Description |
---|---|
rval | The values available for a rval are explained in the following table. If a rval is not explained in the table, it will be considered as TPFAIL. |
rcode | The return code a rcode defines in an application program can be transmitted to a program that receives a service reply. This code will be transmitted, regardless of a rval value, as long as a reply can be transmitted to a client successfully. The client is considered to have received a reply successfully in the following cases: A receiving call was a success or a reply was returned through a [TPSVCFAIL], or the client received either a TPEV_SVCSUCC or a TPEV_SVCFAIL event. A rcode value is transferred to a receiver with a tpurcode global variable. |
data | Reply data to be sent. If it is not NULL, it must indicate a buffer that was allocated by tpalloc() before. If the buffer is the same as the one transferred to the service routine, the Tmax systems will handle it. Therefore, the service routine writer does not need to take care of whether to or not to free the buffer. Indeed, if a user attempts to free the buffer, the attempts will fail. However, if the buffer transferred with tpreturn() is not the same as the one transferred along with the service request, the tpreturn() will free the buffer. |
len | Data length to be sent. If data indicates a buffer that does not require specifying the length, the len will be ignored (0 is used in general). But if data indicates a buffer that needs to specify the length, the len must not be 0. If data is NULL, the len is ignored. In this case, if the program that calls the service is waiting for a reply, the reply without any data will be transmitted. If no reply is expected, the tpreturn() will free the data and returns without transmitting any reply, accordingly. |
flags | Not currently supported. Set to 0. If the service is an interactive type, data would not be transferred in the following two cases: The interactive service was already disconnected when tpreturn( ) is called. That is, the caller receives TPEV_DISCONIMM event. In this case, the tpreturn() simply ends the service routine and if it is in a transaction mode, it will roll back the current transaction. In this case, the caller's data cannot be transferred. If the caller does not have the communication control, either TPEV_SVCFAIL or TPEV_SVCERR event will be transferred to the communication starter as mentioned earlier. Regardless of the event that the communication starter receives, no data is transferred. If the communication starter receives the TPEV_SVCFAIL event, the return code could be used as a tpurcode variable of the starter. |
The following values are available for the rval parameter.
rval Value | Description |
---|---|
TPSUCCESS | The service is successfully completed. If data exists and no error occurs during tpreturn() execution, the data will be transmitted. If the caller is in a transaction mode, a part of this transaction will be determined as it can be committed. It allows the other services belonging to the transaction to be committed if all of them are successfully completed and ready for commit. But the transaction will be rolled back if any of them fails. Note that calling the tpreturn() does not mean to complete the entire transaction. In addition, if there is any waiting reply or inter active connection or a job performed within the service tries to roll back the transaction, the message will be sent as a failure even though the caller has returned TPSUCCESS. That is, the receiver of the reply will receive [TPESVCERR] error or TPEV_SVCERR event. Note that, if transaction is rolled back within a service routine, rval is set to TPFAIL. If TPSUCCESS returns in an interactive, TPEV_SVCSUCC even will occur. |
TPFAIL | .The service is ended due to an error in an application program. The error is returned to the program that receives the reply. That is, the call to receive the reply fails and the receiver receives [TPSVCFAIL] value or TPEV_SVCFAIL event. This value cannot sent data. If the caller is in a transaction mode and is autotransaction, tpreturn() will roll back the transaction. The transaction might have already been determined to be rolled back. |
TPEXIT | When a service is returned, this flag is used to forcibly terminate the server process. The process closed via tpexit() can be restarted through TMM. |
TPDOWN | Similar to TPEXIT, but the process terminated through TPDOWN is not restarted using TMM. |
TMSUCCESS | Same as TPSUCCESS. |
TMFAIL | Same as TPFAIL. |
Return Value
The service routine does not return any value to the caller, that is, the Tmax systems. It is a rule that the service routine returns with tpreturn(). If the service routine returns using return sentence of C language, rather than using the tpreturn() , the server will return a service error to the service requester. In addition, connection that has been kept for interactive communication is disconnected forcibly and all the replies that are waiting asynchronously waiting are ignored.
If the server is in a transaction mode, the transaction will be rolled back. In addition, if tpreturn() is used outside the service routine, it will simply return without performing anything.
Error
Since tpreturn() ends a service routine, if an error occurs while a parameter is being processed, it cannot be not transferred to the service routine, the caller.Errors are sent as follows.
Classification | Description |
---|---|
Synchronous and Asynchronous communication | tperrno is set to [TPESVCERR] for a program that receives a service result through tpcall() or tpgetrply(). |
Interactive communication | Generates a TPEV_SVCERR event for the program that uses tpsend() or tprecv(). |
Example
#include <stdio.h> #include <usrinc/atmi.h> SERVICE1(TPSVCINFO *msg) { char *buf; long len; buf=tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processsing } buf=msg->data; data process.... ret=tpcall(“SERVICE2”, buf, sizeof(buf), &buf, &len, TPNOFLAGS); if (ret==-1) { error processing } data process.... if (buf !=”SUCCESS”) { printf(“svc fail..\n”); tpreturn (TPFAIL, -1, NULL,0,0); } else { tpreturn(TPSUCCESS, 0, msg->data, msg->len, 0); } }
Related Functions
tpalloc(), tpcall(), tpconnect(), tpdiscon(), tpgetrply(), tprecv(), tpsend()
The tpforward function ends its own service processing, and forwards a client’s request to a svc service routine.
This function is called at the end of a service routine, which acts like a tpreturn(). Like a tpreturn(), a tpforward() must be called within a service routine controlled by a Tmax system to be correctly returned to the system.
This function forwards a service request to a service named svc using data. The service routine that forwards the request will not receive a reply. After forwarding the request, a service routine returns to the Tmax system. Then, the service can perform other operations. Because a tpforward() does not expect any response from a requester, it can forward a service request to any service without any particular errors.
If a service routine is in a transaction mode, the transaction can be completed only when the transaction originator completes the transaction by executing either a tx_commit() or a tx_rollback(). In other words, like a tpreturn(), a tpforward() does not complete a transaction. If a transaction is originated within a service routine that uses a tx_begin(), the transaction must be completed before a tpforward() is called, either by using a tx_commit() or a tx_rollback(). This means that all services connected by a tpforward() must be or not be in a transaction mode. The finally forwarded server process sends a reply to a client that requested the service first, using a tpreturn(). In other words, a tpforward() shifts the responsibility of sending a reply for a waiting requester, to another server process. This service is available even in between nodes.
A tpforward() must be called after a service routine receives replies for all services requested. The descriptors of unreceived replies are invalidated and a forward request is not transmitted. A tpforward() cannot be called in a interactive communication.
The following shows the tpforward function flow:
Prototype
# include <atmi.h> void tpforward (char *svc, char *data, long len, long flags)
Parameter
Parameter | Description |
---|---|
svc | The name of a service to receive a buffer. |
data | If data is NULL, it must indicate a buffer that has been allocated with a tpalloc(). If a buffer is the same as the one transmitted to a service routine, ta Tmax system must handle this buffer. If a service routine writer attempts to release the buffer, this attempt will fail. However, if the buffer transmitted to a tpforward() is not the same as the one transferred at the time of calling the service, a tpforward() will release the buffer. |
len | A len is the length of data to be transmitted. If data indicates a buffer that does not require a specific length (e.g., a STRUCT Type buffer), len will be ignored and is set to 0. If data is NULL, len will be ignored and a request that has a data length of 0 will be transmitted. A service routine writer cannot regain control after calling a tpforward(), blocking transmission in the form that a TPSIGRSTRT is defined implicitly is used. Therefore, if a signal is generated during a tpforward() operation to stop an operation, processing will continued later. If a blocking condition is encountered, it will wait until a timeout occurs and then sends a service request. |
flags | Not currently supported. Set to TPNOFLAGS. |
Return Value
A service routine does not return any value to a Tmax system, that is, a caller. In other words, a service routine will be declared as void.
Error
When a tpforward() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESVCERR] | Occurs when an invalid buffer is used; a tpacall()/tpconnect() returns a cd; a tpforward() was used instead of a tpreturn() during interactive communication; a TPEV_DISCONIMM event occurred; or an XA operation (tx_begin(), tx_rollback(), and a tx_commit()) failed in a transaction mode. |
[TPETIME] | Occurs when a transaction timeout occurs during a service routine or while a service request is being transmitted. |
Example
#include <stdio.h> #include <usrinc/atmi.h> SWITCH(TPSVCINFO *msg) { int switch; char *buf; buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } strcpy(buf, msg->data); data process… if (switch>5) tpforward(“SERVICE1”, buf, 0, 0); else tpforward(“SERVICE2”, buf, 0, 0); }
Related Functions
tpalloc(), tpconnect(), tpreturn()
The tpsvrinit function processes an initialization of a service routine. This function is called for initializing the main procedure of a Tmax application server program. This routine is called after a server process is executed but no service request has been processed. It is possible to execute Tmax communications or define a transaction within the tpsvrinit() routine.
If the application program does not provide tpsvrinit(), default routine provided by the Tmax is called instead. If the server belongs to a server group that processes transactions, tpsvrinit() calls tx_open() and userlog(), to inform that the server has started successfully.
Command line parameters (CLOPT) of an application program can be transferred to the server, to be processed by tpsvrinit(). See CLOPT item of SERVER section of tmax configuration file. The parameters are transferred through argc and argv.
As getopt() is used within the Tmax server main, optarg, optind and opterr are used for parameter parsing and error detection within the tpsvrinit() .
Prototype
# include <tmaxapi.h> int tpsvrinit (int argc, char **argv)
Parameter
Parameter | Description |
---|---|
argc | The number of command line parameters. |
argv | A command line parameter. |
Return value
Value | Description |
---|---|
0 | A function call was successful. |
Negative number | A function call failed. No service requests are received and a server process is terminated without generating an error. |
Example
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> EXEC SQL INCLUDE sqlca.h; tpsvrinit(int argc, char **argv) { EXEC SQL begin declare section; char user_name[30]; char user_passwd[30]; EXEC SQL end declare section; EXEC SQL CONNECT scott IDENTIFIED BY tiger; return(0); } SERVICE(TPSVCINFO *msg) { int ret, cd; char *buf; 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.... printf(“ Sevice end\n”); EXEC SQL COMMIT WORK RELEASE; tpreturn(TPSUCCESS, buf, strlen(buf), 0); }
Related Functions
tx_open(), tpsvrdone()
The tpsvrdone function sets a routine to be executed when a UCS-type server process is terminated. A separate main of Tmax application server program, i.e., the main() provided by the Tmax systems calls tpsvrdone() before ending a process after finishing all service request handling. When this routine is executed, a server process will still be a part of Tmax but the process will not provide service. It is possible to execute a Tmax communication or define a transaction within the tpsvrdone() routine.
If the tpsvrdone() is keeping an interactive connection, is waiting for asynchronous replies, or returns during a transaction mode, Tmax will disconnect the interactive connection, ignore the asynchronous replies that have been waiting, and stop the transaction. Then, the server will be terminated immediately.
If a program does not provide a tpsvrdone() routine, a default routine provided by Tmax can be called instead. If a server belongs to a server group that processes transactions, the default tpsvrdone() routine will call tx_close() and userlog() to notify that a server will be terminated. If either tpreturn() or tpforward() are called within tpsvrdone(), a routine will simply return without performing any operations.
Prototype
# include <tmaxapi.h> int tpsvrdone(void)
Return Value
A tpsvrdone() is a function used to perform necessary jobs before a developer ends a server process. Due to this, it does not have a return value and an error cannot be generated.
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.... tpsvrdone(); } void tpsvrdone() { printf(“ Sevice end\n”); EXEC SQL COMMIT WORK RELEASE; }
Related Functions
tx_close(), tpsvrinit()
The tpsvrthrinit function is provided only by Multithread and Multicontext servers. A Tmax server provides a tpsvrinit function that performs an initialization process when a server process starts. Multithread and Multicontext servers provide an initialization function for each thread when a thread is created for service threads managed by a thread pool after a tpsvrinit function is called.
A thread pool works according to MINTHR and MAXTHR fields, so when a server process initially starts, the same number of service threads will be created as the number set in MINTHR and they will call a tpsvrthrinit(). After that, if there are no idle service threads in a thread pool, service threads will be created as needed up to a value set as a MAXTHR. If MINTHR is 0, no service threads will be created when a process starts, so only a upsvrinit() will be called and the process will wait until a service request is received.
This function is processed after a tpsvrinit() is called and before each thread handles a service request. The same parameters with those delivered to a tpsvrinit() are delivered. These parameters are set in a CLOP field in the SERVER section of a configuration file. When writing this function, a user must remember that the parameters delivered to a spsvrinit() and a tpsvrthrinit() must be the same. For more information, refer to "10.1.3. tpsvrinit".
Prototype
# include <tmaxapi.h> int tpsvrthrinit (int argc, char **argv)
Parameter
Parameter | Description |
---|---|
argc | The number of command line parameters. |
argv | A command line parameter. |
Return Value
When performing an initialization using a tpsvrthrinit(), if a process fails, a user will return -1. After a server process calls a tpsvrthrinit(), if -1 is returned, the server process will cancel the starting process and will be terminated.
Value | Description |
---|---|
0 | A function call was successful. |
Negative number | A function call failed. |
Example
#include <stdio.h> #include <pthread.h> #include <usrinc/atmi.h> void tpsvrthrinit(int argc, char **argv) { param_t *param; param = get_threadspecificdata(); if (pthread_create(¶m->tid, NULL, THREAD_ROUTINE, (void *)param) != 0) { printf("user_create_thread failed\n"); return -1; } pthread_mutex_init(¶m->mutex, NULL); pthread_cond_init(¶m->cond, NULL); return 0; } void tpsvrthrdone() { void *ret; param_t *param; param = get_threadspecificdata(); param->state = EXIT; pthread_cond_signal(¶m->cond); pthread_join(param->tid, &ret); pthread_mutex_destroy(¶m->mutex); pthread_cond_destroy(¶m->cond); printf("user_create_thread destroyed\n"); } SERVICE(TPSVCINFO *msg) { param_t *param; param = get_threadspecificdata(); ... ret = tpgetctxt(¶m->ctxtid, TPNOFLAGS); ret = pthread_cond_signal(¶m->cond); ... } void *THREAD_ROUTINE(void *arg) { param_t *param; param = (param_t *)arg; while(1) { pthread_mutex_lock(¶m->mutex); { pthread_cond_wait(¶m->cond, ¶m->mutex); if (param->state == EXIT) break; if (tpsetctxt(param->ctxtid, TPNOFLAGS) == -1) { printf("tpsetctxt(%d) failed, [tperrno:%d]", param->ctxtid, tperrno); return NULL; } tpcall("MTOUPPER", sndbuf, 0, &rcvbuf, &rcvlen, TPNOFLAGS); ... if (tpsetctxt(TPNULLCONTEXT, TPNOFLAGS) == -1) { printf("tpsetctxt(TPNULLCONTEXT) failed, [tperrno:%d]", tperrno); return NULL; } ... } pthread_mutex_unlock(¶m->mutex); } return NULL; }
Related Funciton
tpsvrthrdone()
The tpsvrthrdone function is provided only by Multithread and Multicontext servers. A MultiThread and a MultiContext server terminates service threads before performing a tpsvrdone when a server process is terminated. If this function is defined, a service thread will call this function automatically when it is terminated. Developers needs to write a routine to process required jobs before a thread is terminated. In this function, a Tmax communication or a transaction can be performed. If a function is returned without completing jobs, all incomplete jobs will be ignored when a thread is terminated.
A client can allocate other previously created context to a current client using a function. Most ATMI functions are per-context based. A client can use multiple contexts, but only one context is used at a time. For example, if context1 calls a tpacall(), context1 must be set as the current context at the moment of calling a tpgetrply() to perform a tpgetrply() normally even when other context was used. For more information, refer to "10.1.4. tpsvrdone".
Prototype
# include <tmaxapi.h> int tpsvrthrdone(void)
Return Value
A tpsvrthrdone() is written by a developer to perform necessary jobs before terminating a server process. This function neither has any return value nor generates an error.
Example
Refer to example in the tpsvrthrinit() topic.
Related Function
tpsvrthrinit()
This function returns the context ID, which is currently set in a thread, as the first parameter. This function is used differently in the client and server. For more information, refer to "9.14.1. tpgetctxt".
This function sets the current context. This function is used differently in the client and server. For more information, refer to "9.14.2. tpsetctxt".
This function is available in a server. The tpsendtocli function sends an unrequested message to a specified client. While a tpbroadcast() function sends an unrequested message to any client connected to a Tmax systems, this function sends a message only to a client that has requested a service provided by a server process.
Prototype
# include <tmaxapi.h> int tpsendtocli (int clid, char *data, long len, long flags)
Parameter
Parameter | Description |
---|---|
clid | A unique client number obtained with a tpgetclid(). |
data | A buffer allocated by a tpalloc(). If data indicates a buffer that does not require a specific length, a len is ignored (0 is used in general). If data indicates a buffer that needs to have a length specified, a len must not be 0. In addition, when data is NULL, a len will be ignored. |
len | A buffer length to be transmitted. |
flags | Flag values are listed in the table below. |
The following are possible flag values:
Flag | Description |
---|---|
TPNOFLAG(0) | Messages must be received by a client. However it might take a long time for a client to receive a requested result if a client cannot process received messages fast enough. |
TPUDP | This flag does not mean that data communication with a client is UDP. When a caller transmits data, it is impossible to transfer the data because the internal buffer that the data is transmitted to is filled with messages to be transferred. This flag means that data may be discarded in that situation. In other words, it means that data might be lost similarly to a communication in a UDP. |
TPFLOWCONTROL | Checks the status of a client to decide whether another request message can be sent or not. If there are too many accumulated messages, a tpsendtocli() will return a value of -1 and a tperrno will be set to TPEQFULL. This flag is used to reduce the load of a Tmax system. |
Return Value
Value | Description |
---|---|
1 | A function call was successful. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpsendcli() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPEBADDESC] | An invalid clid. |
[TPEPROTO] | A tpsendcli() was called from an invalid state. |
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. |
[TPEOS] | An operating system error occurred. |
[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()
The tpgetclid function retrieves the ID of a client connected to a Tmax system. This ID is a unique number in a domain system. In other words, even though a domain system is built up with multiple nodes, unique numbers are given to each client. This function is available only for a server. An ID is retrieved so that other functions, such as a tpsendtocli() function, can use it for sending a message to a client.
Prototype
#include <tmaxapi.h> int tpgetclid(void)
Return Value
Value | Description |
---|---|
A positive integer | A function call was successful and a positive integer value that corresponds to a client number is returned. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpgetclid() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A tpgetclid() was called from an invalid state. For example, it was used in a client program. |
[TPEOS] | An operating system error occurred. |
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 process } ret=tpsendtocli(clid, buf, strlen(buf), 0); if (ret==-1) { error processing } data process…. tpreturn(TPSUCCESS,0,buf, strlen(buf), 0); }
Related Function
tpsendtocli()
The tpchkclid function checks if a client corresponding to an ID is connected to a node where a server process resides in. When developing a RDP type server program, if a service routine stores a connected client ID and a usermain() routine sends a message to a tpsendtocli(), unnecessary errors can be prevented.
If a client is not directly connected to the node where a server process resides in a RDP type, a tpsendtocli() cannot be used.
Prototype
#include <tmaxapi.h> int tpchkclid(int clid)
Parameter
Parameter | Description |
---|---|
clid | A unique client number obtained with a tpgetclid(). |
Return Value
Value | Description |
---|---|
-2 | A client is not the client that is connected to a local node. |
-1 | A client is not connected. |
1 | A client is connected normally. |
Error
When a tpchkclid() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPEINVAL] | A client is not connected in a local node or an invalid client number was entered. |
[TPENOREADY] | A client is not normally connected to a server. |
Example
int _discon(char **buf) { int clid, n; clid = tpgetclid(); n = tpchkclid(clid); if (n < 0) { printf(“Invalid Client\n”); return -1; } ... }
Related Function
tpgetclid()
The following describes the functions that are used in a UCS type server program.
API Schedule related API
In a UCS type, the user-developed usermain() routine is used like the main() routine so the usermain() routine must handle various messages received from TMM and CLH using a scheduling API.
Function | Description |
---|---|
tpschedule | Checks if a message is received in CLH or in a user-defined FD within a specified amount of time (sec). |
tpuschedule | Checks if a message is received in CLH or in a user-defined FD within a specified amount of time (microsec). |
Socket FD related macros
Socket related macros are used to use a user socket FD in a USC scheduler such as tpschedule(). These macros are similar to FD_SET, FD_CLR, and FD_ISSET, which are used in a regular network program.
Service Forwarding
When operating with a general host system, a server program, instead of a client, opens a socket to send and receive data. If the connection to an external host system is unstable or the service runtime is long, the server program enters a blocking state and cannot perform additional services.
To resolve this situation, a service routine stores only the client information after receiving a client request. The service routine then sends the request to an external host. The usermain() routine is used to send the response to another service routine with the stored client information. If the service routine sends the result value to a client, a server program can perform all processes without being blocked.
Function | Description |
---|---|
tpsavectx | Stores the client information in a server library. |
tpgetctx | Stores the CTX_T structure value of the server library to a user variable. |
tpcancelctx | Deletes the CTX_T structure content from a server library. |
tprelay | Sends client maintenance to another service routine with the client information/transaction information, which was obtained using tpgetctx() or tpsavectx(). Similar to tpforward(), which is used in a TCS type server program. |
Asynchronous communication in the usermain() routine
If asynchronous communication that requires a long service time is used in the usermain() routine, tpgetreply() may cause blocking, which prolongs the schedule. If the service result is processed through a callback function instead of tpgetreply(), the result value can be processed without affecting the schedule. However, if asynchronous communication occurs every time in the usermain(), which has a short loop time, the maximum number of asynchronous services may be exceeded, which generates an error.
For more information about each function, refer to "Tmax Reference Guide".
The tpschedule function waits for data to be received in a UCS-type server process. It is available only in a UCS-type server process. A tpschedule() sleeps until a maximum timeout value and returns data immediately when data is received.
A tpschedule() function is returned after a corresponding service is automatically executed when data is received. Therefore, a user must not execute any service after data is received.
Note that this is an UCS-type service program, so a service will be performed unconditionally by systems.
Prototype
#include <ucs.h> int tpschedule(int timeout)
Parameter
Parameter | Description |
---|---|
timeout | The amount of time to wait in seconds.
|
Return Value
Value | Description |
---|---|
Positive Integer | A function was performed successfully so data will be received. |
-1 | Data was not received until a timeout or an error occurred due to a function execution failure. If data was not received until a timeout, -1 will be returned and the number 13 error (TPETIME) will be set in a tperrno. In other cases, an error code will be set in a tperrno. |
Error
When a tpschedule() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. |
[TPEOS] | An operating system error occurred. |
[TPETIME] | Data was not received before a timeout. |
[TPEPROTO] | A tpschedule() was called from an invalid state. For example, a tpschedule() was called 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()
The tpuschedule function waits for data to be received in a UCS-type server process. It is available only in UCS-type server processes. A tpuschedule() will sleep until a maximum timeout value is reached and will return data immediately when data is received.
Prototype
#include <ucs.h> int tpuschedule (int timeout)
Parameter
Parameter | Description |
---|---|
timeout | The amount of time to wait in microseconds.
|
Return Value
Value | Description |
---|---|
0 | Data was not received before a timeout. |
Positive integer | Data was received before a timeout. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpuschedule() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A Tmax system error occurred. Detailed error information is recorded in a system log file. |
[TPEOS] | An operating system error occurred. |
Example
... #include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/ucs.h> int usermain(int argc, char *argv[]) { ... while(1) { ... tpuschedule(3000000); ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf, (long *)&rlen, TPNOFLAGS); if (ret == -1) { error processing } ... } }
Related Function
tpschedule()
The tpsetfd function registers a socket fd in an external socket scheduler of a UCS process. This is used to turn on a socket fd, which uses a UCS type process. A UCS scheduler tests a message received in a socket fd as well as messages received in a TMM and a CLH. If a message is received in a user defined socket, a tpschedule() will return a normal result (UCS_USER_MSG) without a separate process. To know in which socket a message has been received, a tpistfd() must be used.
Prototype
#include <ucs.h> int tpsetfd (int fd)
Parameter
Parameter | Description |
---|---|
fd | Sets a socket fd to be registered. |
Return Value
Value | Description |
---|---|
1 | A function call was successful. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpsetfd() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in the system log file. |
[TPEOS] | An operating system error occurred. |
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)){ /* Reads a buffer from a 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()
The tpissetfd function is used to check if data is received in a socket fd in a UCS process. It is used for scheduling an external socket in a UCS-type server process.
Prototype
#include <ucs.h> int tpissetfd (int fd)
Parameter
Parameter | Description |
---|---|
fd | An internal fd of a fdset to be tested. |
Return Values
Value | Description |
---|---|
A positive number | A message was received. |
0 | A message was not received. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpissetfd() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. |
[TPEOS] | An operating system error occurred. |
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)){ /* Reads a buffer from a 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()
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
Value | Description |
---|---|
1 | A function call was successful. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpclrfd() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. |
[TPEOS]an | An operating system error occurred. |
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)){ /* Reads a buffer from a 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()
The tpsavectx function manages client information in a UCS process. This function is used along with a 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 a client.
A 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
A client makes a service request to svc1.
svc1 calls svc2 using a tpforward (...TPNOREPLY).
svc2 is a service which runs in a UCS process, and it calls a tpsavectx() in a service routine to save client information to communicate with an external system.
A result is sent to a usermain and forwarded to svc3 via a tprelay(). svc3 considers that svc2 has called it via a tpforward(), so it finally sends a result to the client.
In this process, because svc1 calls a service via a tpforward with a flag set to TPNOREPLY, 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 a sending and receiving process. It can organize a relatively simple system with efficient system management.
Prototype
#include <ucs.h> CTX_T * tpsavectx(void)
Return Value
Value | Description |
---|---|
CTX_T | A function call was successful. |
NULL | A function call failed. A tperrno is set to an error code. |
Error
When a tpsavectx() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPEPROTO] | A tpsavectx() must be used within a service routine. Otherwise, TPEPROTO will be returned. Accordingly, it cannot be used with a tpsvrinit() or a tpsvrdone(). |
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. The error occurred during memory allocation. |
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()
The tpgetctx function copies current client information to a CTX_T structure that was declared and allocated by a user. If a tpgetctx() is used, and if a tprelay() is not used to use information, a client will keep waiting for a response even after a service routine completes.
The information obtained by a tpgetctx() cannot be canceled with a tpcancelctx(), so a tprelay() must be used only in a service routine.
Prototype
#include <tmaxapi.h> int tpgetctx (CTX_T *ctxp)
Parameter
Parameter | Description |
---|---|
ctxp | Receives client information that was stored with a tpsavectx(), to a CTX_T structure. |
Example
RELAY_SVC(TPSVCINFO *msg) { CTX_T *ctxp; ctxp=(CTX_T *)malloc(sizeof(CTX_T); .... ret = tpgetctx(ctxp); if (ret<0) { error process routine } ..... }
The tpcancelctx function cancels a corresponding structure content among information saved using a tpsavectx(). Even when a tprelay() is not performed, if a service routine is terminated, a result will be returned normally.
A tpgetctx() can be used only in a service routine.
Prototype
#include <ucs.h> int tpcancelctx(CTX_T *ctxp);
Parameter
Parameter | Description |
---|---|
ctxp | Deletes a CTX_T structure saved in a library. |
The following is a CTX_T structure definition:
typedef struct { int version[4]; char data[CTX_USR_SIZE - 16]; } CTX_T;
Example
RELAY_SVC(TPSVCINFO *msg) { ..... ctxp = (CTX_T *)tpsavectx(); ..... ret=tpcancelctx(ctxp); if (ret<0) { error process routine } ..... tpreturn(TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS); }
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 a 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 a tpsavcctx() or a tpgetctx() but before a request is sent to another service using a tprelay(), an error response will be sent to a service caller automatically. For more information about error responses, refer to the CTX_EREPLY option in the SERVER section of an environment configuration. These operations are supported for Tmax versions v5.0 SP2 or later. In earlier versions, an error response will not be sent to a service caller.
Prototype
#include <ucs.h> int tprelay(char *svc, char *data, long len, long flags, CTX_T *ctxp);
Parameter
Parameter | Description |
---|---|
svc | A service name registered in a Tmax configuration file. |
data | Data to be transmitted when a service is called. If data is not NULL, it must indicate a buffer that has been allocated with a tpalloc(). |
len | The length of data to be sent. It must be specified for CARRAY, X_OCTET, and Structure array Types. |
flags | Not currently supported. Set to TPNOFLAGS. |
ctxp | An information structure retrieved through a tpgetctx() or a tpsavectx(). |
Return Value
Value | Description |
---|---|
1 | A function call was successful. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tprelay() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPEINVAL] | An invalid parameter. For example, a ctxp is NULL or an incorrect buffer was used. |
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. |
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()
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 a tpgetrply() in a UCS-type server process.
Prototype
# include <ucs.h> int tpregcb (UcsCallback)
Parameter
Parameter | Description |
---|---|
UcsCallback | Sets a Callback function that handles a response for an asynchronous request in a UCS. |
Value
Return Value | Description |
---|---|
1 | A function call was successful. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpregcb() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. |
[TPEOS] | An operating system error occurred. |
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) { printf(“data....%s\n”, reply->data); }
Related Function
tpunregcb()
The tpunregcb function is used to reset a routine that receives a response for an asynchronous request. It is used in a UCS-type server process.
Prototype
#include <ucs.h> int tpunregcb (void)
Value
Value | Description |
---|---|
1 | A function call was successful. |
-1 | A function call failed. A tperrno is set to an error code. |
Error
When a tpunregcb() fails to execute, a tperrno will be set to one of the following values:
Error Code | Description |
---|---|
[TPESYSTEM] | A Tmax system error occurred. Detailed error information will be recorded in a system log file. |
[TPEOS] | An operating system error occurred. |
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); }
See also
tpregcb()