Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
3.  rpcgen Programming Guide Compile-Time Flags Compile-Time C-style Mode  Previous   Contents   Next 
   
 

The server-side procedure in default mode is shown in the following code example.


Example 3-13 Default Mode Server Stub

#include "add.h"
int *
add_1(argp, rqstp)
	add_arg *argp;
	struct svc_req *rqstp;
{
	static int result;

	result = argp->first + argp->second;
	return(&result);
}

Compile-Time MT-Safe Code

By default, the code generated by rpcgen is not MT safe. It uses unprotected global variables and returns results in the form of static variables. The -M flag generates MT-safe code that can be used in a multithreaded environment. This code can be used with the C-style flag, the ANSI C flag, or both.

An example of an MT-safe program with this interface follows. The rpcgen protocol file is msg.x, shown in the following code example.


Example 3-14 MT-Safe Program: msg

program MESSAGEPROG {
version PRINTMESSAGE {
        int PRINTMESSAGE(string) = 1;
        } = 1;
} = 0x4001;

A string is passed to the remote procedure, which prints it and returns the length of the string to the client. The MT-safe stubs are generated with the rpcgen -M msg.x command.

Client-side code that could be used with this protocol file is shown in the following code example.


Example 3-15 MT-Safe Client Stub

#include "msg.h"
 
void
messageprog_1(host)
	char *host;
{
	CLIENT *clnt;
	enum clnt_stat retval_1;
	int result_1;
	char * printmessage_1_arg;
 
	clnt = clnt_create(host, MESSAGEPROG, 
									PRINTMESSAGE,
									"netpath");
	if (clnt == (CLIENT *) NULL) {
		clnt_pcreateerror(host);
		exit(1);
	}
	printmessage_1_arg = 
							(char *) malloc(256);
	strcpy(printmessage_1_arg, "Hello World");
 
	retval_1 = printmessage_1(&printmessage_1_arg,
											&result_1,clnt);
	if (retval_1 != RPC_SUCCESS) {
		clnt_perror(clnt, "call failed");
	}
	printf("result = %d\n", result_1);
 
	clnt_destroy(clnt);
}
 
main(argc, argv)
	int argc;
	char *argv[];
{
	char *host;
 
	if (argc < 2) {
		printf("usage:  %s server_host\n", argv[0]);
		exit(1);
	}
	host = argv[1];
	messageprog_1(host);
}

A pointer to both the arguments and the results needs to be passed in to the rpcgen-generated code in order to preserve re-entrancy. The value returned by the stub function indicates whether this call is a success or a failure. The stub returns RPC_SUCCESS if the call is successful. Compare the MT-safe client stub, generated with the -M option, and the MT-unsafe client stub shown in Example 3-16. The client stub that is not MT-safe uses a static variable to store returned results and can use only one thread at a time.


Example 3-16 Client Stub (MT Unsafe)

int *
printmessage_1(argp, clnt)
	char **argp;
	CLIENT *clnt;
{
	static int clnt_res;
	memset((char *)&clnt_res, 0, 
								sizeof (clnt_res));
	if (clnt_call(clnt, PRINTMESSAGE,
		(xdrproc_t) xdr_wrapstring, 
										(caddr_t) argp,
		(xdrproc_t) xdr_int, (caddr_t) 
										&clnt_res,
		TIMEOUT) != RPC_SUCCESS) {
		return (NULL);
	}
	return (&clnt_res);
}

The server side code is shown in the following example.


Note - When compiling a server that uses MT-safe mode, you must link in the threads library. To do so, specify the -lthread option in the compile command.



Example 3-17 MT-Safe Server Stub

#include "msg.h"

#include <syslog.h>
 
bool_t
printmessage_1_svc(argp, result, rqstp)
	char **argp;
	int *result;
	struct svc_req *rqstp;
{
	int retval;
 
	if (*argp == NULL) {
		syslog(LOG_INFO, "argp is NULL\n");
		*result = 0;
	}
	else {
		syslog("argp is %s\n", *argp);
		*result = strlen (*argp);
	}
	retval = 1;
	return (retval);
}
 
int
messageprog_1_freeresult(transp, xdr_result, result)
	SVCXPRT *transp;
	xdrproc_t xdr_result;
	caddr_t result;
{
	/*
	 * Insert additional freeing code here,
 * if needed
	 */
	(void) xdr_free(xdr_result, result);}

 
 
 
  Previous   Contents   Next