[gamin] inotify cleanup



Yo,

Here is another inotify cleanup patch...

-- 
John McCutchan <ttb tentacle dhs org>
Index: server/gam_inotify.c
===================================================================
RCS file: /cvs/gnome/gamin/server/gam_inotify.c,v
retrieving revision 1.25
diff -u -r1.25 gam_inotify.c
--- server/gam_inotify.c	12 Jul 2005 21:21:59 -0000	1.25
+++ server/gam_inotify.c	13 Jul 2005 18:03:12 -0000
@@ -19,15 +19,16 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 #include "server_config.h"
 #define _GNU_SOURCE
-#include <fcntl.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <asm/unistd.h>
 #include <glib.h>
 #include "gam_error.h"
 #include "gam_poll.h"
@@ -47,9 +48,21 @@
 
 #include <errno.h>
 
-#define INOTIFY_INIT 291
-#define INOTIFY_ADD 292
-#define INOTIFY_RM 293
+/* Setup system calls */
+#define __NR_inotify_init       291
+#define __NR_inotify_add_watch  292
+#define __NR_inotify_rm_watch   293
+
+int inotify_init (void);
+int inotify_add_watch (int fd, const char *path, __u32 mask);
+int inotify_rm_watch (int fd, __u32 wd);
+
+_syscall0(int, inotify_init);
+_syscall3(int, inotify_add_watch, int, fd, const char *, name, __u32, mask);
+_syscall2(int, inotify_rm_watch, int, fd, __u32, wd);
+
+int gam_inotify_add_watch (const char *path, __u32 mask);
+int gam_inotify_rm_watch (const char *path, __u32 wd);
 
 typedef struct {
     char *path;
@@ -200,182 +213,156 @@
 static void
 gam_inotify_directory_handler_internal(const char *path, pollHandlerMode mode)
 {
-    inotify_data_t *data;
-    int path_wd = -1;
-    switch (mode) {
-        case GAMIN_ACTIVATE:
-	    GAM_DEBUG(DEBUG_INFO, "Adding %s to inotify\n", path);
-	    break;
-        case GAMIN_DESACTIVATE:
-	    GAM_DEBUG(DEBUG_INFO, "Removing %s from inotify\n", path);
-	    break;
+	inotify_data_t *data;
+	int path_wd = -1;
+
+	switch (mode) {
+	case GAMIN_ACTIVATE:
+	case GAMIN_DESACTIVATE:
 	case GAMIN_FLOWCONTROLSTART:
-	    GAM_DEBUG(DEBUG_INFO, "inotify: Start flow control for %s\n", path);
-	    break;
 	case GAMIN_FLOWCONTROLSTOP:
-	    GAM_DEBUG(DEBUG_INFO, "inotify: Stop flow control for %s\n", path);
-	    break;
+		break;
 	default:
-	    gam_error(DEBUG_INFO, "Unknown inotify operation %d for %s\n",
-	              mode, path);
-	    return;
-    }
+		gam_error(DEBUG_INFO, "Unknown operation %d for %s\n", mode, path);
+		return;
+	}
 
-    G_LOCK(inotify);
+	G_LOCK(inotify);
 
-    if (mode == GAMIN_ACTIVATE) {
-        if ((data = g_hash_table_lookup(path_hash, path)) != NULL) {
-            data->refcount++;
-	    GAM_DEBUG(DEBUG_INFO, "  found incremented refcount: %d\n",
-	              data->refcount);
-            G_UNLOCK(inotify);
+	if (mode == GAMIN_ACTIVATE) {
+		data = g_hash_table_lookup (path_hash, path);
+
+		if (data != NULL) {
+			data->refcount++;
+			GAM_DEBUG (DEBUG_INFO, "inotify: incremented refcount for %s (ref = %d)\n", path, data->refcount);
 #ifdef GAMIN_DEBUG_API
-            gam_debug_report(GAMinotifyChange, path, data->refcount);
+			gam_debug_report(GAMinotifyChange, path, data->refcount);
 #endif
-            GAM_DEBUG(DEBUG_INFO, "inotify updated refcount\n");
-            return;
-        }
-
-	path_wd = syscall (INOTIFY_ADD, inotify_device_fd, path, should_poll_mask);
-
-	if (path_wd < 0) {
-		int e = errno;
-		GAM_DEBUG(DEBUG_INFO, "INOTIFY_ADD failed for %s\n", path);
-		GAM_DEBUG(DEBUG_INFO, "Error = %s\n", strerror(e));
-		G_UNLOCK(inotify);
-		return;
-	}
+			G_UNLOCK(inotify);
+			return;
+		}
 
-        data = gam_inotify_data_new(path, path_wd);
-        g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd), data);
-        g_hash_table_insert(path_hash, data->path, data);
+		/* We aren't already watching this path */
+		path_wd = gam_inotify_add_watch (path, should_poll_mask);
+		if (path_wd < 0) {
+			G_UNLOCK(inotify);
+			return;
+		}
 
-        GAM_DEBUG(DEBUG_INFO, "activated inotify for %s\n", path);
+		data = gam_inotify_data_new (path, path_wd);
+		g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd), data);
+		g_hash_table_insert(path_hash, data->path, data);
 #ifdef GAMIN_DEBUG_API
