>>>>> "Dick" == Dick Porter <[EMAIL PROTECTED]> writes:

Dick> On Thu, Jun 06, 2002 at 10:42:38PM +0200, Dennis Haney wrote:
>>  This is primarily a documentation patch, but it also adds a single
>> error check (assert if unref is called with refcnt==0) and many
>> g_warning with a exit(-1) right after was changed to
>> g_critical. The states a daemon was running in was replaced by an
>> enum to make it more clean what is what.

Dick> Mostly OK.  I've commented on some details below.

Dick> - Dick


>> + +The mono_handle_d is a process which takes care of the
>> (de)allocation +of scratch shared memory and filehandles and
>> refcounts of the +filehandles. It is designed to be run by a user
>> and to be fast, thus

Dick> Not just file handles, there are many sorts.  Please change this
Dick> wording throughout the doc and the comments.

I believe that was the only place I was wrong. All other places I talk
about filehandles I refer to the filehandle of the client-sockets...

>> + +=head2 How to start the deamon

Dick> Please make sure you've spelled "daemon" correctly throughout
Dick> (including in typedefs :) )

;)


>> + +Deallocate a shared memory area, this must have been allocated
>> before +deallocating. A L<WapiHandleResponse> with
>> +.type=WapiHandleResponseType_Scratch Freewill be sent back (works
>> just

Dick> Some typos here

All I can see is the Free having a <sp> before instead of
after. Anymore?

>> Index: daemon-messages.c @@ -71,7 +71,11 @@ int ret;
>> 
>> ret=recv (fd, req, sizeof(WapiHandleRequest), MSG_NOSIGNAL); + //we
>> cant check ret != sizeof(WapiHandleRequest) because its a + //union

Dick> Please replace the // comments with /* */

Done

>>  ret=send (fd, resp, sizeof(WapiHandleResponse), MSG_NOSIGNAL); -
>> if(ret==-1) { #ifdef DEBUG + if(ret==-1 || ret !=
>> sizeof(WapiHandleResponse)) {

Dick> I don't understand this bit.  Earlier you said you can't use
Dick> sizeof on a union, but here you are doing it.

I now do the check both places. Point was that given a struct like:

struct p {
   int a;
   union b {
        int c[1000];
        int d;
   }
}

If the client only fills out d, then it might only send a package
which is two ints long.

When the daemon itself sends a package we _know_ that we must send the
whole package or something is wrong.

>> Index: daemon-messages.h @@ -18,6 +18,7 @@
>> WapiHandleRequestType_Close, WapiHandleRequestType_Scratch,
>> WapiHandleRequestType_ScratchFree, + WapiHandleRequestType_Error, }
>> WapiHandleRequestType;

Dick> Please move the Error enum to the top of the list, to be
Dick> symmetrical with the responses.

Okay, this breaks binary compat though...

>> -static gpointer *handle_refs=NULL; +static guint32
>> **handle_refs=NULL;

Dick> Good catch.

>> static gboolean unref_handle (guint32 idx, guint32 handle) {
>> guint32 *open_handles=handle_refs[idx]; @@ -104,6 +137,8 @@
>> return(FALSE); }
>> 
>> + g_assert(open_handles[handle] != 0); +

Dick> Shouldn't use assert in the daemon.  Just g_warning and ignore
Dick> the request if the handle isn't open.

Better?

>> @@ -325,9 +433,19 @@ case WapiHandleRequestType_ScratchFree:
>> process_scratch_free (idx, req.u.scratch_free.idx); break; + case
>> WapiHandleRequestType_Error: /* Falltrough */ + default: + /*FIXME:
>> call rem_fd?*/ + break; }

Dick> I prefer to not use default in switch statements like this, so
Dick> the compiler will remind me when I've forgotten to add a case.

It is to catch faulty packages...

Dick> The rest is fine though.

Great[1] ;)

I just have one question about the daemon... Why does it exist? Isn't
it better performancewise[2] 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)

[1]
Attaching a new version per comments

