![]() |
![]() |
|
|
Writing Code to Enable Multicontexting and Multithreading in an ATMI Server
This topic includes the following sections:
Note: The instructions and sample code provided in this section refer to the C library functions provided by the BEA Tuxedo system. (See the BEA Tuxedo C Function Reference for details.) Equivalent COBOL routines are not available because multithreading (which is required to create a multicontexted server) is not supported for COBOL applications.
Context Attributes
When writing your code, keep in mind the following considerations about contexts:
Coding Rules for a Multicontexted ATMI Server
Keep in mind the following rules for coding multicontexted servers:
If this rule is violated, then tpreturn() or tpforward() writes a message to the user log, indicates TPESVCERR to the caller, and returns control to the main server dispatch loop. The threads that had been in the context where the invalid tpreturn() was done are placed in an invalid context.
Initializing and Terminating ATMI Servers and Server Threads
To initialize and terminate your servers and server threads, you can use the default functions provided by the BEA Tuxedo system or you can use your own.
Default Functions for Initialization and Termination
To . . . |
Use the default function |
---|---|
Initialize a server |
|
Initialize a server thread |
|
Terminate a server |
|
Terminate a server thread |
Programming an ATMI Server to Create Threads You may create additional threads within an application server, although most applications using multicontexted servers use only the dispatched server threads created by the system. This section provides instructions for doing so. Creating Threads You may create additional threads within an application server by using OS threads functions. These new threads may operate independently of the BEA Tuxedo system, or they may operate in the same context as one of the server-dispatched threads. Associating Threads with a Context Initially, application-created server threads are not associated with any server-dispatched context. If called before being initialized, however, most ATMI functions perform an implicit tpinit(). Such calls introduce problems because servers are prohibited from calling tpinit(). (If a server process calls tpinit(), tpinit() returns -1 and sets tperrno(5) to TPEPROTO.) Therefore, an application-created server thread must associate itself with an existing context before calling any ATMI functions. To associate an application-created server thread with an existing context, you must write code that implements the following procedure.
If this rule is not observed, then tpforward() or tpreturn() fails and indicates a service error to the caller.
Sample Code for Creating an Application Thread in a Multicontexted ATMI Server
For those applications with a need to create an application thread in a server, the following code sample shows a multicontexted server in which a service creates another thread to help perform its work. Operating system (OS) threads functions differ from one OS to another. In this sample POSIX and ATMI functions are used.
Notes: In order to simplify the sample, error checking code is not included. Also, an example of a multicontexted server using only threads dispatched by the BEA Tuxedo system is not included because such a server is coded in exactly the same way as a single-contexted server, as long as thread-safe programming practices are used.
Code Sample for Creating a Thread in a Multicontexted Server
#include <pthread.h>
#include <atmi.h>
void *withdrawalthread(void *);
struct sdata {
TPCONTEXT_T ctxt;
TPSVCINFO *svcinfoptr;
};
void
TRANSFER(TPSVCINFO *svcinfo)
{
struct sdata transferdata;
pthread_t withdrawalthreadid;
tpgetctxt(&transferdata.ctxt, 0);
transferdata.svcinfoptr = svcinfo;
pthread_create(&withdrawalthreadid, NULL, withdrawalthread, &transferdata);
tpcall("DEPOSIT", ...);
pthread_join(withdrawalthreadid, NULL);
tpreturn(TPSUCCESS, ...);
}
void *
withdrawalthread(void *arg)
{
tpsetctxt(arg->ctxt, 0);
tpopen();
tpcall("WITHDRAWAL", ...);
tpclose();
return(NULL);
}
The previous example accomplishes a funds transfer by invoking the DEPOSIT service in the originally dispatched thread, and WITHDRAWAL in an application-created thread. This example is based on the assumption that the resource manager being used allows a mixed model such that multiple threads of a server can be associated with a particular database connection without all threads of the server being associated with that instance. Most resource managers, however, do not support such a model.
A simpler way to code this example is to avoid the use of an application-created thread. To obtain the same concurrency provided by the two calls to tpcall() in the example, substitute two calls to tpacall() and two calls to tpgetrply() in the server-dispatched thread.
See Also
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|