Merge branch 'glib-2-72' into 'glib-2-72'

Prepare for 2.72.4

See merge request GNOME/glib!2908
This commit is contained in:
Matthias Clasen 2022-09-20 19:07:34 +00:00
commit 0e4922c8bc
39 changed files with 590 additions and 200 deletions

View File

@ -26,8 +26,12 @@ extra_c_args = cc.get_supported_arguments('-Werror=unused-function')
# Links in a static library provided by oss-fuzz, else a standalone driver.
# https://google.github.io/oss-fuzz/getting-started/new-project-guide/#buildsh-script-environment
fuzzing_engine = cxx.find_library('FuzzingEngine', required : get_option('oss_fuzz'))
if fuzzing_engine.found()
have_fuzzing_engine = false
if have_cxx
fuzzing_engine = cxx.find_library('FuzzingEngine', required : get_option('oss_fuzz'))
have_fuzzing_engine = fuzzing_engine.found()
endif
if have_fuzzing_engine
deps += fuzzing_engine
else
extra_sources += 'driver.c'

View File

@ -739,8 +739,8 @@ g_action_group_action_state_changed (GActionGroup *action_group,
* @action_group: a #GActionGroup
* @action_name: the name of an action in the group
* @enabled: (out): if the action is presently enabled
* @parameter_type: (out) (optional): the parameter type, or %NULL if none needed
* @state_type: (out) (optional): the state type, or %NULL if stateless
* @parameter_type: (out) (transfer none) (optional): the parameter type, or %NULL if none needed
* @state_type: (out) (transfer none) (optional): the state type, or %NULL if stateless
* @state_hint: (out) (optional): the state hint, or %NULL if none
* @state: (out) (optional): the current state, or %NULL if stateless
*

View File

@ -483,6 +483,7 @@ gchar *
g_content_type_get_description (const gchar *type)
{
static GHashTable *type_comment_cache = NULL;
gchar *type_copy = NULL;
gchar *comment;
g_return_val_if_fail (type != NULL, NULL);
@ -497,16 +498,21 @@ g_content_type_get_description (const gchar *type)
comment = g_hash_table_lookup (type_comment_cache, type);
comment = g_strdup (comment);
G_UNLOCK (gio_xdgmime);
if (comment != NULL)
return comment;
{
G_UNLOCK (gio_xdgmime);
return comment;
}
comment = load_comment_for_mime (type);
type_copy = g_strdup (type);
G_UNLOCK (gio_xdgmime);
comment = load_comment_for_mime (type_copy);
G_LOCK (gio_xdgmime);
g_hash_table_insert (type_comment_cache,
g_strdup (type),
g_steal_pointer (&type_copy),
g_strdup (comment));
G_UNLOCK (gio_xdgmime);

View File

@ -784,13 +784,13 @@ _g_dbus_auth_run_client (GDBusAuth *auth,
if (line == NULL)
goto out;
debug_print ("CLIENT: WaitingForData, read='%s'", line);
if (g_str_has_prefix (line, "DATA "))
if (g_str_equal (line, "DATA") || g_str_has_prefix (line, "DATA "))
{
gchar *encoded;
gchar *decoded_data;
gsize decoded_data_len = 0;
encoded = g_strdup (line + 5);
encoded = g_strdup (line + 4);
g_free (line);
g_strstrip (encoded);
decoded_data = hexdecode (encoded, &decoded_data_len, error);
@ -1265,13 +1265,13 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
debug_print ("SERVER: WaitingForData, read '%s'", line);
if (line == NULL)
goto out;
if (g_str_has_prefix (line, "DATA "))
if (g_str_equal (line, "DATA") || g_str_has_prefix (line, "DATA "))
{
gchar *encoded;
gchar *decoded_data;
gsize decoded_data_len = 0;
encoded = g_strdup (line + 5);
encoded = g_strdup (line + 4);
g_free (line);
g_strstrip (encoded);
decoded_data = hexdecode (encoded, &decoded_data_len, error);

View File

@ -38,6 +38,7 @@ struct _GDBusAuthMechanismExternalPrivate
gboolean is_client;
gboolean is_server;
GDBusAuthMechanismState state;
gboolean empty_data_sent;
};
static gint mechanism_get_priority (void);
@ -198,14 +199,24 @@ data_matches_credentials (const gchar *data,
if (credentials == NULL)
goto out;
if (data == NULL || data_len == 0)
goto out;
#if defined(G_OS_UNIX)
{
gint64 alleged_uid;
gchar *endp;
/* If we were unable to find out the uid, then nothing
* can possibly match it. */
if (g_credentials_get_unix_user (credentials, NULL) == (uid_t) -1)
goto out;
/* An empty authorization identity means we want to be
* whatever identity the out-of-band credentials say we have
* (RFC 4422 appendix A.1). This effectively matches any uid. */
if (data == NULL || data_len == 0)
{
match = TRUE;
goto out;
}
/* on UNIX, this is the uid as a string in base 10 */
alleged_uid = g_ascii_strtoll (data, &endp, 10);
if (*endp == '\0')
@ -251,7 +262,9 @@ mechanism_server_initiate (GDBusAuthMechanism *mechanism,
}
else
{
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;
/* The initial-response optimization was not used, so we need to
* send an empty challenge to prompt the client to respond. */
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND;
}
}
@ -286,12 +299,22 @@ mechanism_server_data_send (GDBusAuthMechanism *mechanism,
g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL);
g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);
/* can never end up here because we are never in the HAVE_DATA_TO_SEND state */
g_assert_not_reached ();
if (out_data_len)
*out_data_len = 0;
return NULL;
if (m->priv->empty_data_sent)
{
/* We have already sent an empty data response.
Reject the connection. */
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
return NULL;
}
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;
m->priv->empty_data_sent = TRUE;
return g_strdup ("");
}
static gchar *

View File

@ -706,7 +706,7 @@ merge_directory_results (void)
static_total_results = g_renew (struct search_result, static_total_results, static_total_results_allocated);
}
if (static_total_results + static_total_results_size != 0)
if (static_search_results_size != 0)
memcpy (static_total_results + static_total_results_size,
static_search_results,
static_search_results_size * sizeof (struct search_result));
@ -3107,6 +3107,9 @@ launch_uris_with_dbus_signal_cb (GObject *object,
if (data->callback)
data->callback (object, result, data->user_data);
else if (!g_task_had_error (G_TASK (result)))
g_variant_unref (g_dbus_connection_call_finish (G_DBUS_CONNECTION (object),
result, NULL));
launch_uris_with_dbus_data_free (data);
}
@ -3280,15 +3283,19 @@ launch_uris_with_dbus_cb (GObject *object,
{
GTask *task = G_TASK (user_data);
GError *error = NULL;
GVariant *ret;
g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
if (error != NULL)
{
g_dbus_error_strip_remote_error (error);
g_task_return_error (task, g_steal_pointer (&error));
}
else
g_task_return_boolean (task, TRUE);
{
g_task_return_boolean (task, TRUE);
g_variant_unref (ret);
}
g_object_unref (task);
}
@ -3347,11 +3354,16 @@ launch_uris_bus_get_cb (GObject *object,
g_task_return_error (task, g_steal_pointer (&error));
g_object_unref (task);
}
else
else if (session_bus)
g_dbus_connection_flush (session_bus,
cancellable,
launch_uris_flush_cb,
g_steal_pointer (&task));
else
{
g_task_return_boolean (task, TRUE);
g_clear_object (&task);
}
}
g_clear_object (&session_bus);

View File

@ -201,6 +201,7 @@ g_document_portal_add_documents (GList *uris,
else
{
ruris = g_list_copy_deep (uris, (GCopyFunc)g_strdup, NULL);
g_variant_builder_clear (&builder);
}
out:

View File

@ -119,6 +119,12 @@ g_io_error_from_errno (gint err_no)
break;
#endif
#ifdef EMLINK
case EMLINK:
return G_IO_ERROR_TOO_MANY_LINKS;
break;
#endif
#ifdef ELOOP
case ELOOP:
return G_IO_ERROR_TOO_MANY_LINKS;
@ -211,6 +217,12 @@ g_io_error_from_errno (gint err_no)
break;
#endif
#ifdef ETXTBSY
case ETXTBSY:
return G_IO_ERROR_BUSY;
break;
#endif
#ifdef EWOULDBLOCK
case EWOULDBLOCK:
return G_IO_ERROR_WOULD_BLOCK;

View File

@ -21,7 +21,7 @@
#include "gsimplepermission.h"
#include "gsettingsbackendinternal.h"
#include "giomodule.h"
#include "giomodule-priv.h"
#define G_TYPE_MEMORY_SETTINGS_BACKEND (g_memory_settings_backend_get_type())
@ -39,6 +39,7 @@ typedef struct
G_DEFINE_TYPE_WITH_CODE (GMemorySettingsBackend,
g_memory_settings_backend,
G_TYPE_SETTINGS_BACKEND,
_g_io_modules_ensure_extension_points_registered ();
g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
g_define_type_id, "memory", 10))

View File

@ -21,7 +21,7 @@
#include "gsettingsbackendinternal.h"
#include "gsimplepermission.h"
#include "giomodule.h"
#include "giomodule-priv.h"
#import <Foundation/Foundation.h>
@ -44,6 +44,7 @@ struct _GNextstepSettingsBackend
G_DEFINE_TYPE_WITH_CODE (GNextstepSettingsBackend,
g_nextstep_settings_backend,
G_TYPE_SETTINGS_BACKEND,
_g_io_modules_ensure_extension_points_registered ();
g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
g_define_type_id, "nextstep", 90));

View File

@ -20,7 +20,7 @@
#include "config.h"
#include "gsettingsbackendinternal.h"
#include "giomodule.h"
#include "giomodule-priv.h"
#include "gsimplepermission.h"
@ -36,6 +36,7 @@ typedef GSettingsBackend GNullSettingsBackend;
G_DEFINE_TYPE_WITH_CODE (GNullSettingsBackend,
g_null_settings_backend,
G_TYPE_SETTINGS_BACKEND,
_g_io_modules_ensure_extension_points_registered ();
g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
g_define_type_id, "null", 10))

