View | Details | Raw Unified | Return to bug 226920 | Differences between
and this patch

Collapse All | Expand All

(-)Makefile (-1 / +18 lines)
Lines 3-9 Link Here
3
3
4
PORTNAME=	glib
4
PORTNAME=	glib
5
PORTVERSION=	2.50.3
5
PORTVERSION=	2.50.3
6
PORTREVISION=	1
6
PORTREVISION=	2
7
PORTEPOCH=	1
7
PORTEPOCH=	1
8
CATEGORIES=	devel
8
CATEGORIES=	devel
9
MASTER_SITES=	GNOME
9
MASTER_SITES=	GNOME
Lines 28-33 Link Here
28
# (wchar_t is used by glibmm, rawtherapee triggered this)
28
# (wchar_t is used by glibmm, rawtherapee triggered this)
29
USES+=		compiler:c11 gettext gmake gnome iconv:wchar_t libtool \
29
USES+=		compiler:c11 gettext gmake gnome iconv:wchar_t libtool \
30
		localbase pathfix perl5 pkgconfig python shebangfix
30
		localbase pathfix perl5 pkgconfig python shebangfix
31
USES+=		autoreconf
31
USE_PYTHON=	py3kplist
32
USE_PYTHON=	py3kplist
32
CONFIGURE_ARGS=	--disable-gtk-doc --with-html-dir=${PREFIX}/share/doc \
33
CONFIGURE_ARGS=	--disable-gtk-doc --with-html-dir=${PREFIX}/share/doc \
33
		--disable-man --without-xml-catalog \
34
		--disable-man --without-xml-catalog \
Lines 94-103 Link Here
94
	@${REINPLACE_CMD} -e 's|/usr/local|${LOCALBASE}|g ; \
95
	@${REINPLACE_CMD} -e 's|/usr/local|${LOCALBASE}|g ; \
95
		s|/usr/share/locale/locale|${LOCALBASE}/share/locale/locale|g' \
96
		s|/usr/share/locale/locale|${LOCALBASE}/share/locale/locale|g' \
96
			${WRKSRC}/glib/gutils.c
97
			${WRKSRC}/glib/gutils.c
98
.if 0
97
	@${REINPLACE_CMD} -e 's|inotify_support=yes|inotify_support=no| ; \
99
	@${REINPLACE_CMD} -e 's|inotify_support=yes|inotify_support=no| ; \
98
		s|-Werror|| ; \
100
		s|-Werror|| ; \
99
		s|#define HAVE_SYS_INOTIFY_H 1||' ${WRKSRC}/configure
101
		s|#define HAVE_SYS_INOTIFY_H 1||' ${WRKSRC}/configure
102
.else
103
	@${REINPLACE_CMD} -e '/sys\/inotify.h/,/^])/d ; \
104
		s|G_THREAD_LIBS_FOR_GTHREAD.*-lpthread/.*|LDFLAGS="$$LDFLAGS -pthread"|' \
105
		${WRKSRC}/configure.ac
106
	@${REINPLACE_CMD} -e '/^SUBDIRS =/d' \
107
		${WRKSRC}/docs/reference/Makefile.am
108
	@${REINPLACE_CMD} -e 's|^install-exec-local:|not-&|' \
109
		${WRKSRC}/glib/libcharset/Makefile.am
110
	@${REINPLACE_CMD} -e 's|-Werror ||' \
111
		${WRKSRC}/m4macros/attributes.m4
100
112
113
post-patch-COLLATION_FIX-on:
114
	@${REINPLACE_CMD} -e 's|GLIB_LINK_FLAGS)|& -licui18n|' \
115
		${WRKSRC}/glib/Makefile.am
116
.endif
117
101
post-install:
118
post-install:
102
	@${MKDIR} ${STAGEDIR}${PREFIX}/share/GConf/gsettings
119
	@${MKDIR} ${STAGEDIR}${PREFIX}/share/GConf/gsettings
103
	@${MKDIR} ${STAGEDIR}${PREFIX}/lib/gio/modules
120
	@${MKDIR} ${STAGEDIR}${PREFIX}/lib/gio/modules
(-)files/patch-gio_filemonitor (+1043 lines)
Line 0 Link Here
1
# gio: Always purge kqueue subs from missing list
2
# https://github.com/GNOME/glib/commit/e305fe971e4647d971428a772b7290b9c308a96f
3
# kqueue: Fix invalid emission of G_FILE_MONITOR_EVENT_MOVED event
4
# https://github.com/GNOME/glib/commit/76072a2dde4a4acc8be8d3c47efbc6811ebe0c1e
5
# kqueue: Multiple fixes and simplifications
6
# https://github.com/GNOME/glib/commit/aa39a0557c679fc345b0ba72a87c33152eb8ebcd
7
# gpollfilemonitor: Fix use-after-free caused by leaking GSource
8
# https://github.com/GNOME/glib/commit/ba4a9538e14e8ba0ea037cab5f4b23aa47272a4c
9
10
--- gio/gpollfilemonitor.c.orig	2016-10-22 05:17:34 UTC
11
+++ gio/gpollfilemonitor.c
12
@@ -50,7 +50,9 @@ g_poll_file_monitor_finalize (GObject* o
13
   
14
   poll_monitor = G_POLL_FILE_MONITOR (object);
15
 
16
+  g_poll_file_monitor_cancel (G_FILE_MONITOR (poll_monitor));
17
   g_object_unref (poll_monitor->file);
18
+  g_clear_object (&poll_monitor->last_info);
19
 
20
   G_OBJECT_CLASS (g_poll_file_monitor_parent_class)->finalize (object);
21
 }
22
--- gio/kqueue/Makefile.am.orig	2016-10-22 05:18:22 UTC
23
+++ gio/kqueue/Makefile.am
24
@@ -4,19 +4,9 @@ noinst_LTLIBRARIES += libkqueue.la
25
 
26
 libkqueue_la_SOURCES = \
27
        gkqueuefilemonitor.c \
28
-       gkqueuefilemonitor.h \
29
        kqueue-helper.c \
30
        kqueue-helper.h \
31
-       kqueue-thread.c \
32
-       kqueue-thread.h \
33
-       kqueue-sub.c \
34
-       kqueue-sub.h \
35
        kqueue-missing.c \
