=pod

=head1 Internal design document for the mono_handle_d

This document is designed to hold the design of the mono_handle_d and
not as an api reference.

=head2 Primary goal and purpose

The mono_handle_d is a process which takes care of the (de)allocation
of scratch shared memory and handles (of files, threads, mutexes,
sockets etc. see L<WapiHandleType>) and refcounts of the
filehandles. It is designed to be run by a user and to be fast, thus
minimal error checking on input is done and will most likely crash if
given a faulty package. No effort has been, or should be, made to have
the daemon talking to machine of different endianness/size of int.

=head2 How to start the daemon

To start the daemon you either run the mono_handle_d executable or try
to attach to the shared memory segment via L<_wapi_shm_attach> which
will start a daemon if one does not exist.

=head1 Internal details

The daemon works by opening a socket and listening to clients. These
clients send packages over the socket complying to L<struct
WapiHandleRequest>.

=head2 Possible requests

=over

=item WapiHandleRequest_New

Find a handle in the shared memory segment that is free and allocate
it to the specified type. To destroy use
L</WapiHandleRequest_Close>. A L<WapiHandleResponse> with
.type=WapiHandleResponseType_New will be sent back with .u.new.handle
set to the handle that was allocated. .u.new.type is the type that was
requested.

=item WapiHandleRequestType_Open

Increase the ref count of an already created handle. A
L<WapiHandleResponse> with .type=WapiHandleResponseType_Open will be sent
back with .u.new.handle set to the handle, .u.new.type is set to the
type of handle this is.

=item WapiHandleRequestType_Close

Decrease the ref count of an already created handle. A
L<WapiHandleResponse> with .type=WapiHandleResponseType_Close will be
sent back with .u.close.destroy set to TRUE if ref count for this
client reached 0.

=item WapiHandleRequestType_Scratch

Allocate a shared memory area of size .u.scratch.length in bytes. A
L<WapiHandleResponse> with .type=WapiHandleResponseType_Scratch will be
sent back with .u.scratch.idx set to the index into the shared
memory's scratch area where to memory begins. (works just like
malloc(3))

=item WapiHandleRequestType_Scratch

Deallocate a shared memory area, this must have been allocated before
deallocating. A L<WapiHandleResponse> with
.type=WapiHandleResponseType_ScratchFree will be sent back (works just
like free(3))

=back

=head1 Why a daemon

From an email:

Dennis: I just have one question about the daemon... Why does it
exist? Isn't it better performancewise to just protect the shared area
with a mutex when allocation a new handle/shared mem segment or
changing refcnt? It will however be a less resilient to clients that
crash (the deamon cleans up ref'd handles if socket closes)

Dick: It's precisely because with a mutex the shared memory segment
can be left in a locked state. Also, it's not so easy to clean up
shared memory without it (you can't just mark it deleted when creating
it, because you can't attach any more readers to the same segment
after that).  I did some minimal performance testing, and I don't
think the daemon is particularly slow.


=head1 Authors

Documentaion: Dennis Haney

Implementation: Dick Porter

=cut
