Index: trunk/src/sh_inotify.c
===================================================================
--- trunk/src/sh_inotify.c	(revision 363)
+++ trunk/src/sh_inotify.c	(revision 364)
@@ -39,4 +39,5 @@
 #include "sh_inotify.h"
 #include "sh_mem.h"
+#include "sh_utils.h"
 #include "slib.h"
 
@@ -115,4 +116,12 @@
 /*--- nothing thread-related below this point --- */
 
+#include "zAVLTree.h"
+
+typedef struct 
+{
+  int    watch;
+  int    flag;
+  char * file;
+} sh_watch;
 
 /**************************************************
@@ -181,24 +190,135 @@
 #define SH_INOTIFY_MODIFY 1
 
+static void sh_inotify_init(sh_watches * watches)
+{
+  watches->list_of_watches = NULL;
+  watches->count           = 0;
+  watches->max_count       = 0;
+  return;
+}
+
+static void sh_inotify_free_watch(void * item)
+{
+  sh_watch * this = (sh_watch *) item;
+
+  if (this->file)
+    SH_FREE(this->file);
+  SH_FREE(this);
+  return;
+}
+
+static sh_watch * sh_inotify_create_watch(char * file, int nwatch, int flag)
+{
+  sh_watch * this = SH_ALLOC(sizeof(sh_watch));
+
+  this->file  = sh_util_strdup(file);
+  this->watch = nwatch;
+  this->flag  = flag;
+  return this;
+}
+
+/********** List Handling ******************/
+
+struct sh_inotify_litem
+{
+  sh_watch * watch;
+  struct sh_inotify_litem * next;
+};
+
+typedef struct {
+  struct sh_inotify_litem *prenode;
+  struct sh_inotify_litem *curnode;
+} sh_inotify_listCursor;
+
+static sh_watch * sh_inotify_list_first(sh_inotify_listCursor * listcursor, sh_watches * watches)
+{
+  listcursor->prenode = watches->dormant_watches;
+  listcursor->curnode = watches->dormant_watches;
+
+  return listcursor->curnode->watch;
+}
+
+static sh_watch * sh_inotify_list_next(sh_inotify_listCursor * listcursor, sh_watches * watches)
+{
+  (void) watches;
+
+  listcursor->prenode = listcursor->curnode;
+  listcursor->curnode = listcursor->curnode->next;
+
+  if (listcursor->curnode)
+    return listcursor->curnode->watch;
+  return NULL;
+}
+
+static void sh_inotify_listitem_destroy(struct sh_inotify_litem * this)
+{
+  SH_FREE(this);
+  return;
+}
+
+static sh_watch * sh_inotify_list_del_current(sh_inotify_listCursor * listcursor, sh_watches * watches)
+{
+  sh_watch * ret = NULL;
+
+  if (listcursor->curnode)
+    {
+      struct sh_inotify_litem * this = listcursor->curnode;
+
+      if (listcursor->prenode == this)
+	{
+	  watches->dormant_watches = this->next;
+
+	  listcursor->prenode = watches->dormant_watches;
+	  listcursor->curnode = watches->dormant_watches;
+	}
+      else
+	{
+	  listcursor->prenode->next = this->next;
+	  listcursor->curnode       = this->next;
+	}
+      ret = listcursor->curnode->watch;
+      sh_inotify_listitem_destroy(this);
+    }
+  return ret;
+}
+
+static int sh_inotify_add_dormant(sh_watches * watches, sh_watch * item)
+{
+  struct sh_inotify_litem * this = SH_ALLOC(sizeof(struct sh_inotify_litem));
+
+  this->watch = item;
+  this->next  = (struct sh_inotify_litem *) watches->dormant_watches;
+  
+  watches->dormant_watches = this;
+  return 0;
+}
+
+/********** End List Handling **************/
+
+static zAVLKey sh_inotify_getkey(void const *item)
+{
+  return (&((sh_watch *)item)->watch);
+}
+
+
+/* This function removes all watches from the list,
+ * and closes the inode file descriptor in this thread.
+ */
 void sh_inotify_remove(sh_watches * watches)
 {
-  int     i;
   int     ifd = sh_inotify_getfd();
-
-  for (i = 0; i < watches->count; ++i)
-    {
-      if (watches->file[i])
-	{
-	  SH_FREE (watches->file[i]);
-	  watches->file[i] = 0;
-	}
-      watches->watch[i] = 0;
-      watches->flag[i] = 0;
-    }
-  watches->count = 0;
+  zAVLTree   * all_watches = (zAVLTree *)(watches->list_of_watches);
+
+  if (all_watches)
+    zAVLFreeTree(all_watches, sh_inotify_free_watch);
+
+  sh_inotify_init(watches);
+
   if (ifd >= 0)
     close(ifd);
   sh_set_inotify_fd(-1);
 
+  watches->count = 0;
+
   return;
 }