-        gam_debug_report(GAMinotifyCreate, path, 0);
+		gam_debug_report(GAMinotifyCreate, path, 0);
 #endif
-    } else if (mode == GAMIN_DESACTIVATE) {
-	data = g_hash_table_lookup(path_hash, path);
+		G_UNLOCK(inotify);
+		return;
+	} else if (mode == GAMIN_DESACTIVATE) {
+		data = g_hash_table_lookup(path_hash, path);
 
-	if (!data) {
-	    GAM_DEBUG(DEBUG_INFO, "  not found !!!\n");
+		if (!data) {
+			GAM_DEBUG (DEBUG_INFO, "inotify: requested DEACTIVATE on unknown path: %s\n", data->path);
+			G_UNLOCK (inotify);
+			return;
+		}
 
-            G_UNLOCK(inotify);
-            return;
-	}
+		data->refcount--;
+		GAM_DEBUG (DEBUG_INFO, "inotify: decremented refcount for %s (ref = %d)\n", path, data->refcount);
 
-        data->refcount--;
-        GAM_DEBUG(DEBUG_INFO, "inotify decremeneted refcount for %s\n",
-                  path);
-
-        if (data->refcount == 0) {
-	    int wd = data->wd;
-	    g_assert (data->wd >= 0);
-	    GAM_DEBUG(DEBUG_INFO, "removed inotify watch for %s\n", 
-                    data->path);
-	    g_hash_table_remove(path_hash, data->path);
-	    g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd));
+		if (data->refcount == 0) {
+		    int wd = data->wd;
+		    g_assert (wd >= 0);
+
+		    GAM_DEBUG (DEBUG_INFO, "inotify: refcount == 0 for %s (wd = %d)\n", path, wd);
+		    g_hash_table_remove(path_hash, data->path);
+		    g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd));
 
