gdbus-tool: simplify some logic
[platform/upstream/glib.git] / gio / inotify / inotify-kernel.c
index e712ee7..b672cb1 100644 (file)
@@ -13,8 +13,7 @@
 
    You should have received a copy of the GNU Library General Public
    License along with the Gnome Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.
+   see <http://www.gnu.org/licenses/>.
 
    Authors:.
                John McCutchan <john@johnmccutchan.com>
@@ -31,6 +30,8 @@
 #include "inotify-kernel.h"
 #include <sys/inotify.h>
 
+#include "glib-private.h"
+
 /* Timings for pairing MOVED_TO / MOVED_FROM events */
 #define PROCESS_EVENTS_TIME 1000 /* 1000 milliseconds (1 hz) */
 #define DEFAULT_HOLD_UNTIL_TIME 0 /* 0 millisecond */
@@ -116,6 +117,7 @@ ik_source_check (GSource *source)
 
   if (pending_count < MAX_PENDING_COUNT)
     {
+      GSource *timeout_source;
       unsigned int pending;
       
       if (ioctl (inotify_instance_fd, FIONREAD, &pending) == -1)
@@ -146,8 +148,12 @@ ik_source_check (GSource *source)
       ik_poll_fd_enabled = FALSE;
       /* Set a timeout to re-add the PollFD to the source */
       g_source_ref (source);
-      g_timeout_add (TIMEOUT_MILLISECONDS, ik_source_timeout, source);
-      
+
+      timeout_source = g_timeout_source_new (TIMEOUT_MILLISECONDS);
+      g_source_set_callback (timeout_source, ik_source_timeout, source, NULL);
+      g_source_attach (timeout_source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
+      g_source_unref (timeout_source);
+
       return FALSE;
     }
 
@@ -190,11 +196,8 @@ gboolean _ik_startup (void (*cb)(ik_event_t *event))
 
   initialized = TRUE;
 
-#ifdef HAVE_INOTIFY_INIT1
   inotify_instance_fd = inotify_init1 (IN_CLOEXEC);
-#else
-  inotify_instance_fd = -1;
-#endif
+
   if (inotify_instance_fd < 0)
     inotify_instance_fd = inotify_init ();
 
@@ -211,7 +214,7 @@ gboolean _ik_startup (void (*cb)(ik_event_t *event))
   g_source_set_name (source, "GIO Inotify");
   g_source_add_poll (source, &ik_poll_fd);
   g_source_set_callback (source, ik_read_callback, NULL, NULL);
-  g_source_attach (source, NULL);
+  g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
   g_source_unref (source);
 
   cookie_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -257,25 +260,6 @@ ik_event_new (char *buffer)
   return event;
 }
 