@@ -206,10 +326,19 @@
 static int index_watched_file(char * filename, sh_watches * watches)
 {
-  int i;
-
-  for (i = 0; i < watches->count; ++i)
-    {
-      if (0 == strcmp(filename, watches->file[i]))
-	return i;
+  sh_watch   * item;
+  zAVLCursor   avlcursor;
+  zAVLTree   * all_watches = (zAVLTree *)(watches->list_of_watches);
+
+  if (all_watches)
+    {
+      for (item = (sh_watch *) zAVLFirst(&avlcursor, all_watches); item;
+	   item = (sh_watch *) zAVLNext(&avlcursor))
+	{
+	  if (item->file)
+	    {
+	      if (0 == strcmp(filename, item->file))
+		return item->watch;
+	    }
+	}
     }
   return -1;
@@ -220,5 +349,4 @@
 int sh_inotify_add_watch(char * filename, sh_watches * watches, int  * errnum)
 {
-  size_t len;
   *errnum = 0;
 
@@ -226,4 +354,5 @@
     {
       int nwatch;
+      sh_watch   * item;
       int index = index_watched_file(filename, watches);
       
@@ -231,4 +360,6 @@
 	{
 	  int     ifd = sh_inotify_getfd();
+
+	  /*************************************
 
 	  if (watches->count == SH_INOTIFY_MAX)
@@ -241,4 +372,5 @@
 	      return -1;
 	    }
+	  **************************************/
 
 	  nwatch = inotify_add_watch (ifd, filename, 
@@ -249,11 +381,24 @@
 	      return -1;
 	    }
+
+	  item = sh_inotify_create_watch(filename, nwatch, /* flag */ 0);
 	  
-	  watches->watch[watches->count] = nwatch;
-	  watches->flag[watches->count]  = 0;
-
-	  len = strlen(filename) + 1;
-	  watches->file[watches->count] = SH_ALLOC(len);
-	  sl_strlcpy(watches->file[watches->count], filename, len);
+	  if (NULL == watches->list_of_watches)
+	    watches->list_of_watches = zAVLAllocTree (sh_inotify_getkey, zAVL_KEY_INT);
+ 
+	  if (watches->list_of_watches)
+	    {
+	      *errnum =  zAVLInsert((zAVLTree *)(watches->list_of_watches), item);
+	      if (*errnum != 0)
+		{
+		  sh_inotify_free_watch(item);
+		  return -1;
+		}
+	    }
+	  else
+	    {
+	      *errnum = -1;
+	      return -1;
+	    }
 
 	  ++(watches->count);
@@ -266,5 +411,7 @@
 			       int  * errnum, int waitsec)
 {
-  int     ifd = sh_inotify_getfd();
+  sh_watch   * item;
+  zAVLTree   * all_watches = (zAVLTree *)(watches->list_of_watches);
+  int          ifd = sh_inotify_getfd();
   
   *errnum = 0;
@@ -279,4 +426,6 @@
       char buffer[1024];
 
+      sh_inotify_listCursor listcursor;
+
       /* -- Add watch if required 
        */
@@ -290,9 +439,21 @@
 	}
 
-      for (i = 0; i < watches->count; ++i)
-	{
-	  if (watches->watch[i] == -1)
-	    watches->watch[i] = inotify_add_watch (ifd, watches->file[i], 
-					 IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);
+      /* -- Check dormant watches for reopening.
+       */
+      for (item = sh_inotify_list_first(&listcursor, watches); item;
+	   item = sh_inotify_list_next(&listcursor, watches))
+	{
+	have_next:
+	  if (item->file && item->watch == -1)
+	    {
+	      item->watch = inotify_add_watch (ifd, item->file, 
+					       IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);
+	      if (item->watch >= 0)
+		{
+		  zAVLInsert(all_watches, item);
+		  item = sh_inotify_list_del_current(&listcursor, watches);
+		  goto have_next;
+		}
+	    }
 	}
 
@@ -306,5 +467,4 @@
       if (len > 0)
 	{
-	  int j;
 	  struct inotify_event *event;
 
@@ -315,24 +475,26 @@
 	    event = (struct inotify_event *) &buffer[i];
 
-	    for (j = 0; j < watches->count; ++j)
+	    item = zAVLSearch(all_watches, &(event->wd));
+
+	    if (item)
 	      {
-		if (watches->watch[j] == event->wd)
+		if (event->mask & IN_MODIFY)
 		  {
-		    if (event->mask & IN_MODIFY)
-		      {
-			watches->flag[j] |= SH_INOTIFY_MODIFY;
-			flag |= SH_INOTIFY_MODIFY;
-		      }
-		    else if (event->mask & IN_DELETE_SELF || 
-			event->mask & IN_UNMOUNT     || 
-			event->mask & IN_MOVE_SELF   )
-		      {
-			watches->flag[j] |= SH_INOTIFY_REOPEN;
-			(void) inotify_rm_watch(ifd, watches->watch[j]);
-			watches->watch[j] = -1;
-			flag |= SH_INOTIFY_REOPEN;
-		      }
+		    item->flag |= SH_INOTIFY_MODIFY;
+		    flag |= SH_INOTIFY_MODIFY;
+		  }
+		else if (event->mask & IN_DELETE_SELF || 
+			 event->mask & IN_UNMOUNT     || 
+			 event->mask & IN_MOVE_SELF   )
+		  {
+		    item->flag |= SH_INOTIFY_REOPEN;
+		    (void) inotify_rm_watch(ifd, item->watch);
+		    zAVLDelete(all_watches, item);
+		    sh_inotify_add_dormant(watches, item);
+		    item->watch    = -1;
+		    flag |= SH_INOTIFY_REOPEN;
 		  }
 	      }
+	    
 	    i += sizeof (struct inotify_event) + event->len;
 	  }
