blob: 7d6cf68eaf88a7ce2a03e6cf4e581b51499b6ad5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
https://bugzilla.gnome.org/show_bug.cgi?id=739424
https://bug739424.bugzilla-attachments.gnome.org/attachment.cgi?id=351191
--- gio/kqueue/gkqueuefilemonitor.c.orig 2018-01-15 21:00:32.535064000 +0100
+++ gio/kqueue/gkqueuefilemonitor.c 2018-01-15 21:07:20.920334000 +0100
@@ -29,6 +29,15 @@
#include <gio/gfile.h>
#include <gio/giomodule.h>
+/*
+ * Because ``kqueue_sub'' are not refcounted, we need
+ * ensure no other thread is getting a reference to
+ * the element we want to free.
+ *
+ * That's why _kh_cancel_sub() must be called with
+ * this lock held to prevent a race.
+ */
+G_LOCK_EXTERN (hash_lock);
struct _GKqueueFileMonitor
{
@@ -80,9 +89,11 @@ g_kqueue_file_monitor_finalize (GObject *object)
if (kqueue_monitor->sub)
{
+ G_LOCK (hash_lock);
_kh_cancel_sub (kqueue_monitor->sub);
_kh_sub_free (kqueue_monitor->sub);
kqueue_monitor->sub = NULL;
+ G_UNLOCK (hash_lock);
}
if (kqueue_monitor->fallback)
@@ -181,9 +192,11 @@ g_kqueue_file_monitor_cancel (GFileMonitor *monitor)
if (kqueue_monitor->sub)
{
+ G_LOCK (hash_lock);
_kh_cancel_sub (kqueue_monitor->sub);
_kh_sub_free (kqueue_monitor->sub);
kqueue_monitor->sub = NULL;
+ G_UNLOCK (hash_lock);
}
else if (kqueue_monitor->fallback)
{
|