SIGNALS AND WRITES TO CLIENT:
because AFP/TCP uses a streaming protocol, we need to make sure that
writes to the client are atomic. notably, signal handlers which write
data can't interrupt data currently being written. in addition, some
functions get called from the signal handlers or can write partial
packets. we need to SIG_BLOCK/SIG_SETMASK those functions instead of
SIG_BLOCK/SIG_UNBLOCK'ing them. furthermore, certain functions which
write to the client can get called at any time. to avoid corruption,
we need to make sure that these functions DO NOT touch any common-use
buffers.

signals that send data to the client and should block other signals
(afp_dsi.c):
	SIGALRM (tickle handler)
	SIGHUP (attention)
	SIGTERM (attention)

functions which need SIG_BLOCK/SIG_SETMASK: dsi_send, dsi_attention
functions which can use SIG_BLOCK/SIG_UNBLOCK: dsi_read

functions which need their own buffers: dsi_attention, dsi_tickle


PERFORMANCE TWEAKING:
sending complete packets or the header and a partial packet to the
client should always be handled by proto_send. for dsi_tcp.c,
proto_send will coalesce the header and data by using writev.
in addition, appleshare sessions often involve
the sending and receiving of many small packets. as a consequence, i
use TCP_NODELAY to speed up the turnaround time.

because dsi_read can send incomplete packets, proto_send should not
use the length parameter to specify the dsi_len field in the
header. instead, anything that uses proto_send needs to specify
dsi_len (in network byte order) before calling proto_send. the
dsi_send() macro already does this.

functions that need to specify .dsi_len: dsi_readinit, dsi_cmdreply

mmap doesn't actually help things that much, so i don't use it.

to reduce the amount of tickles generated on a slow link, i actually
turn off SIGALRM for the duration of a "known" large file transfer
(i.e., dsi_read/write).

