mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-07-26 03:47:52 +02:00
kqueue: Multiple fixes and simplifications
- Stop using a custom thread for listening to kqueue(2) events. Instead call kevent(2) in non blocking mode in a monitor callback. Under the hood poll(2) is used to figure out if new events are available. - Do not use a socketpair with a custom protocol requiring 2 supplementary context switches per event to commicate between multiple threads. Calling kevent(2), in non blocking mode, to add/remove events is fine from any context. - Add kqueue(2) events without the EV_ONESHOT flag. This removes a race where some notifications were lost because events had to be re-added for every new notification. - Get rid of the global hash table and its associated lock and races. Use the 'cookie' argument of kevent(2) to pass the associated descriptor when registering an event. - Fix _kh_file_appeared_cb() by properly passing a monitor instead of a source to g_file_monitor_emit_event(). - Properly refcount sources. - Remove a lot of abstraction making it harder to fix the remaining issues. https://bugzilla.gnome.org/show_bug.cgi?id=739424
This commit is contained in:
committed by
Philip Withnall
parent
46eedd12c0
commit
aa39a0557c
@@ -23,12 +23,12 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include "kqueue-helper.h"
|
||||
#include "kqueue-sub.h"
|
||||
#include "kqueue-missing.h"
|
||||
|
||||
|
||||
#define SCAN_MISSING_TIME 4 /* 1/4 Hz */
|
||||
|
||||
void _kh_file_appeared_cb (kqueue_sub *sub);
|
||||
|
||||
static gboolean km_scan_missing (gpointer user_data);
|
||||
|
||||
static gboolean km_debug_enabled = FALSE;
|
||||
@@ -38,21 +38,6 @@ static GSList *missing_subs_list = NULL;
|
||||
G_LOCK_DEFINE_STATIC (missing_lock);
|
||||
|
||||
static volatile gboolean scan_missing_running = FALSE;
|
||||
static on_create_cb file_appeared_callback;
|
||||
|
||||
|
||||
/**
|
||||
* _km_init:
|
||||
* @cb: a callback function. It will be called when a watched file
|
||||
* will appear.
|
||||
*
|
||||
* Initialize the kqueue-missing module (optional).
|
||||
**/
|
||||
void
|
||||
_km_init (on_create_cb cb)
|
||||
{
|
||||
file_appeared_callback = cb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -83,6 +68,35 @@ _km_add_missing (kqueue_sub *sub)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _kh_file_appeared_cb:
|
||||
* @sub: a #kqueue_sub
|
||||
*
|
||||
* A callback function for kqueue-missing subsystem.
|
||||
*
|
||||
* Signals that a missing file has finally appeared in the filesystem.
|
||||
* Emits %G_FILE_MONITOR_EVENT_CREATED.
|
||||
**/
|
||||
void
|
||||
_kh_file_appeared_cb (kqueue_sub *sub)
|
||||
{
|
||||
GFile *child;
|
||||
|
||||
g_assert (sub != NULL);
|
||||
g_assert (sub->filename);
|
||||
|
||||
if (!g_file_test (sub->filename, G_FILE_TEST_EXISTS))
|
||||
return;
|
||||
|
||||
child = g_file_new_for_path (sub->filename);
|
||||
|
||||
g_file_monitor_emit_event (G_FILE_MONITOR (sub->mon),
|
||||
child,
|
||||
NULL,
|
||||
G_FILE_MONITOR_EVENT_CREATED);
|
||||
|
||||
g_object_unref (child);
|
||||
}
|
||||
|
||||
/**
|
||||
* km_scan_missing:
|
||||
@@ -114,11 +128,10 @@ km_scan_missing (gpointer user_data)
|
||||
g_assert (sub != NULL);
|
||||
g_assert (sub->filename != NULL);
|
||||
|
||||
if (_kh_start_watching (sub))
|
||||
if (_kqsub_start_watching (sub))
|
||||
{
|
||||
KM_W ("file %s now exists, starting watching", sub->filename);
|
||||
if (file_appeared_callback)
|
||||
file_appeared_callback (sub);
|
||||
_kh_file_appeared_cb (sub);
|
||||
not_missing = g_slist_prepend (not_missing, head);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user