Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Nov 1996 14:38:46 -0800 (PST)
From:      Bill Paul <wpaul>
To:        CVS-committers, cvs-all, cvs-usrsbin
Subject:   cvs commit:  src/usr.sbin/ypserv yp_async.c Makefile yp_extern.h yp_main.c yp_server.c
Message-ID:  <199611302238.OAA10397@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
wpaul       96/11/30 14:38:46

  Modified:    usr.sbin/ypserv  Makefile yp_extern.h yp_main.c yp_server.c
  Added:       usr.sbin/ypserv  yp_async.c
  Log:
  This commit changes the YPPROC_ALL procecdure so that it handles requests
  _without_ using fork().
  
  The problem with YPPROC_ALL is that it transmits an entire map through
  a TCP pipe as the result of a single RPC call. First of all, this requires
  certain hackery in the XDR filter. Second, if the map being sent is
  large, the server can end up spending lots of time in the XDR filter
  sending to just the one client, while requests for other clients will
  go unanswered.
  
  My original solution for this was to fork() the request into a child
  process which terminates after the map has been transmitted (or the
  transfer is interrupted due to an error). This leaves the parent free
  to handle other requests. But this solution is kind of lame: fork()
  is relatively expensive, and we have to keep a cap on the number of
  child processes to keep from swamping the system.
  
  What we do now is grab control of the service transport handle and XDR
  handle from the RPC library and send the records one at a time ourselves
  instead of letting the RPC library do it. We send a record, then go
  back to the svc_run() loop and select() on the socket. If select() says
  we can still write data, we send the next record. Then we call
  svc_getreqset() and handle other RPCs and loop around again. This way,
  we can handle other RPCs between records.
  
  We manage multiple YPPROC_ALL requests using a circular queue. When a
  request is done, we dequeue it and destroy the handle. We also tag
  each request with a ttl which is decremented whevever we run the queue
  and a handle isn't serviced. This lets us nuke requests that have sat
  idle for too long (if we didn't do this, we might run out of socket
  descriptors.)
  
  Now all I have to do is come up with an async resolver, and ypserv
  won't need to fork() at all. :)
  
  Note: these changes should not go into 2.2 unless they get a very
  throrough shakedown before the final cutoff date.
  
  Revision  Changes    Path
  1.7       +2 -2      src/usr.sbin/ypserv/Makefile
  1.6       +5 -1      src/usr.sbin/ypserv/yp_extern.h
  1.7       +3 -42     src/usr.sbin/ypserv/yp_main.c
  1.13      +16 -50    src/usr.sbin/ypserv/yp_server.c



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611302238.OAA10397>