ONC+ Developer's Guide

MT Auto Mode

In the Auto mode, the RPC library creates and manages threads. The service developer invokes a new interface call, rpc_control(), to put the server into MT Auto mode before invoking the svc_run() call. In this mode, the programmer needs only to ensure that service procedures are MT safe.

rpc_control() enables applications to set and modify global RPC attributes. At present, this function supports only server-side operations. The following table shows the rpc_control() operations defined for Auto mode. See also the rpc_control(3NSL) man page for additional information.

Table 7–1 rpc_control() Library Routines

Routine 

Description 

RPC_SVC_MTMODE_SET()

Set multithread mode 

RPC_SVC_MTMODE_GET()

Get multithread mode 

RPC_SVC_THRMAX_SET()

Set maximum number of threads 

RPC_SVC_THRMAX_GET()

Get maximum number of threads 

RPC_SVC_THRTOTAL_GET()

Total number of threads currently active 

RPC_SVC_THRCREATES_GET()

Cumulative total number of threads created by the RPC library 

RPC_SVC_THRERRORS_GET()

Number of thr_create() errors within RPC library


Note –

All of the get operations in Table 7–1, except RPC_SVC_MTMODE_GET(), apply only to the Auto MT mode. If used in MT User mode or the single-threaded default mode, the results of the operations might be undefined.


By default, the maximum number of threads that the RPC server library creates at any time is 16. If a server needs to process more than 16 client requests concurrently, the maximum number of threads must be set to the desired number. This parameter can be set at any time by the server. It enables the service developer to put an upper bound on the thread resources consumed by the server. Example 7–1 is an example RPC program written in MT Auto mode. In this case, the maximum number of threads is set at 20.

MT performance is enhanced if the function svc_getargs() is called by every procedure other than NULLPROCS, even if there are no arguments (you can use xdr_void() in this case). This is true for both the MT Auto and MT User modes. For more information on this call, see the rpc_svc_calls(3NSL) man page.


Note –

You must link in the thread library when writing RPC multithreaded-safe applications. The thread library must be the last named library on the link line. Specify the -lthread option in the compile command.


The following example illustrates the server in MT Auto mode. To compile this program, type cc time_svc.c -lnsl -lthread.


Example 7–1 Server for MT Auto Mode

#include <stdio.h>

		#include <rpc/rpc.h>
		#include <synch.h>

		#include <thread.h>
		#include "time_prot.h"
 
		void time_prog();
 
		main(argc, argv)
		int argc;
		char *argv[];
		{
		int transpnum;
		char *nettype;
		int mode = RPC_SVC_MT_AUTO;
		int max = 20;      /* Set maximum number of threads to 20 */
 
		if (argc > 2) {
			fprintf(stderr, "usage: %s [nettype]\n", argv[0]);
			exit(1);
		}
 
		if (argc == 2)
			nettype = argv[1];
		else
			nettype = "netpath";
 
		if (!rpc_control(RPC_SVC_MTMODE_SET, &mode)) {
			printf("RPC_SVC_MTMODE_SET: failed\n");
			exit(1);
		}
		if (!rpc_control(RPC_SVC_THRMAX_SET, &max)) {
			printf("RPC_SVC_THRMAX_SET: failed\n");
			exit(1);
		}
		transpnum = svc_create( time_prog, TIME_PROG, TIME_VERS,
 			nettype);
 
		if (transpnum == 0) {
			fprintf(stderr, "%s: cannot create %s service.\n",
			argv[0], nettype);	
			exit(1);
		}
		svc_run();
	}
 
	/*
	 * The server dispatch function.
	 * The RPC server library creates a thread which executes
 * the server dispatcher routine time_prog().  After which
 * the RPC library destroys the thread.
 */
 
	static void
	time_prog(rqstp, transp)
		struct svc_req *rqstp;
		SVCXPRT *transp;
	{
 
		switch (rqstp->rq_proc) {
			case NULLPROC:
				svc_sendreply(transp, xdr_void, NULL);
				return;
			case TIME_GET:
				dotime(transp);
				break;
			default:
				svcerr_noproc(transp);
				return;
		}
	}
	dotime(transp)
	SVCXPRT *transp;
	{
	
		struct timev rslt;
		time_t thetime;
	
		thetime = time((time_t *)0);
		rslt.second = thetime % 60;
		thetime /= 60;
		rslt.minute = thetime % 60;
		thetime /= 60;
		rslt.hour = thetime % 24;
	if (!svc_sendreply(transp, xdr_timev,(caddr_t) &rslt)) {
			svcerr_systemerr(transp);
		}
	}

The following code example shows the time_prot.h header file for the server.


Example 7–2 MT Auto Mode: time_prot.h

#include <rpc/types.h>

 
		struct timev {
			int second;

			int minute;
			int hour;
		};

 
		typedef struct timev timev;

		bool_t xdr_timev();
 
		#define TIME_PROG 0x40000001

		#define TIME_VERS 1
		#define TIME_GET 1