[gamin] Flow control patch



Yo,

I'm attaching a patch that reworks flow control. The new code is quicker
to re-enable kernel monitoring but I think it works fairly well. With
the patch if we get more than 4 events in 1 second, we disable kernel
monitoring, and start polling. When in poll mode, if 1 poll pass goes by
without an event happening, we re-enable kernel monitoring.

John
Index: gamin/server/gam_poll.c
===================================================================
--- gamin.orig/server/gam_poll.c
+++ gamin/server/gam_poll.c
@@ -39,7 +39,7 @@
 
 /* #define VERBOSE_POLL */
 
-#define DEFAULT_POLL_TIMEOUT 3
+#define DEFAULT_POLL_TIMEOUT 1
 
 #define FLAG_NEW_NODE 1 << 5
 
@@ -60,7 +60,6 @@ static GList *all_resources = NULL;
 static GamPollHandler dir_handler = NULL;
 static GamPollHandler file_handler = NULL;
 static pollHandlerKernel type_khandler = GAMIN_K_NONE;
-G_LOCK_DEFINE_STATIC(poll_lock);
 
 static int poll_mode = 0;
 
@@ -187,12 +186,12 @@ trigger_file_handler(const char *path, p
 	    dir = parent->path;
 	    switch (mode) {
 	        case GAMIN_ACTIVATE:
-		    GAM_DEBUG(DEBUG_INFO, "File activating dnotify on %s\n",
+		    GAM_DEBUG(DEBUG_INFO, "File activating kernel monitoring on %s\n",
 			      dir);
 		    (*dir_handler) (dir, mode);
 		    break;
 	        case GAMIN_DESACTIVATE:
-		    GAM_DEBUG(DEBUG_INFO, "File deactivating dnotify on %s\n",
+		    GAM_DEBUG(DEBUG_INFO, "File deactivating kernel monitoring on %s\n",
 			      dir);
 		    (*dir_handler) (dir, mode);
 		    break;
@@ -207,7 +206,7 @@ trigger_file_handler(const char *path, p
 		    break;
 		case GAMIN_FLOWCONTROLSTOP:
 		    if (parent->pflags & MON_BUSY) {
-			GAM_DEBUG(DEBUG_INFO, "File dir no more busy %s\n",
+			GAM_DEBUG(DEBUG_INFO, "File dir no longer busy %s\n",
 				  dir);
 			(*dir_handler) (dir, mode);
 			gam_poll_remove_busy(parent);
@@ -542,62 +541,65 @@ poll_file(GamNode * node)
     if (node->pflags & MON_NOKERNEL)
         return (event);
 
-    /*
-     * load control, switch back to poll on very busy resources
-     * and back when no update has happened in 5 seconds
-     */
-    if (current_time == node->lasttime) {
-        if (!(node->pflags & MON_BUSY)) {
-            if (sbuf.st_mtime == current_time)
-                node->checks++;
-        }
-    } else {
-        node->lasttime = current_time;
-        if (node->pflags & MON_BUSY) {
-            if (event == 0)
-                node->checks++;
-        } else {
-            node->checks = 0;
-        }
+    if (!(node->flags & MON_BUSY)) 
+    {
+	    if (current_time == node->lasttime)
+	    {
+		    if (sbuf.st_mtime == current_time)
+			    node->flow_on_ticks++;
+	    } else {
+		    node->flow_on_ticks = 0;
+	    }
     }
 
-    if ((node->checks >= 4) && (!(node->pflags & MON_BUSY))) {
-        if ((gam_node_get_subscriptions(node) != NULL) &&
-            (!gam_exclude_check(node->path))) {
-            GAM_DEBUG(DEBUG_INFO, "switching %s back to polling\n", path);
-            node->pflags |= MON_BUSY;
-            node->checks = 0;
-            gam_poll_add_busy(node);
-            gam_poll_flowon_node(node);
-            /*
-             * DNotify can be nasty here, we will miss events for parent dir
-             * if we are not careful about it
-             */
-            if (!gam_node_is_dir(node)) {
-                GamNode *parent = gam_node_parent(node);
-
-                if ((parent != NULL) &&
-                    (gam_node_get_subscriptions(parent) != NULL)) {
-                    gam_poll_add_busy(parent);
-                    /* gam_poll_flowon_node(parent); */
-                }
-            }
-        }
-    }
+    /* if this path is excluded from kernel monitoring, stop here */
+    if (gam_exclude_check (node->path)) 
+	    return (event);
+
+    /* if no one is subscribed to this node, stop here */
+    if (!gam_node_get_subscriptions (node))
+	    return (event);
+
+	/* Is this node currently being monitored by the kernel? */
+	if (!(node->pflags & MON_BUSY))
+	{
+		if (node->flow_on_ticks >= 4)
+		{
+		// enable flow control
+			GAM_DEBUG(DEBUG_INFO, "switching %s back to polling\n", path);
+			node->pflags |= MON_BUSY;
+			node->flow_on_ticks = 0;
+			gam_poll_add_busy(node);
+			gam_poll_flowon_node(node);
+			/*
+			* DNotify can be nasty here, we will miss events for parent dir
+			* if we are not careful about it
+			*/
+			if (!gam_node_is_dir(node)) {
+				GamNode *parent = gam_node_parent(node);
+
+				if ((parent != NULL) &&
+				    (gam_node_get_subscriptions(parent) != NULL)) {
+				    gam_poll_add_busy(parent);
+				    /* gam_poll_flowon_node(parent); */
+				}
+			}
+		}
+	} else {
+		/* Time has passed, and no event has come in */
+		if (current_time != node->lasttime && event == 0) {
+			GAM_DEBUG(DEBUG_INFO, "switching %s back to kernel monitoring\n", path);
+			node->pflags &= ~MON_BUSY;
+			node->flow_on_ticks = 0;
+			gam_poll_remove_busy(node);
+			gam_poll_flowoff_node(node);
+		}
+	}
 
-    if ((event == 0) && (node->pflags & MON_BUSY) && (node->checks > 5)) {
-        if ((gam_node_get_subscriptions(node) != NULL) &&
-            (!gam_exclude_check(node->path))) {
-            GAM_DEBUG(DEBUG_INFO,
-                      "switching %s back to kernel monitoring\n", path);
-            node->pflags &= ~MON_BUSY;
-            node->checks = 0;
-            gam_poll_remove_busy(node);
-            gam_poll_flowoff_node(node);
-        }
-    }
+	if (node->lasttime != current_time)
+		node->lasttime = current_time;
 
-    return (event);
+	return (event);
 }
 
 static void
@@ -880,7 +882,6 @@ static gboolean
 gam_poll_scan_all_callback(gpointer data)
 {
     int idx;
-    GList *subs, *l;
     GamNode *node;
 
     static int in_poll_callback = 0;
@@ -933,10 +934,10 @@ gam_poll_init_full(gboolean start_scan_t
         return(FALSE);
 
     if (!start_scan_thread) {
-        g_timeout_add(1000, gam_poll_scan_callback, NULL);
+        g_timeout_add(DEFAULT_POLL_TIMEOUT * 1000, gam_poll_scan_callback, NULL);
         poll_mode = 1;
     } else {
-        g_timeout_add(1000, gam_poll_scan_all_callback, NULL);
+        g_timeout_add(DEFAULT_POLL_TIMEOUT * 1000, gam_poll_scan_all_callback, NULL);
         poll_mode = 2;
     }
     tree = gam_tree_new();


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