Merge branch 'migrate-to-gi-docgen10' into 'main'

Switch to using gi-docgen for docs (batch 10)

See merge request GNOME/glib!3709
This commit is contained in:
Philip Withnall 2023-11-14 15:46:30 +00:00
commit 09b728b2da
43 changed files with 874 additions and 1008 deletions

View File

@ -0,0 +1,79 @@
Title: D-Bus Error Handling
SPDX-License-Identifier: LGPL-2.1-or-later
SPDX-FileCopyrightText: 2010 David Zeuthen
SPDX-FileCopyrightText: 2012 Aleksander Morgado
# D-Bus Error Handling
All facilities that return errors from remote methods (such as
[method@Gio.DBusConnection.call_sync]) use [type@GLib.Error] to represent both
D-Bus errors (e.g. errors returned from the other peer) and locally in-process
generated errors.
To check if a returned [type@GLib.Error] is an error from a remote peer, use
[func@Gio.DBusError.is_remote_error]. To get the actual D-Bus error name,
use [func@Gio.DBusError.get_remote_error]. Before presenting an error, always
use [func@Gio.DBusError.strip_remote_error].
In addition, facilities used to return errors to a remote peer also use
[type@GLib.Error]. See [method@Gio.DBusMethodInvocation.return_error] for
discussion about how the D-Bus error name is set.
Applications can associate a [type@GLib.Error] error domain with a set of D-Bus
errors in order to automatically map from D-Bus errors to [type@GLib.Error] and
back. This is typically done in the function returning the [type@GLib.Quark] for
the error domain:
```c
// foo-bar-error.h:
#define FOO_BAR_ERROR (foo_bar_error_quark ())
GQuark foo_bar_error_quark (void);
typedef enum
{
FOO_BAR_ERROR_FAILED,
FOO_BAR_ERROR_ANOTHER_ERROR,
FOO_BAR_ERROR_SOME_THIRD_ERROR,
FOO_BAR_N_ERRORS / *< skip >* /
} FooBarError;
// foo-bar-error.c:
static const GDBusErrorEntry foo_bar_error_entries[] =
{
{FOO_BAR_ERROR_FAILED, "org.project.Foo.Bar.Error.Failed"},
{FOO_BAR_ERROR_ANOTHER_ERROR, "org.project.Foo.Bar.Error.AnotherError"},
{FOO_BAR_ERROR_SOME_THIRD_ERROR, "org.project.Foo.Bar.Error.SomeThirdError"},
};
// Ensure that every error code has an associated D-Bus error name
G_STATIC_ASSERT (G_N_ELEMENTS (foo_bar_error_entries) == FOO_BAR_N_ERRORS);
GQuark
foo_bar_error_quark (void)
{
static gsize quark = 0;
g_dbus_error_register_error_domain ("foo-bar-error-quark",
&quark,
foo_bar_error_entries,
G_N_ELEMENTS (foo_bar_error_entries));
return (GQuark) quark;
}
```
With this setup, a D-Bus peer can transparently pass e.g.
`FOO_BAR_ERROR_ANOTHER_ERROR` and other peers will see the D-Bus error name
`org.project.Foo.Bar.Error.AnotherError`.
If the other peer is using GDBus, and has registered the association with
[func@Gio.DBusError.register_error_domain] in advance (e.g. by invoking the
`FOO_BAR_ERROR` quark generation itself in the previous example) the peer will
see also `FOO_BAR_ERROR_ANOTHER_ERROR` instead of `G_IO_ERROR_DBUS_ERROR`. Note
that GDBus clients can still recover `org.project.Foo.Bar.Error.AnotherError`
using [func@Gio.DBusError.get_remote_error].
Note that the `G_DBUS_ERROR` error domain is intended only for returning errors
from a remote message bus process. Errors generated locally in-process by e.g.
[class@Gio.DBusConnection] should use the `G_IO_ERROR` domain.

View File

@ -0,0 +1,23 @@
Title: D-Bus Introspection Data
SPDX-License-Identifier: LGPL-2.1-or-later
SPDX-FileCopyrightText: 2010 David Zeuthen
SPDX-FileCopyrightText: 2010 Matthias Clasen
# D-Bus Introspection Data
Various data structures and convenience routines to parse and
generate D-Bus introspection XML. Introspection information is
used when registering objects with [method@Gio.DBusConnection.register_object].
The format of D-Bus introspection XML is specified in the
[D-Bus specification](http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format).
The main introspection data structures are:
* [type@Gio.DBusNodeInfo]
* [type@Gio.DBusInterfaceInfo]
* [type@Gio.DBusPropertyInfo]
* [type@Gio.DBusMethodInfo]
* [type@Gio.DBusSignalInfo]
* [type@Gio.DBusArgInfo]
* [type@Gio.DBusAnnotationInfo]

View File

@ -0,0 +1,14 @@
Title: D-Bus Name Owning
SPDX-License-Identifier: LGPL-2.1-or-later
SPDX-FileCopyrightText: 2010 David Zeuthen
# D-Bus Name Owning
Convenience API for owning bus names.
A simple example for owning a name can be found in
[`gdbus-example-own-name.c`](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-own-name.c).
The main API for owning names is:
* [func@Gio.bus_own_name]
* [func@Gio.bus_unown_name]

View File

@ -0,0 +1,14 @@
Title: D-Bus Name Watching
SPDX-License-Identifier: LGPL-2.1-or-later
SPDX-FileCopyrightText: 2010 David Zeuthen
# D-Bus Name Watching
Convenience API for watching bus names.
A simple example for watching a name can be found in
[`gdbus-example-watch-name.c`](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-name.c).
The main API for watching names is:
* [func@Gio.bus_watch_name]
* [func@Gio.bus_unwatch_name]

View File

@ -0,0 +1,28 @@
Title: D-Bus Utilities
SPDX-License-Identifier: LGPL-2.1-or-later
SPDX-FileCopyrightText: 2010 David Zeuthen
# D-Bus Utilities
Various utility routines related to D-Bus.
GUID support:
* [func@Gio.dbus_is_guid]
* [func@Gio.dbus_generate_guid]
Name validation:
* [func@Gio.dbus_is_name]
* [func@Gio.dbus_is_unique_name]
* [func@Gio.dbus_is_member_name]
* [func@Gio.dbus_is_interface_name]
* [func@Gio.dbus_is_error_name]
Conversion between [type@GLib.Variant] and [type@GObject.Value]:
* [func@Gio.dbus_gvariant_to_gvalue]
* [func@Gio.dbus_gvalue_to_gvariant]
Path escaping:
* [func@Gio.dbus_escape_object_path_bytestring]
* [func@Gio.dbus_escape_object_path]
* [func@Gio.dbus_unescape_object_path]

View File

@ -0,0 +1,12 @@
Title: GIOError
SPDX-License-Identifier: LGPL-2.1-or-later
SPDX-FileCopyrightText: 2007 A. Walton
# GIOError
Contains helper functions for reporting errors to the user.
Functions for converting between different error reporting mechanisms:
* [func@Gio.io_error_from_errno]
* [func@Gio.io_error_from_file_error]

View File