-ik_event_t *
-_ik_event_new_dummy (const char *name, 
-                     gint32      wd, 
-                     guint32     mask)
-{
-  ik_event_t *event = g_new0 (ik_event_t, 1);
-  event->wd = wd;
-  event->mask = mask;
-  event->cookie = 0;
-  if (name)
-    event->name = g_strdup (name);
-  else
-    event->name = g_strdup("");
-  
-  event->len = strlen (event->name);
-  
-  return event;
-}
-
 void
 _ik_event_free (ik_event_t *event)
 {
@@ -327,98 +311,6 @@ _ik_ignore (const char *path,
   return 0;
 }
 
-void
-_ik_move_stats (guint32 *matches, 
-                guint32 *misses)
-{
-  if (matches)
-    *matches = ik_move_matches;
-  
-  if (misses)
-    *misses = ik_move_misses;
-}
-
-const char *
-_ik_mask_to_string (guint32 mask)
-{
-  gboolean is_dir = mask & IN_ISDIR;
-  mask &= ~IN_ISDIR;
-  
-  if (is_dir)
-    {
-      switch (mask)
-       {
-       case IN_ACCESS:
-         return "ACCESS (dir)";
-       case IN_MODIFY:
-         return "MODIFY (dir)";
-       case IN_ATTRIB:
-         return "ATTRIB (dir)";
-       case IN_CLOSE_WRITE:
-         return "CLOSE_WRITE (dir)";
-       case IN_CLOSE_NOWRITE:
-         return "CLOSE_NOWRITE (dir)"; 
-       case IN_OPEN:
-         return "OPEN (dir)";
-       case IN_MOVED_FROM:
-         return "MOVED_FROM (dir)";
-       case IN_MOVED_TO:
-         return "MOVED_TO (dir)";
-       case IN_DELETE:
-         return "DELETE (dir)";
-       case IN_CREATE:
-         return "CREATE (dir)";
-       case IN_DELETE_SELF:
-         return "DELETE_SELF (dir)";
-       case IN_UNMOUNT:
-         return "UNMOUNT (dir)";
-       case IN_Q_OVERFLOW:
-         return "Q_OVERFLOW (dir)";
-       case IN_IGNORED:
-         return "IGNORED (dir)";
-       default:
-         return "UNKNOWN_EVENT (dir)";
-       }
-    }
-  else
-    {
-      switch (mask)
-       {
-       case IN_ACCESS:
-         return "ACCESS";
-       case IN_MODIFY:
-         return "MODIFY";
-       case IN_ATTRIB:
-         return "ATTRIB";
-       case IN_CLOSE_WRITE:
-         return "CLOSE_WRITE";
-       case IN_CLOSE_NOWRITE:
-         return "CLOSE_NOWRITE";
-       case IN_OPEN:
-         return "OPEN";
-       case IN_MOVED_FROM:
-         return "MOVED_FROM";
-       case IN_MOVED_TO:
-         return "MOVED_TO";
-       case IN_DELETE:
-         return "DELETE";
-       case IN_CREATE:
-         return "CREATE";
-       case IN_DELETE_SELF:
-         return "DELETE_SELF";
-       case IN_UNMOUNT:
-         return "UNMOUNT";
-       case IN_Q_OVERFLOW:
-         return "Q_OVERFLOW";
-       case IN_IGNORED:
-         return "IGNORED";
-       default:
-         return "UNKNOWN_EVENT";
-       }
-    }
-}
-
-
 static void
 ik_read_events (gsize  *buffer_size_out, 
                 gchar **buffer_out)
@@ -470,8 +362,13 @@ ik_read_callback (gpointer user_data)
   /* If the event process callback is off, turn it back on */
   if (!process_eq_running && events)
     {
+      GSource *timeout_source;
+
       process_eq_running = TRUE;
-      g_timeout_add (PROCESS_EVENTS_TIME, ik_process_eq_callback, NULL);
+      timeout_source = g_timeout_source_new (PROCESS_EVENTS_TIME);
+      g_source_set_callback (timeout_source, ik_process_eq_callback, NULL, NULL);
+      g_source_attach (timeout_source, GLIB_PRIVATE_CALL (g_get_worker_context ()));
+      g_source_unref (timeout_source);
     }
   
   G_UNLOCK (inotify_lock);
@@ -480,27 +377,37 @@ ik_read_callback (gpointer user_data)
 }
 
 static gboolean
-g_timeval_lt (GTimeVal *val1, 
+g_timeval_lt (GTimeVal *val1,
               GTimeVal *val2)
 {
   if (val1->tv_sec < val2->tv_sec)
     return TRUE;
-  
+
   if (val1->tv_sec > val2->tv_sec)
     return FALSE;
-  
+
   /* val1->tv_sec == val2->tv_sec */
   if (val1->tv_usec < val2->tv_usec)
     return TRUE;
-  
+
   return FALSE;
 }
 
 static gboolean
-g_timeval_eq (GTimeVal *val1, 
+g_timeval_le (GTimeVal *val1,
               GTimeVal *val2)
 {
-  return (val1->tv_sec == val2->tv_sec) && (val1->tv_usec == val2->tv_usec);
+  if (val1->tv_sec < val2->tv_sec)
+    return TRUE;
+
+  if (val1->tv_sec > val2->tv_sec)
+    return FALSE;
+
+  /* val1->tv_sec == val2->tv_sec */
+  if (val1->tv_usec <= val2->tv_usec)
+    return TRUE;
+
+  return FALSE;
 }
 
 static void
@@ -512,14 +419,15 @@ ik_pair_events (ik_event_internal_t *event1,
   g_assert (event1->event->cookie == event2->event->cookie);
   /* We shouldn't pair an event that already is paired */
   g_assert (event1->pair == NULL && event2->pair == NULL);
-  
+
   /* Pair the internal structures and the ik_event_t structures */
   event1->pair = event2;
   event1->event->pair = event2->event;
-  
+  event2->event->is_second_in_pair = TRUE;
+
   if (g_timeval_lt (&event1->hold_until, &event2->hold_until))
     event1->hold_until = event2->hold_until;
-  
+
   event2->hold_until = event1->hold_until;
 }
 
@@ -548,8 +456,7 @@ ik_event_ready (ik_event_internal_t *event)
   return
     event->event->cookie == 0 ||
     event->pair != NULL ||
-    g_timeval_lt (&event->hold_until, &tv) ||
-    g_timeval_eq (&event->hold_until, &tv);
+    g_timeval_le (&event->hold_until, &tv);
 }
 
 static void
@@ -634,7 +541,8 @@ ik_process_events (void)
           * the event masks */
          /* Changeing MOVED_FROM to DELETE and MOVED_TO to create lets us make
           * the gaurantee that you will never see a non-matched MOVE event */
-         
+         event->event->original_mask = event->event->mask;
+
          if (event->event->mask & IN_MOVED_FROM)
            {
              event->event->mask = IN_DELETE|(event->event->mask & IN_ISDIR);