ONC+ Developer's Guide

MT Auto Mode

In the Automatic 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() allows applications to set and modify global RPC attributes. At present, it supports only server-side operations. Table 4-10 shows the rpc_control() operations defined for Auto mode. See also the rpc_control(3N) man page for additional information.

Table 4-10 rpc_control() Library Routines

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 4-10, 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 may 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 may be set at any time by the server, and it allows the service developer to put an upper bound on the thread resources consumed by the server. Example 4-39 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 (xdr_void() may be used 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.

Example 4-39 illustrates the server in MT Auto mode.


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. To do this, specify the -lthread option in the compile command.


Compile the program in Example 4-39 by typing:

$ cc time_svc.c -lnsl -lthread


Example 4-39 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 will take care of destroying 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);
		}
	}

Example 4-40 shows the time_prot.h header file for the server.


Example 4-40 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