36
-       kqueue-missing.h \
37
-       kqueue-utils.c \
38
-       kqueue-utils.h \
39
-       kqueue-exclusions.c \
40
-       kqueue-exclusions.h \
41
        dep-list.c \
42
        dep-list.h \
43
        $(NULL)
44
--- gio/kqueue/gkqueuefilemonitor.c.orig	2016-10-22 05:18:22 UTC
45
+++ gio/kqueue/gkqueuefilemonitor.c
46
@@ -22,33 +22,73 @@
47
 
48
 #include "config.h"
49
 
50
-#include "gkqueuefilemonitor.h"
51
-#include "kqueue-helper.h"
52
-#include "kqueue-exclusions.h"
53
+#include <sys/types.h>
54
+#include <sys/event.h>
55
+#include <sys/time.h>
56
+#include <sys/socket.h>
57
+#include <sys/stat.h>
58
+
59
+#include <errno.h>
60
+#include <fcntl.h>
61
+#include <string.h>
62
+
63
+#include <glib-object.h>
64
+#include <gio/gfilemonitor.h>
65
+#include <gio/glocalfilemonitor.h>
66
+#include <gio/giomodule.h>
67
 #include <gio/gpollfilemonitor.h>
68
 #include <gio/gfile.h>
69
-#include <gio/giomodule.h>
70
+#include <glib-unix.h>
71
+#include "glib-private.h"
72
 
73
+#include "kqueue-helper.h"
74
+#include "dep-list.h"
75
 
76
-struct _GKqueueFileMonitor
77
+G_LOCK_DEFINE_STATIC (kq_lock);
78
+static GSource       *kq_source;
79
+static int	      kq_queue = -1;
80
+
81
+#define G_TYPE_KQUEUE_FILE_MONITOR	(g_kqueue_file_monitor_get_type ())
82
+#define G_KQUEUE_FILE_MONITOR(inst)	(G_TYPE_CHECK_INSTANCE_CAST ((inst), \
83
+					G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitor))
84
+
85
+typedef GLocalFileMonitorClass GKqueueFileMonitorClass;
86
+
87
+typedef struct
88
 {
89
   GLocalFileMonitor parent_instance;
90
 
91
   kqueue_sub *sub;
92
-
93
+#ifndef O_EVTONLY
94
   GFileMonitor *fallback;
95
   GFile *fbfile;
96
-};
97
+#endif
98
+} GKqueueFileMonitor;
99
+
100
+GType g_kqueue_file_monitor_get_type (void);
101
+G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
102
+	g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
103
+		g_define_type_id,
104
+                "kqueue",
105
+		20))
106
+
107
+#ifndef O_EVTONLY
108
+#define O_KQFLAG O_RDONLY
109
+#else
110
+#define O_KQFLAG O_EVTONLY
111
+#endif
112
+
113
+#define NOTE_ALL (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_RENAME)
114
 
115
 static gboolean g_kqueue_file_monitor_cancel (GFileMonitor* monitor);
116
+static gboolean g_kqueue_file_monitor_is_supported (void);
117
 
118
-G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
119
-       g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
120
-               g_define_type_id,
121
-               "kqueue",
122
-               20))
123
+static kqueue_sub	*_kqsub_new (const gchar *, GLocalFileMonitor *, GFileMonitorSource *);
124
+static void		 _kqsub_free (kqueue_sub *);
125
+static gboolean		 _kqsub_cancel (kqueue_sub *);
126
 
127
 
128
+#ifndef O_EVTONLY
129
 static void