-	    if (data->ignored) {
-		    GAM_DEBUG(DEBUG_INFO, "INOTIFY_IGNORE IGNORED for %s (wd = %d)\n", data->path, data->wd);
-	    }
-	    if (data->deactivated == FALSE) {
-		    if (syscall (INOTIFY_RM, inotify_device_fd, wd) < 0) {
-			int e = errno;
-			GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE failed for %s (wd = %d)\n", data->path, data->wd);
+		    if (data->ignored) {
+			    GAM_DEBUG (DEBUG_INFO, "inotify: removing IGNORED watch for %s (wd = %d)\n", data->path, data->wd);
+		    }
 
-			GAM_DEBUG(DEBUG_INFO, "reason = %s\n", strerror (e));
+		    if (data->deactivated == FALSE) {
+			    gam_inotify_rm_watch (data->path, data->wd);
 		    } else {
-			GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE success for %s (wd = %d)\n", data->path, data->wd);
+			    GAM_DEBUG (DEBUG_INFO, "inotify: removing deactivated watch for %s\n", data->path);
 		    }
-	    } else {
-		    GAM_DEBUG (DEBUG_INFO, "removed deactivated inotify watch for %s\n", data->path);
-	    }
 #ifdef GAMIN_DEBUG_API
-	    gam_debug_report(GAMinotifyDelete, data->path, 0);
+		    gam_debug_report(GAMinotifyDelete, data->path, 0);
 #endif
-	    gam_inotify_data_free(data);
-        } else {
-	    GAM_DEBUG(DEBUG_INFO, "  found decremented refcount: %d\n",
-	              data->refcount);
-#ifdef GAMIN_DEBUG_API
-            gam_debug_report(GAMinotifyChange, data->path, data->refcount);
-#endif
-	}
-    } else if ((mode == GAMIN_FLOWCONTROLSTART) ||
-               (mode == GAMIN_FLOWCONTROLSTOP)) {
-        data = g_hash_table_lookup(path_hash, path);
-        if (!data) {
-            GAM_DEBUG(DEBUG_INFO, "  not found !!!\n");
-            G_UNLOCK(inotify);
-            return;
-        }
-        if (data != NULL) {
-	    if (mode == GAMIN_FLOWCONTROLSTART) {
-		GAM_DEBUG(DEBUG_INFO, "inotify: GAMIN_FLOWCONTROLSTART for %s\n", data->path);
-		if (!data->deactivated) {
-		    if (syscall (INOTIFY_RM, inotify_device_fd, data->wd) < 0) {
-			int e = errno;
-			GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE failed for %s (wd = %d)\n", data->path, data->wd);
-			GAM_DEBUG(DEBUG_INFO, "reason = %s\n", strerror (e));
-		    } else {
-			GAM_DEBUG (DEBUG_INFO, "INOTIFY_IGNORE success for %s (wd = %d)\n", data->path, data->wd);
-		    }
-		    data->deactivated = TRUE;
-		    GAM_DEBUG(DEBUG_INFO, "deactivated inotify for %s\n",
-			      data->path);
+		    gam_inotify_data_free(data);
+		    G_UNLOCK (inotify);
+		    return;
+		} else {
 #ifdef GAMIN_DEBUG_API
-		    gam_debug_report(GAMinotifyFlowOn, data->path, 0);
+		    gam_debug_report(GAMinotifyChange, data->path, data->refcount);
 #endif
-		} else {
-			GAM_DEBUG(DEBUG_INFO, "inotify: GAMIN_FLOWCONTROLSTART for %s -- AGAIN!!!!\n", data->path);
 		}
-		data->busy++;
-	    } else {
-		GAM_DEBUG(DEBUG_INFO, "inotify: GAMIN_FLOWCONTROLSTOP for %s\n", data->path);
-	        if (data->busy > 0) {
-		    GAM_DEBUG(DEBUG_INFO, "inotify: data->busy > 0 for %s\n", data->path);
-		    data->busy--;
-		    if (data->busy == 0) {
-			GAM_DEBUG(DEBUG_INFO, "inotify: data->busy == 0 for %s\n", data->path);
-
-			path_wd = syscall (INOTIFY_ADD, inotify_device_fd, data->path, should_poll_mask);
-
-			if (path_wd < 0) {
-			    int e = errno;
-			    G_UNLOCK(inotify);
-			    GAM_DEBUG(DEBUG_INFO,
-			              "failed to reactivate inotify for %s\n",
-				      data->path);
-			    GAM_DEBUG(DEBUG_INFO, "reason = %s\n", strerror (e));
+	} 
+	else if ((mode == GAMIN_FLOWCONTROLSTART) || (mode == GAMIN_FLOWCONTROLSTOP))
+	{
+		data = g_hash_table_lookup(path_hash, path);
+
+		if (!data) {
+			GAM_DEBUG (DEBUG_INFO, "inotify: requested FLOWOP on unknown path: %s\n", data->path);
+			G_UNLOCK (inotify);
+			return;
+		}
 
-                            return;
+		if (mode == GAMIN_FLOWCONTROLSTART) {
+			if (!data->deactivated) {
+				GAM_DEBUG (DEBUG_INFO, "inotify: enabling flow control for %s\n", data->path);
+				if (gam_inotify_rm_watch (data->path, data->wd) < 0)
+				{
+					G_UNLOCK(inotify);
+					return;
+				}
+				data->deactivated = TRUE;
+#ifdef GAMIN_DEBUG_API
+				gam_debug_report(GAMinotifyFlowOn, data->path, 0);
+#endif
 			}
-			g_assert (data->wd >= 0);
-			g_assert (path_wd >= 0);
-
-			/* Remove the old wd from the hash table */
-			g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd));
-			data->wd = path_wd;
-			data->deactivated = FALSE;
-
-			/* Insert the new wd into the hash table */
-			g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd),
-			                    data);
-			GAM_DEBUG(DEBUG_INFO, "reactivated inotify for %s\n",
-			          data->path);
+			data->busy++;
+			GAM_DEBUG (DEBUG_INFO, "inotify: incremented busy count for %s (busy = %d)\n", data->path, data->busy);
+			G_UNLOCK(inotify);
+			return;
+		} else {
+			if (data->busy > 0) {
+				data->busy--;
+				GAM_DEBUG (DEBUG_INFO, "inotify: incremented busy count for %s (busy = %d)\n", data->path, data->busy);
+				if (data->busy == 0) {
+					GAM_DEBUG(DEBUG_INFO, "inotify: disabling flow control for %s\n", data->path);
+
+					path_wd = gam_inotify_add_watch (data->path, should_poll_mask);
+
+					if (path_wd < 0) {
+						G_UNLOCK(inotify);
+						return;
+					}
+
+					g_assert (data->wd >= 0);
+					g_assert (path_wd >= 0);
+
+					/* Remove the old wd from the hash table */
+					g_hash_table_remove(wd_hash, GINT_TO_POINTER(data->wd));
+
+
+					/* Insert the new wd into the hash table */
+					data->wd = path_wd;
+					data->deactivated = FALSE;
+					g_hash_table_insert(wd_hash, GINT_TO_POINTER(data->wd), data);
 #ifdef GAMIN_DEBUG_API
-			gam_debug_report(GAMinotifyFlowOff, path, 0);
+					gam_debug_report(GAMinotifyFlowOff, path, 0);
 #endif
-		    }
+					G_UNLOCK(inotify);
+					return;
+				}
+			} else {
+				GAM_DEBUG (DEBUG_INFO, "inotify: requested FLOWSTOP for watch with busy count <= 0 for %s (busy = %d)\n", data->path, data->busy);
+				G_UNLOCK (inotify);
+				return;
+			}
 		}
-	    }
 	}