@ -44,6 +44,14 @@ content_files = [
"file-attributes.md",
"tls-overview.md",
"error.md",
"dbus-error.md",
"dbus-introspection.md",
"dbus-name-owning.md",
"dbus-name-watching.md",
"dbus-utils.md",
"migrating-gdbus.md",
"migrating-gconf.md",
"migrating-gnome-vfs.md",

View File

@ -225,6 +225,12 @@ endif
# gi-docgen version
expand_content_files = [
'dbus-error.md',
'dbus-introspection.md',
'dbus-name-owning.md',
'dbus-name-watching.md',
'dbus-utils.md',
'error.md',
'file-attributes.md',
'migrating-gconf.md',
'migrating-gdbus.md',

View File

@ -33,82 +33,6 @@
#include "glibintl.h"
/**
* SECTION:gdbuserror
* @title: GDBusError
* @short_description: Mapping D-Bus errors to and from GError
* @include: gio/gio.h
*
* All facilities that return errors from remote methods (such as
* g_dbus_connection_call_sync()) use #GError to represent both D-Bus
* errors (e.g. errors returned from the other peer) and locally
* in-process generated errors.
*
* To check if a returned #GError is an error from a remote peer, use
* g_dbus_error_is_remote_error(). To get the actual D-Bus error name,
* use g_dbus_error_get_remote_error(). Before presenting an error,
* always use g_dbus_error_strip_remote_error().
*
* In addition, facilities used to return errors to a remote peer also
* use #GError. See g_dbus_method_invocation_return_error() for
* discussion about how the D-Bus error name is set.
*
* Applications can associate a #GError error domain with a set of D-Bus errors in order to
* automatically map from D-Bus errors to #GError and back. This
* is typically done in the function returning the #GQuark for the
* error domain:
* |[<!-- language="C" -->
* // foo-bar-error.h:
*
* #define FOO_BAR_ERROR (foo_bar_error_quark ())
* GQuark foo_bar_error_quark (void);
*
* typedef enum
* {
* FOO_BAR_ERROR_FAILED,
* FOO_BAR_ERROR_ANOTHER_ERROR,
* FOO_BAR_ERROR_SOME_THIRD_ERROR,
* FOO_BAR_N_ERRORS / *< skip >* /
* } FooBarError;
*
* // foo-bar-error.c:
*
* static const GDBusErrorEntry foo_bar_error_entries[] =
* {
* {FOO_BAR_ERROR_FAILED, "org.project.Foo.Bar.Error.Failed"},
* {FOO_BAR_ERROR_ANOTHER_ERROR, "org.project.Foo.Bar.Error.AnotherError"},
* {FOO_BAR_ERROR_SOME_THIRD_ERROR, "org.project.Foo.Bar.Error.SomeThirdError"},
* };
*
* // Ensure that every error code has an associated D-Bus error name
* G_STATIC_ASSERT (G_N_ELEMENTS (foo_bar_error_entries) == FOO_BAR_N_ERRORS);
*
* GQuark
* foo_bar_error_quark (void)
* {
* static gsize quark = 0;
* g_dbus_error_register_error_domain ("foo-bar-error-quark",
* &quark,
* foo_bar_error_entries,
* G_N_ELEMENTS (foo_bar_error_entries));
* return (GQuark) quark;
* }
* ]|
* With this setup, a D-Bus peer can transparently pass e.g. %FOO_BAR_ERROR_ANOTHER_ERROR and
* other peers will see the D-Bus error name org.project.Foo.Bar.Error.AnotherError.
*
* If the other peer is using GDBus, and has registered the association with
* g_dbus_error_register_error_domain() in advance (e.g. by invoking the %FOO_BAR_ERROR quark
* generation itself in the previous example) the peer will see also %FOO_BAR_ERROR_ANOTHER_ERROR instead
* of %G_IO_ERROR_DBUS_ERROR. Note that GDBus clients can still recover
* org.project.Foo.Bar.Error.AnotherError using g_dbus_error_get_remote_error().
*
* Note that the %G_DBUS_ERROR error domain is intended only
* for returning errors from a remote message bus process. Errors
* generated locally in-process by e.g. #GDBusConnection should use the
* %G_IO_ERROR domain.
*/
static const GDBusErrorEntry g_dbus_error_entries[] =
{
{G_DBUS_ERROR_FAILED, "org.freedesktop.DBus.Error.Failed"},

View File

@ -29,20 +29,6 @@
#include "glibintl.h"
/**
* SECTION:gdbusintrospection
* @title: D-Bus Introspection Data
* @short_description: Node and interface description data structures
* @include: gio/gio.h
*
* Various data structures and convenience routines to parse and
* generate D-Bus introspection XML. Introspection information is
* used when registering objects with g_dbus_connection_register_object().
*
* The format of D-Bus introspection XML is specified in the
* [D-Bus specification](http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format)
*/
/* ---------------------------------------------------------------------------------------------------- */
#define _MY_DEFINE_BOXED_TYPE(TypeName, type_name) \

View File

@ -28,23 +28,12 @@
/* Prelude {{{1 */
/**
* SECTION:gdbusmenumodel
* @title: GDBusMenuModel
* @short_description: A D-Bus GMenuModel implementation
* @include: gio/gio.h
* @see_also: [GMenuModel Exporter][gio-GMenuModel-exporter]
*
* #GDBusMenuModel is an implementation of #GMenuModel that can be used
* as a proxy for a menu model that is exported over D-Bus with
* g_dbus_connection_export_menu_model().
*/
/**
* GDBusMenuModel:
*
* #GDBusMenuModel is an opaque data structure and can only be accessed
* using the following functions.
* `GDBusMenuModel` is an implementation of [class@Gio.MenuModel] that can be
* used as a proxy for a menu model that is exported over D-Bus with
* [method@Gio.DBusConnection.export_menu_model].
*/
/*

View File

@ -32,18 +32,6 @@
#include "glibintl.h"
/**
* SECTION:gdbusnameowning
* @title: Owning Bus Names
* @short_description: Simple API for owning bus names
* @include: gio/gio.h
*
* Convenience API for owning bus names.
*
* A simple example for owning a name can be found in
* [gdbus-example-own-name.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-own-name.c)
*/
G_LOCK_DEFINE_STATIC (lock);
/* ---------------------------------------------------------------------------------------------------- */

View File

@ -33,18 +33,6 @@
#include "glibintl.h"
/**
* SECTION:gdbusnamewatching
* @title: Watching Bus Names
* @short_description: Simple API for watching bus names
* @include: gio/gio.h
*
* Convenience API for watching bus names.
*
* A simple example for watching a name can be found in
* [gdbus-example-watch-name.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-name.c)
*/
G_LOCK_DEFINE_STATIC (lock);
/* ---------------------------------------------------------------------------------------------------- */

View File

@ -30,25 +30,16 @@
#include "glibintl.h"
#include "gmarshal-internal.h"
/**
* SECTION:gdbusobjectmanager
* @short_description: Base type for D-Bus object managers
* @include: gio/gio.h
*
* The #GDBusObjectManager type is the base type for service- and
* client-side implementations of the standardized
* [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
* interface.
*
* See #GDBusObjectManagerClient for the client-side implementation
* and #GDBusObjectManagerServer for the service-side implementation.
*/
/**
* GDBusObjectManager:
*
* #GDBusObjectManager is an opaque data structure and can only be accessed
* using the following functions.
* The `GDBusObjectManager` type is the base type for service- and
* client-side implementations of the standardized
* [`org.freedesktop.DBus.ObjectManager`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
* interface.
*
* See [class@Gio.DBusObjectManagerClient] for the client-side implementation
* and [class@Gio.DBusObjectManagerServer] for the service-side implementation.
*/
typedef GDBusObjectManagerIface GDBusObjectManagerInterface;

View File

@ -37,13 +37,11 @@
#include "glibintl.h"
/**
* SECTION:gdbusobjectmanagerserver
* @short_description: Service-side object manager
* @include: gio/gio.h
* GDBusObjectManagerServer:
*
* #GDBusObjectManagerServer is used to export #GDBusObject instances using
* the standardized
* [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
* `GDBusObjectManagerServer` is used to export [iface@Gio.DBusObject] instances
* using the standardized
* [`org.freedesktop.DBus.ObjectManager`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
* interface. For example, remote D-Bus clients can get all objects
* and properties in a single call. Additionally, any change in the
* object hierarchy is broadcast using signals. This means that D-Bus
@ -59,10 +57,11 @@
* It is supported, but not recommended, to export an object manager at the root
* path, `/`.
*
* See #GDBusObjectManagerClient for the client-side code that is
* intended to be used with #GDBusObjectManagerServer or any D-Bus
* object implementing the org.freedesktop.DBus.ObjectManager
* interface.
* See [class@Gio.DBusObjectManagerClient] for the client-side code that is
* intended to be used with `GDBusObjectManagerServer` or any D-Bus
* object implementing the `org.freedesktop.DBus.ObjectManager` interface.
*
* Since: 2.30
*/
typedef struct

View File

@ -37,14 +37,6 @@ G_BEGIN_DECLS
typedef struct _GDBusObjectManagerServerClass GDBusObjectManagerServerClass;
typedef struct _GDBusObjectManagerServerPrivate GDBusObjectManagerServerPrivate;
/**
* GDBusObjectManagerServer:
*
* The #GDBusObjectManagerServer structure contains private data and should
* only be accessed using the provided API.
*
* Since: 2.30
*/
struct _GDBusObjectManagerServer
{
/*< private >*/

View File

@ -34,15 +34,15 @@
#include "glibintl.h"
/**
* SECTION:gdbusobjectskeleton
* @short_description: Service-side D-Bus object
* @include: gio/gio.h
* GDBusObjectSkeleton:
*
* A #GDBusObjectSkeleton instance is essentially a group of D-Bus
* A `GDBusObjectSkeleton` instance is essentially a group of D-Bus
* interfaces. The set of exported interfaces on the object may be
* dynamic and change at runtime.
*
* This type is intended to be used with #GDBusObjectManager.
* This type is intended to be used with [iface@Gio.DBusObjectManager].
*
* Since: 2.30
*/
struct _GDBusObjectSkeletonPrivate

View File

@ -37,14 +37,6 @@ G_BEGIN_DECLS
typedef struct _GDBusObjectSkeletonClass GDBusObjectSkeletonClass;
typedef struct _GDBusObjectSkeletonPrivate GDBusObjectSkeletonPrivate;
/**
* GDBusObjectSkeleton:
*
* The #GDBusObjectSkeleton structure contains private data and should only be
* accessed using the provided API.
*
* Since: 2.30
*/
struct _GDBusObjectSkeleton
{
/*< private >*/

View File

@ -47,54 +47,56 @@
#include "gmarshal-internal.h"
/**
* SECTION:gdbusproxy
* @short_description: Client-side D-Bus interface proxy
* @include: gio/gio.h
* GDBusProxy:
*
* #GDBusProxy is a base class used for proxies to access a D-Bus
* interface on a remote object. A #GDBusProxy can be constructed for
* `GDBusProxy` is a base class used for proxies to access a D-Bus
* interface on a remote object. A `GDBusProxy` can be constructed for
* both well-known and unique names.
*
* By default, #GDBusProxy will cache all properties (and listen to
* By default, `GDBusProxy` will cache all properties (and listen to
* changes) of the remote object, and proxy all signals that get
* emitted. This behaviour can be changed by passing suitable
* #GDBusProxyFlags when the proxy is created. If the proxy is for a
* [flags@Gio.DBusProxyFlags] when the proxy is created. If the proxy is for a
* well-known name, the property cache is flushed when the name owner
* vanishes and reloaded when a name owner appears.
*
* The unique name owner of the proxy's name is tracked and can be read from
* #GDBusProxy:g-name-owner. Connect to the #GObject::notify signal to
* get notified of changes. Additionally, only signals and property
* changes emitted from the current name owner are considered and
* calls are always sent to the current name owner. This avoids a
* number of race conditions when the name is lost by one owner and
* claimed by another. However, if no name owner currently exists,
* The unique name owner of the proxys name is tracked and can be read from
* [property@Gio.DBusProxy:g-name-owner]. Connect to the
* [signal@GObject.Object::notify] signal to get notified of changes.
* Additionally, only signals and property changes emitted from the current name
* owner are considered and calls are always sent to the current name owner.
* This avoids a number of race conditions when the name is lost by one owner
* and claimed by another. However, if no name owner currently exists,
* then calls will be sent to the well-known name which may result in
* the message bus launching an owner (unless
* %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is set).
* `G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START` is set).
*
* If the proxy is for a stateless D-Bus service, where the name owner may
* be started and stopped between calls, the #GDBusProxy:g-name-owner tracking
* of #GDBusProxy will cause the proxy to drop signal and property changes from
* the service after it has restarted for the first time. When interacting
* with a stateless D-Bus service, do not use #GDBusProxy use direct D-Bus
* method calls and signal connections.
* be started and stopped between calls, the
* [property@Gio.DBusProxy:g-name-owner] tracking of `GDBusProxy` will cause the
* proxy to drop signal and property changes from the service after it has
* restarted for the first time. When interacting with a stateless D-Bus
* service, do not use `GDBusProxy` use direct D-Bus method calls and signal
* connections.
*
* The generic #GDBusProxy::g-properties-changed and
* #GDBusProxy::g-signal signals are not very convenient to work with.
* Therefore, the recommended way of working with proxies is to subclass
* #GDBusProxy, and have more natural properties and signals in your derived
* class. This [example][gdbus-example-gdbus-codegen] shows how this can
* easily be done using the [gdbus-codegen][gdbus-codegen] tool.
* The generic [signal@Gio.DBusProxy::g-properties-changed] and
* [signal@Gio.DBusProxy::g-signal] signals are not very convenient to work
* with. Therefore, the recommended way of working with proxies is to subclass
* `GDBusProxy`, and have more natural properties and signals in your derived
* class. This [example](migrating-gdbus.html#using-gdbus-codegen) shows how
* this can easily be done using the [`gdbus-codegen`](gdbus-codegen.html) tool.
*
* A #GDBusProxy instance can be used from multiple threads but note
* that all signals (e.g. #GDBusProxy::g-signal, #GDBusProxy::g-properties-changed
* and #GObject::notify) are emitted in the
* [thread-default main context][g-main-context-push-thread-default]
* of the thread where the instance was constructed.
* A `GDBusProxy` instance can be used from multiple threads but note
* that all signals (e.g. [signal@Gio.DBusProxy::g-signal],
* [signal@Gio.DBusProxy::g-properties-changed] and
* [signal@GObject.Object::notify]) are emitted in the thread-default main
* context (see [method@GLib.MainContext.push_thread_default]) of the thread
* where the instance was constructed.
*
* An example using a proxy for a well-known name can be found in
* [gdbus-example-watch-proxy.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-proxy.c)
* [`gdbus-example-watch-proxy.c`](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-proxy.c).
*
* Since: 2.26
*/
/* lock protecting the mutable properties: name_owner, timeout_msec,

View File

@ -42,14 +42,6 @@ G_BEGIN_DECLS
typedef struct _GDBusProxyClass GDBusProxyClass;
typedef struct _GDBusProxyPrivate GDBusProxyPrivate;
/**
* GDBusProxy:
*
* The #GDBusProxy structure contains only private data and
* should only be accessed using the provided API.
*
* Since: 2.26
*/
struct _GDBusProxy
{
/*< private >*/

View File

@ -29,15 +29,6 @@
#include "glibintl.h"
/**
* SECTION:gdbusutils
* @title: D-Bus Utilities
* @short_description: Various utilities related to D-Bus
* @include: gio/gio.h
*
* Various utility routines related to D-Bus.
*/
static gboolean
is_valid_bus_name_character (gint c,
gboolean allow_hyphen)

View File

@ -86,94 +86,99 @@ typedef off_t loff_t;
/**
* SECTION:gfile
* @short_description: File and Directory Handling
* @include: gio/gio.h
* @see_also: #GFileInfo, #GFileEnumerator
* GFile:
*
* #GFile is a high level abstraction for manipulating files on a
* virtual file system. #GFiles are lightweight, immutable objects
* `GFile` is a high level abstraction for manipulating files on a
* virtual file system. `GFile`s are lightweight, immutable objects
* that do no I/O upon creation. It is necessary to understand that
* #GFile objects do not represent files, merely an identifier for a
* `GFile` objects do not represent files, merely an identifier for a
* file. All file content I/O is implemented as streaming operations
* (see #GInputStream and #GOutputStream).
* (see [class@Gio.InputStream] and [class@Gio.OutputStream]).
*
* To construct a #GFile, you can use:
* - g_file_new_for_path() if you have a path.
* - g_file_new_for_uri() if you have a URI.
* - g_file_new_for_commandline_arg() for a command line argument.
* - g_file_new_tmp() to create a temporary file from a template.
* - g_file_new_tmp_async() to asynchronously create a temporary file.
* - g_file_new_tmp_dir_async() to asynchronously create a temporary directory.
* - g_file_parse_name() from a UTF-8 string gotten from g_file_get_parse_name().
* - g_file_new_build_filename() or g_file_new_build_filenamev() to create a file from path elements.
* To construct a `GFile`, you can use:
*
* One way to think of a #GFile is as an abstraction of a pathname. For
* - [func@Gio.File.new_for_path] if you have a path.
* - [func@Gio.File.new_for_uri] if you have a URI.
* - [func@Gio.File.new_for_commandline_arg] or
* [func@Gio.File.new_for_commandline_arg_and_cwd] for a command line
* argument.
* - [func@Gio.File.new_tmp] to create a temporary file from a template.
* - [func@Gio.File.new_tmp_async] to asynchronously create a temporary file.
* - [func@Gio.File.new_tmp_dir_async] to asynchronously create a temporary
* directory.
* - [func@Gio.File.parse_name] from a UTF-8 string gotten from
* [method@Gio.File.get_parse_name].
* - [func@Gio.File.new_build_filename] or [func@Gio.File.new_build_filenamev]
* to create a file from path elements.
*
* One way to think of a `GFile` is as an abstraction of a pathname. For
* normal files the system pathname is what is stored internally, but as
* #GFiles are extensible it could also be something else that corresponds
* `GFile`s are extensible it could also be something else that corresponds
* to a pathname in a userspace implementation of a filesystem.
*
* #GFiles make up hierarchies of directories and files that correspond to
* `GFile`s make up hierarchies of directories and files that correspond to
* the files on a filesystem. You can move through the file system with
* #GFile using g_file_get_parent() to get an identifier for the parent
* directory, g_file_get_child() to get a child within a directory,
* g_file_resolve_relative_path() to resolve a relative path between two
* #GFiles. There can be multiple hierarchies, so you may not end up at
* the same root if you repeatedly call g_file_get_parent() on two different
* files.
* `GFile` using [method@Gio.File.get_parent] to get an identifier for the
* parent directory, [method@Gio.File.get_child] to get a child within a
* directory, and [method@Gio.File.resolve_relative_path] to resolve a relative
* path between two `GFile`s. There can be multiple hierarchies, so you may not
* end up at the same root if you repeatedly call [method@Gio.File.get_parent]
* on two different files.
*
* All #GFiles have a basename (get with g_file_get_basename()). These names
* are byte strings that are used to identify the file on the filesystem
* All `GFile`s have a basename (get with [method@Gio.File.get_basename]). These
* names are byte strings that are used to identify the file on the filesystem
* (relative to its parent directory) and there is no guarantees that they
* have any particular charset encoding or even make any sense at all. If
* you want to use filenames in a user interface you should use the display
* name that you can get by requesting the
* %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME attribute with g_file_query_info().
* This is guaranteed to be in UTF-8 and can be used in a user interface.
* But always store the real basename or the #GFile to use to actually
* access the file, because there is no way to go from a display name to
* the actual name.
* `G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME` attribute with
* [method@Gio.File.query_info]. This is guaranteed to be in UTF-8 and can be
* used in a user interface. But always store the real basename or the `GFile`
* to use to actually access the file, because there is no way to go from a
* display name to the actual name.
*
* Using #GFile as an identifier has the same weaknesses as using a path
* Using `GFile` as an identifier has the same weaknesses as using a path
* in that there may be multiple aliases for the same file. For instance,
* hard or soft links may cause two different #GFiles to refer to the same
* hard or soft links may cause two different `GFile`s to refer to the same
* file. Other possible causes for aliases are: case insensitive filesystems,
* short and long names on FAT/NTFS, or bind mounts in Linux. If you want to
* check if two #GFiles point to the same file you can query for the
* %G_FILE_ATTRIBUTE_ID_FILE attribute. Note that #GFile does some trivial
* check if two `GFile`s point to the same file you can query for the
* `G_FILE_ATTRIBUTE_ID_FILE` attribute. Note that `GFile` does some trivial
* canonicalization of pathnames passed in, so that trivial differences in
* the path string used at creation (duplicated slashes, slash at end of
* path, "." or ".." path segments, etc) does not create different #GFiles.
* path, `.` or `..` path segments, etc) does not create different `GFile`s.
*
* Many #GFile operations have both synchronous and asynchronous versions
* Many `GFile` operations have both synchronous and asynchronous versions
* to suit your application. Asynchronous versions of synchronous functions
* simply have _async() appended to their function names. The asynchronous
* I/O functions call a #GAsyncReadyCallback which is then used to finalize
* the operation, producing a GAsyncResult which is then passed to the
* function's matching _finish() operation.
* simply have `_async()` appended to their function names. The asynchronous
* I/O functions call a [callback@Gio.AsyncReadyCallback] which is then used to
* finalize the operation, producing a [iface@Gio.AsyncResult] which is then
* passed to the functions matching `_finish()` operation.
*
* It is highly recommended to use asynchronous calls when running within a
* shared main loop, such as in the main thread of an application. This avoids
* I/O operations blocking other sources on the main loop from being dispatched.
* Synchronous I/O operations should be performed from worker threads. See the
* [introduction to asynchronous programming section][async-programming] for
* more.
* [introduction to asynchronous programming section](overview.html#asynchronous-programming)
* for more.
*
* Some #GFile operations almost always take a noticeable amount of time, and
* Some `GFile` operations almost always take a noticeable amount of time, and
* so do not have synchronous analogs. Notable cases include:
* - g_file_mount_mountable() to mount a mountable file.
* - g_file_unmount_mountable_with_operation() to unmount a mountable file.
* - g_file_eject_mountable_with_operation() to eject a mountable file.
*
* ## Entity Tags # {#gfile-etag}
* - [method@Gio.File.mount_mountable] to mount a mountable file.
* - [method@Gio.File.unmount_mountable_with_operation] to unmount a mountable
* file.
* - [method@Gio.File.eject_mountable_with_operation] to eject a mountable file.
*
* One notable feature of #GFiles are entity tags, or "etags" for
* ## Entity Tags
*
* One notable feature of `GFile`s are entity tags, or etags for
* short. Entity tags are somewhat like a more abstract version of the
* traditional mtime, and can be used to quickly determine if the file
* has been modified from the version on the file system. See the
* HTTP 1.1
* [specification](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)
* for HTTP Etag headers, which are a very similar concept.
* for HTTP `ETag` headers, which are a very similar concept.
*/
static void g_file_real_query_info_async (GFile *file,
@ -1833,7 +1838,7 @@ g_file_create (GFile *file,
/**
* g_file_replace:
* @file: input #GFile
* @etag: (nullable): an optional [entity tag][gfile-etag]
* @etag: (nullable): an optional [entity tag](#entity-tags)
* for the current #GFile, or #NULL to ignore
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
@ -2038,7 +2043,7 @@ g_file_create_readwrite (GFile *file,
/**
* g_file_replace_readwrite:
* @file: a #GFile
* @etag: (nullable): an optional [entity tag][gfile-etag]
* @etag: (nullable): an optional [entity tag](#entity-tags)
* for the current #GFile, or #NULL to ignore
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
@ -2302,7 +2307,7 @@ g_file_create_finish (GFile *file,
/**
* g_file_replace_async:
* @file: input #GFile
* @etag: (nullable): an [entity tag][gfile-etag] for the current #GFile,
* @etag: (nullable): an [entity tag](#entity-tags) for the current #GFile,
* or %NULL to ignore
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
@ -2526,7 +2531,7 @@ g_file_create_readwrite_finish (GFile *file,
/**
* g_file_replace_readwrite_async:
* @file: input #GFile
* @etag: (nullable): an [entity tag][gfile-etag] for the current #GFile,
* @etag: (nullable): an [entity tag](#entity-tags) for the current #GFile,
* or %NULL to ignore
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
@ -8309,11 +8314,11 @@ g_file_load_contents_finish (GFile *file,
* @file: input #GFile
* @contents: (element-type guint8) (array length=length): a string containing the new contents for @file
* @length: the length of @contents in bytes
* @etag: (nullable): the old [entity-tag][gfile-etag] for the document,
* @etag: (nullable): the old [entity-tag](#entity-tags) for the document,
* or %NULL
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
* @new_etag: (out) (optional) (nullable): a location to a new [entity tag][gfile-etag]
* @new_etag: (out) (optional) (nullable): a location to a new [entity tag](#entity-tags)
* for the document. This should be freed with g_free() when no longer
* needed, or %NULL
* @cancellable: optional #GCancellable object, %NULL to ignore
@ -8516,7 +8521,7 @@ replace_contents_open_callback (GObject *obj,
* @file: input #GFile
* @contents: (element-type guint8) (array length=length): string of contents to replace the file with
* @length: the length of @contents in bytes
* @etag: (nullable): a new [entity tag][gfile-etag] for the @file, or %NULL
* @etag: (nullable): a new [entity tag](#entity-tags) for the @file, or %NULL
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
* @cancellable: optional #GCancellable object, %NULL to ignore
@ -8566,7 +8571,7 @@ g_file_replace_contents_async (GFile *file,
* g_file_replace_contents_bytes_async:
* @file: input #GFile
* @contents: a #GBytes
* @etag: (nullable): a new [entity tag][gfile-etag] for the @file, or %NULL
* @etag: (nullable): a new [entity tag](#entity-tags) for the @file, or %NULL
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
* @cancellable: optional #GCancellable object, %NULL to ignore
@ -8621,7 +8626,7 @@ g_file_replace_contents_bytes_async (GFile *file,
* g_file_replace_contents_finish:
* @file: input #GFile
* @res: a #GAsyncResult
* @new_etag: (out) (optional) (nullable): a location of a new [entity tag][gfile-etag]
* @new_etag: (out) (optional) (nullable): a location of a new [entity tag](#entity-tags)
* for the document. This should be freed with g_free() when it is no
* longer needed, or %NULL
* @error: a #GError, or %NULL

View File

@ -36,16 +36,6 @@ G_BEGIN_DECLS
#define G_IS_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_FILE))
#define G_FILE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_FILE, GFileIface))
#if 0
/**
* GFile:
*
* A handle to an object implementing the #GFileIface interface.
* Generally stores a location within the file system. Handles do not
* necessarily represent files or directories that currently exist.
**/
typedef struct _GFile GFile; /* Dummy typedef */
#endif
typedef struct _GFileIface GFileIface;

View File

@ -2066,7 +2066,7 @@ g_file_info_get_symlink_target (GFileInfo *info)
* g_file_info_get_etag:
* @info: a #GFileInfo.
*
* Gets the [entity tag][gfile-etag] for a given
* Gets the [entity tag](iface.File.html#entity-tags) for a given
* #GFileInfo. See %G_FILE_ATTRIBUTE_ETAG_VALUE.
*
* It is an error to call this if the #GFileInfo does not contain

View File

@ -34,31 +34,28 @@
/**
* SECTION:gfileiostream
* @short_description: File read and write streaming operations
* @include: gio/gio.h
* @see_also: #GIOStream, #GFileInputStream, #GFileOutputStream, #GSeekable
* GFileIOStream:
*
* GFileIOStream provides io streams that both read and write to the same
* `GFileIOStream` provides I/O streams that both read and write to the same
* file handle.
*
* GFileIOStream implements #GSeekable, which allows the io
* `GFileIOStream` implements [iface@Gio.Seekable], which allows the I/O
* stream to jump to arbitrary positions in the file and to truncate
* the file, provided the filesystem of the file supports these
* operations.
*
* To find the position of a file io stream, use
* g_seekable_tell().
* To find the position of a file I/O stream, use [method@Gio.Seekable.tell].
*
* To find out if a file io stream supports seeking, use g_seekable_can_seek().
* To position a file io stream, use g_seekable_seek().
* To find out if a file io stream supports truncating, use
* g_seekable_can_truncate(). To truncate a file io
* stream, use g_seekable_truncate().
* To find out if a file I/O stream supports seeking, use
* [method@Gio.Seekable.can_seek]. To position a file I/O stream, use
* [method@Gio.Seekable.seek]. To find out if a file I/O stream supports
* truncating, use [method@Gio.Seekable.can_truncate]. To truncate a file I/O
* stream, use [method@Gio.Seekable.truncate].
*
* The default implementation of all the `GFileIOStream` operations
* and the implementation of [iface@Gio.Seekable] just call into the same
* operations on the output stream.
*
* The default implementation of all the #GFileIOStream operations
* and the implementation of #GSeekable just call into the same operations
* on the output stream.
* Since: 2.22
**/

View File

@ -38,14 +38,6 @@ G_BEGIN_DECLS
#define G_IS_FILE_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_IO_STREAM))
#define G_FILE_IO_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_IO_STREAM, GFileIOStreamClass))
/**
* GFileIOStream:
*
* A subclass of GIOStream for opened files. This adds
* a few file-specific operations and seeking and truncating.
*
* #GFileIOStream implements GSeekable.
**/
typedef struct _GFileIOStreamClass GFileIOStreamClass;
typedef struct _GFileIOStreamPrivate GFileIOStreamPrivate;

View File

@ -30,14 +30,6 @@
#include <winsock2.h>
#endif
/**
* SECTION:gioerror
* @short_description: Error helper functions
* @include: gio/gio.h
*
* Contains helper functions for reporting errors to the user.
**/
/**
* g_io_error_quark:
*

View File

@ -77,53 +77,47 @@
#undef __GLIB_H_INSIDE__
/**
* SECTION:giomodule
* @short_description: Loadable GIO Modules
* @include: gio/gio.h
* GIOModule:
*
* Provides an interface and default functions for loading and unloading
* modules. This is used internally to make GIO extensible, but can also
* be used by others to implement module loading.
*
**/
*/
/**
* SECTION:extensionpoints
* @short_description: Extension Points
* @include: gio.h
* @see_also: [Extending GIO][extending-gio]
* GIOExtensionPoint:
*
* #GIOExtensionPoint provides a mechanism for modules to extend the
* `GIOExtensionPoint` provides a mechanism for modules to extend the
* functionality of the library or application that loaded it in an
* organized fashion.
* organized fashion.
*
* An extension point is identified by a name, and it may optionally
* require that any implementation must be of a certain type (or derived
* thereof). Use g_io_extension_point_register() to register an
* extension point, and g_io_extension_point_set_required_type() to
* thereof). Use [func@Gio.IOExtensionPoint.register] to register an
* extension point, and [method@Gio.IOExtensionPoint.set_required_type] to
* set a required type.
*
* A module can implement an extension point by specifying the #GType
* that implements the functionality. Additionally, each implementation
* of an extension point has a name, and a priority. Use
* g_io_extension_point_implement() to implement an extension point.
* A module can implement an extension point by specifying the
* [type@GObject.Type] that implements the functionality. Additionally, each
* implementation of an extension point has a name, and a priority. Use
* [func@Gio.IOExtensionPoint.implement] to implement an extension point.
*
* |[<!-- language="C" -->
* GIOExtensionPoint *ep;
* ```c
* GIOExtensionPoint *ep;
*
* // Register an extension point
* ep = g_io_extension_point_register ("my-extension-point");
* g_io_extension_point_set_required_type (ep, MY_TYPE_EXAMPLE);
* ]|
* // Register an extension point
* ep = g_io_extension_point_register ("my-extension-point");
* g_io_extension_point_set_required_type (ep, MY_TYPE_EXAMPLE);
* ```
*
* |[<!-- language="C" -->
* // Implement an extension point
* G_DEFINE_TYPE (MyExampleImpl, my_example_impl, MY_TYPE_EXAMPLE)
* g_io_extension_point_implement ("my-extension-point",
* my_example_impl_get_type (),
* "my-example",
* 10);
* ]|
* ```c
* // Implement an extension point
* G_DEFINE_TYPE (MyExampleImpl, my_example_impl, MY_TYPE_EXAMPLE)
* g_io_extension_point_implement ("my-extension-point",
* my_example_impl_get_type (),
* "my-example",
* 10);
* ```
*
* It is up to the code that registered the extension point how
* it uses the implementations that have been associated with it.
@ -133,7 +127,7 @@
*
* To avoid opening all modules just to find out what extension
* points they implement, GIO makes use of a caching mechanism,
* see [gio-querymodules][gio-querymodules].
* see [gio-querymodules](gio-querymodules.html).
* You are expected to run this command after installing a
* GIO module.
*
@ -267,12 +261,6 @@ struct _GIOExtension {
gint priority;
};
/**
* GIOExtensionPoint:
*
* #GIOExtensionPoint is an opaque data structure and can only be accessed
* using the following functions.
*/
struct _GIOExtensionPoint {
GType required_type;
char *name;

View File

@ -49,11 +49,6 @@ void g_io_module_scope_block (GIOModuleScope *scope,
#define G_IO_IS_MODULE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_IO_TYPE_MODULE))
#define G_IO_MODULE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_IO_TYPE_MODULE, GIOModuleClass))
/**
* GIOModule:
*
* Opaque module base class for extending GIO.
**/
typedef struct _GIOModuleClass GIOModuleClass;
GIO_AVAILABLE_IN_ALL

View File

@ -76,13 +76,6 @@ typedef struct _GFileMonitor GFileMonitor;
typedef struct _GFilterInputStream GFilterInputStream;
typedef struct _GFilterOutputStream GFilterOutputStream;
/**
* GFile:
*
* A handle to an object implementing the #GFileIface interface.
* Generally stores a location within the file system. Handles do not
* necessarily represent files or directories that currently exist.
**/
typedef struct _GFile GFile; /* Dummy typedef */
typedef struct _GFileInfo GFileInfo;
@ -162,12 +155,6 @@ typedef struct _GSimpleAsyncResult GSimpleAsyncResult;
**/
typedef struct _GSocket GSocket;
/**
* GSocketControlMessage:
*
* Base class for socket-type specific control messages that can be sent and
* received over #GSocket.
**/
typedef struct _GSocketControlMessage GSocketControlMessage;
/**
* GSocketClient:
@ -638,13 +625,6 @@ typedef GType (*GDBusProxyTypeFunc) (GDBusObjectManagerClient *manager,
typedef struct _GTestDBus GTestDBus;
/**
* GSubprocess:
*
* A child process.
*
* Since: 2.40
*/
typedef struct _GSubprocess GSubprocess;
/**
* GSubprocessLauncher:

View File

@ -24,17 +24,15 @@
/**
* SECTION:gsocketconnectable
* @short_description: Interface for potential socket endpoints
* @include: gio/gio.h
* GSocketConnectable:
*
* Objects that describe one or more potential socket endpoints
* implement #GSocketConnectable. Callers can then use
* g_socket_connectable_enumerate() to get a #GSocketAddressEnumerator
* to try out each socket address in turn until one succeeds, as shown
* in the sample code below.
* implement `GSocketConnectable`. Callers can then use
* [method@Gio.SocketConnectable.enumerate] to get a
* [class@Gio.SocketAddressEnumerator] to try out each socket address in turn
* until one succeeds, as shown in the sample code below.
*
* |[<!-- language="C" -->
* ```c
* MyConnectionType *
* connect_to_host (const char *hostname,
* guint16 port,
@ -84,7 +82,7 @@
* return NULL;
* }
* }
* ]|
* ```
*/

View File

@ -34,11 +34,6 @@ G_BEGIN_DECLS
#define G_IS_SOCKET_CONNECTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SOCKET_CONNECTABLE))
#define G_SOCKET_CONNECTABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_SOCKET_CONNECTABLE, GSocketConnectableIface))
/**
* GSocketConnectable:
*
* Interface for objects that contain or generate a #GSocketAddress.
*/
typedef struct _GSocketConnectableIface GSocketConnectableIface;
/**

View File

@ -15,32 +15,28 @@
*/
/**
* SECTION:gsocketcontrolmessage
* @title: GSocketControlMessage
* @short_description: A GSocket control message
* @include: gio/gio.h
* @see_also: #GSocket.
* GSocketControlMessage:
*
* A #GSocketControlMessage is a special-purpose utility message that
* can be sent to or received from a #GSocket. These types of
* messages are often called "ancillary data".
* A `GSocketControlMessage` is a special-purpose utility message that
* can be sent to or received from a [class@Gio.Socket]. These types of
* messages are often called ancillary data.
*
* The message can represent some sort of special instruction to or
* information from the socket or can represent a special kind of
* transfer to the peer (for example, sending a file descriptor over
* a UNIX socket).
*
* These messages are sent with g_socket_send_message() and received
* with g_socket_receive_message().
* These messages are sent with [method@Gio.Socket.send_message] and received
* with [method@Gio.Socket.receive_message].
*
* To extend the set of control message that can be sent, subclass this
* class and override the get_size, get_level, get_type and serialize
* class and override the `get_size`, `get_level`, `get_type` and `serialize`
* methods.
*
* To extend the set of control messages that can be received, subclass
* this class and implement the deserialize method. Also, make sure your
* class is registered with the GType typesystem before calling
* g_socket_receive_message() to read such a message.
* this class and implement the `deserialize` method. Also, make sure your
* class is registered with the [type@GObject.Type] type system before calling
* [method@Gio.Socket.receive_message] to read such a message.
*
* Since: 2.22
*/

View File

@ -17,18 +17,14 @@
*/
/**
* SECTION:gsubprocess
* @title: GSubprocess
* @short_description: Child processes
* @include: gio/gio.h
* @see_also: #GSubprocessLauncher
* GSubprocess:
*
* #GSubprocess allows the creation of and interaction with child
* `GSubprocess` allows the creation of and interaction with child
* processes.
*
* Processes can be communicated with using standard GIO-style APIs (ie:
* #GInputStream, #GOutputStream). There are GIO-style APIs to wait for
* process termination (ie: cancellable and with an asynchronous
* [class@Gio.InputStream], [class@Gio.OutputStream]). There are GIO-style APIs
* to wait for process termination (ie: cancellable and with an asynchronous
* variant).
*
* There is an API to force a process to terminate, as well as a
@ -36,50 +32,50 @@
*
* One major advantage that GIO brings over the core GLib library is
* comprehensive API for asynchronous I/O, such
* g_output_stream_splice_async(). This makes GSubprocess
* [method@Gio.OutputStream.splice_async]. This makes `GSubprocess`
* significantly more powerful and flexible than equivalent APIs in
* some other languages such as the `subprocess.py`
* included with Python. For example, using #GSubprocess one could
* included with Python. For example, using `GSubprocess` one could
* create two child processes, reading standard output from the first,
* processing it, and writing to the input stream of the second, all
* without blocking the main loop.
*
* A powerful g_subprocess_communicate() API is provided similar to the
* A powerful [method@Gio.Subprocess.communicate] API is provided similar to the
* `communicate()` method of `subprocess.py`. This enables very easy
* interaction with a subprocess that has been opened with pipes.
*
* #GSubprocess defaults to tight control over the file descriptors open
* in the child process, avoiding dangling-fd issues that are caused by
* a simple fork()/exec(). The only open file descriptors in the
* `GSubprocess` defaults to tight control over the file descriptors open
* in the child process, avoiding dangling-FD issues that are caused by
* a simple `fork()`/`exec()`. The only open file descriptors in the
* spawned process are ones that were explicitly specified by the
* #GSubprocess API (unless %G_SUBPROCESS_FLAGS_INHERIT_FDS was
* `GSubprocess` API (unless `G_SUBPROCESS_FLAGS_INHERIT_FDS` was
* specified).
*
* #GSubprocess will quickly reap all child processes as they exit,
* avoiding "zombie processes" remaining around for long periods of
* time. g_subprocess_wait() can be used to wait for this to happen,
* `GSubprocess` will quickly reap all child processes as they exit,
* avoiding zombie processes remaining around for long periods of
* time. [method@Gio.Subprocess.wait] can be used to wait for this to happen,
* but it will happen even without the call being explicitly made.
*
* As a matter of principle, #GSubprocess has no API that accepts
* As a matter of principle, `GSubprocess` has no API that accepts
* shell-style space-separated strings. It will, however, match the
* typical shell behaviour of searching the PATH for executables that do
* typical shell behaviour of searching the `PATH` for executables that do
* not contain a directory separator in their name. By default, the `PATH`
* of the current process is used. You can specify
* %G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP to use the `PATH` of the
* `G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP` to use the `PATH` of the
* launcher environment instead.
*
* #GSubprocess attempts to have a very simple API for most uses (ie:
* `GSubprocess` attempts to have a very simple API for most uses (ie:
* spawning a subprocess with arguments and support for most typical
* kinds of input and output redirection). See g_subprocess_new(). The
* #GSubprocessLauncher API is provided for more complicated cases
* kinds of input and output redirection). See [ctor@Gio.Subprocess.new]. The
* [class@Gio.SubprocessLauncher] API is provided for more complicated cases
* (advanced types of redirection, environment variable manipulation,
* change of working directory, child setup functions, etc).
*
* A typical use of #GSubprocess will involve calling
* g_subprocess_new(), followed by g_subprocess_wait_async() or
* g_subprocess_wait(). After the process exits, the status can be
* checked using functions such as g_subprocess_get_if_exited() (which
* are similar to the familiar WIFEXITED-style POSIX macros).
* A typical use of `GSubprocess` will involve calling
* [ctor@Gio.Subprocess.new], followed by [method@Gio.Subprocess.wait_async] or
* [method@Gio.Subprocess.wait]. After the process exits, the status can be
* checked using functions such as [method@Gio.Subprocess.get_if_exited] (which
* are similar to the familiar `WIFEXITED`-style POSIX macros).
*
* Since: 2.40
**/

View File

@ -33,520 +33,518 @@
#include <string.h>
/**
* SECTION:gtask
* @short_description: Cancellable synchronous or asynchronous task
* and result
* @include: gio/gio.h
* @see_also: #GAsyncResult
* GTask:
*
* A #GTask represents and manages a cancellable "task".
* A `GTask` represents and manages a cancellable task.
*
* ## Asynchronous operations
*
* The most common usage of #GTask is as a #GAsyncResult, to
* The most common usage of `GTask` is as a [iface@Gio.AsyncResult], to
* manage data during an asynchronous operation. You call
* g_task_new() in the "start" method, followed by
* g_task_set_task_data() and the like if you need to keep some
* [ctor@Gio.Task.new] in the start method, followed by
* [method@Gio.Task.set_task_data] and the like if you need to keep some
* additional data associated with the task, and then pass the
* task object around through your asynchronous operation.
* Eventually, you will call a method such as
* g_task_return_pointer() or g_task_return_error(), which will
* save the value you give it and then invoke the task's callback
* function in the
* [thread-default main context][g-main-context-push-thread-default]
* [method@Gio.Task.return_pointer] or [method@Gio.Task.return_error], which
* will save the value you give it and then invoke the tasks callback
* function in the thread-default main context (see
* [method@GLib.MainContext.push_thread_default])
* where it was created (waiting until the next iteration of the main
* loop first, if necessary). The caller will pass the #GTask back to
* the operation's finish function (as a #GAsyncResult), and you can
* use g_task_propagate_pointer() or the like to extract the
* loop first, if necessary). The caller will pass the `GTask` back to
* the operations finish function (as a [iface@Gio.AsyncResult]), and you can
* use [method@Gio.Task.propagate_pointer] or the like to extract the
* return value.
*
* Using #GTask requires the thread-default #GMainContext from when the
* #GTask was constructed to be running at least until the task has completed
* and its data has been freed.
* Using `GTask` requires the thread-default [struct@GLib.MainContext] from when
* the `GTask` was constructed to be running at least until the task has
* completed and its data has been freed.
*
* If a #GTask has been constructed and its callback set, it is an error to
* If a `GTask` has been constructed and its callback set, it is an error to
* not call `g_task_return_*()` on it. GLib will warn at runtime if this happens
* (since 2.76).
*
* Here is an example for using GTask as a GAsyncResult:
* |[<!-- language="C" -->
* typedef struct {
* CakeFrostingType frosting;
* char *message;
* } DecorationData;
* Here is an example for using `GTask` as a [iface@Gio.AsyncResult]:
* ```c
* typedef struct {
* CakeFrostingType frosting;
* char *message;
* } DecorationData;
*
* static void
* decoration_data_free (DecorationData *decoration)
* static void
* decoration_data_free (DecorationData *decoration)
* {
* g_free (decoration->message);
* g_slice_free (DecorationData, decoration);
* }
*
* static void
* baked_cb (Cake *cake,
* gpointer user_data)
* {
* GTask *task = user_data;
* DecorationData *decoration = g_task_get_task_data (task);
* GError *error = NULL;
*
* if (cake == NULL)
* {
* g_free (decoration->message);
* g_slice_free (DecorationData, decoration);
* g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR,
* "Go to the supermarket");
* g_object_unref (task);
* return;
* }
*
* static void
* baked_cb (Cake *cake,
* gpointer user_data)
* if (!cake_decorate (cake, decoration->frosting, decoration->message, &error))
* {
* GTask *task = user_data;
* DecorationData *decoration = g_task_get_task_data (task);
* GError *error = NULL;
* g_object_unref (cake);
* // g_task_return_error() takes ownership of error
* g_task_return_error (task, error);
* g_object_unref (task);
* return;
* }
*
* if (cake == NULL)
* {
* g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR,
* "Go to the supermarket");
* g_object_unref (task);
* return;
* }
* g_task_return_pointer (task, cake, g_object_unref);
* g_object_unref (task);
* }
*
* if (!cake_decorate (cake, decoration->frosting, decoration->message, &error))
* {
* g_object_unref (cake);
* // g_task_return_error() takes ownership of error
* g_task_return_error (task, error);
* g_object_unref (task);
* return;
* }
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* {
* GTask *task;
* DecorationData *decoration;
* Cake *cake;
*
* task = g_task_new (self, cancellable, callback, user_data);
* if (radius < 3)
* {
* g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_TOO_SMALL,
* "%ucm radius cakes are silly",
* radius);
* g_object_unref (task);
* return;
* }
*
* cake = _baker_get_cached_cake (self, radius, flavor, frosting, message);
* if (cake != NULL)
* {
* // _baker_get_cached_cake() returns a reffed cake
* g_task_return_pointer (task, cake, g_object_unref);
* g_object_unref (task);
* return;
* }
*
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* {
* GTask *task;
* DecorationData *decoration;
* Cake *cake;
* decoration = g_slice_new (DecorationData);
* decoration->frosting = frosting;
* decoration->message = g_strdup (message);
* g_task_set_task_data (task, decoration, (GDestroyNotify) decoration_data_free);
*
* task = g_task_new (self, cancellable, callback, user_data);
* if (radius < 3)
* {
* g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_TOO_SMALL,
* "%ucm radius cakes are silly",
* radius);
* g_object_unref (task);
* return;
* }
* _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task);
* }
*
* cake = _baker_get_cached_cake (self, radius, flavor, frosting, message);
* if (cake != NULL)
* {
* // _baker_get_cached_cake() returns a reffed cake
* g_task_return_pointer (task, cake, g_object_unref);
* g_object_unref (task);
* return;
* }
* Cake *
* baker_bake_cake_finish (Baker *self,
* GAsyncResult *result,
* GError **error)
* {
* g_return_val_if_fail (g_task_is_valid (result, self), NULL);
*
* decoration = g_slice_new (DecorationData);
* decoration->frosting = frosting;
* decoration->message = g_strdup (message);
* g_task_set_task_data (task, decoration, (GDestroyNotify) decoration_data_free);
*
* _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task);
* }
*
* Cake *
* baker_bake_cake_finish (Baker *self,
* GAsyncResult *result,
* GError **error)
* {
* g_return_val_if_fail (g_task_is_valid (result, self), NULL);
*
* return g_task_propagate_pointer (G_TASK (result), error);
* }
* ]|
* return g_task_propagate_pointer (G_TASK (result), error);
* }
* ```
*
* ## Chained asynchronous operations
*
* #GTask also tries to simplify asynchronous operations that
* `GTask` also tries to simplify asynchronous operations that
* internally chain together several smaller asynchronous
* operations. g_task_get_cancellable(), g_task_get_context(),
* and g_task_get_priority() allow you to get back the task's
* #GCancellable, #GMainContext, and [I/O priority][io-priority]
* when starting a new subtask, so you don't have to keep track
* of them yourself. g_task_attach_source() simplifies the case
* operations. [method@Gio.Task.get_cancellable], [method@Gio.Task.get_context],
* and [method@Gio.Task.get_priority] allow you to get back the tasks
* [class@Gio.Cancellable], [struct@GLib.MainContext], and
* [I/O priority](iface.AsyncResult.html#io-priority)
* when starting a new subtask, so you dont have to keep track
* of them yourself. [method@Gio.Task.attach_source] simplifies the case
* of waiting for a source to fire (automatically using the correct
* #GMainContext and priority).
* [struct@GLib.MainContext] and priority).
*
* Here is an example for chained asynchronous operations:
* |[<!-- language="C" -->
* typedef struct {
* Cake *cake;
* CakeFrostingType frosting;
* char *message;
* } BakingData;
* ```c
* typedef struct {
* Cake *cake;
* CakeFrostingType frosting;
* char *message;
* } BakingData;
*
* static void
* decoration_data_free (BakingData *bd)
* static void
* decoration_data_free (BakingData *bd)
* {
* if (bd->cake)
* g_object_unref (bd->cake);
* g_free (bd->message);
* g_slice_free (BakingData, bd);
* }
*
* static void
* decorated_cb (Cake *cake,
* GAsyncResult *result,
* gpointer user_data)
* {
* GTask *task = user_data;
* GError *error = NULL;
*
* if (!cake_decorate_finish (cake, result, &error))
* {
* if (bd->cake)
* g_object_unref (bd->cake);
* g_free (bd->message);
* g_slice_free (BakingData, bd);
* }
*
* static void
* decorated_cb (Cake *cake,
* GAsyncResult *result,
* gpointer user_data)
* {
* GTask *task = user_data;
* GError *error = NULL;
*
* if (!cake_decorate_finish (cake, result, &error))
* {
* g_object_unref (cake);
* g_task_return_error (task, error);
* g_object_unref (task);
* return;
* }
*
* // baking_data_free() will drop its ref on the cake, so we have to
* // take another here to give to the caller.
* g_task_return_pointer (task, g_object_ref (cake), g_object_unref);
* g_object_unref (cake);
* g_task_return_error (task, error);
* g_object_unref (task);
* return;
* }
*
* static gboolean
* decorator_ready (gpointer user_data)
* // baking_data_free() will drop its ref on the cake, so we have to
* // take another here to give to the caller.
* g_task_return_pointer (task, g_object_ref (cake), g_object_unref);
* g_object_unref (task);
* }
*
* static gboolean
* decorator_ready (gpointer user_data)
* {
* GTask *task = user_data;
* BakingData *bd = g_task_get_task_data (task);
*
* cake_decorate_async (bd->cake, bd->frosting, bd->message,
* g_task_get_cancellable (task),
* decorated_cb, task);
*
* return G_SOURCE_REMOVE;
* }
*
* static void
* baked_cb (Cake *cake,
* gpointer user_data)
* {
* GTask *task = user_data;
* BakingData *bd = g_task_get_task_data (task);
* GError *error = NULL;
*
* if (cake == NULL)
* {
* GTask *task = user_data;
* BakingData *bd = g_task_get_task_data (task);
*
* cake_decorate_async (bd->cake, bd->frosting, bd->message,
* g_task_get_cancellable (task),
* decorated_cb, task);
*
* return G_SOURCE_REMOVE;
* g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR,
* "Go to the supermarket");
* g_object_unref (task);
* return;
* }
*
* static void
* baked_cb (Cake *cake,
* gpointer user_data)
* bd->cake = cake;
*
* // Bail out now if the user has already cancelled
* if (g_task_return_error_if_cancelled (task))
* {
* GTask *task = user_data;
* BakingData *bd = g_task_get_task_data (task);
* GError *error = NULL;
*
* if (cake == NULL)
* {
* g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR,
* "Go to the supermarket");
* g_object_unref (task);
* return;
* }
*
* bd->cake = cake;
*
* // Bail out now if the user has already cancelled
* if (g_task_return_error_if_cancelled (task))
* {
* g_object_unref (task);
* return;
* }
*
* if (cake_decorator_available (cake))
* decorator_ready (task);
* else
* {
* GSource *source;
*
* source = cake_decorator_wait_source_new (cake);
* // Attach @source to @task's GMainContext and have it call
* // decorator_ready() when it is ready.
* g_task_attach_source (task, source, decorator_ready);
* g_source_unref (source);
* }
* g_object_unref (task);
* return;
* }
*
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* gint priority,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* if (cake_decorator_available (cake))
* decorator_ready (task);
* else
* {
* GTask *task;
* BakingData *bd;
* GSource *source;
*
* task = g_task_new (self, cancellable, callback, user_data);
* g_task_set_priority (task, priority);
*
* bd = g_slice_new0 (BakingData);
* bd->frosting = frosting;
* bd->message = g_strdup (message);
* g_task_set_task_data (task, bd, (GDestroyNotify) baking_data_free);
*
* _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task);
* source = cake_decorator_wait_source_new (cake);
* // Attach @source to @tasks GMainContext and have it call
* // decorator_ready() when it is ready.
* g_task_attach_source (task, source, decorator_ready);
* g_source_unref (source);
* }
* }
*
* Cake *
* baker_bake_cake_finish (Baker *self,
* GAsyncResult *result,
* GError **error)
* {
* g_return_val_if_fail (g_task_is_valid (result, self), NULL);
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* gint priority,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* {
* GTask *task;
* BakingData *bd;
*
* return g_task_propagate_pointer (G_TASK (result), error);
* }
* ]|
* task = g_task_new (self, cancellable, callback, user_data);
* g_task_set_priority (task, priority);
*
* bd = g_slice_new0 (BakingData);
* bd->frosting = frosting;
* bd->message = g_strdup (message);
* g_task_set_task_data (task, bd, (GDestroyNotify) baking_data_free);
*
* _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task);
* }
*
* Cake *
* baker_bake_cake_finish (Baker *self,
* GAsyncResult *result,
* GError **error)
* {
* g_return_val_if_fail (g_task_is_valid (result, self), NULL);
*
* return g_task_propagate_pointer (G_TASK (result), error);
* }
* ```
*
* ## Asynchronous operations from synchronous ones
*
* You can use g_task_run_in_thread() to turn a synchronous
* You can use [method@Gio.Task.run_in_thread] to turn a synchronous
* operation into an asynchronous one, by running it in a thread.
* When it completes, the result will be dispatched to the
* [thread-default main context][g-main-context-push-thread-default]
* where the #GTask was created.
* When it completes, the result will be dispatched to the thread-default main
* context (see [method@GLib.MainContext.push_thread_default]) where the `GTask`
* was created.
*
* Running a task in a thread:
* |[<!-- language="C" -->
* typedef struct {
* guint radius;
* CakeFlavor flavor;
* CakeFrostingType frosting;
* char *message;
* } CakeData;
* ```c
* typedef struct {
* guint radius;
* CakeFlavor flavor;
* CakeFrostingType frosting;
* char *message;
* } CakeData;
*
* static void
* cake_data_free (CakeData *cake_data)
* {
* g_free (cake_data->message);
* g_slice_free (CakeData, cake_data);
* }
* static void
* cake_data_free (CakeData *cake_data)
* {
* g_free (cake_data->message);
* g_slice_free (CakeData, cake_data);
* }
*
* static void
* bake_cake_thread (GTask *task,
* gpointer source_object,
* gpointer task_data,
* GCancellable *cancellable)
* {
* Baker *self = source_object;
* CakeData *cake_data = task_data;
* Cake *cake;
* GError *error = NULL;
* static void
* bake_cake_thread (GTask *task,
* gpointer source_object,
* gpointer task_data,
* GCancellable *cancellable)
* {
* Baker *self = source_object;
* CakeData *cake_data = task_data;
* Cake *cake;
* GError *error = NULL;
*
* cake = bake_cake (baker, cake_data->radius, cake_data->flavor,
* cake_data->frosting, cake_data->message,
* cancellable, &error);
* if (cake)
* g_task_return_pointer (task, cake, g_object_unref);
* else
* g_task_return_error (task, error);
* }
* cake = bake_cake (baker, cake_data->radius, cake_data->flavor,
* cake_data->frosting, cake_data->message,
* cancellable, &error);
* if (cake)
* g_task_return_pointer (task, cake, g_object_unref);
* else
* g_task_return_error (task, error);
* }
*
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* {
* CakeData *cake_data;
* GTask *task;
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* {
* CakeData *cake_data;
* GTask *task;
*
* cake_data = g_slice_new (CakeData);
* cake_data->radius = radius;
* cake_data->flavor = flavor;
* cake_data->frosting = frosting;
* cake_data->message = g_strdup (message);
* task = g_task_new (self, cancellable, callback, user_data);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
* g_task_run_in_thread (task, bake_cake_thread);
* g_object_unref (task);
* }
* cake_data = g_slice_new (CakeData);
* cake_data->radius = radius;
* cake_data->flavor = flavor;
* cake_data->frosting = frosting;
* cake_data->message = g_strdup (message);
* task = g_task_new (self, cancellable, callback, user_data);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
* g_task_run_in_thread (task, bake_cake_thread);
* g_object_unref (task);
* }
*
* Cake *
* baker_bake_cake_finish (Baker *self,
* GAsyncResult *result,
* GError **error)
* {
* g_return_val_if_fail (g_task_is_valid (result, self), NULL);
* Cake *
* baker_bake_cake_finish (Baker *self,
* GAsyncResult *result,
* GError **error)
* {
* g_return_val_if_fail (g_task_is_valid (result, self), NULL);
*
* return g_task_propagate_pointer (G_TASK (result), error);
* }
* ]|
* return g_task_propagate_pointer (G_TASK (result), error);
* }
* ```
*
* ## Adding cancellability to uncancellable tasks
*
* Finally, g_task_run_in_thread() and g_task_run_in_thread_sync()
* can be used to turn an uncancellable operation into a
* cancellable one. If you call g_task_set_return_on_cancel(),
* passing %TRUE, then if the task's #GCancellable is cancelled,
* it will return control back to the caller immediately, while
* allowing the task thread to continue running in the background
* (and simply discarding its result when it finally does finish).
* Finally, [method@Gio.Task.run_in_thread] and
* [method@Gio.Task.run_in_thread_sync] can be used to turn an uncancellable
* operation into a cancellable one. If you call
* [method@Gio.Task.set_return_on_cancel], passing `TRUE`, then if the tasks
* [class@Gio.Cancellable] is cancelled, it will return control back to the
* caller immediately, while allowing the task thread to continue running in the
* background (and simply discarding its result when it finally does finish).
* Provided that the task thread is careful about how it uses
* locks and other externally-visible resources, this allows you
* to make "GLib-friendly" asynchronous and cancellable
* to make GLib-friendly asynchronous and cancellable
* synchronous variants of blocking APIs.
*
* Cancelling a task:
* |[<!-- language="C" -->
* static void
* bake_cake_thread (GTask *task,
* gpointer source_object,
* gpointer task_data,
* GCancellable *cancellable)
* ```c
* static void
* bake_cake_thread (GTask *task,
* gpointer source_object,
* gpointer task_data,
* GCancellable *cancellable)
* {
* Baker *self = source_object;
* CakeData *cake_data = task_data;
* Cake *cake;
* GError *error = NULL;
*
* cake = bake_cake (baker, cake_data->radius, cake_data->flavor,
* cake_data->frosting, cake_data->message,
* &error);
* if (error)
* {
* Baker *self = source_object;
* CakeData *cake_data = task_data;
* Cake *cake;
* GError *error = NULL;
*
* cake = bake_cake (baker, cake_data->radius, cake_data->flavor,
* cake_data->frosting, cake_data->message,
* &error);
* if (error)
* {
* g_task_return_error (task, error);
* return;
* }
*
* // If the task has already been cancelled, then we don't want to add
* // the cake to the cake cache. Likewise, we don't want to have the
* // task get cancelled in the middle of updating the cache.
* // g_task_set_return_on_cancel() will return %TRUE here if it managed
* // to disable return-on-cancel, or %FALSE if the task was cancelled
* // before it could.
* if (g_task_set_return_on_cancel (task, FALSE))
* {
* // If the caller cancels at this point, their
* // GAsyncReadyCallback won't be invoked until we return,
* // so we don't have to worry that this code will run at
* // the same time as that code does. But if there were
* // other functions that might look at the cake cache,
* // then we'd probably need a GMutex here as well.
* baker_add_cake_to_cache (baker, cake);
* g_task_return_pointer (task, cake, g_object_unref);
* }
* g_task_return_error (task, error);
* return;
* }
*
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* // If the task has already been cancelled, then we dont want to add
* // the cake to the cake cache. Likewise, we dont want to have the
* // task get cancelled in the middle of updating the cache.
* // g_task_set_return_on_cancel() will return %TRUE here if it managed
* // to disable return-on-cancel, or %FALSE if the task was cancelled
* // before it could.
* if (g_task_set_return_on_cancel (task, FALSE))
* {
* CakeData *cake_data;
* GTask *task;
*
* cake_data = g_slice_new (CakeData);
*
* ...
*
* task = g_task_new (self, cancellable, callback, user_data);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
* g_task_set_return_on_cancel (task, TRUE);
* g_task_run_in_thread (task, bake_cake_thread);
* // If the caller cancels at this point, their
* // GAsyncReadyCallback wont be invoked until we return,
* // so we dont have to worry that this code will run at
* // the same time as that code does. But if there were
* // other functions that might look at the cake cache,
* // then wed probably need a GMutex here as well.
* baker_add_cake_to_cache (baker, cake);
* g_task_return_pointer (task, cake, g_object_unref);
* }
* }
*
* Cake *
* baker_bake_cake_sync (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GError **error)
* {
* CakeData *cake_data;
* GTask *task;
* Cake *cake;
* void
* baker_bake_cake_async (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GAsyncReadyCallback callback,
* gpointer user_data)
* {
* CakeData *cake_data;
* GTask *task;
*
* cake_data = g_slice_new (CakeData);
* cake_data = g_slice_new (CakeData);
*
* ...
* ...
*
* task = g_task_new (self, cancellable, NULL, NULL);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
* g_task_set_return_on_cancel (task, TRUE);
* g_task_run_in_thread_sync (task, bake_cake_thread);
* task = g_task_new (self, cancellable, callback, user_data);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
* g_task_set_return_on_cancel (task, TRUE);
* g_task_run_in_thread (task, bake_cake_thread);
* }
*
* cake = g_task_propagate_pointer (task, error);
* g_object_unref (task);
* return cake;
* }
* ]|
* Cake *
* baker_bake_cake_sync (Baker *self,
* guint radius,
* CakeFlavor flavor,
* CakeFrostingType frosting,
* const char *message,
* GCancellable *cancellable,
* GError **error)
* {
* CakeData *cake_data;
* GTask *task;
* Cake *cake;
*
* ## Porting from GSimpleAsyncResult
* cake_data = g_slice_new (CakeData);
*
* ...
*
* task = g_task_new (self, cancellable, NULL, NULL);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
* g_task_set_return_on_cancel (task, TRUE);
* g_task_run_in_thread_sync (task, bake_cake_thread);
*
* cake = g_task_propagate_pointer (task, error);
* g_object_unref (task);
* return cake;
* }
* ```
*
* ## Porting from [class@Gio.SimpleAsyncResult]
*
* #GTask's API attempts to be simpler than #GSimpleAsyncResult's
* `GTask`s API attempts to be simpler than [class@Gio.SimpleAsyncResult]s
* in several ways:
* - You can save task-specific data with g_task_set_task_data(), and
* retrieve it later with g_task_get_task_data(). This replaces the
* abuse of g_simple_async_result_set_op_res_gpointer() for the same
* purpose with #GSimpleAsyncResult.
* - In addition to the task data, #GTask also keeps track of the
* [priority][io-priority], #GCancellable, and
* #GMainContext associated with the task, so tasks that consist of
* a chain of simpler asynchronous operations will have easy access
*
* - You can save task-specific data with [method@Gio.Task.set_task_data], and
* retrieve it later with [method@Gio.Task.get_task_data]. This replaces the
* abuse of [method@Gio.SimpleAsyncResult.set_op_res_gpointer] for the same
* purpose with [class@Gio.SimpleAsyncResult].
* - In addition to the task data, `GTask` also keeps track of the
* [priority](iface.AsyncResult.html#io-priority), [class@Gio.Cancellable],
* and [struct@GLib.MainContext] associated with the task, so tasks that
* consist of a chain of simpler asynchronous operations will have easy access
* to those values when starting each sub-task.
* - g_task_return_error_if_cancelled() provides simplified
* - [method@Gio.Task.return_error_if_cancelled] provides simplified
* handling for cancellation. In addition, cancellation
* overrides any other #GTask return value by default, like
* #GSimpleAsyncResult does when
* g_simple_async_result_set_check_cancellable() is called.
* (You can use g_task_set_check_cancellable() to turn off that
* behavior.) On the other hand, g_task_run_in_thread()
* overrides any other `GTask` return value by default, like
* [class@Gio.SimpleAsyncResult] does when
* [method@Gio.SimpleAsyncResult.set_check_cancellable] is called.
* (You can use [method@Gio.Task.set_check_cancellable] to turn off that
* behavior.) On the other hand, [method@Gio.Task.run_in_thread]
* guarantees that it will always run your
* `task_func`, even if the task's #GCancellable
* `task_func`, even if the tasks [class@Gio.Cancellable]
* is already cancelled before the task gets a chance to run;
* you can start your `task_func` with a
* g_task_return_error_if_cancelled() check if you need the
* [method@Gio.Task.return_error_if_cancelled] check if you need the
* old behavior.
* - The "return" methods (eg, g_task_return_pointer())
* automatically cause the task to be "completed" as well, and
* there is no need to worry about the "complete" vs "complete
* in idle" distinction. (#GTask automatically figures out
* whether the task's callback can be invoked directly, or
* if it needs to be sent to another #GMainContext, or delayed
* until the next iteration of the current #GMainContext.)
* - The "finish" functions for #GTask based operations are generally
* much simpler than #GSimpleAsyncResult ones, normally consisting
* of only a single call to g_task_propagate_pointer() or the like.
* Since g_task_propagate_pointer() "steals" the return value from
* the #GTask, it is not necessary to juggle pointers around to
* - The return methods (eg, [method@Gio.Task.return_pointer])
* automatically cause the task to be completed as well, and
* there is no need to worry about the complete vs complete in idle
* distinction. (`GTask` automatically figures out
* whether the tasks callback can be invoked directly, or
* if it needs to be sent to another [struct@GLib.MainContext], or delayed
* until the next iteration of the current [struct@GLib.MainContext].)
* - The finish functions for `GTask` based operations are generally
* much simpler than [class@Gio.SimpleAsyncResult] ones, normally consisting
* of only a single call to [method@Gio.Task.propagate_pointer] or the like.
* Since [method@Gio.Task.propagate_pointer] steals the return value from
* the `GTask`, it is not necessary to juggle pointers around to
* prevent it from being freed twice.
* - With #GSimpleAsyncResult, it was common to call
* g_simple_async_result_propagate_error() from the
* - With [class@Gio.SimpleAsyncResult], it was common to call
* [method@Gio.SimpleAsyncResult.propagate_error] from the
* `_finish()` wrapper function, and have
* virtual method implementations only deal with successful
* returns. This behavior is deprecated, because it makes it
* difficult for a subclass to chain to a parent class's async
* difficult for a subclass to chain to a parent classs async
* methods. Instead, the wrapper function should just be a
* simple wrapper, and the virtual method should call an
* appropriate `g_task_propagate_` function.
* Note that wrapper methods can now use
* g_async_result_legacy_propagate_error() to do old-style
* #GSimpleAsyncResult error-returning behavior, and
* g_async_result_is_tagged() to check if a result is tagged as
* [method@Gio.AsyncResult.legacy_propagate_error] to do old-style
* [class@Gio.SimpleAsyncResult] error-returning behavior, and
* [method@Gio.AsyncResult.is_tagged] to check if a result is tagged as
* having come from the `_async()` wrapper
* function (for "short-circuit" results, such as when passing
* 0 to g_input_stream_read_async()).
* function (for short-circuit results, such as when passing
* `0` to [method@Gio.InputStream.read_async]).
*
* ## Thread-safety considerations
*
* Due to some infelicities in the API design, there is a
* thread-safety concern that users of GTask have to be aware of:
* thread-safety concern that users of `GTask` have to be aware of:
*
* If the `main` thread drops its last reference to the source object
* or the task data before the task is finalized, then the finalizers
@ -556,19 +554,11 @@
* can lead to hard-to-debug crashes. Possible workarounds include:
*
* - Clear task data in a signal handler for `notify::completed`
*
* - Keep iterating a main context in the main thread and defer
* dropping the reference to the source object to that main
* context when the task is finalized
*/
/**
* GTask:
*
* The opaque object representing a synchronous or asynchronous task
* and its result.
*/
struct _GTask {
GObject parent_instance;
@ -962,7 +952,7 @@ g_task_set_task_data (GTask *task,
/**
* g_task_set_priority:
* @task: the #GTask
* @priority: the [priority][io-priority] of the request
* @priority: the [priority](iface.AsyncResult.html#io-priority) of the request
*
* Sets @task's priority. If you do not call this, it will default to
* %G_PRIORITY_DEFAULT.
@ -1787,8 +1777,9 @@ g_task_run_in_thread_sync (GTask *task,
*
* A utility function for dealing with async operations where you need
* to wait for a #GSource to trigger. Attaches @source to @task's
* #GMainContext with @task's [priority][io-priority], and sets @source's
* callback to @callback, with @task as the callback's `user_data`.
* #GMainContext with @task's [priority](iface.AsyncResult.html#io-priority),
* and sets @source's callback to @callback, with @task as the callback's
* `user_data`.
*
* It will set the @sources name to the tasks name (as set with
* g_task_set_name()), if one has been set on the task and the source doesnt

View File

@ -33,26 +33,16 @@
#include "glibintl.h"
#include "gmarshal-internal.h"
/**
* SECTION:gtlsconnection
* @short_description: TLS connection type
* @include: gio/gio.h
*
* #GTlsConnection is the base TLS connection class type, which wraps
* a #GIOStream and provides TLS encryption on top of it. Its
* subclasses, #GTlsClientConnection and #GTlsServerConnection,
* implement client-side and server-side TLS, respectively.
*
* For DTLS (Datagram TLS) support, see #GDtlsConnection.
*
* Since: 2.28
*/
/**
* GTlsConnection:
*
* Abstract base class for the backend-specific #GTlsClientConnection
* and #GTlsServerConnection types.
* `GTlsConnection` is the base TLS connection class type, which wraps
* a [class@Gio.IOStream] and provides TLS encryption on top of it. Its
* subclasses, [iface@Gio.TlsClientConnection] and
* [iface@Gio.TlsServerConnection], implement client-side and server-side TLS,
* respectively.
*
* For DTLS (Datagram TLS) support, see [iface@Gio.DtlsConnection].
*
* Since: 2.28
*/

View File

@ -15,34 +15,23 @@
*/
/**
* SECTION:gunixfdmessage
* @title: GUnixFDMessage
* @short_description: A GSocketControlMessage containing a GUnixFDList
* @include: gio/gunixfdmessage.h
* @see_also: #GUnixConnection, #GUnixFDList, #GSocketControlMessage
* GUnixFDMessage:
*
* This #GSocketControlMessage contains a #GUnixFDList.
* It may be sent using g_socket_send_message() and received using
* g_socket_receive_message() over UNIX sockets (ie: sockets in the
* %G_SOCKET_FAMILY_UNIX family). The file descriptors are copied
* This [class@Gio.SocketControlMessage] contains a [class@Gio.UnixFDList].
* It may be sent using [method@Gio.Socket.send_message] and received using
* [method@Gio.Socket.receive_message] over UNIX sockets (ie: sockets in the
* `G_SOCKET_FAMILY_UNIX` family). The file descriptors are copied
* between processes by the kernel.
*
* For an easier way to send and receive file descriptors over
* stream-oriented UNIX sockets, see g_unix_connection_send_fd() and
* g_unix_connection_receive_fd().
* stream-oriented UNIX sockets, see [method@Gio.UnixConnection.send_fd] and
* [method@Gio.UnixConnection.receive_fd].
*
* Note that `<gio/gunixfdmessage.h>` belongs to the UNIX-specific GIO
* interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config
* file when using it.
*/
/**
* GUnixFDMessage:
*
* #GUnixFDMessage is an opaque data structure and can only be accessed
* using the following functions.
**/
#include "config.h"
#include <unistd.h>

View File

@ -31,12 +31,9 @@
/**
* SECTION:gvfs
* @short_description: Virtual File System
* @include: gio/gio.h
* GVfs:
*
* Entry point for using GIO functionality.
*
*/
static GRWLock additional_schemes_lock;

View File

@ -68,11 +68,6 @@ typedef GFile * (* GVfsFileLookupFunc) (GVfs *vfs,
*/
#define G_VFS_EXTENSION_POINT_NAME "gio-vfs"
/**
* GVfs:
*
* Virtual File System object.
**/
typedef struct _GVfsClass GVfsClass;
struct _GVfs

View File

@ -42,19 +42,18 @@
#include "gtestutils.h"
/**
* SECTION:caches
* @title: Caches
* @short_description: caches allow sharing of complex data structures
* to save resources
* GCache:
*
* A #GCache allows sharing of complex data structures, in order to
* A `GCache` allows sharing of complex data structures, in order to
* save system resources.
*
* GCache uses keys and values. A GCache key describes the properties
* of a particular resource. A GCache value is the actual resource.
* `GCache` uses keys and values. A `GCache` key describes the properties
* of a particular resource. A `GCache` value is the actual resource.
*
* GCache has been marked as deprecated, since this API is rarely
* `GCache` has been marked as deprecated, since this API is rarely
* used and not very actively maintained.
*
* Deprecated:2.32: Use a #GHashTable instead
*/
typedef struct _GCacheNode GCacheNode;
@ -66,15 +65,6 @@ struct _GCacheNode
gint ref_count;
};
/**
* GCache:
*
* The #GCache struct is an opaque data structure containing
* information about a #GCache. It should only be accessed via the
* following functions.
*
* Deprecated:2.32: Use a #GHashTable instead
*/
struct _GCache
{
/* Called to create a value from a key */
@ -147,6 +137,7 @@ g_cache_node_destroy (GCacheNode *node)
* value corresponding to the key.
*
* Returns: a new #GCache value corresponding to the key.
* Deprecated:2.32: Use a #GHashTable instead
*/
/**
@ -157,6 +148,8 @@ g_cache_node_destroy (GCacheNode *node)
* functions passed to g_cache_new(). The functions are passed a
* pointer to the #GCache key or #GCache value and should free any
* memory and other resources associated with it.
*
* Deprecated:2.32: Use a #GHashTable instead
*/
/**
@ -170,6 +163,7 @@ g_cache_node_destroy (GCacheNode *node)
* should return a duplicate of the key.
*
* Returns: a copy of the #GCache key
* Deprecated:2.32: Use a #GHashTable instead
*/
GCache*
g_cache_new (GCacheNewFunc value_new_func,

View File

@ -43,34 +43,6 @@
#include <string.h>
/**
* SECTION:completion
* @title: Automatic String Completion
* @short_description: support for automatic completion using a group
* of target strings
*
* #GCompletion provides support for automatic completion of a string
* using any group of target strings. It is typically used for file
* name completion as is common in many UNIX shells.
*
* A #GCompletion is created using g_completion_new(). Target items are
* added and removed with g_completion_add_items(),
* g_completion_remove_items() and g_completion_clear_items(). A
* completion attempt is requested with g_completion_complete() or
* g_completion_complete_utf8(). When no longer needed, the
* #GCompletion is freed with g_completion_free().
*
* Items in the completion can be simple strings (e.g. filenames), or
* pointers to arbitrary data structures. If data structures are used
* you must provide a #GCompletionFunc in g_completion_new(), which
* retrieves the item's string from the data structure. You can change
* the way in which strings are compared by setting a different
* #GCompletionStrncmpFunc in g_completion_set_compare().
*
* GCompletion has been marked as deprecated, since this API is rarely
* used and not very actively maintained.
**/
/**
* GCompletion:
* @items: list of target items (strings or data structures).
@ -82,7 +54,29 @@
* @strncmp_func: The function to use when comparing strings. Use
* g_completion_set_compare() to modify this function.
*
* The data structure used for automatic completion.
* `GCompletion` provides support for automatic completion of a string
* using any group of target strings. It is typically used for file
* name completion as is common in many UNIX shells.
*
* A `GCompletion` is created using [func@GLib.Completion.new]. Target items are
* added and removed with [method@GLib.Completion.add_items],
* [method@GLib.Completion.remove_items] and
* [method@GLib.Completion.clear_items]. A completion attempt is requested with
* [method@GLib.Completion.complete] or [method@GLib.Completion.complete_utf8].
* When no longer needed, the `GCompletion` is freed with
* [method@GLib.Completion.free].
*
* Items in the completion can be simple strings (e.g. filenames), or
* pointers to arbitrary data structures. If data structures are used
* you must provide a [type@GLib.CompletionFunc] in [func@GLib.Completion.new],
* which retrieves the items string from the data structure. You can change
* the way in which strings are compared by setting a different
* [type@GLib.CompletionStrncmpFunc] in [method@GLib.Completion.set_compare].
*
* `GCompletion` has been marked as deprecated, since this API is rarely
* used and not very actively maintained.
*
* Deprecated: 2.26: Rarely used API
**/
/**
@ -94,6 +88,7 @@
* This is used when you use data structures as #GCompletion items.
*
* Returns: the string corresponding to the item.
* Deprecated: 2.26: Rarely used API
**/
/**
@ -110,6 +105,7 @@
* the first @n bytes of @s1 is found, respectively, to be
* less than, to match, or to be greater than the first @n
* bytes of @s2.
* Deprecated: 2.26: Rarely used API
**/
static void completion_check_cache (GCompletion* cmp,
@ -124,6 +120,7 @@ static void completion_check_cache (GCompletion* cmp,
* Creates a new #GCompletion.
*
* Returns: the new #GCompletion.
* Deprecated: 2.26: Rarely used API
**/
GCompletion*
g_completion_new (GCompletionFunc func)

View File

@ -48,61 +48,53 @@
#include <string.h>
/**
* SECTION:relations
* @title: Relations and Tuples
* @short_description: tables of data which can be indexed on any
* number of fields
* GRelation:
*
* A #GRelation is a table of data which can be indexed on any number
* of fields, rather like simple database tables. A #GRelation contains
* A `GRelation` is a table of data which can be indexed on any number
* of fields, rather like simple database tables. A `GRelation` contains
* a number of records, called tuples. Each record contains a number of
* fields. Records are not ordered, so it is not possible to find the
* record at a particular index.
*
* Note that #GRelation tables are currently limited to 2 fields.
* Note that `GRelation` tables are currently limited to 2 fields.
*
* To create a GRelation, use g_relation_new().
* To create a `GRelation`, use [func@GLib.Relation.new].
*
* To specify which fields should be indexed, use g_relation_index().
* To specify which fields should be indexed, use [method@GLib.Relation.index].
* Note that this must be called before any tuples are added to the
* #GRelation.
* `GRelation`.
*
* To add records to a #GRelation use g_relation_insert().
* To add records to a `GRelation` use [method@GLib.Relation.insert].
*
* To determine if a given record appears in a #GRelation, use
* g_relation_exists(). Note that fields are compared directly, so
* To determine if a given record appears in a `GRelation`, use
* [method@GLib.Relation.exists]. Note that fields are compared directly, so
* pointers must point to the exact same position (i.e. different
* copies of the same string will not match.)
*
* To count the number of records which have a particular value in a
* given field, use g_relation_count().
* given field, use [method@GLib.Relation.count].
*
* To get all the records which have a particular value in a given
* field, use g_relation_select(). To access fields of the resulting
* records, use g_tuples_index(). To free the resulting records use
* g_tuples_destroy().
* field, use [method@GLib.Relation.select]. To access fields of the resulting
* records, use [method@GLib.Tuples.index]. To free the resulting records use
* [method@GLib.Tuples.destroy].
*
* To delete all records which have a particular value in a given
* field, use g_relation_delete().
* field, use [method@GLib.Relation.delete].
*
* To destroy the #GRelation, use g_relation_destroy().
* To destroy the `GRelation`, use [method@GLib.Relation.destroy].
*
* To help debug #GRelation objects, use g_relation_print().
* To help debug `GRelation` objects, use [method@GLib.Relation.print].
*
* GRelation has been marked as deprecated, since this API has never
* `GRelation` has been marked as deprecated, since this API has never
* been fully implemented, is not very actively maintained and rarely
* used.
*
* Deprecated: 2.26: Rarely used API
**/
typedef struct _GRealTuples GRealTuples;
/**
* GRelation:
*
* The #GRelation struct is an opaque data structure to represent a
* [Relation][glib-Relations-and-Tuples]. It should
* only be accessed via the following functions.
**/
struct _GRelation
{
gint fields;
@ -122,6 +114,8 @@ struct _GRelation
* #GRelation by g_relation_select(). It only contains one public
* member - the number of records that matched. To access the matched
* records, you must use g_tuples_index().
*
* Deprecated: 2.26: Rarely used API
**/
struct _GRealTuples
{

View File

@ -43,29 +43,6 @@ struct _GTuples
guint len;
};
/* GRelation
*
* Indexed Relations. Imagine a really simple table in a
* database. Relations are not ordered. This data type is meant for
* maintaining a N-way mapping.
*
* g_relation_new() creates a relation with FIELDS fields
*
* g_relation_destroy() frees all resources
* g_tuples_destroy() frees the result of g_relation_select()
*
* g_relation_index() indexes relation FIELD with the provided
* equality and hash functions. this must be done before any
* calls to insert are made.
*
* g_relation_insert() inserts a new tuple. you are expected to
* provide the right number of fields.
*
* g_relation_delete() deletes all relations with KEY in FIELD
* g_relation_select() returns ...
* g_relation_count() counts ...
*/
GLIB_DEPRECATED_IN_2_26
GRelation* g_relation_new (gint fields);
GLIB_DEPRECATED_IN_2_26