Now that we have these new functions,
we can also make them return an error
instead of calling sysfatal() like
postmountsrv().
Remove the confusing Srv.srvfd, as it
is only temporarily used and return
it from postsrv() instead.
To use srvrease()/srvaquire() we need to have a way to spawn
new processes to handle the service loop. This functionality
was provided by the internal _forker() function which was
eigther rfork or libthread based implementation depending on
if postmountsrv() or threadpostmountsrv() where called.
For servers who want to use srv() directly, _forker would not
be initialized so srvrelease() could not be used.
To untangle this, we get rid of the global _forker handler
and put the handler in the Srv structure. Which will get
initialized (when nil) to eigther srvforker() or threadsrvforker()
depending on if the thread or non-thread entry points where used.
For symmetry, we provde new threadsrv() and threadpostsrv()
functions which handle the default initialization of Srv.forker.
This also allows a user to provide his own forker function,
maybe to conserve stack space.
To avoid dead code, we put each of these function in their
own object file. Note, this also allows a user to define its
own srvforker() symbol.
in case listensrv() is called with a previously active Srv,
we have to make sure that per connection state is zeroed
out (locks and reference conuts).
also, dont assume anything about the Ref structure. there
might be implementations that have a spinlock in them.
listensrv() used to override Srv.end() with its own handler
to free the malloc'd Srv structure and close the fd. this
makes it impossible to register your own cleanup handler.
instead, we introduce the private Srv.free() handler that
is used by listensrv to register its cleanup code. Srv.free()
is called once all the srv procs have been exited and all
requests on that srv have been responded to while Srv.end()
is called once all the procs exited the srv loop regardless
of the requests still being in flight.
use the Srv.end callback for freeing the srv and closing the
file descriptor of a connection. this makes sure we wont free
the srv while there are still outstanding requests that would
access the srv when doing the respond() call.