-    } else {
-	GAM_DEBUG(DEBUG_INFO, "Unimplemented operation\n");
-    }
-
-    G_UNLOCK(inotify);
 }
 
 static void
@@ -418,17 +405,17 @@
     G_LOCK(inotify);
 
     if (ioctl(inotify_device_fd, FIONREAD, &buffer_size) < 0) {
-	G_UNLOCK(inotify);
 	GAM_DEBUG(DEBUG_INFO, "inotify FIONREAD < 0. kaboom!\n");
+	G_UNLOCK(inotify);
 	return FALSE;
     }
 
     buffer = g_malloc(buffer_size);
 
     if (g_io_channel_read_chars(inotify_read_ioc, (char *)buffer, buffer_size, &read_size, NULL) != G_IO_STATUS_NORMAL) {
-	G_UNLOCK(inotify);
 	GAM_DEBUG(DEBUG_INFO, "inotify failed to read events from inotify fd.\n");
 	g_free (buffer);
+	G_UNLOCK(inotify);
 	return FALSE;
     }
 
@@ -444,12 +431,13 @@
 
 	data = g_hash_table_lookup (wd_hash, GINT_TO_POINTER(event->wd));
 	if (!data) {
-	    GAM_DEBUG(DEBUG_INFO, "processing event: inotify can't find wd %d\n", event->wd);
+	    GAM_DEBUG(DEBUG_INFO, "inotify: processing event and I can't find wd %d\n", event->wd);
 	} else if (data->deactivated) {
 	    GAM_DEBUG(DEBUG_INFO, "inotify: ignoring event on temporarily deactivated watch %s\n", data->path);
             data->deactivated_events++;
 	} else if (data->ignored) {
             GAM_DEBUG(DEBUG_INFO, "inotify: got event on ignored watch %s\n", data->path);
+	    data->ignored_events++;
         } else {
 	    if (event->mask == IN_IGNORED) {
 		GAM_DEBUG(DEBUG_INFO, "inotify: IN_IGNORE on wd=%d\n", event->wd);
@@ -457,14 +445,13 @@
                 data->ignored_events++;
 	    } else if (event->mask != IN_Q_OVERFLOW) {
 		if (event->mask & should_poll_mask) {
-		    GAM_DEBUG(DEBUG_INFO, "inotify requesting poll for %s\n", data->path);
-		    GAM_DEBUG(DEBUG_INFO, "poll was requested for event = ");
+		    GAM_DEBUG(DEBUG_INFO, "inotify: requesting poll for %s event = ", data->path);
 		    print_mask (event->mask);
                     data->events++;
 		    gam_poll_scan_directory (data->path);
 		}
 	    } else if (event->mask == IN_Q_OVERFLOW) {
-		    GAM_DEBUG(DEBUG_INFO, "inotify queue over flowed, requesting poll on all watched paths\n");
+		    GAM_DEBUG(DEBUG_INFO, "inotify: queue over flowed, requesting poll on all watched paths\n");
                     g_hash_table_foreach (path_hash, gam_inotify_q_overflow, NULL);
 	    }
 	}