130
 _fallback_callback (GFileMonitor      *unused,
131
                     GFile             *first,
132
@@ -57,21 +97,41 @@ _fallback_callback (GFileMonitor      *u
133
                     gpointer           udata)
134
 {
135
   GKqueueFileMonitor *kq_mon = G_KQUEUE_FILE_MONITOR (udata);
136
-  GFileMonitor *mon = G_FILE_MONITOR (kq_mon);
137
-  g_assert (kq_mon != NULL);
138
-  g_assert (mon != NULL);
139
-  (void) unused;
140
-
141
-  if (event == G_FILE_MONITOR_EVENT_CHANGED)
142
-    {
143
-      GLocalFileMonitor *local_monitor = G_LOCAL_FILE_MONITOR (kq_mon);
144
 
145
-      _kh_dir_diff (kq_mon->sub, local_monitor->source);
146
-    }
147
-  else
148
-    g_file_monitor_emit_event (mon, first, second, event);
149
+  g_file_monitor_emit_event (G_FILE_MONITOR (kq_mon), first, second, event);
150
 }
151
 
152
+/*
153
+ * _ke_is_excluded:
154
+ * @full_path - a path to file to check.
155
+ *
156
+ * Returns: TRUE if the file should be excluded from the kqueue-powered
157
+ *      monitoring, FALSE otherwise.
158
+ **/
159
+gboolean
160
+_ke_is_excluded (const char *full_path)
161
+{
162
+  GFile *f = NULL;
163
+  GMount *mount = NULL;
164
+
165
+  f = g_file_new_for_path (full_path);
166
+
167
+  if (f != NULL) {
168
+    mount = g_file_find_enclosing_mount (f, NULL, NULL);
169
+    g_object_unref (f);
170
+  }
171
+
172
+  if ((mount != NULL && (g_mount_can_unmount (mount))) || g_str_has_prefix (full_path, "/mnt/"))
173
+  {
174
+    g_warning ("Excluding %s from kernel notification, falling back to poll", full_path);
175
+    if (mount)
176
+      g_object_unref (mount);
177
+    return TRUE;
178
+  }
179
+
180
+  return FALSE;
181
+}
182
+#endif /* !O_EVTONLY */
183
 
184
 static void
185
 g_kqueue_file_monitor_finalize (GObject *object)
186
@@ -80,16 +140,18 @@ g_kqueue_file_monitor_finalize (GObject 
187
 
188
   if (kqueue_monitor->sub)
189
     {
190
-      _kh_cancel_sub (kqueue_monitor->sub);
191
-      _kh_sub_free (kqueue_monitor->sub);
192
+      _kqsub_cancel (kqueue_monitor->sub);
193
+      _kqsub_free (kqueue_monitor->sub);
194
       kqueue_monitor->sub = NULL;
195
     }
196
 
197
+#ifndef O_EVTONLY
198
   if (kqueue_monitor->fallback)
199
     g_object_unref (kqueue_monitor->fallback);
200
 
201
   if (kqueue_monitor->fbfile)
202
     g_object_unref (kqueue_monitor->fbfile);
203
+#endif
204
 
205
   if (G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize)
206
     (*G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize) (object);
207
@@ -103,21 +165,25 @@ g_kqueue_file_monitor_start (GLocalFileM
208
                              GFileMonitorSource *source)
209
 {
210
   GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (local_monitor);
211
-  GObject *obj;
212
-  GKqueueFileMonitorClass *klass;
213
-  GObjectClass *parent_class;
214
-  kqueue_sub *sub = NULL;
215
-  gboolean ret_kh_startup = FALSE;
216
-  const gchar *path = NULL; 
217
-
218
-
219
-  ret_kh_startup = _kh_startup ();
220
-  g_assert (ret_kh_startup);
221
+  kqueue_sub *sub;
222
+  const gchar *path;
223
 
224
   path = filename;
225
-  if (!path)
226
+  if (path == NULL)
227
     path = dirname;
228
 
229
+#ifndef O_EVTONLY
230
+  if (_ke_is_excluded (path))
231
+    {
232
+      GFile *file = g_file_new_for_path (path);
233
+      kqueue_monitor->fbfile = file;
234
+      kqueue_monitor->fallback = _g_poll_file_monitor_new (file);
235
+      g_signal_connect (kqueue_monitor->fallback, "changed",
236
+			G_CALLBACK (_fallback_callback), kqueue_monitor);
237
+      return;
238
+    }
239
+#endif
240
+
241
   /* For a directory monitor, create a subscription object anyway.
242
    * It will be used for directory diff calculation routines. 
243
    * Wait, directory diff in a GKqueueFileMonitor?
244
@@ -125,33 +191,13 @@ g_kqueue_file_monitor_start (GLocalFileM
245
    * file, GIO uses a GKqueueFileMonitor object for that. If a directory
246
    * will be created under that path, GKqueueFileMonitor will have to
247
    * handle the directory notifications. */
248
+  sub = _kqsub_new (path, local_monitor, source);
249
+  if (sub == NULL)
250
+    return;
251
 
252
-  sub = _kh_sub_new (path, TRUE, source);
253
-
254
-  /* FIXME: what to do about errors here? we can't return NULL or another
255
-   * kind of error and an assertion is probably too hard (same issue as in
256
-   * the inotify backend) */
257
-  g_assert (sub != NULL);
258
   kqueue_monitor->sub = sub;
259
-
260
-  if (!_ke_is_excluded (path))
261
-    _kh_add_sub (sub);
262
-  else
263
-    {
264
-      GFile *file = g_file_new_for_path (path);
265
-      kqueue_monitor->fbfile = file;
266
-      kqueue_monitor->fallback = _g_poll_file_monitor_new (file);
267
-      g_signal_connect (kqueue_monitor->fallback,
268
-                        "changed",
269
-                        G_CALLBACK (_fallback_callback),
270
-                        kqueue_monitor);
271
-    }
272
-}
273
-
274
-static gboolean
275
-g_kqueue_file_monitor_is_supported (void)
276
-{
277
-  return _kh_startup ();
278
+  if (!_kqsub_start_watching (sub))
279
+    _km_add_missing (sub);
280
 }
281
 
282
 static void
283
@@ -175,24 +221,218 @@ g_kqueue_file_monitor_init (GKqueueFileM
284
 }
285
 
286
 static gboolean
287
+g_kqueue_file_monitor_callback (gint fd, GIOCondition condition, gpointer user_data)
288
+{
289
+  gint64 now = g_source_get_time (kq_source);
290
+  kqueue_sub *sub;
291
+  GFileMonitorSource *source;
292
+  struct kevent ev;
293
+  struct timespec ts;
294
+
295
+  memset (&ts, 0, sizeof(ts));
296
+  while (kevent(fd, NULL, 0, &ev, 1, &ts) > 0)
297
+    {
298
+        GFileMonitorEvent mask = 0;
299
+
300
+        if (ev.filter != EVFILT_VNODE || ev.udata == NULL)
301
+          continue;
302
+
303
+	sub = ev.udata;
304
+        source = sub->source;
305
+
306
+        if (ev.flags & EV_ERROR)
307
+          ev.fflags = NOTE_REVOKE;
308
+
309
+        if (ev.fflags & (NOTE_DELETE | NOTE_REVOKE))
310
+          {
311
+            _kqsub_cancel (sub);
312
+            _km_add_missing (sub);
313
+          }
314
+
315
+        if (sub->is_dir && ev.fflags & (NOTE_WRITE | NOTE_EXTEND))
316
+          {
317
+            _kh_dir_diff (sub);
318
+            ev.fflags &= ~(NOTE_WRITE | NOTE_EXTEND);
319
+          }
320
+
321
+        if (ev.fflags & NOTE_DELETE)
322
+          {
323
+            mask = G_FILE_MONITOR_EVENT_DELETED;
324
+          }
325
+        else if (ev.fflags & NOTE_ATTRIB)
326
+          {
327
+            mask = G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED;
328
+          }
329
+        else if (ev.fflags & (NOTE_WRITE | NOTE_EXTEND))
330
+          {
331
+            mask = G_FILE_MONITOR_EVENT_CHANGED;
332
+          }
333
+        else if (ev.fflags & NOTE_RENAME)
334
+          {
335
+            /* Since there’s apparently no way to get the new name of the
336
+             * file out of kqueue(), all we can do is say that this one has
337
+             * been deleted. */
338
+            mask = G_FILE_MONITOR_EVENT_DELETED;
339
+          }
340
+        else if (ev.fflags & NOTE_REVOKE)
341
+          {
342
+            mask = G_FILE_MONITOR_EVENT_UNMOUNTED;
343
+          }
344
+
345
+        if (mask)
346
+          g_file_monitor_source_handle_event (source, mask, NULL, NULL, NULL, now);
347
+    }
348
+
349
+  return TRUE;
350
+}
351
+
352
+static gboolean
353
+g_kqueue_file_monitor_is_supported (void)
354
+{
355
+  int errsv;
356
+
357
+  G_LOCK (kq_lock);
358
+
359
+  if (kq_queue == -1)
360
+    {
361
+      kq_queue = kqueue ();
362
+      errsv = errno;
363
+
364
+      if (kq_queue == -1)
365
+        {
366
+          g_warning ("Unable to create a kqueue: %s", g_strerror (errsv));
367
+          G_UNLOCK (kq_lock);
368
+          return FALSE;
369
+        }
370
+
371
+      kq_source = g_unix_fd_source_new (kq_queue, G_IO_IN);
372
+      g_source_set_callback (kq_source, (GSourceFunc) g_kqueue_file_monitor_callback, NULL, NULL);
373
+      g_source_attach (kq_source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
374
+    }
375
+
376
+  G_UNLOCK (kq_lock);
377
+
378
+  return TRUE;
379
+}
380
+
381
+static gboolean
382
 g_kqueue_file_monitor_cancel (GFileMonitor *monitor)
383
 {
384
   GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (monitor);
385
 
386
   if (kqueue_monitor->sub)
387
     {
388
-      _kh_cancel_sub (kqueue_monitor->sub);
389
-      _kh_sub_free (kqueue_monitor->sub);
390
+      _kqsub_cancel (kqueue_monitor->sub);
391
+      _kqsub_free (kqueue_monitor->sub);
392
       kqueue_monitor->sub = NULL;
393
     }
394
+#ifndef O_EVTONLY
395
   else if (kqueue_monitor->fallback)
396
     {
397
       g_signal_handlers_disconnect_by_func (kqueue_monitor->fallback, _fallback_callback, kqueue_monitor);
398
       g_file_monitor_cancel (kqueue_monitor->fallback);
399
     }
400
+#endif
401
 
402
   if (G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel)
403
     (*G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel) (monitor);
404
 
405
   return TRUE;
406
 }
407
+
408
+static kqueue_sub *
409
+_kqsub_new (const gchar *filename, GLocalFileMonitor *mon, GFileMonitorSource *source)
410
+{
411
+  kqueue_sub *sub;
412
+
413
+  sub = g_slice_new (kqueue_sub);
414
+  sub->filename = g_strdup (filename);
415
+  sub->mon = mon;
416
+  g_source_ref ((GSource *) source);
417
+  sub->source = source;
418
+  sub->fd = -1;
419
+  sub->deps = NULL;
420
+  sub->is_dir = 0;
421
+
422
+  return sub;
423
+}
424
+
425
+static void
426
+_kqsub_free (kqueue_sub *sub)
427
+{
428
+  g_assert (sub->deps == NULL);
429
+  g_assert (sub->fd == -1);
430
+
431
+  g_source_unref ((GSource *) sub->source);
432
+  g_free (sub->filename);
433
+  g_slice_free (kqueue_sub, sub);
434
+}
435
+
436
+static gboolean
437
+_kqsub_cancel (kqueue_sub *sub)
438
+{
439
+  struct kevent ev;
440
+
441
+  if (sub->deps)
442
+    {
443
+      dl_free (sub->deps);
444
+      sub->deps = NULL;
445
+    }
446
+
447
+  _km_remove (sub);
448
+
449
+  /* Only in the missing list?  We're done! */
450
+  if (sub->fd == -1)
451
+    return TRUE;
452
+
453
+  EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_DELETE, NOTE_ALL, 0, sub);
454
+  if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1)
455
+    {
456
+      g_warning ("Unable to remove event for %s: %s", sub->filename, g_strerror (errno));
457
+      return FALSE;
458
+    }
459
+
460
+  close (sub->fd);
461
+  sub->fd = -1;
462
+
463
+  return TRUE;
464
+}
465
+
466
+gboolean
467
+_kqsub_start_watching (kqueue_sub *sub)
468
+{
469
+  struct stat st;
470
+  struct kevent ev;
471
+
472
+  sub->fd = open (sub->filename, O_KQFLAG);
473
+  if (sub->fd == -1)
474
+      return FALSE;
475
+
476
+  if (fstat (sub->fd, &st) == -1)
477
+    {
478
+      g_warning ("fstat failed for %s: %s", sub->filename, g_strerror (errno));
479
+      close (sub->fd);
480
+      sub->fd = -1;
481
+      return FALSE;
482
+    }
483
+
484
+  sub->is_dir = (st.st_mode & S_IFDIR) ? 1 : 0;
485
+  if (sub->is_dir)
486
+    {
487
+      if (sub->deps)
488
+        dl_free (sub->deps);
489
+
490
+      sub->deps = dl_listing (sub->filename);
491
+    }
492
+
493
+  EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_ALL, 0, sub);
494
+  if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1)
495
+    {
496
+      g_warning ("Unable to add event for %s: %s", sub->filename, g_strerror (errno));
497
+      close (sub->fd);
498
+      sub->fd = -1;
499
+      return FALSE;
500
+    }
501
+
502
+  return TRUE;
503
+}
504
--- gio/kqueue/kqueue-helper.c.orig	2016-10-22 05:18:22 UTC
505
+++ gio/kqueue/kqueue-helper.c
506
@@ -34,81 +34,6 @@
507
 #include <errno.h>