View File

@ -91,7 +91,7 @@
#include "gregistrysettingsbackend.h"
#include "gsettingsbackend.h"
#include "giomodule.h"
#include "giomodule-priv.h"
#include <windows.h>
@ -177,6 +177,7 @@ typedef struct {
G_DEFINE_TYPE_WITH_CODE (GRegistryBackend,
g_registry_backend,
G_TYPE_SETTINGS_BACKEND,
_g_io_modules_ensure_extension_points_registered ();
g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
g_define_type_id, "registry", 90))

View File

@ -415,7 +415,7 @@ g_simple_proxy_resolver_class_init (GSimpleProxyResolverClass *resolver_class)
object_class->finalize = g_simple_proxy_resolver_finalize;
/**
* GSimpleProxyResolver:default-proxy:
* GSimpleProxyResolver:default-proxy: (nullable)
*
* The default proxy URI that will be used for any URI that doesn't
* match #GSimpleProxyResolver:ignore-hosts, and doesn't match any
@ -518,7 +518,7 @@ g_simple_proxy_resolver_new (const gchar *default_proxy,
/**
* g_simple_proxy_resolver_set_default_proxy:
* @resolver: a #GSimpleProxyResolver
* @default_proxy: the default proxy to use
* @default_proxy: (nullable): the default proxy to use
*
* Sets the default proxy on @resolver, to be used for any URIs that
* don't match #GSimpleProxyResolver:ignore-hosts or a proxy set
@ -535,6 +535,7 @@ g_simple_proxy_resolver_set_default_proxy (GSimpleProxyResolver *resolver,
const gchar *default_proxy)
{
g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver));
g_return_if_fail (default_proxy == NULL || g_uri_is_valid (default_proxy, G_URI_FLAGS_NONE, NULL));
g_free (resolver->priv->default_proxy);
resolver->priv->default_proxy = g_strdup (default_proxy);

View File

@ -85,7 +85,7 @@ g_socket_address_enumerator_class_init (GSocketAddressEnumeratorClass *enumerato
* internal errors (other than @cancellable being triggered) will be
* ignored.
*
* Returns: (transfer full): a #GSocketAddress (owned by the caller), or %NULL on
* Returns: (transfer full) (nullable): a #GSocketAddress (owned by the caller), or %NULL on
* error (in which case *@error will be set) or if there are no
* more addresses.
*/
@ -179,7 +179,7 @@ g_socket_address_enumerator_real_next_finish (GSocketAddressEnumerator *enumera
* g_socket_address_enumerator_next() for more information about
* error handling.
*
* Returns: (transfer full): a #GSocketAddress (owned by the caller), or %NULL on
* Returns: (transfer full) (nullable): a #GSocketAddress (owned by the caller), or %NULL on
* error (in which case *@error will be set) or if there are no
* more addresses.
*/

View File

@ -624,7 +624,7 @@ create_certificate_chain_from_list (GSList *pem_list,
/* root will point to the last certificate in the file. */
if (!root)
root = cert;
root = g_object_ref (cert);
pem = g_slist_next (pem);
}
@ -639,6 +639,8 @@ create_certificate_chain_from_list (GSList *pem_list,
g_clear_object (&cert);
}
g_clear_object (&root);
return cert;
}

