mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 07:26:15 +01:00
gio: Remove fam file monitor support
libgamin was last released in 2007 and is dead [upstream](https://gitlab.gnome.org/Archive/gamin). Distributions may still ship it (although Fedora no longer does), but we want people to use inotify on Linux since it’s actively supported. BSDs use kqueue. Windows uses win32filemonitor. FAM might still be used on some commercial Unix distributions, but there are no contributors from those distributions, and certainly no CI for them to prevent regressions. Signed-off-by: Philip Withnall <pwithnall@endlessos.org> Fixes: #2614
This commit is contained in:
parent
2759dd71be
commit
6aa210e6af
@ -135,7 +135,6 @@ debian-stable-x86_64:
|
||||
--libdir=lib
|
||||
-Dsystemtap=true
|
||||
-Ddtrace=true
|
||||
-Dfam=true
|
||||
-Dinstalled_tests=true
|
||||
_build
|
||||
- ninja -C _build
|
||||
|
@ -24,7 +24,6 @@ RUN apt-get update -qq && apt-get install --no-install-recommends -qq -y \
|
||||
libdbus-1-dev \
|
||||
libelf-dev \
|
||||
libffi-dev \
|
||||
libgamin-dev \
|
||||
libmount-dev \
|
||||
libpcre3-dev \
|
||||
libselinux1-dev \
|
||||
|
@ -3,7 +3,6 @@ if get_option('gtk_doc')
|
||||
subdir('xml')
|
||||
|
||||
ignore_headers = [
|
||||
'fam',
|
||||
'gdbus-2.0',
|
||||
'gvdb',
|
||||
'inotify',
|
||||
|
@ -392,7 +392,7 @@ Gvfs is also heavily distributed and relies on a session bus to be present.
|
||||
The #GFileMonitor implementation for local files that is included
|
||||
in GIO on Linux has the name <literal>inotify</literal>, others that are built
|
||||
are built as modules (depending on the platform) are called
|
||||
<literal>fam</literal>, <literal>kqueue</literal> and <literal>win32filemonitor</literal>.
|
||||
<literal>kqueue</literal> and <literal>win32filemonitor</literal>.
|
||||
</para><para>
|
||||
The special value <literal>help</literal> can be used to print a list of
|
||||
available implementations to standard output.
|
||||
@ -665,7 +665,7 @@ Gvfs is also heavily distributed and relies on a session bus to be present.
|
||||
</para>
|
||||
<para>
|
||||
GIO uses this extension point internally, to switch between
|
||||
its fam-based and inotify-based file monitoring implementations.
|
||||
its kqueue-based and inotify-based file monitoring implementations.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
|
@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015 Canonical Limited
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Ryan Lortie <desrt@desrt.ca>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gio/glocalfilemonitor.h>
|
||||
#include <gio/giomodule.h>
|
||||
#include "glib-private.h"
|
||||
#include <glib-unix.h>
|
||||
#include <fam.h>
|
||||
|
||||
static GMutex fam_lock;
|
||||
static gboolean fam_initialised;
|
||||
static FAMConnection fam_connection;
|
||||
static GSource *fam_source;
|
||||
|
||||
#define G_TYPE_FAM_FILE_MONITOR (g_fam_file_monitor_get_type ())
|
||||
#define G_FAM_FILE_MONITOR(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||
G_TYPE_FAM_FILE_MONITOR, GFamFileMonitor))
|
||||
|
||||
typedef GLocalFileMonitorClass GFamFileMonitorClass;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLocalFileMonitor parent_instance;
|
||||
|
||||
FAMRequest request;
|
||||
} GFamFileMonitor;
|
||||
|
||||
static GType g_fam_file_monitor_get_type (void);
|
||||
G_DEFINE_DYNAMIC_TYPE (GFamFileMonitor, g_fam_file_monitor, G_TYPE_LOCAL_FILE_MONITOR)
|
||||
|
||||
static gboolean
|
||||
g_fam_file_monitor_callback (gint fd,
|
||||
GIOCondition condition,
|
||||
gpointer user_data)
|
||||
{
|
||||
gint64 now = g_source_get_time (fam_source);
|
||||
|
||||
g_mutex_lock (&fam_lock);
|
||||
|
||||
while (FAMPending (&fam_connection))
|
||||
{
|
||||
const gchar *child;
|
||||
FAMEvent ev;
|
||||
|
||||
if (FAMNextEvent (&fam_connection, &ev) != 1)
|
||||
{
|
||||
/* The daemon died. We're in a really bad situation now
|
||||
* because we potentially have a bunch of request structures
|
||||
* outstanding which no longer make any sense to anyone.
|
||||
*
|
||||
* The best thing that we can do is do nothing. Notification
|
||||
* won't work anymore for this process.
|
||||
*/
|
||||
g_mutex_unlock (&fam_lock);
|
||||
|
||||
g_warning ("Lost connection to FAM (file monitoring) service. Expect no further file monitor events.");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We expect ev.filename to be a relative path for children in a
|
||||
* monitored directory, and an absolute path for a monitored file
|
||||
* or the directory itself.
|
||||
*/
|
||||
if (ev.filename[0] != '/')
|
||||
child = ev.filename;
|
||||
else
|
||||
child = NULL;
|
||||
|
||||
switch (ev.code)
|
||||
{
|
||||
case FAMAcknowledge:
|
||||
g_source_unref (ev.userdata);
|
||||
break;
|
||||
|
||||
case FAMChanged:
|
||||
g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CHANGED, child, NULL, NULL, now);
|
||||
break;
|
||||
|
||||
case FAMDeleted:
|
||||
g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_DELETED, child, NULL, NULL, now);
|
||||
break;
|
||||
|
||||
case FAMCreated:
|
||||
g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CREATED, child, NULL, NULL, now);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unknown type */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock (&fam_lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_fam_file_monitor_is_supported (void)
|
||||
{
|
||||
g_mutex_lock (&fam_lock);
|
||||
|
||||
if (!fam_initialised)
|
||||
{
|
||||
fam_initialised = FAMOpen2 (&fam_connection, "GLib GIO") == 0;
|
||||
|
||||
if (fam_initialised)
|
||||
{
|
||||
#ifdef HAVE_FAM_NO_EXISTS
|
||||
/* This is a gamin extension that avoids sending all the
|
||||
* Exists event for dir monitors
|
||||
*/
|
||||
FAMNoExists (&fam_connection);
|
||||
#endif
|
||||
|
||||
fam_source = g_unix_fd_source_new (FAMCONNECTION_GETFD (&fam_connection), G_IO_IN);
|
||||
g_source_set_callback (fam_source, (GSourceFunc) g_fam_file_monitor_callback, NULL, NULL);
|
||||
g_source_attach (fam_source, GLIB_PRIVATE_CALL(g_get_worker_context) ());
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock (&fam_lock);
|
||||
|
||||
return fam_initialised;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_fam_file_monitor_cancel (GFileMonitor *monitor)
|
||||
{
|
||||
GFamFileMonitor *gffm = G_FAM_FILE_MONITOR (monitor);
|
||||
|
||||
g_mutex_lock (&fam_lock);
|
||||
|
||||
g_assert (fam_initialised);
|
||||
|
||||
FAMCancelMonitor (&fam_connection, &gffm->request);
|
||||
|
||||
g_mutex_unlock (&fam_lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
g_fam_file_monitor_start (GLocalFileMonitor *local_monitor,
|
||||
const gchar *dirname,
|
||||
const gchar *basename,
|
||||
const gchar *filename,
|
||||
GFileMonitorSource *source)
|
||||
{
|
||||
GFamFileMonitor *gffm = G_FAM_FILE_MONITOR (local_monitor);
|
||||
|
||||
g_mutex_lock (&fam_lock);
|
||||
|
||||
g_assert (fam_initialised);
|
||||
|
||||
g_source_ref ((GSource *) source);
|
||||
|
||||
if (dirname)
|
||||
FAMMonitorDirectory (&fam_connection, dirname, &gffm->request, source);
|
||||
else
|
||||
FAMMonitorFile (&fam_connection, filename, &gffm->request, source);
|
||||
|
||||
g_mutex_unlock (&fam_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
g_fam_file_monitor_init (GFamFileMonitor* monitor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
g_fam_file_monitor_class_init (GFamFileMonitorClass *class)
|
||||
{
|
||||
GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (class);
|
||||
|
||||
class->is_supported = g_fam_file_monitor_is_supported;
|
||||
class->start = g_fam_file_monitor_start;
|
||||
file_monitor_class->cancel = g_fam_file_monitor_cancel;
|
||||
}
|
||||
|
||||
static void
|
||||
g_fam_file_monitor_class_finalize (GFamFileMonitorClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
g_io_module_load (GIOModule *module)
|
||||
{
|
||||
g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
g_fam_file_monitor_register_type (G_TYPE_MODULE (module));
|
||||
|
||||
g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
|
||||
G_TYPE_FAM_FILE_MONITOR, "fam", 10);
|
||||
|
||||
g_io_extension_point_implement (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME,
|
||||
G_TYPE_FAM_FILE_MONITOR, "fam", 10);
|
||||
}
|
||||
|
||||
void
|
||||
g_io_module_unload (GIOModule *module)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
char **
|
||||
g_io_module_query (void)
|
||||
{
|
||||
char *eps[] = {
|
||||
G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
|
||||
G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
return g_strdupv (eps);
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
global:
|
||||
g_io_module_load;
|
||||
g_io_module_unload;
|
||||
g_io_module_query;
|
||||
local:
|
||||
*;
|
||||
};
|
@ -1,42 +0,0 @@
|
||||
if not get_option('fam')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
fam_dep = cc.find_library('fam')
|
||||
fam_c_args = gio_c_args
|
||||
if cc.has_function('FAMNoExists', dependencies : fam_dep)
|
||||
fam_c_args += '-DHAVE_FAM_NO_EXISTS=1'
|
||||
endif
|
||||
|
||||
deps = [
|
||||
fam_dep,
|
||||
libglib_dep,
|
||||
libgobject_dep,
|
||||
libgio_dep,
|
||||
]
|
||||
|
||||
symbol_map = join_paths(meson.current_source_dir(), 'gfamfilemonitor.map')
|
||||
fam_ldflags = cc.get_supported_link_arguments([
|
||||
'-Wl,--version-script,' + symbol_map,
|
||||
'-Wl,-no-undefined',
|
||||
])
|
||||
|
||||
module = shared_module('giofam', 'gfamfilemonitor.c',
|
||||
include_directories : [gmoduleinc],
|
||||
dependencies : deps,
|
||||
c_args : fam_c_args,
|
||||
link_args : fam_ldflags,
|
||||
link_depends : symbol_map,
|
||||
install_dir : glib_giomodulesdir,
|
||||
install : true,
|
||||
)
|
||||
|
||||
if not meson.is_cross_build()
|
||||
meson.add_install_script('../gio-querymodules-wrapper.py', gio_querymodules.full_path(), glib_giomodulesdir)
|
||||
endif
|
||||
|
||||
if meson.version().version_compare('>=0.58')
|
||||
env = environment()
|
||||
env.prepend('GIO_EXTRA_MODULES', meson.current_build_dir())
|
||||
meson.add_devenv(env)
|
||||
endif
|
@ -1033,7 +1033,6 @@ if enable_systemtap
|
||||
)
|
||||
endif
|
||||
|
||||
subdir('fam')
|
||||
if build_tests
|
||||
subdir('tests')
|
||||
endif
|
||||
|
@ -74,11 +74,6 @@ option('force_posix_threads',
|
||||
value : false,
|
||||
description : 'Also use posix threads in case the platform defaults to another implementation (on Windows for example)')
|
||||
|
||||
option('fam',
|
||||
type : 'boolean',
|
||||
value : false,
|
||||
description : 'Use fam for file system monitoring')
|
||||
|
||||
option('tests',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
|
Loading…
Reference in New Issue
Block a user