508
 #include <pthread.h>
509
 #include "kqueue-helper.h"
510
-#include "kqueue-utils.h"
511
-#include "kqueue-thread.h"
512
-#include "kqueue-missing.h"
513
-#include "kqueue-exclusions.h"
514
-
515
-static gboolean kh_debug_enabled = FALSE;
516
-#define KH_W if (kh_debug_enabled) g_warning
517
-
518
-static GHashTable *subs_hash_table = NULL;
519
-G_LOCK_DEFINE_STATIC (hash_lock);
520
-
521
-static int kqueue_descriptor = -1;
522
-static int kqueue_socket_pair[] = {-1, -1};
523
-static pthread_t kqueue_thread;
524
-
525
-
526
-void _kh_file_appeared_cb (kqueue_sub *sub);
527
-
528
-/**
529
- * accessor function for kqueue_descriptor
530
- **/
531
-int
532
-get_kqueue_descriptor()
533
-{
534
-  return kqueue_descriptor;
535
-}
536
-
537
-/**
538
- * convert_kqueue_events_to_gio:
539
- * @flags: a set of kqueue filter flags
540
- * @done: a pointer to #gboolean indicating that the
541
- *      conversion has been done (out)
542
- *
543
- * Translates kqueue filter flags into GIO event flags.
544
- *
545
- * Returns: a #GFileMonitorEvent
546
- **/
547
-static GFileMonitorEvent
548
-convert_kqueue_events_to_gio (uint32_t flags, gboolean *done)
549
-{
550
-  g_assert (done != NULL);
551
-  *done = FALSE;
552
-
553
-  /* TODO: The following notifications should be emulated, if possible:
554
-   * - G_FILE_MONITOR_EVENT_PRE_UNMOUNT
555
-   */
556
-  if (flags & NOTE_DELETE)
557
-    {    
558
-      *done = TRUE;
559
-      return G_FILE_MONITOR_EVENT_DELETED;
560
-    }
561
-  if (flags & NOTE_ATTRIB)
562
-    {
563
-      *done = TRUE;
564
-      return G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED;
565
-    }
566
-  if (flags & (NOTE_WRITE | NOTE_EXTEND))
567
-    {
568
-      *done = TRUE;
569
-      return G_FILE_MONITOR_EVENT_CHANGED;
570
-    }
571
-  if (flags & NOTE_RENAME)
572
-    {
573
-      *done = TRUE;
574
-      return G_FILE_MONITOR_EVENT_MOVED;
575
-    }
576
-  if (flags & NOTE_REVOKE)
577
-    {
578
-      *done = TRUE;
579
-      return G_FILE_MONITOR_EVENT_UNMOUNTED;
580
-    }
581
-
582
-  /* done is FALSE */
583
-  return 0;
584
-}
585
 
