ONC+ Developer's Guide

poll() on the Server Side

This section applies only to servers running RPC in single-threaded (default) mode.

A process that services RPC requests and performs some other activity cannot always call svc_run(). If the other activity periodically updates a data structure, the process can set a SIGALRM signal before calling svc_run(). This allows the signal handler to process the data structure and return control to svc_run() when done.

A process can bypass svc_run() and access the dispatcher directly with the svc_getreqset() call. Given the file descriptors of the transport endpoints associated with the programs being waited on, the process can have its own poll() that waits on both the RPC file descriptors and its own descriptors.

Example 4-20 shows svc_run(). svc_pollset is an array of pollfd structures that is derived, through a call to __rpc_select_to_poll(), from svc_fdset(). The array can change every time any RPC library routine is called, because descriptors are constantly being opened and closed. svc_getreq_poll() is called when poll() determines that an RPC request has arrived on some RPC file descriptors.


Note -

The functions __rpc_dtbsize() and __rpc_select_to_poll() are not part of the SVID, but they are available in the libnsl library. The descriptions of these functions are included here so that you may create versions of these functions for non-Solaris implementations.


int __rpc_select_to_poll(int fdmax, fd_set *fdset,
															struct pollfd *pollset)

Given an fd_set pointer and the number of bits to check in it, this function initializes the supplied pollfd array for RPC's use. RPC polls only for input events. The number of pollfd slots that were initialized is returned.

int __rpc_dtbsize()

This function calls the getrlimit() function to determine the maximum value that the system may assign to a newly created file descriptor. The result is cached for efficiency.

For more information on the SVID routines in this section, see the rpc_svc_calls(3NSL) and the poll(2) man pages.


Example 4-20 svc_run() and poll()

void
svc_run()
{
	int nfds;
	int dtbsize = __rpc_dtbsize();
	int i;
	struct pollfd svc_pollset[fd_setsize];

	for (;;) {
		/*
		 * Check whether there is any server fd on which we may have
		 * to wait.
		 */
		nfds = __rpc_select_to_poll(dtbsize, &svc_fdset,
		                            svc_pollset);
		if (nfds == 0)
			break;	/* None waiting, hence quit */

		switch (i = poll(svc_pollset, nfds, -1)) {
		case -1:
			/*
			 * We ignore all errors, continuing with the assumption
			 * that it was set by the signal handlers (or any
			 * other outside event) and not caused by poll().
			 */
		case 0:
			continue;
		default:
			svc_getreq_poll(svc_pollset, i);
		}
	}
}