[gamin] Flow control patch
- From: John McCutchan <ttb tentacle dhs org>
- To: gamin-list gnome org
- Subject: [gamin] Flow control patch
- Date: Tue, 26 Jul 2005 18:38:03 -0400
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]