@@ -534,7 +521,7 @@
 
     g_return_val_if_fail(gam_poll_init_full(FALSE), FALSE);
 
-    inotify_device_fd = syscall(INOTIFY_INIT);
+    inotify_device_fd = inotify_init ();
 
     if (inotify_device_fd < 0) {
         GAM_DEBUG(DEBUG_INFO, "Could not open /dev/inotify\n");
@@ -630,4 +617,50 @@
     return TRUE;
 }
 
+
+int gam_inotify_add_watch (const char *path, __u32 mask)
+{
+	int wd = -1;
+
+	g_assert (path&&*path);
+	g_assert (inotify_device_fd >= 0);
+
+	wd = inotify_add_watch (inotify_device_fd, path, mask);
+
+	if (wd < 0)
+	{
+		int e = errno;
+		GAM_DEBUG (DEBUG_INFO, "inotify: failed to add watch for %s\n", path);
+		GAM_DEBUG (DEBUG_INFO, "inotify: reason = %s\n", strerror (e));
+		return wd;
+	} 
+	else 
+	{
+		GAM_DEBUG (DEBUG_INFO, "inotify: success adding watch for %s (wd = %d)\n", path, wd);
+	}
+
+	g_assert (wd >= 0);
+
+	return wd;
+}
+
+int gam_inotify_rm_watch (const char *path, __u32 wd)
+{
+	g_assert (wd >= 0);
+
+	if (inotify_rm_watch (inotify_device_fd, wd) < 0) 
+	{
+		int e = errno;
+		GAM_DEBUG (DEBUG_INFO, "inotify: failed to rm watch for %s (wd = %d)\n", path, wd);
+		GAM_DEBUG (DEBUG_INFO, "inotify: reason = %s\n", strerror (e));
+		return -1;
+	}
+	else
+	{
+		GAM_DEBUG (DEBUG_INFO, "inotify: success removing watch for %s (wd = %d)\n", path, wd);
+	}
+
+	return 0;
+}
+
 /** @} */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]