586
 typedef struct {
587
   kqueue_sub *sub;
588
@@ -236,323 +161,21 @@ static const traverse_cbs cbs = {
589
 
590
 
591
 void
592
-_kh_dir_diff (kqueue_sub *sub, GFileMonitorSource *source)
593
+_kh_dir_diff (kqueue_sub *sub)
594
 {
595
   dep_list *was;
596
   handle_ctx ctx;
597
 
598
-  g_assert (sub != NULL);
599
-  g_assert (source != NULL);
600
-
601
   memset (&ctx, 0, sizeof (handle_ctx));
602
   ctx.sub = sub;
603
-  ctx.source = source;
604
+  ctx.source = sub->source;
605
 
606
   was = sub->deps;
607
   sub->deps = dl_listing (sub->filename);
608
- 
609
+
610
   dl_calculate (was, sub->deps, &cbs, &ctx);
611
 
612
   dl_free (was);
613
 }
614
 
615
 
616
-/**
617
- * process_kqueue_notifications:
618
- * @gioc: unused.
619
- * @cond: unused.
620
- * @data: unused.
621
- *
622
- * Processes notifications, coming from the kqueue thread.
623
- *
624
- * Reads notifications from the command file descriptor, emits the
625
- * "changed" event on the appropriate monitor.
626
- *
627
- * A typical GIO Channel callback function.
628
- *
629
- * Returns: %TRUE
630
- **/
631
-static gboolean
632
-process_kqueue_notifications (GIOChannel   *gioc,
633
-                              GIOCondition  cond,
634
-                              gpointer      data)
635
-{
636
-  struct kqueue_notification n;
637
-  kqueue_sub *sub = NULL;
638
-  GFileMonitorSource *source = NULL;
639
-  GFileMonitorEvent mask = 0;
640
-  
641
-  g_assert (kqueue_socket_pair[0] != -1);
642
-  if (!_ku_read (kqueue_socket_pair[0], &n, sizeof (struct kqueue_notification)))
643
-    {
644
-      KH_W ("Failed to read a kqueue notification, error %d", errno);
645
-      return TRUE;
646
-    }
647
-
648
-  G_LOCK (hash_lock);
649
-  sub = (kqueue_sub *) g_hash_table_lookup (subs_hash_table, GINT_TO_POINTER (n.fd));
650
-  G_UNLOCK (hash_lock);
651
-
652
-  if (sub == NULL)
653
-    {
654
-      KH_W ("Got a notification for a deleted or non-existing subscription %d",
655
-             n.fd);
656
-      return TRUE;
657
-    }
658
-
659
-  source = sub->user_data;
660
-  g_assert (source != NULL);
661
-
662
-  if (n.flags & (NOTE_DELETE | NOTE_REVOKE))
663
-    {
664
-      if (sub->deps)
665
-        {
666
-          dl_free (sub->deps);
667
-          sub->deps = NULL;  
668
-        }  
669
-      _km_add_missing (sub);
670
-
671
-      if (!(n.flags & NOTE_REVOKE))
672
-        {
673
-          /* Note that NOTE_REVOKE is issued by the kqueue thread
674
-           * on EV_ERROR kevent. In this case, a file descriptor is
675
-           * already closed from the kqueue thread, no need to close
676
-           * it manually */ 
677
-          _kh_cancel_sub (sub);
678
-        }
679
-    }
680
-
681
-  if (sub->is_dir && n.flags & (NOTE_WRITE | NOTE_EXTEND))
682
-    {
683
-      _kh_dir_diff (sub, source);
684
-      n.flags &= ~(NOTE_WRITE | NOTE_EXTEND);
685
-    }
686
-
687
-  if (n.flags)
688
-    {
689
-      gboolean done = FALSE;
690
-      mask = convert_kqueue_events_to_gio (n.flags, &done);
691
-      if (done == TRUE)
692
-        g_file_monitor_source_handle_event (source, mask, NULL, NULL, NULL, g_get_monotonic_time ());
693
-    }
694
-
695
-  return TRUE;
696
-}
697
-
698
-
699
-/*
700
- * _kh_startup_impl:
701
- * @unused: unused
702
- *
703
- * Kqueue backend startup code. Should be called only once.
704
- *
705
- * Returns: %TRUE on success, %FALSE otherwise.
706
- **/
707
-static gpointer
708
-_kh_startup_impl (gpointer unused)
709
-{
710
-  GIOChannel *channel = NULL;
711
-  gboolean result = FALSE;
712
-
713
-  kqueue_descriptor = kqueue ();
714
-  result = (kqueue_descriptor != -1);
715
-  if (!result)
716
-    {
717
-      KH_W ("Failed to initialize kqueue\n!");
718
-      return GINT_TO_POINTER (FALSE);
719
-    }
720
-
721
-  result = socketpair (AF_UNIX, SOCK_STREAM, 0, kqueue_socket_pair);
722
-  if (result != 0)
723
-    {
724
-      KH_W ("Failed to create socket pair\n!");
725
-      return GINT_TO_POINTER (FALSE) ;
726
-    }
727
-
728
-  result = pthread_create (&kqueue_thread,
729
-                           NULL,
730
-                           _kqueue_thread_func,
731
-                           &kqueue_socket_pair[1]);
732
-  if (result != 0)
733
-    {
734
-      KH_W ("Failed to run kqueue thread\n!");
735
-      return GINT_TO_POINTER (FALSE);
736
-    }
737
-
738
-  _km_init (_kh_file_appeared_cb);
739
-
740
-  channel = g_io_channel_unix_new (kqueue_socket_pair[0]);
741
-  g_io_add_watch (channel, G_IO_IN, process_kqueue_notifications, NULL);
742
-
743
-  subs_hash_table = g_hash_table_new (g_direct_hash, g_direct_equal);
744
-
745
-  KH_W ("started gio kqueue backend\n");
746
-  return GINT_TO_POINTER (TRUE);
747
-}
748
-
749
-
750
-/*
751
- * _kh_startup:
752
- * Kqueue backend initialization.
753
- *
754
- * Returns: %TRUE on success, %FALSE otherwise.
755
- **/
756
-gboolean
757
-_kh_startup (void)
758
-{
759
-  static GOnce init_once = G_ONCE_INIT;
760
-  g_once (&init_once, _kh_startup_impl, NULL);
761
-  return GPOINTER_TO_INT (init_once.retval);
762
-}
763
-
764
-
765
-/**
766
- * _kh_start_watching:
767
- * @sub: a #kqueue_sub
768
- *
769
- * Starts watching on a subscription.
770
- *
771
- * Returns: %TRUE on success, %FALSE otherwise.
772
- **/
773
-gboolean
774
-_kh_start_watching (kqueue_sub *sub)
775
-{
776
-  g_assert (kqueue_socket_pair[0] != -1);
777
-  g_assert (sub != NULL);
778
-  g_assert (sub->filename != NULL);
779
-
780
-  /* kqueue requires a file descriptor to monitor. Sad but true */
781
-#if defined (O_EVTONLY)
782
-  sub->fd = open (sub->filename, O_EVTONLY);
783
-#else
784
-  sub->fd = open (sub->filename, O_RDONLY);
785
-#endif
786
-
787
-  if (sub->fd == -1)
788
-    {
789
-      KH_W ("failed to open file %s (error %d)", sub->filename, errno);
790
-      return FALSE;
791
-    }
792
-
793
-  _ku_file_information (sub->fd, &sub->is_dir, NULL);
794
-  if (sub->is_dir)
795
-    {
796
-      /* I know, it is very bad to make such decisions in this way and here.
797
-       * We already do have an user_data at the #kqueue_sub, and it may point to
798
-       * GKqueueFileMonitor or GKqueueDirectoryMonitor. For a directory case,
799
-       * we need to scan in contents for the further diffs. Ideally this process
800
-       * should be delegated to the GKqueueDirectoryMonitor, but for now I will
801
-       * do it in a dirty way right here. */
802
-      if (sub->deps)
803
-        dl_free (sub->deps);
804
-
805
-      sub->deps = dl_listing (sub->filename);  
806
-    }
807
-
808
-  G_LOCK (hash_lock);
809
-  g_hash_table_insert (subs_hash_table, GINT_TO_POINTER (sub->fd), sub);
810
-  G_UNLOCK (hash_lock);
811
-
812
-  _kqueue_thread_push_fd (sub->fd);
813
-  
814
-  /* Bump the kqueue thread. It will pick up a new sub entry to monitor */
815
-  if (!_ku_write (kqueue_socket_pair[0], "A", 1))
816
-    KH_W ("Failed to bump the kqueue thread (add fd, error %d)", errno);
817
-  return TRUE;
818
-}
819
-
820
-
821
-/**
822
- * _kh_add_sub:
823
- * @sub: a #kqueue_sub
824
- *
825
- * Adds a subscription for monitoring.
826
- *
827
- * This funciton tries to start watching a subscription with
828
- * _kh_start_watching(). On failure, i.e. when a file does not exist yet,
829
- * the subscription will be added to a list of missing files to continue
830
- * watching when the file will appear.
831
- *
832
- * Returns: %TRUE
833
- **/
834
-gboolean
835
-_kh_add_sub (kqueue_sub *sub)
836
-{
837
-  g_assert (sub != NULL);
838
-
839
-  if (!_kh_start_watching (sub))
840
-    _km_add_missing (sub);
841
-
842
-  return TRUE;
843
-}
844
-
845
-
846
-/**
847
- * _kh_cancel_sub:
848
- * @sub a #kqueue_sub
849
- *
850
- * Stops monitoring on a subscription.
851
- *
852
- * Returns: %TRUE
853
- **/
854
-gboolean
855
-_kh_cancel_sub (kqueue_sub *sub)
856
-{
857
-  gboolean missing = FALSE;
858
-  g_assert (kqueue_socket_pair[0] != -1);
859
-  g_assert (sub != NULL);
860
-
861
-  G_LOCK (hash_lock);
862
-  missing = !g_hash_table_remove (subs_hash_table, GINT_TO_POINTER (sub->fd));
863
-  G_UNLOCK (hash_lock);
864
-
865
-  if (missing)
866
-    {
867
-      /* If there were no fd for this subscription, file is still
868
-       * missing. */
869
-      KH_W ("Removing subscription from missing");
870
-      _km_remove (sub);
871
-    }
872
-  else
873
-    {
874
-      /* fd will be closed in the kqueue thread */
875
-      _kqueue_thread_remove_fd (sub->fd);
876
-
877
-      /* Bump the kqueue thread. It will pick up a new sub entry to remove*/
878
-      if (!_ku_write (kqueue_socket_pair[0], "R", 1))
879
-        KH_W ("Failed to bump the kqueue thread (remove fd, error %d)", errno);
880
-    }
881
-
882
-  return TRUE;
883
-}
884
-
885
-
886
-/**
887
- * _kh_file_appeared_cb:
888
- * @sub: a #kqueue_sub
889
- *
890
- * A callback function for kqueue-missing subsystem.
891
- *
892
- * Signals that a missing file has finally appeared in the filesystem.
893
- * Emits %G_FILE_MONITOR_EVENT_CREATED.
894
- **/
895
-void
896
-_kh_file_appeared_cb (kqueue_sub *sub)
897
-{
898
-  GFile* child;
899
-
900
-  g_assert (sub != NULL);
901
-  g_assert (sub->filename);
902
-
903
-  if (!g_file_test (sub->filename, G_FILE_TEST_EXISTS))
904
-    return;
905
-
906
-  child = g_file_new_for_path (sub->filename);
907
-
908
-  g_file_monitor_emit_event (G_FILE_MONITOR (sub->user_data),
909
-                             child,
910
-                             NULL,
911
-                             G_FILE_MONITOR_EVENT_CREATED);
912
-
913
-  g_object_unref (child);
914
-}
915
--- gio/kqueue/kqueue-helper.h.orig	2016-10-22 05:18:22 UTC
916
+++ gio/kqueue/kqueue-helper.h
917
@@ -23,16 +23,31 @@
918
 #ifndef __KQUEUE_HELPER_H
919
 #define __KQUEUE_HELPER_H
920
 
921
-#include "kqueue-sub.h"
922
 #include <gio/glocalfilemonitor.h>
923
 #include <gio/gfilemonitor.h>
924
 
925
-gboolean _kh_startup        (void);
926
-gboolean _kh_add_sub        (kqueue_sub *sub);
927
-gboolean _kh_cancel_sub     (kqueue_sub *sub);
928
+#include "dep-list.h"
929
 
930
-gboolean _kh_start_watching (kqueue_sub *sub);
931
+/**
932
+ * kqueue_sub:
933
+ * @filename: a name of the file to monitor
934
+ * @fd: the associated file descriptor (used by kqueue)
935
+ *
936
+ * Represents a subscription on a file or directory.
937
+ */
938
+typedef struct
939
+{
940
+  GLocalFileMonitor   *mon;
941
+  GFileMonitorSource  *source;
942
+  gchar*    filename;
943
+  int       fd;
944
+  dep_list* deps;
945
+  int       is_dir;
946
+} kqueue_sub;
947
 
948
-void     _kh_dir_diff       (kqueue_sub *sub, GFileMonitorSource *source);
949
+gboolean _kqsub_start_watching (kqueue_sub *sub);
950
+void _kh_dir_diff    (kqueue_sub *sub);
951
+void _km_add_missing (kqueue_sub *sub);
952
+void _km_remove      (kqueue_sub *sub);
953
 
954
 #endif /* __KQUEUE_HELPER_H */
955
--- gio/kqueue/kqueue-missing.c.orig	2016-10-22 05:18:22 UTC
956
+++ gio/kqueue/kqueue-missing.c
957
@@ -23,12 +23,12 @@
958
 #include <glib.h>
959
 
960
 #include "kqueue-helper.h"
961
-#include "kqueue-sub.h"
962
-#include "kqueue-missing.h"
963
 
964
 
965
 #define SCAN_MISSING_TIME 4 /* 1/4 Hz */
966
 
967
+void _kh_file_appeared_cb (kqueue_sub *sub);
968
+
969
 static gboolean km_scan_missing (gpointer user_data);
970
 
971
 static gboolean km_debug_enabled = FALSE;
972
@@ -38,21 +38,6 @@ static GSList *missing_subs_list = NULL;
973
 G_LOCK_DEFINE_STATIC (missing_lock);
974
 
975
 static volatile gboolean scan_missing_running = FALSE;
976
-static on_create_cb file_appeared_callback;
977
-
978
-
979
-/**
980
- * _km_init:
981
- * @cb: a callback function. It will be called when a watched file
982
- *     will appear.
983
- *
984
- * Initialize the kqueue-missing module (optional).
985
- **/
986
-void
987
-_km_init (on_create_cb cb)
988
-{
989
-  file_appeared_callback = cb;
990
-}
991
 
992
 
993
 /**
994
@@ -83,6 +68,35 @@ _km_add_missing (kqueue_sub *sub)
995
     }
996
 }
997
 
998
+/**
999
+ * _kh_file_appeared_cb:
1000
+ * @sub: a #kqueue_sub
1001
+ *
1002
+ * A callback function for kqueue-missing subsystem.
1003
+ *
1004
+ * Signals that a missing file has finally appeared in the filesystem.
1005
+ * Emits %G_FILE_MONITOR_EVENT_CREATED.
1006
+ **/
1007
+void
1008
+_kh_file_appeared_cb (kqueue_sub *sub)
1009
+{
1010
+  GFile *child;
1011
+
1012
+  g_assert (sub != NULL);
1013
+  g_assert (sub->filename);
1014
+
1015
+  if (!g_file_test (sub->filename, G_FILE_TEST_EXISTS))
1016
+    return;
1017
+
1018
+  child = g_file_new_for_path (sub->filename);
1019
+
1020
+  g_file_monitor_emit_event (G_FILE_MONITOR (sub->mon),
1021
+                             child,
1022
+                             NULL,
1023
+                             G_FILE_MONITOR_EVENT_CREATED);
1024
+
1025
+  g_object_unref (child);
1026
+}
1027
 
1028
 /**
1029
  * km_scan_missing:
1030
@@ -114,11 +128,10 @@ km_scan_missing (gpointer user_data)
1031
       g_assert (sub != NULL);
1032
       g_assert (sub->filename != NULL);
1033
 
1034
-      if (_kh_start_watching (sub))
1035
+      if (_kqsub_start_watching (sub))
1036
         {
1037
           KM_W ("file %s now exists, starting watching", sub->filename);
1038
-          if (file_appeared_callback)
1039
-            file_appeared_callback (sub);
1040
+          _kh_file_appeared_cb (sub);
1041
           not_missing = g_slist_prepend (not_missing, head);
1042
         }
1043
     }
(-)files/patch-gio_kqueue_gkqueuefilemonitor.c (-45 lines)
Lines 1-45 Link Here
1
https://bugzilla.gnome.org/show_bug.cgi?id=739424
2
https://bug739424.bugzilla-attachments.gnome.org/attachment.cgi?id=351191
3
4
--- gio/kqueue/gkqueuefilemonitor.c.orig	2018-01-15 21:00:32.535064000 +0100
5
+++ gio/kqueue/gkqueuefilemonitor.c	2018-01-15 21:07:20.920334000 +0100
6
@@ -29,6 +29,15 @@
7
 #include <gio/gfile.h>
8
 #include <gio/giomodule.h>
9
 
10
+/*
11
+ * Because ``kqueue_sub'' are not refcounted, we need
12
+ * ensure no other thread is getting a reference to
13
+ * the element we want to free.
14
+ *
15
+ * That's why _kh_cancel_sub() must be called with
16
+ * this lock held to prevent a race.
17
+ */
18
+G_LOCK_EXTERN (hash_lock);
19
 
20
 struct _GKqueueFileMonitor
21
 {
22
@@ -80,9 +89,11 @@ g_kqueue_file_monitor_finalize (GObject *object)
23
 
24
   if (kqueue_monitor->sub)
25
     {
26
+      G_LOCK (hash_lock);
27
       _kh_cancel_sub (kqueue_monitor->sub);
28
       _kh_sub_free (kqueue_monitor->sub);
29
       kqueue_monitor->sub = NULL;
30
+      G_UNLOCK (hash_lock);
31
     }
32
 
33
   if (kqueue_monitor->fallback)
34
@@ -181,9 +192,11 @@ g_kqueue_file_monitor_cancel (GFileMonitor *monitor)
35
 
36
   if (kqueue_monitor->sub)
37
     {
38
+      G_LOCK (hash_lock);
39
       _kh_cancel_sub (kqueue_monitor->sub);
40
       _kh_sub_free (kqueue_monitor->sub);
41
       kqueue_monitor->sub = NULL;
42
+      G_UNLOCK (hash_lock);
43
     }
44
   else if (kqueue_monitor->fallback)
45
     {
(-)files/patch-gio_kqueue_kqueue-helper.c (-96 lines)
Lines 1-96 Link Here
1
This bug combines serveral patches:
2
https://bugzilla.gnome.org/show_bug.cgi?id=778515
3
and
4
https://bugzilla.gnome.org/show_bug.cgi?id=739424
5
https://bug739424.bugzilla-attachments.gnome.org/attachment.cgi?id=351191
6
7
https://bugzilla.gnome.org/show_bug.cgi?id=776147
8
https://git.gnome.org/browse/glib/commit/?id=76072a2dde4a4acc8be8d3c47efbc6811ebe0c1e
9
10
--- gio/kqueue/kqueue-helper.c.orig	2018-01-28 21:18:25.213606000 +0100
11
+++ gio/kqueue/kqueue-helper.c	2018-01-28 21:18:34.964780000 +0100
12
@@ -43,7 +43,7 @@ static gboolean kh_debug_enabled = FALSE;
13
 #define KH_W if (kh_debug_enabled) g_warning
14
 
15
 static GHashTable *subs_hash_table = NULL;
16
-G_LOCK_DEFINE_STATIC (hash_lock);
17
+G_LOCK_DEFINE (hash_lock);
18
 
19
 static int kqueue_descriptor = -1;
20
 static int kqueue_socket_pair[] = {-1, -1};
21
@@ -97,8 +97,10 @@ convert_kqueue_events_to_gio (uint32_t flags, gboolean
22
     }
23
   if (flags & NOTE_RENAME)
24
     {
25
+      /* Since there’s apparently no way to get the new name of the file out of
26
+       * kqueue(), all we can do is say that this one has been deleted. */
27
       *done = TRUE;
28
-      return G_FILE_MONITOR_EVENT_MOVED;
29
+      return G_FILE_MONITOR_EVENT_DELETED;
30
     }
31
   if (flags & NOTE_REVOKE)
32
     {
33
@@ -291,10 +293,10 @@ process_kqueue_notifications (GIOChannel   *gioc,
34
 
35
   G_LOCK (hash_lock);
36
   sub = (kqueue_sub *) g_hash_table_lookup (subs_hash_table, GINT_TO_POINTER (n.fd));
37
-  G_UNLOCK (hash_lock);
38
 
39
   if (sub == NULL)
40
     {
41
+      G_UNLOCK (hash_lock);
42
       KH_W ("Got a notification for a deleted or non-existing subscription %d",
43
              n.fd);
44
       return TRUE;
45
@@ -336,6 +338,7 @@ process_kqueue_notifications (GIOChannel   *gioc,
46
         g_file_monitor_source_handle_event (source, mask, NULL, NULL, NULL, g_get_monotonic_time ());
47
     }
48
 
49
+  G_UNLOCK (hash_lock);
50
   return TRUE;
51
 }
52
 
53
@@ -451,13 +454,14 @@ _kh_start_watching (kqueue_sub *sub)
54
 
55
   G_LOCK (hash_lock);
56
   g_hash_table_insert (subs_hash_table, GINT_TO_POINTER (sub->fd), sub);
57
-  G_UNLOCK (hash_lock);
58
 
59
   _kqueue_thread_push_fd (sub->fd);
60
   
61
   /* Bump the kqueue thread. It will pick up a new sub entry to monitor */
62
   if (!_ku_write (kqueue_socket_pair[0], "A", 1))
63
     KH_W ("Failed to bump the kqueue thread (add fd, error %d)", errno);
64
+  G_UNLOCK (hash_lock);
65
+
66
   return TRUE;
67
 }
68
 
69
@@ -498,22 +502,15 @@ _kh_add_sub (kqueue_sub *sub)
70
 gboolean
71
 _kh_cancel_sub (kqueue_sub *sub)
72
 {
73
-  gboolean missing = FALSE;
74
+  gboolean removed = FALSE;
75
   g_assert (kqueue_socket_pair[0] != -1);
76
   g_assert (sub != NULL);
77
 
78
-  G_LOCK (hash_lock);
79
-  missing = !g_hash_table_remove (subs_hash_table, GINT_TO_POINTER (sub->fd));
80
-  G_UNLOCK (hash_lock);
81
+  _km_remove (sub);
82
 
83
-  if (missing)
84
-    {
85
-      /* If there were no fd for this subscription, file is still
86
-       * missing. */
87
-      KH_W ("Removing subscription from missing");
88
-      _km_remove (sub);
89
-    }
90
-  else
91
+  removed = g_hash_table_remove (subs_hash_table, GINT_TO_POINTER (sub->fd));
92
+
93
+  if (removed)
94
     {
95
       /* fd will be closed in the kqueue thread */
96
       _kqueue_thread_remove_fd (sub->fd);

Return to bug 226920