View File

@ -1408,17 +1408,13 @@ _g_get_unix_mount_points (void)
{
struct fstab *fstab = NULL;
GUnixMountPoint *mount_point;
GList *return_list;
GList *return_list = NULL;
G_LOCK_DEFINE_STATIC (fsent);
#ifdef HAVE_SYS_SYSCTL_H
int usermnt = 0;
struct stat sb;
#endif
if (!setfsent ())
return NULL;
return_list = NULL;
#ifdef HAVE_SYS_SYSCTL_H
#if defined(HAVE_SYSCTLBYNAME)
{
@ -1447,6 +1443,13 @@ _g_get_unix_mount_points (void)
#endif
#endif
G_LOCK (fsent);
if (!setfsent ())
{
G_UNLOCK (fsent);
return NULL;
}
while ((fstab = getfsent ()) != NULL)
{
gboolean is_read_only = FALSE;
@ -1482,6 +1485,7 @@ _g_get_unix_mount_points (void)
}
endfsent ();
G_UNLOCK (fsent);
return g_list_reverse (return_list);
}

View File

@ -358,6 +358,84 @@ test_flatpak_doc_export (void)
g_object_unref (flatpak_appinfo);
}
static void
on_flatpak_launch_invalid_uri_finish (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GApplication *app = user_data;
GError *error = NULL;
g_app_info_launch_uris_finish (G_APP_INFO (object), result, &error);
g_assert_no_error (error);
g_application_release (app);
}
static void
on_flatpak_activate_invalid_uri (GApplication *app,
gpointer user_data)
{
GDesktopAppInfo *flatpak_appinfo = user_data;
GList *uris;
/* The app will be released in on_flatpak_launch_uris_finish */
g_application_hold (app);
uris = g_list_prepend (NULL, "file:///hopefully/an/invalid/path.desktop");
g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, NULL,
NULL, on_flatpak_launch_invalid_uri_finish, app);
g_list_free (uris);
}
static void
on_flatpak_open_invalid_uri (GApplication *app,
GFile **files,
gint n_files,
const char *hint)
{
GFile *f;
g_assert_cmpint (n_files, ==, 1);
g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0]));
/* The file has been exported via the document portal */
f = g_file_new_for_uri ("file:///hopefully/an/invalid/path.desktop");
g_assert_true (g_file_equal (files[0], f));
g_object_unref (f);
}
static void
test_flatpak_missing_doc_export (void)
{
const gchar *argv[] = { "myapp", NULL };
gchar *desktop_file = NULL;
GDesktopAppInfo *flatpak_appinfo;
GApplication *app;
int status;
g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal.");
desktop_file = g_test_build_filename (G_TEST_DIST,
"org.gtk.test.dbusappinfo.flatpak.desktop",
NULL);
flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file);
g_assert_nonnull (flatpak_appinfo);
app = g_application_new ("org.gtk.test.dbusappinfo.flatpak",
G_APPLICATION_HANDLES_OPEN);
g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate_invalid_uri),
flatpak_appinfo);
g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open_invalid_uri), NULL);
status = g_application_run (app, 1, (gchar **) argv);
g_assert_cmpint (status, ==, 0);
g_object_unref (app);
g_object_unref (flatpak_appinfo);
g_free (desktop_file);
}
int
main (int argc, char **argv)
{
@ -365,6 +443,7 @@ main (int argc, char **argv)
g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo);
g_test_add_func ("/appinfo/flatpak-doc-export", test_flatpak_doc_export);
g_test_add_func ("/appinfo/flatpak-missing-doc-export", test_flatpak_missing_doc_export);
return session_bus_run ();
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2022 Ryan Hope
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: Ryan Hope <ryanhope97@gmail.com>
*/
#include <gio/gio.h>
#include <locale.h>
#define G_SETTINGS_ENABLE_BACKEND
#include <gio/gsettingsbackend.h>
/* Test that the "gsettings-backend" extension point has been registered.
* Must be run first and separetly from other GSettingsBackend,
* as they will register the extension point making the test useless.
*/
static void
test_extension_point_registered (void)
{
GSettingsBackend *backend;
GIOExtensionPoint *extension_point;
backend = g_memory_settings_backend_new ();
g_assert_true (G_IS_SETTINGS_BACKEND (backend));
extension_point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
g_assert_nonnull (extension_point);
g_object_unref (backend);
}
int
main (int argc, char *argv[])
{
setlocale (LC_ALL, "");
g_test_init (&argc, &argv, NULL);
/* Must be run first */
g_test_add_func ("/memory-settings-backend/extension-point-registered", test_extension_point_registered);
return g_test_run ();
}