[2]
Process of a client requesting a new handle:

client connects to shared segment (possibly starting a daemon)
client connects to daemon
...
client constructs a WapiHandleRequest package
client sends this package over a socket
process switch to the daemon
daemon scans sockets to find who is asking
daemon reads package
daemon allocates a new handle
daemon constructs a response package
daemon sends package
daemon listens to sockets again
process switch to the client
client reads package
client verifies package


With a lock:
client connects to shared segment (possibly init the locks)
...
client locks shared segment
client allocates a new handle
client unlocks shared segment

-- 
Dennis
use Inline C => qq{void p(char*g){
printf("Just Another %s Hacker\n",g);}};p("Perl");
Index: daemon-messages.c
===================================================================
RCS file: /mono/mono/mono/io-layer/daemon-messages.c,v
retrieving revision 1.3
diff -u -b -B -r1.3 daemon-messages.c
--- daemon-messages.c   31 May 2002 09:54:14 -0000      1.3
+++ daemon-messages.c   7 Jun 2002 13:55:20 -0000
@@ -25,7 +25,7 @@
 
 /* Send request on fd, wait for response (called by applications, not
  * the daemon)
-*/
+ */
 void _wapi_daemon_request_response (int fd, WapiHandleRequest *req,
                                    WapiHandleResponse *resp)
 {
@@ -41,7 +41,7 @@
        ret=send (fd, req, sizeof(WapiHandleRequest), MSG_NOSIGNAL);
        if(ret!=sizeof(WapiHandleRequest)) {
                if(errno==EPIPE) {
-                       g_warning (G_GNUC_PRETTY_FUNCTION ": The handle daemon 
vanished!");
+                       g_critical (G_GNUC_PRETTY_FUNCTION ": The handle daemon 
+vanished!");
                        exit (-1);
                } else {
                        g_warning (G_GNUC_PRETTY_FUNCTION ": Send error: %s",
@@ -53,7 +53,7 @@
        ret=recv (fd, resp, sizeof(WapiHandleResponse), MSG_NOSIGNAL);
        if(ret==-1) {
                if(errno==EPIPE) {
-                       g_warning (G_GNUC_PRETTY_FUNCTION ": The handle daemon 
vanished!");
+                       g_critical (G_GNUC_PRETTY_FUNCTION ": The handle daemon 
+vanished!");
                        exit (-1);
                } else {
                        g_warning (G_GNUC_PRETTY_FUNCTION ": Send error: %s",
@@ -71,7 +71,9 @@
        int ret;
        
        ret=recv (fd, req, sizeof(WapiHandleRequest), MSG_NOSIGNAL);
-       if(ret==-1) {
+       if(ret==-1 || ret != sizeof(WapiHandleRequest) {
+               /* make sure we dont do anything with this response */
+               req->type=WapiHandleRequestType_Error;
 #ifdef DEBUG
                g_warning (G_GNUC_PRETTY_FUNCTION ": Recv error: %s",
                           strerror (errno));
@@ -86,11 +88,11 @@
        int ret;
        
        ret=send (fd, resp, sizeof(WapiHandleResponse), MSG_NOSIGNAL);
-       if(ret==-1) {
 #ifdef DEBUG
+       if(ret==-1 || ret != sizeof(WapiHandleResponse)) {
                g_warning (G_GNUC_PRETTY_FUNCTION ": Send error: %s",
                           strerror (errno));
-#endif
                /* The next loop around poll() should tidy up */
        }
+#endif
 }
Index: daemon-messages.h
===================================================================
RCS file: /mono/mono/mono/io-layer/daemon-messages.h,v
retrieving revision 1.2
diff -u -b -B -r1.2 daemon-messages.h
--- daemon-messages.h   9 May 2002 13:10:18 -0000       1.2
+++ daemon-messages.h   7 Jun 2002 13:55:20 -0000
@@ -13,6 +13,7 @@
 #include <mono/io-layer/wapi-private.h>
 
 typedef enum {
+       WapiHandleRequestType_Error,
        WapiHandleRequestType_New,
        WapiHandleRequestType_Open,
        WapiHandleRequestType_Close,
Index: daemon.c
===================================================================
RCS file: /mono/mono/mono/io-layer/daemon.c,v
retrieving revision 1.4
diff -u -b -B -r1.4 daemon.c
--- daemon.c    31 May 2002 10:41:30 -0000      1.4
+++ daemon.c    7 Jun 2002 13:55:20 -0000
@@ -27,9 +27,13 @@
 
 #undef DEBUG
 
+/* Array to hold the filehandles we are currently polling */
 static struct pollfd *pollfds=NULL;
+/* Keep track of the size and usage of pollfds */
 static int nfds=0, maxfds=0;
-static gpointer *handle_refs=NULL;
+/* Array to keep track of arrays of handles that belong to a given client */
+static guint32 **handle_refs=NULL;
+/* The sockey which we listen to new connections on */
 static int main_sock;
 
 /* Deletes the shared memory segment.  If we're exiting on error,
@@ -40,12 +44,23 @@
        _wapi_shm_destroy ();
 }
 
+/*
+ * signal_handler:
+ * @unused: unused
+ *
+ * Called if daemon receives a SIGTERM or SIGINT
+ */
 static void signal_handler (int unused)
 {
        cleanup ();
        exit (-1);
 }
 
+/*
+ * startup:
+ *
+ * Bind signals and attach to shared memory
+ */
 static void startup (void)
 {
        struct sigaction sa;
@@ -76,6 +91,15 @@
                  time (NULL));
 }
 
+
+/*
+ * ref_handle:
+ * @idx: idx into pollfds
+ * @handle: handle to inc refcnt
+ *
+ * Increase ref count of handle for idx's filehandle and the
+ * shm. Handle 0 is ignored.
+ */
 static void ref_handle (guint32 idx, guint32 handle)
 {
        guint32 *open_handles=handle_refs[idx];
@@ -95,6 +119,15 @@
 #endif
 }
 
+/*
+ * unref_handle:
+ * @idx: idx into pollfds
+ * @handle: handle to inc refcnt
+ *
+ * Decrease ref count of handle for idx's filehandle and the shm. If
+ * global ref count reaches 0 it is free'ed. Return TRUE if the local
+ * ref count is 0. Handle 0 is ignored.
+ */
 static gboolean unref_handle (guint32 idx, guint32 handle)
 {
        guint32 *open_handles=handle_refs[idx];
@@ -104,6 +137,13 @@
                return(FALSE);
        }
        
+       if (open_handles[handle] == 0) {
+                g_warning(G_GNUC_PRETTY_FUNCTION
+                          ": unref on %d called when ref was already 0", 
+                          handle);
+                return TRUE;
+        }
+
        _wapi_shared_data->handles[handle].ref--;
        open_handles[handle]--;
        
@@ -120,9 +160,7 @@
        }
        
        if(_wapi_shared_data->handles[handle].ref==0) {
-               if (open_handles[handle]!=0) {
-                       g_warning (G_GNUC_PRETTY_FUNCTION ": per-process open_handles 
mismatch, set to %d, should be 0", open_handles[handle]);
-               }
+               g_assert(open_handles[handle] == 0);
                
 #ifdef DEBUG
                g_message (G_GNUC_PRETTY_FUNCTION ": Destroying handle 0x%x",
@@ -140,13 +178,21 @@
        return(destroy);
 }
 
+/*
+ * add_fd:
+ * @fd: Filehandle to add
+ *
+ * Add fd to the pollfds array, expand if necessary
+ */
 static void add_fd(int fd)
 {
        if(nfds==maxfds) {
                /* extend the array */
                maxfds+=10;
+               /* no need to memset the extra memory, we init it
+                * before use anyway */
                pollfds=g_renew (struct pollfd, pollfds, maxfds);
-               handle_refs=g_renew (gpointer, handle_refs, maxfds);
+               handle_refs=g_renew (guint32*, handle_refs, maxfds);
        }
 
        pollfds[nfds].fd=fd;
@@ -158,6 +204,14 @@
        nfds++;
 }
 
+/*
+ * rem_fd:
+ * @idx: idx into pollfds to remove
+ *
+ * Close filehandle and remove it from the pollfds array. Closes all
+ * handles that it may have open. If only main_sock is open, the daemon
+ * is shut down.
+ */
 static void rem_fd(int idx)
 {
        guint32 *open_handles=handle_refs[idx], handle_count;
@@ -205,12 +259,28 @@
        }
 }
 
+
+/*
+ * send_reply:
+ * @idx: idx into pollfds.
+ * @rest: Package to send
+ *
+ * Send a package to a client
+ */
 static void send_reply (guint32 idx, WapiHandleResponse *resp)
 {
        /* send message */
        _wapi_daemon_response (pollfds[idx].fd, resp);
 }
 
+/*
+ * process_new:
+ * @idx: idx into pollfds.
+ * @type: type to init handle to
+ *
+ * Find a free handle and initialize it to 'type', increase refcnt and
+ * send back a reply to the client.
+ */
 static void process_new (guint32 idx, WapiHandleType type)
 {
        guint32 handle;
@@ -231,6 +301,14 @@
        send_reply (idx, &resp);
 }
 
+/*
+ * process_open:
+ * @idx: idx into pollfds.
+ * @handle: handle no.
+ *
+ * Increase refcnt on a previously created handle and send back a
+ * response to the client.
+ */
 static void process_open (guint32 idx, guint32 handle)
 {
        WapiHandleResponse resp;
@@ -259,6 +337,14 @@
        send_reply (idx, &resp);
 }
 
+/*
+ * process_close:
+ * @idx: idx into pollfds.
+ * @handle: handle no.
+ *
+ * Decrease refcnt on a previously created handle and send back a
+ * response to the client with notice of it being destroyed.
+ */
 static void process_close (guint32 idx, guint32 handle)
 {
        WapiHandleResponse resp;
@@ -273,6 +359,13 @@
        send_reply (idx, &resp);
 }
 
+/*
+ * process_scratch:
+ * @idx: idx into pollfds.
+ * @length: allocate this much scratch space
+ *
+ * Allocate some scratch space and send a reply to the client.
+ */
 static void process_scratch (guint32 idx, guint32 length)
 {
        WapiHandleResponse resp;
@@ -288,6 +381,13 @@
        send_reply (idx, &resp);
 }
 
+/*
+ * process_scratch_free:
+ * @idx: idx into pollfds.
+ * @scratch_idx: deallocate this scratch space
+ *
+ * Deallocate scratch space and send a reply to the client.
+ */
 static void process_scratch_free (guint32 idx, guint32 scratch_idx)
 {
        WapiHandleResponse resp;
@@ -303,6 +403,13 @@
        send_reply (idx, &resp);
 }
 
+/*
+ * read_message:
+ * @idx: idx into pollfds.
+ *
+ * Read a message (A WapiHandleRequest) from a client and dispatch
+ * whatever it wants to the process_* calls.
+ */
 static void read_message (guint32 idx)
 {
        WapiHandleRequest req;
@@ -314,9 +421,15 @@
                process_new (idx, req.u.new.type);
                break;
        case WapiHandleRequestType_Open:
+#ifdef DEBUG
+               g_assert(req.u.open.handle < _WAPI_MAX_HANDLES);
+#endif
                process_open (idx, req.u.open.handle);
                break;
        case WapiHandleRequestType_Close:
+#ifdef DEBUG
+               g_assert(req.u.close.handle < _WAPI_MAX_HANDLES);
+#endif
                process_close (idx, req.u.close.handle);
                break;
        case WapiHandleRequestType_Scratch:
@@ -325,9 +438,19 @@
        case WapiHandleRequestType_ScratchFree:
                process_scratch_free (idx, req.u.scratch_free.idx);
                break;
+       case WapiHandleRequestType_Error: /* Falltrough */
+       default: /* Catch faulty packages */
+               /*FIXME: call rem_fd?*/
+               break;
        }
 }
 
+/*
+ * main:
+ *
+ * Open socket, create shared mem segment and begin listening for
+ * clients.
+ */
 int main(int argc, char **argv)
 {
        struct sockaddr_un main_socket_address;
@@ -347,8 +470,8 @@
        ret=bind(main_sock, (struct sockaddr *)&main_socket_address,
                 sizeof(struct sockaddr_un));
        if(ret==-1) {
-               g_warning ("bind failed: %s", strerror (errno));
-               _wapi_shared_data->daemon_running=2;
+               g_critical ("bind failed: %s", strerror (errno));
+               _wapi_shared_data->daemon_running=DAEMON_DIED_AT_STARTUP;
                exit(-1);
        }
 
@@ -358,8 +481,8 @@
 
        ret=listen(main_sock, 5);
        if(ret==-1) {
-               g_warning ("listen failed: %s", strerror (errno));
-               _wapi_shared_data->daemon_running=2;
+               g_critical ("listen failed: %s", strerror (errno));
+               _wapi_shared_data->daemon_running=DAEMON_DIED_AT_STARTUP;
                exit(-1);
        }
 
@@ -373,7 +496,7 @@
         * ready.  From now on, it's up to us to delete the shared
         * memory segment when appropriate.
         */
-       _wapi_shared_data->daemon_running=1;
+       _wapi_shared_data->daemon_running=DAEMON_RUNNING;
 
        while(TRUE) {
                int i;
@@ -385,21 +508,29 @@
                /* Block until something happens */
                ret=poll(pollfds, nfds, -1);
                if(ret==-1) {
-                       g_message ("poll error: %s", strerror (errno));
+                       g_critical ("poll error: %s", strerror (errno));
                        cleanup ();
                        exit(-1);
                }
 
                for(i=0; i<nfds; i++) {
-                       if(((pollfds[i].revents&POLLHUP)==POLLHUP) ||
-                          ((pollfds[i].revents&POLLERR)==POLLERR) ||
-                          ((pollfds[i].revents&POLLNVAL)==POLLNVAL)) {
+                       if(((pollfds[i].revents & POLLHUP)  == POLLHUP) ||
+                          ((pollfds[i].revents & POLLERR)  == POLLERR) ||
+                          ((pollfds[i].revents & POLLNVAL) == POLLNVAL)) {
 #ifdef DEBUG
                                g_message ("fd[%d] %d error", i,
                                           pollfds[i].fd);
 #endif
                                rem_fd(i);
                        } else if((pollfds[i].revents&POLLIN)==POLLIN) {
+                               /* If a client is connecting, accept
+                                * it and begin listening to that
+                                * socket too otherwise it must be a
+                                * client we already have that wants
+                                * something
+                                */
+
+                               /* FIXME: Isn't this only true for i==0??? */
                                if(pollfds[i].fd==main_sock) {
                                        int newsock;
                                        struct sockaddr addr;
@@ -407,7 +538,7 @@
                                        newsock=accept(main_sock, &addr,
                                                       &addrlen);
                                        if(newsock==-1) {
-                                               g_message("accept error: %s",
+                                               g_critical("accept error: %s",
                                                          strerror (errno));
                                                cleanup ();
                                                exit(-1);
Index: handles.c
===================================================================
RCS file: /mono/mono/mono/io-layer/handles.c,v
retrieving revision 1.12
diff -u -b -B -r1.12 handles.c
--- handles.c   31 May 2002 10:41:30 -0000      1.12
+++ handles.c   7 Jun 2002 13:55:20 -0000
@@ -136,6 +136,13 @@
        thread_handle=_wapi_handle_new (WAPI_HANDLE_THREAD);
 }
 
+/*
+ * _wapi_handle_new_internal:
+ * @type: Init handle to this type
+ *
+ * Search for a free handle and initialize it. Return the handle on
+ * succes and 0 on failure.
+ */
 guint32 _wapi_handle_new_internal (WapiHandleType type)
 {
        guint32 i;
@@ -150,7 +157,7 @@
                struct _WapiHandleShared *shared=&_wapi_shared_data->handles[i];
                
                if(shared->type==WAPI_HANDLE_UNUSED) {
-                       last=i;
+                       last=i+1;
                        shared->type=type;
                        shared->signalled=FALSE;
                        mono_mutex_init (&_wapi_shared_data->handles[i].signal_mutex, 
&mutex_shared_attr);
@@ -350,6 +357,13 @@
 
 #define HDRSIZE sizeof(struct _WapiScratchHeader)
 
+/*
+ * _wapi_handle_scratch_store_internal:
+ * @bytes: Allocate no. bytes
+ *
+ * Like malloc(3) except its for the shared memory segment's scratch
+ * part. Memory block returned is zeroed out.
+ */
 guint32 _wapi_handle_scratch_store_internal (guint32 bytes)
 {
        guint32 idx=0, last_idx=0;
@@ -400,6 +414,10 @@
                        g_message (G_GNUC_PRETTY_FUNCTION ": new header at %d, length 
%d", idx+bytes, hdr->length);
 #endif
                        
+                       /*
+                        * It was memset(0..) when free/made so no need to do it here
+                        */
+
                        return(idx);
                } else if(hdr->flags & WAPI_SHM_SCRATCH_FREE &&
                          last_was_free == FALSE) {
@@ -516,6 +534,13 @@
        return(str);
 }
 
+/*
+ * _wapi_handle_scratch_delete_internal:
+ * @idx: Index to free block
+ *
+ * Like free(3) except its for the shared memory segment's scratch
+ * part.
+ */
 void _wapi_handle_scratch_delete_internal (guint32 idx)
 {
        struct _WapiScratchHeader *hdr;
Index: shared.c
===================================================================
RCS file: /mono/mono/mono/io-layer/shared.c,v
retrieving revision 1.4
diff -u -b -B -r1.4 shared.c
--- shared.c    9 May 2002 13:10:18 -0000       1.4
+++ shared.c    7 Jun 2002 13:55:20 -0000
@@ -56,6 +56,17 @@
 
 #undef DEBUG
 
+/*
+ * _wapi_shm_attach:
+ * @daemon: Is it the daemon trying to attach to the segment
+ * @success: Was it a success
+ * @shm_id: The ID of the segment created/attached to
+ *
+ * Attach to the shared memory segment or create it if it did not
+ * exist. If it was created and daemon was FALSE a new daemon is
+ * forked into existence. Returns the memory area the segment was
+ * attached to.
+ */
 gpointer _wapi_shm_attach (gboolean daemon, gboolean *success, int *shm_id)
 {
        gpointer shm_seg;
@@ -99,7 +110,7 @@
                 */
        } else {
                /* Some error other than EEXIST */
-               g_message (G_GNUC_PRETTY_FUNCTION ": shmget error: %s",
+               g_critical (G_GNUC_PRETTY_FUNCTION ": shmget error: %s",
                           strerror (errno));
                exit (-1);
        }
@@ -110,7 +121,7 @@
         */
        shm_seg=shmat (*shm_id, NULL, 0);
        if(shm_seg==(gpointer)-1) {
-               g_message (G_GNUC_PRETTY_FUNCTION ": shmat error: %s",
+               g_critical (G_GNUC_PRETTY_FUNCTION ": shmat error: %s",
                           strerror (errno));
                if(fork_daemon==TRUE) {
                        _wapi_shm_destroy ();
@@ -131,7 +142,7 @@
                        
                pid=fork ();
                if(pid==-1) {
-                       g_message (G_GNUC_PRETTY_FUNCTION ": fork error: %s",
+                       g_critical (G_GNUC_PRETTY_FUNCTION ": fork error: %s",
                                   strerror (errno));
                        _wapi_shm_destroy ();
                        exit (-1);
@@ -140,9 +151,9 @@
                        setsid ();
                        execl (MONO_BINDIR "/mono-handle-d", "mono-handle-d",
                               NULL);
-                       g_warning (": exec of %s/mono-handle-d failed: %s",
+                       g_critical (": exec of %s/mono-handle-d failed: %s",
                                   MONO_BINDIR, strerror (errno));
-                       data->daemon_running=2;
+                       data->daemon_running=DAEMON_DIED_AT_STARTUP;
                        exit (-1);
                }
                /* parent carries on */
@@ -150,8 +161,9 @@
                /* Do some sanity checking on the shared memory we
                 * attached
                 */
-               if(!(data->daemon_running==0 || data->daemon_running==1 ||
-                    data->daemon_running==2) ||
+               if(!(data->daemon_running==DAEMON_STARTING || 
+                    data->daemon_running==DAEMON_RUNNING ||
+                    data->daemon_running==DAEMON_DIED_AT_STARTUP) ||
                   (strncmp (data->daemon+1, "mono-handle-daemon-", 19)!=0)) {
                        g_warning ("Shared memory sanity check failed.");
                        *success=FALSE;
@@ -159,7 +171,7 @@
                }
        }
                
-       for(tries=0; data->daemon_running==0 && tries < 100; tries++) {
+       for(tries=0; data->daemon_running==DAEMON_STARTING && tries < 100; tries++) {
                /* wait for the daemon to sort itself out.  To be
                 * completely safe, we should have a timeout before
                 * giving up.
@@ -171,7 +183,7 @@
                        
                nanosleep (&sleepytime, NULL);
        }
-       if(tries==100 && data->daemon_running==0) {
+       if(tries==100 && data->daemon_running==DAEMON_STARTING) {
                /* Daemon didnt get going */
                if(fork_daemon==TRUE) {
                        _wapi_shm_destroy ();
@@ -181,7 +193,7 @@
                return(NULL);
        }
        
-       if(data->daemon_running==2) {
+       if(data->daemon_running==DAEMON_DIED_AT_STARTUP) {
                /* Oh dear, the daemon had an error starting up */
                if(fork_daemon==TRUE) {
                        _wapi_shm_destroy ();
Index: wapi-private.h
===================================================================
RCS file: /mono/mono/mono/io-layer/wapi-private.h,v
retrieving revision 1.12
diff -u -b -B -r1.12 wapi-private.h
--- wapi-private.h      9 May 2002 13:10:19 -0000       1.12
+++ wapi-private.h      7 Jun 2002 13:55:20 -0000
@@ -95,6 +95,12 @@
 #define _WAPI_MAX_HANDLES 4096
 #define _WAPI_HANDLE_INVALID (gpointer)-1
 
+typedef enum {
+       DAEMON_STARTING = 0,
+       DAEMON_RUNNING  = 1,
+       DAEMON_DIED_AT_STARTUP = 2,
+} _wapi_daemon_status;
+
 /*
  * This is the layout of the shared memory segment
  */
@@ -104,7 +110,7 @@
         * header file
         */
        guchar daemon[108];
-       guint32 daemon_running;
+       _wapi_daemon_status daemon_running;
        
 #ifdef _POSIX_THREAD_PROCESS_SHARED
        mono_mutex_t signal_mutex;
--- /dev/null   Thu Jan  1 01:00:00 1970
+++ docs/mono_handle_d  Fri Jun  7 15:19:57 2002
@@ -0,0 +1,80 @@
+=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_Scratch Freewill be sent back (works just
+like free(3))
+
+=back
+
+=head1 Authors
+
+Documentaion: Dennis Haney
+
+Implementation: Dick Porter
+
+=cut
--- /dev/null   Thu Jan  1 01:00:00 1970
+++ docs/.cvsignore     Sun Jun  2 00:00:05 2002
@@ -0,0 +1 @@
+Makefile Makefile.in

Reply via email to