BEA Logo BEA Tuxedo Release 7.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   Tuxedo Doc Home   |   Programming   |   Topic List   |   Previous   |   Next   |   Contents

   Programming a BEA Tuxedo Application Using C

Writing Code to Enable Multicontexting in a Client

To enable multicontexting in a client, you must write code that:

If your application uses transactions, you should also keep in mind the consequences of multicontexting for transactions. For more information, see Coding Rules for Transactions in a Multithreaded/Multicontexted Application.

Note: The instructions and sample code provided in this section refer to the C library functions provided by the BEA Tuxedo system. Equivalent COBOL library functions are also available; for details, see the BEA Tuxedo COBOL Function Reference.

Context Attributes

When writing your code, keep in mind the following considerations about contexts:

Setting Up Multicontexting at Initialization

When a client is ready to join an application, specify tpinit() with the TPMULTICONTEXTS flag set, as shown in the following sample code.

Sample Code for a Client Joining a Multicontexted Application


#include <stdio.h>
#include <atmi.h>

TPINIT * tpinitbuf;

main()
{
tpinitbuf = tpalloc(TPINIT, NULL, TPINITNEED(0));

tpinitbuf->flags = TPMULTICONTEXTS;
.
.
.
if (tpinit (tpinitbuf) == -1) {

    		ERROR_PROCESSING_CODE
}
.
.
.

}


A new application association is created and assigned to the BEA Tuxedo domain specified in the TUXCONFIG or WSENVFILE/WSNADDR environment variable.

Note: In any one process, either all calls to tpinit() must include the TPMULTICONTEXTS flag or else no call to tpinit() may include this flag. The only exception to this rule is that if all of a client's application associations are terminated by successful calls to tpterm(), then the process is restored to a state in which the inclusion of the TPMULTICONTEXTS flag in the next call to tpinit() is optional.

Implementing Security for a Multicontexted Client

Each application association in the same process requires a separate security validation. The nature of that validation depends on the type of security mechanisms used in your application. In a BEA Tuxedo application you might, for example, use a system-level password or an application password.

As the programmer of a multicontexted application, you are responsible for identifying the type of security used in your application and implementing it for each application association in a process.

Synchronizing Threads Before a Client Termination

When you are ready to disconnect a client from an application, invoke tpterm(). Keep in mind, however, that in a multicontexted application tpterm() destroys the current context. All the threads operating on that context are affected. As the application programmer, you must carefully coordinate the use of multiple threads to make sure that tpterm() is not called unexpectedly.

It is important to avoid calling tpterm() on a context while other threads are still working on that context. If such a call to tpterm() is made, the BEA Tuxedo system places the other threads that had been associated with that context in a special invalid context state. When in the invalid context state, most ATMI functions are disallowed. A thread may exit from the invalid context state by calling tpsetctxt(3c) or tpterm(). Most well designed applications never have to deal with the invalid context state.

Note: The BEA Tuxedo system does not support multithreading in COBOL applications.

Switching Contexts

The following is a summary of the coding steps that might be made by a client that calls services from two contexts.

  1. Set the TUXCONFIG environment variable to the value required by firstapp.

  2. Join the first application by calling tpinit() with the TPMULTICONTEXTS flag set.

  3. Obtain a handle to the current context by calling tpgetctxt(3c).

  4. Switch the value of the TUXCONFIG environment variable to the value required by the secondapp context, by calling tuxputenv().

  5. Join the second application by calling tpinit() with the TPMULTICONTEXTS flag set.

  6. Get a handle to the current context by calling tpgetctxt(3c).

  7. Beginning with the firstapp context, start toggling between contexts by calling tpsetctxt(3c).

  8. Call firstapp services.

  9. Switch the client to the secondapp context (by calling tpsetctxt(3c)) and call secondapp services.

  10. Switch the client to the firstapp context (by calling tpsetctxt(3c)) and call firstapp services.

  11. Terminate the firstapp context by calling tpterm().

  12. Switch the client to the secondapp context (by calling tpsetctxt(3c)) and call secondapp services.

  13. Terminate the secondapp context by calling tpterm().

The following sample code provides an example of these steps.

Note: In order to simplify the sample, error checking code is not included.

Sample Code for Switching Contexts in a Client


#include <stdio.h>
#include "atmi.h" /* BEA Tuxedo header file */

#if defined(__STDC__) || defined(__cplusplus)
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{

TPINIT * tpinitbuf;
TPCONTEXT_T firstapp_contextID, secondapp_contextID;
/* Assume that TUXCONFIG is initially set to /home/firstapp/TUXCONFIG*/
/*
* Attach to the BEA Tuxedo system in multicontext mode.
*/
tpinitbuf=tpalloc(TPINIT, NULL, TPINITNEED(0));
tpinitbuf->flags = TPMULTICONTEXTS;

if (tpinit((TPINIT *) tpinitbuf) == -1) {
(void) fprintf(stderr, "Tpinit failed\n");
exit(1);
}

/*
* Obtain a handle to the current context.
*/
tpgetctxt(&firstapp_contextID, 0);

/*
* Use tuxputenv to change the value of TUXCONFIG,
* so we now tpinit to another application.
*/
tuxputenv("TUXCONFIG=/home/second_app/TUXCONFIG");

/*
* tpinit to secondapp.
*/
if (tpinit((TPINIT *) tpinitbuf) == -1) {
(void) fprintf(stderr, "Tpinit failed\n");
exit(1);
}

/*
* Get a handle to the context of secondapp.
*/
tpgetctxt(&secondapp_contextID, 0);

/*
* Now you can alternate between the two contexts
* using tpsetctxt and the handles you obtained from
* tpgetctxt. You begin with firstapp.
*/

tpsetctxt(firstapp_contextID, 0);

/*
* You call services offered by firstapp and then switch
* to secondapp.
*/

tpsetctxt(secondapp_contextID, 0);

/*
* You call services offered by secondapp.
* Then you switch back to firstapp.
*/

tpsetctxt(firstapp_contextID, 0);

/*
* You call services offered by firstapp. When you have
* finished, you terminate the context for firstapp.
*/

tpterm();

/*
* Then you switch back to secondapp.
*/

tpsetctxt(secondapp_contextID, 0);
/*
* You call services offered by secondapp. When you have
finished, you terminate the context for secondapp and
end your program.
*/

tpterm();

return(0);
}


Handling Unsolicited Messages

For each context in which you want to handle unsolicited messages, you must set up an unsolicited message handler or use the process handler default if you have set one up.

If tpsetunsol() is called from a thread that is not associated with a context, a per-process default unsolicited message handler for all new tpinit() contexts created is established. A specific context may change the unsolicited message handler for that context by calling tpsetunsol() again when the context is active. The per-process default unsolicited message handler may be changed by again calling tpsetunsol() in a thread not currently associated with a context.

Set up the handler in the same way you set one up for a single-threaded or single-contexted application. See tpsetunsol() for details.

You can use tpgetctxt(3c) in an unsolicited message handler if you want to identify the context in which you are currently working.

Coding Rules for Transactions in a Multithreaded/Multicontexted Application

The following consequences of using transactions should be kept in mind while you are writing your application:

See Also