View File

@ -58,9 +58,6 @@ gio_tests = {
},
'converter-stream' : {},
'credentials' : {},
'cxx' : {
'source' : ['cxx.cpp'],
},
'data-input-stream' : {},
'data-output-stream' : {},
'fileattributematcher' : {},
@ -86,10 +83,12 @@ gio_tests = {
'memory-input-stream' : {},
'memory-monitor' : {},
'memory-output-stream' : {},
'memory-settings-backend' : {},
'mount-operation' : {},
'network-address' : {'extra_sources': ['mock-resolver.c']},
'network-monitor' : {},
'network-monitor-race' : {},
'null-settings-backend' : {},
'permission' : {},
'pollable' : {'dependencies' : [libdl_dep]},
'power-profile-monitor' : {},
@ -122,6 +121,14 @@ gio_tests = {
'win32-appinfo' : {},
}
if have_cxx
gio_tests += {
'cxx' : {
'source' : ['cxx.cpp'],
},
}
endif
test_extra_programs = {
'gdbus-connection-flush-helper' : {},
'gdbus-testserver' : {},

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2022 Ryan Hope
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: Ryan Hope <ryanhope97@gmail.com>
*/
#include <gio/gio.h>
#define G_SETTINGS_ENABLE_BACKEND
#include <gio/gsettingsbackend.h>
/* Test that the "gsettings-backend" extension point has been registered.
* Must be run first and separetly from other GSettingsBackend,
* as they will register the extension point making the test useless.
*/
static void
test_extension_point_registered (void)
{
GSettingsBackend *backend;
GIOExtensionPoint *extension_point;
backend = g_null_settings_backend_new ();
g_assert_true (G_IS_SETTINGS_BACKEND (backend));
extension_point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
g_assert_nonnull (extension_point);
g_object_unref (backend);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
/* Must be run first */
g_test_add_func ("/null-settings-backend/extension-point-registered", test_extension_point_registered);
return g_test_run ();
}

View File

@ -350,8 +350,7 @@ xdg_mime_set_dirs (const char * const *dirs)
for (i = 0; xdg_dirs != NULL && xdg_dirs[i] != NULL; i++)
free (xdg_dirs[i]);
if (xdg_dirs != NULL)
free (xdg_dirs[i]);
free (xdg_dirs);
xdg_dirs = NULL;
if (dirs != NULL)

View File

@ -1169,8 +1169,9 @@ g_ptr_array_new (void)
* g_assert (chunk_buffer->len == 0);
* ]|
*
* Returns: (transfer full): the element data, which should be
* freed using g_free().
* Returns: (transfer full) (nullable): the element data, which should be
* freed using g_free(). This may be %NULL if the array doesnt have any
* elements (i.e. if `*len` is zero).
*
* Since: 2.64
*/
@ -1307,7 +1308,7 @@ g_array_copy (GArray *array)
* either via g_ptr_array_unref(), when g_ptr_array_free() is called with
* @free_segment set to %TRUE or when removing elements.
*
* Returns: A new #GPtrArray
* Returns: (transfer full): A new #GPtrArray
*
* Since: 2.22
*/
@ -1331,7 +1332,7 @@ g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
* g_ptr_array_unref(), when g_ptr_array_free() is called with
* @free_segment set to %TRUE or when removing elements.
*
* Returns: A new #GPtrArray
* Returns: (transfer full): A new #GPtrArray
*
* Since: 2.30
*/

View File

@ -70,7 +70,7 @@ g_unix_set_error_from_errno (GError **error,
/**
* g_unix_open_pipe:
* @fds: Array of two integers
* @fds: (array fixed-size=2): Array of two integers
* @flags: Bitfield of file descriptor flags, as for fcntl()
* @error: a #GError
*
@ -203,11 +203,11 @@ g_unix_set_fd_nonblocking (gint fd,
*
* For example, an effective use of this function is to handle `SIGTERM`
* cleanly; flushing any outstanding files, and then calling
* g_main_loop_quit (). It is not safe to do any of this a regular
* UNIX signal handler; your handler may be invoked while malloc() or
* another library function is running, causing reentrancy if you
* attempt to use it from the handler. None of the GLib/GObject API
* is safe against this kind of reentrancy.
* g_main_loop_quit(). It is not safe to do any of this from a regular
* UNIX signal handler; such a handler may be invoked while malloc() or
* another library function is running, causing reentrancy issues if the
* handler attempts to use those functions. None of the GLib/GObject
* API is safe against this kind of reentrancy.
*
* The interaction of this source when combined with native UNIX
* functions like sigprocmask() is not defined.

View File

@ -342,6 +342,8 @@ struct _GChildWatchSource
{
GSource source;
GPid pid;
/* On Unix this is a wait status, which is the thing you pass to WEXITSTATUS()
* to get the status returned from the process main() or passed to exit(): */
gint child_status;
#ifdef G_OS_WIN32
GPollFD poll;

View File

@ -113,6 +113,9 @@ static GMemVTable glib_mem_vtable = {
* Allocates @n_bytes bytes of memory.
* If @n_bytes is 0 it returns %NULL.
*
* If the allocation fails (because the system is out of memory),
* the program is terminated.
*
* Returns: a pointer to the allocated memory
*/
gpointer
@ -143,6 +146,9 @@ g_malloc (gsize n_bytes)
* Allocates @n_bytes bytes of memory, initialized to 0's.
* If @n_bytes is 0 it returns %NULL.
*
* If the allocation fails (because the system is out of memory),
* the program is terminated.
*
* Returns: a pointer to the allocated memory
*/
gpointer
@ -177,6 +183,9 @@ g_malloc0 (gsize n_bytes)
* have zero-length. @n_bytes may be 0, in which case %NULL will be returned
* and @mem will be freed unless it is %NULL.
*
* If the allocation fails (because the system is out of memory),
* the program is terminated.
*
* Returns: the new address of the allocated memory
*/
gpointer
@ -347,6 +356,9 @@ g_try_realloc (gpointer mem,
* This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
* but care is taken to detect possible overflow during multiplication.
*
* If the allocation fails (because the system is out of memory),
* the program is terminated.
*
* Since: 2.24
* Returns: a pointer to the allocated memory
*/
@ -371,6 +383,9 @@ g_malloc_n (gsize n_blocks,
* This function is similar to g_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
* but care is taken to detect possible overflow during multiplication.
*
* If the allocation fails (because the system is out of memory),
* the program is terminated.
*
* Since: 2.24
* Returns: a pointer to the allocated memory
*/
@ -396,6 +411,9 @@ g_malloc0_n (gsize n_blocks,
* This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
* but care is taken to detect possible overflow during multiplication.
*
* If the allocation fails (because the system is out of memory),
* the program is terminated.
*
* Since: 2.24
* Returns: the new address of the allocated memory
*/
@ -554,6 +572,9 @@ g_mem_profile (void)
* alignment value. Additionally, it will detect possible overflow during
* multiplication.
*
* If the allocation fails (because the system is out of memory),
* the program is terminated.
*
* Aligned memory allocations returned by this function can only be
* freed using g_aligned_free().
*

View File

@ -903,7 +903,8 @@ fork_exec (gint *exit_status,
0, TRUE, DUPLICATE_SAME_ACCESS))
{
char *emsg = g_win32_error_message (GetLastError ());
g_print("%s\n", emsg);
g_print ("%s\n", emsg);
g_free (emsg);
*child_pid = 0;
}
}

View File

@ -193,7 +193,7 @@ g_mutex_init (GMutex *mutex)
* Calling g_mutex_clear() on a locked mutex leads to undefined
* behaviour.
*
* Sine: 2.32
* Since: 2.32
*/
void
g_mutex_clear (GMutex *mutex)
@ -368,7 +368,7 @@ g_rec_mutex_init (GRecMutex *rec_mutex)
* Calling g_rec_mutex_clear() on a locked recursive mutex leads
* to undefined behaviour.
*
* Sine: 2.32
* Since: 2.32
*/
void
g_rec_mutex_clear (GRecMutex *rec_mutex)
@ -525,7 +525,7 @@ g_rw_lock_init (GRWLock *rw_lock)
* Calling g_rw_lock_clear() when any thread holds the lock
* leads to undefined behaviour.
*
* Sine: 2.32
* Since: 2.32
*/
void
g_rw_lock_clear (GRWLock *rw_lock)
@ -1599,6 +1599,13 @@ g_cond_wait_until (GCond *cond,
{
struct timespec now;
struct timespec span;
#ifdef __NR_futex_time64
long span_arg[2];
G_STATIC_ASSERT (sizeof (span_arg[0]) == 4);
#else
struct timespec span_arg;
#endif
guint sampled;
int res;
gboolean success;
@ -1618,9 +1625,33 @@ g_cond_wait_until (GCond *cond,
if (span.tv_sec < 0)
return FALSE;
/* On x32 (ILP32 ABI on x86_64) and potentially sparc64, the raw futex()
* syscall takes a 32-bit timespan argument *regardless* of whether userspace
* is using 32-bit or 64-bit `struct timespec`. This means that we cant
* unconditionally pass a `struct timespec` pointer into the syscall.
*
* Assume that any such platform is new enough to define the
* `__NR_futex_time64` workaround syscall (which accepts 64-bit timespecs,
* introduced in kernel 5.1), and use that as a proxy for whether to pass in
* `long[2]` or `struct timespec`.
*
* As per https://lwn.net/Articles/776427/, the `time64` syscalls only exist
* on 32-bit platforms, so in this case `sizeof(long)` should always be
* 32 bits.
*
* Dont bother actually calling `__NR_futex_time64` as the `span` is relative
* and hence very unlikely to overflow, even if using 32-bit longs.
*/
#ifdef __NR_futex_time64
span_arg[0] = span.tv_sec;
span_arg[1] = span.tv_nsec;
#else
span_arg = span;
#endif
sampled = cond->i[0];
g_mutex_unlock (mutex);
res = syscall (__NR_futex, &cond->i[0], (gsize) FUTEX_WAIT_PRIVATE, (gsize) sampled, &span);
res = syscall (__NR_futex, &cond->i[0], (gsize) FUTEX_WAIT_PRIVATE, (gsize) sampled, &span_arg);
success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE;
g_mutex_lock (mutex);

View File

@ -165,8 +165,6 @@ g_thread_pool_wait_for_new_pool (void)
local_max_idle_time = g_atomic_int_get (&max_idle_time);
last_wakeup_thread_serial = g_atomic_int_get (&wakeup_thread_serial);
g_atomic_int_inc (&unused_threads);
do
{
if ((guint) g_atomic_int_get (&unused_threads) >= local_max_unused_threads)
@ -235,8 +233,6 @@ g_thread_pool_wait_for_new_pool (void)
}
while (pool == wakeup_thread_marker);
g_atomic_int_add (&unused_threads, -1);
return pool;
}
@ -403,12 +399,16 @@ g_thread_pool_thread_proxy (gpointer data)
}
}
g_atomic_int_inc (&unused_threads);
g_async_queue_unlock (pool->queue);
if (free_pool)
g_thread_pool_free_internal (pool);
if ((pool = g_thread_pool_wait_for_new_pool ()) == NULL)
pool = g_thread_pool_wait_for_new_pool ();
g_atomic_int_add (&unused_threads, -1);
if (pool == NULL)
break;
g_async_queue_lock (pool->queue);

View File

@ -437,7 +437,7 @@ g_utf8_pointer_to_offset (const gchar *str,
* must be valid UTF-8 encoded text. (Use g_utf8_validate() on all
* text before trying to use UTF-8 utility functions with it.)
*
* Note you must ensure @dest is at least 4 * @n to fit the
* Note you must ensure @dest is at least 4 * @n + 1 to fit the
* largest possible UTF-8 characters
*
* Returns: (transfer none): @dest

View File

@ -15,9 +15,6 @@ glib_tests = {
'completion' : {},
'cond' : {},
'convert' : {},
'cxx' : {
'source' : ['cxx.cpp'],
},
'dataset' : {},
'date' : {
# FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392
@ -142,6 +139,14 @@ glib_tests = {
},
}
if have_cxx
glib_tests += {
'cxx' : {
'source' : ['cxx.cpp'],
}
}
endif
if cc.get_id() != 'msvc'
glib_tests += {'autoptr' : {}}
endif

View File

@ -417,7 +417,8 @@ test_search_path_heap_allocation (void)
if (skip_win32 ())
return;
memset (placeholder, '_', sizeof (placeholder));
memset (placeholder, '_', sizeof (placeholder) - 1);
placeholder[sizeof (placeholder) - 1] = '\0';
/* Force search_path_buffer to be heap-allocated */
long_dir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", placeholder, NULL);
long_path = g_strjoin (G_SEARCHPATH_SEPARATOR_S, subdir, long_dir, NULL);

View File

@ -1,8 +1,10 @@
gmodule_tests = {
'cxx' : {
'source' : ['cxx.cpp'],
},
}
if have_cxx
gmodule_tests = {
'cxx' : {
'source' : ['cxx.cpp'],
},
}
endif
test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())

View File

@ -572,22 +572,25 @@ g_object_do_class_init (GObjectClass *class)
g_type_add_interface_check (NULL, object_interface_check_properties);
}
/* Sinks @pspec if its a floating ref. */
static inline gboolean
install_property_internal (GType g_type,
guint property_id,
GParamSpec *pspec)
{
g_param_spec_ref_sink (pspec);
if (g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type, FALSE))
{
g_warning ("When installing property: type '%s' already has a property named '%s'",
g_type_name (g_type),
pspec->name);
g_param_spec_unref (pspec);
return FALSE;
}
g_param_spec_ref_sink (pspec);
PARAM_SPEC_SET_PARAM_ID (pspec, property_id);
g_param_spec_pool_insert (pspec_pool, pspec, g_type);
g_param_spec_pool_insert (pspec_pool, g_steal_pointer (&pspec), g_type);
return TRUE;
}
@ -608,6 +611,7 @@ validate_pspec_to_install (GParamSpec *pspec)
return TRUE;
}
/* Sinks @pspec if its a floating ref. */
static gboolean
validate_and_install_class_property (GObjectClass *class,
GType oclass_type,
@ -616,7 +620,11 @@ validate_and_install_class_property (GObjectClass *class,
GParamSpec *pspec)
{
if (!validate_pspec_to_install (pspec))
return FALSE;
{
g_param_spec_ref_sink (pspec);
g_param_spec_unref (pspec);
return FALSE;
}
if (pspec->flags & G_PARAM_WRITABLE)
g_return_val_if_fail (class->set_property != NULL, FALSE);
@ -824,7 +832,11 @@ g_object_interface_install_property (gpointer g_iface,
g_return_if_fail (!G_IS_PARAM_SPEC_OVERRIDE (pspec)); /* paranoid */
if (!validate_pspec_to_install (pspec))
return;
{
g_param_spec_ref_sink (pspec);
g_param_spec_unref (pspec);
return;
}
(void) install_property_internal (iface_class->g_type, 0, pspec);
}

View File

@ -423,8 +423,8 @@ g_param_spec_is_valid_name (const gchar *name)
* g_param_spec_internal: (skip)
* @param_type: the #GType for the property; must be derived from %G_TYPE_PARAM
* @name: the canonical name of the property
* @nick: the nickname of the property
* @blurb: a short description of the property
* @nick: (nullable): the nickname of the property
* @blurb: (nullable): a short description of the property
* @flags: a combination of #GParamFlags
*
* Creates a new #GParamSpec instance.
@ -433,11 +433,12 @@ g_param_spec_is_valid_name (const gchar *name)
* the rules for @name. Names which violate these rules lead to undefined
* behaviour.
*
* Beyond the name, #GParamSpecs have two more descriptive
* strings associated with them, the @nick, which should be suitable
* for use as a label for the property in a property editor, and the
* @blurb, which should be a somewhat longer description, suitable for
* e.g. a tooltip. The @nick and @blurb should ideally be localized.
* Beyond the name, #GParamSpecs have two more descriptive strings, the
* @nick and @blurb, which may be used as a localized label and description.
* For GTK and related libraries these are considered deprecated and may be
* omitted, while for other libraries such as GStreamer and its plugins they
* are essential. When in doubt, follow the conventions used in the
* surrounding code and supporting libraries.
*
* Returns: (type GObject.ParamSpec): (transfer floating): a newly allocated
* #GParamSpec instance, which is initially floating

View File

@ -1634,8 +1634,8 @@ _g_param_spec_types_init (void)
/**
* g_param_spec_char:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -1676,8 +1676,8 @@ g_param_spec_char (const gchar *name,
/**
* g_param_spec_uchar:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -1718,8 +1718,8 @@ g_param_spec_uchar (const gchar *name,
/**
* g_param_spec_boolean:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
@ -1760,8 +1760,8 @@ g_param_spec_boolean (const gchar *name,
/**
* g_param_spec_int:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -1804,8 +1804,8 @@ g_param_spec_int (const gchar *name,
/**
* g_param_spec_uint:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -1848,8 +1848,8 @@ g_param_spec_uint (const gchar *name,
/**
* g_param_spec_long:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -1892,8 +1892,8 @@ g_param_spec_long (const gchar *name,
/**
* g_param_spec_ulong:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -1937,8 +1937,8 @@ g_param_spec_ulong (const gchar *name,
/**
* g_param_spec_int64:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -1981,8 +1981,8 @@ g_param_spec_int64 (const gchar *name,
/**
* g_param_spec_uint64:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -2026,8 +2026,8 @@ g_param_spec_uint64 (const gchar *name,
/**
* g_param_spec_unichar:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
@ -2064,8 +2064,8 @@ g_param_spec_unichar (const gchar *name,
/**
* g_param_spec_enum:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @enum_type: a #GType derived from %G_TYPE_ENUM
* @default_value: default value for the property specified
* @flags: flags for the property specified
@ -2115,8 +2115,8 @@ g_param_spec_enum (const gchar *name,
/**
* g_param_spec_flags:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @flags_type: a #GType derived from %G_TYPE_FLAGS
* @default_value: default value for the property specified
* @flags: flags for the property specified
@ -2166,8 +2166,8 @@ g_param_spec_flags (const gchar *name,
/**
* g_param_spec_float:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -2210,8 +2210,8 @@ g_param_spec_float (const gchar *name,
/**
* g_param_spec_double:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
@ -2255,8 +2255,8 @@ g_param_spec_double (const gchar *name,
/**
* g_param_spec_string:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @default_value: (nullable): default value for the property specified
* @flags: flags for the property specified
*
@ -2290,8 +2290,8 @@ g_param_spec_string (const gchar *name,
/**
* g_param_spec_param:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @param_type: a #GType derived from %G_TYPE_PARAM
* @flags: flags for the property specified
*
@ -2329,8 +2329,8 @@ g_param_spec_param (const gchar *name,
/**
* g_param_spec_boxed:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @boxed_type: %G_TYPE_BOXED derived type of this property
* @flags: flags for the property specified
*
@ -2369,8 +2369,8 @@ g_param_spec_boxed (const gchar *name,
/**
* g_param_spec_pointer:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecPointer instance specifying a pointer property.
@ -2403,8 +2403,8 @@ g_param_spec_pointer (const gchar *name,
/**
* g_param_spec_gtype:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @is_a_type: a #GType whose subtypes are allowed as values
* of the property (use %G_TYPE_NONE for any type)
* @flags: flags for the property specified
@ -2443,8 +2443,8 @@ g_param_spec_gtype (const gchar *name,
/**
* g_param_spec_value_array: (skip)
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @element_spec: a #GParamSpec describing the elements contained in
* arrays of this property, may be %NULL
* @flags: flags for the property specified
@ -2490,8 +2490,8 @@ g_param_spec_value_array (const gchar *name,
/**
* g_param_spec_object:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @object_type: %G_TYPE_OBJECT derived type of this property
* @flags: flags for the property specified
*
@ -2574,8 +2574,8 @@ g_param_spec_override (const gchar *name,
/**
* g_param_spec_variant:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @type: a #GVariantType
* @default_value: (nullable) (transfer full): a #GVariant of type @type to
* use as the default value, or %NULL

View File

@ -1547,7 +1547,7 @@ g_signal_new (const gchar *signal_name,
* an object definition, instead the function pointer is passed
* directly and can be overridden by derived classes with
* g_signal_override_class_closure() or
* g_signal_override_class_handler()and chained to with
* g_signal_override_class_handler() and chained to with
* g_signal_chain_from_overridden() or
* g_signal_chain_from_overridden_handler().
*
@ -2616,6 +2616,10 @@ g_signal_connect_data (gpointer instance,
return handler_seq_no;
}
static void
signal_handler_block_unlocked (gpointer instance,
gulong handler_id);
/**
* g_signal_handler_block:
* @instance: (type GObject.Object): The instance to block the signal handler of.
@ -2634,12 +2638,20 @@ void
g_signal_handler_block (gpointer instance,
gulong handler_id)
{
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0);
SIGNAL_LOCK ();
signal_handler_block_unlocked (instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_block_unlocked (gpointer instance,
gulong handler_id)
{
Handler *handler;
handler = handler_lookup (instance, handler_id, NULL, NULL);
if (handler)
{
@ -2651,9 +2663,12 @@ g_signal_handler_block (gpointer instance,
}
else
g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_unblock_unlocked (gpointer instance,
gulong handler_id);
/**
* g_signal_handler_unblock:
* @instance: (type GObject.Object): The instance to unblock the signal handler of.
@ -2677,12 +2692,20 @@ void
g_signal_handler_unblock (gpointer instance,
gulong handler_id)
{
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0);
SIGNAL_LOCK ();
signal_handler_unblock_unlocked (instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_unblock_unlocked (gpointer instance,
gulong handler_id)
{
Handler *handler;
handler = handler_lookup (instance, handler_id, NULL, NULL);
if (handler)
{
@ -2693,9 +2716,12 @@ g_signal_handler_unblock (gpointer instance,
}
else
g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_disconnect_unlocked (gpointer instance,
gulong handler_id);
/**
* g_signal_handler_disconnect:
* @instance: (type GObject.Object): The instance to remove the signal handler from.
@ -2712,12 +2738,20 @@ void
g_signal_handler_disconnect (gpointer instance,
gulong handler_id)
{
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0);
SIGNAL_LOCK ();
signal_handler_disconnect_unlocked (instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_disconnect_unlocked (gpointer instance,
gulong handler_id)
{
Handler *handler;
handler = handler_lookup (instance, handler_id, 0, 0);
if (handler)
{
@ -2729,7 +2763,6 @@ g_signal_handler_disconnect (gpointer instance,
}
else
g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
SIGNAL_UNLOCK ();
}
/**
@ -2860,16 +2893,17 @@ g_signal_handler_find (gpointer instance,
return handler_seq_no;
}
typedef void (*CallbackHandlerFunc) (gpointer instance, gulong handler_seq_no);
static guint
signal_handlers_foreach_matched_R (gpointer instance,
GSignalMatchType mask,
guint signal_id,
GQuark detail,
GClosure *closure,
gpointer func,
gpointer data,
void (*callback) (gpointer instance,
gulong handler_seq_no))
signal_handlers_foreach_matched_unlocked_R (gpointer instance,
GSignalMatchType mask,
guint signal_id,
GQuark detail,
GClosure *closure,
gpointer func,
gpointer data,
CallbackHandlerFunc callback)
{
HandlerMatch *mlist;
guint n_handlers = 0;
@ -2879,11 +2913,8 @@ signal_handlers_foreach_matched_R (gpointer instance,
{
n_handlers++;
if (mlist->handler->sequential_number)
{
SIGNAL_UNLOCK ();
callback (instance, mlist->handler->sequential_number);
SIGNAL_LOCK ();
}
callback (instance, mlist->handler->sequential_number);
mlist = handler_match_free1_R (mlist, instance);
}
@ -2928,9 +2959,10 @@ g_signal_handlers_block_matched (gpointer instance,
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{
SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
closure, func, data,
g_signal_handler_block);
n_handlers =
signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
closure, func, data,
signal_handler_block_unlocked);
SIGNAL_UNLOCK ();
}
@ -2976,9 +3008,10 @@ g_signal_handlers_unblock_matched (gpointer instance,
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{
SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
closure, func, data,
g_signal_handler_unblock);
n_handlers =
signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
closure, func, data,
signal_handler_unblock_unlocked);
SIGNAL_UNLOCK ();
}
@ -3024,9 +3057,10 @@ g_signal_handlers_disconnect_matched (gpointer instance,
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{
SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
closure, func, data,
g_signal_handler_disconnect);
n_handlers =
signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
closure, func, data,
signal_handler_disconnect_unlocked);
SIGNAL_UNLOCK ();
}

View File

@ -29,9 +29,6 @@ marshalers_c = custom_target('marshalers_c',
gobject_tests = {
'qdata' : {},
'boxed' : {},
'cxx' : {
'source' : ['cxx.cpp'],
},
'enums' : {},
'param' : {},
'threadtests' : {},
@ -59,6 +56,14 @@ gobject_tests = {
'type-flags' : {},
}
if have_cxx
gobject_tests += {
'cxx' : {
'source' : ['cxx.cpp'],
},
}
endif
if cc.get_id() != 'msvc'
gobject_tests += {'autoptr' : {}}
endif

View File

@ -104,8 +104,7 @@ test_object_set_property (GObject *gobject,
TestObject *tobj = (TestObject *) gobject;
g_assert_cmpint (prop_id, !=, 0);
g_assert_cmpint (prop_id, !=, N_PROPERTIES);
g_assert (pspec == properties[prop_id]);
g_assert_true (prop_id < N_PROPERTIES && pspec == properties[prop_id]);
switch (prop_id)
{
@ -139,8 +138,7 @@ test_object_get_property (GObject *gobject,
TestObject *tobj = (TestObject *) gobject;
g_assert_cmpint (prop_id, !=, 0);
g_assert_cmpint (prop_id, !=, N_PROPERTIES);
g_assert (pspec == properties[prop_id]);
g_assert_true (prop_id < N_PROPERTIES && pspec == properties[prop_id]);
switch (prop_id)
{

View File

@ -1,4 +1,4 @@
project('glib', 'c', 'cpp',
project('glib', 'c',
version : '2.72.3',
# NOTE: We keep this pinned at 0.52 because that's what Debian Stable ships
meson_version : '>= 0.52.0',
@ -10,7 +10,14 @@ project('glib', 'c', 'cpp',
)
cc = meson.get_compiler('c')
cxx = meson.get_compiler('cpp')
if meson.version().version_compare('>= 0.54.0')
have_cxx = add_languages('cpp', native: false, required: get_option('oss_fuzz').enabled())
else
have_cxx = add_languages('cpp', required: get_option('oss_fuzz').enabled())
endif
if have_cxx
cxx = meson.get_compiler('cpp')
endif
cc_can_run = not meson.is_cross_build() or meson.has_exe_wrapper()
@ -495,7 +502,9 @@ else
endif
add_project_arguments(cc.get_supported_arguments(warning_c_args), language: 'c')
add_project_arguments(cxx.get_supported_arguments(warning_cxx_args), language: 'cpp')
if have_cxx
add_project_arguments(cxx.get_supported_arguments(warning_cxx_args), language: 'cpp')
endif
# FIXME: We cannot build some of the GResource tests with -z nodelete, which
# means we cannot use that flag in add_project_link_arguments(), and must add
@ -1734,18 +1743,20 @@ if g_have_iso_c_varargs
#endif''')
endif
g_have_iso_cxx_varargs = cxx.compiles('''
void some_func (void) {
int a(int p1, int p2, int p3);
#define call_a(...) a(1,__VA_ARGS__)
call_a(2,3);
}''', name : 'ISO C99 varargs macros in C++')
if have_cxx
g_have_iso_cxx_varargs = cxx.compiles('''
void some_func (void) {
int a(int p1, int p2, int p3);
#define call_a(...) a(1,__VA_ARGS__)
call_a(2,3);
}''', name : 'ISO C99 varargs macros in C++')
if g_have_iso_cxx_varargs
glibconfig_conf.set('g_have_iso_cxx_varargs', '''
#ifdef __cplusplus
# define G_HAVE_ISO_VARARGS 1
#endif''')
if g_have_iso_cxx_varargs
glibconfig_conf.set('g_have_iso_cxx_varargs', '''
#ifdef __cplusplus
# define G_HAVE_ISO_VARARGS 1
#endif''')
endif
endif
g_have_gnuc_varargs = cc.compiles('''