mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-28 00:16:15 +01:00
Merge branch 'scan-build2-the-false-positives' into 'main'
Squash various false positives from scan-build Closes #1767 See merge request GNOME/glib!4007
This commit is contained in:
commit
640ff0c4da
@ -741,6 +741,7 @@ scan-build:
|
|||||||
--exclude glib/libcharset/
|
--exclude glib/libcharset/
|
||||||
--exclude gio/xdgmime/
|
--exclude gio/xdgmime/
|
||||||
-disable-checker deadcode.DeadStores
|
-disable-checker deadcode.DeadStores
|
||||||
|
--status-bugs
|
||||||
script:
|
script:
|
||||||
- meson setup ${MESON_COMMON_OPTIONS}
|
- meson setup ${MESON_COMMON_OPTIONS}
|
||||||
--werror
|
--werror
|
||||||
|
@ -5668,7 +5668,7 @@ g_dbus_connection_register_object_with_closures (GDBusConnection *connection
|
|||||||
object_path,
|
object_path,
|
||||||
interface_info,
|
interface_info,
|
||||||
&vtable,
|
&vtable,
|
||||||
data,
|
g_steal_pointer (&data),
|
||||||
register_object_free_func,
|
register_object_free_func,
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
@ -199,6 +199,16 @@ name_ref (Name *name)
|
|||||||
static void
|
static void
|
||||||
name_unref (Name *name)
|
name_unref (Name *name)
|
||||||
{
|
{
|
||||||
|
/* scan-build with clang-17 can’t follow the refcounting of `Name` structs
|
||||||
|
* throughout this file. Probably because there are structures like `NameOwner`
|
||||||
|
* which cause a ref to be added to a `Name` while they exist, but which don’t
|
||||||
|
* actually have a pointer to the `Name`, so the unref of the `Name` when they
|
||||||
|
* are freed looks like a double-unref.
|
||||||
|
*
|
||||||
|
* So, until the static analysis improves, or we find some way to restructure
|
||||||
|
* the code, squash the false positive use-after-free or double-unref warnings
|
||||||
|
* by making this function a no-op to the static analyser. */
|
||||||
|
#ifndef G_ANALYZER_ANALYZING
|
||||||
g_assert (name->refcount > 0);
|
g_assert (name->refcount > 0);
|
||||||
if (--name->refcount == 0)
|
if (--name->refcount == 0)
|
||||||
{
|
{
|
||||||
@ -206,6 +216,7 @@ name_unref (Name *name)
|
|||||||
g_free (name->name);
|
g_free (name->name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static Name *
|
static Name *
|
||||||
|
@ -2687,7 +2687,7 @@ prepend_terminal_to_vector (int *argc,
|
|||||||
size_t term_argc;
|
size_t term_argc;
|
||||||
char *found_terminal;
|
char *found_terminal;
|
||||||
char **the_argv;
|
char **the_argv;
|
||||||
const char *term_arg;
|
const char *term_arg = NULL;
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *exec;
|
const char *exec;
|
||||||
const char *exec_arg;
|
const char *exec_arg;
|
||||||
|
@ -310,7 +310,6 @@ read_netlink_messages (GNetworkMonitorNetlink *nl,
|
|||||||
struct sockaddr_nl source_sockaddr;
|
struct sockaddr_nl source_sockaddr;
|
||||||
gsize attrlen;
|
gsize attrlen;
|
||||||
guint8 *dest, *gateway, *oif;
|
guint8 *dest, *gateway, *oif;
|
||||||
gboolean retval = TRUE;
|
|
||||||
|
|
||||||
iv.buffer = NULL;
|
iv.buffer = NULL;
|
||||||
iv.size = 0;
|
iv.size = 0;
|
||||||
@ -319,26 +318,17 @@ read_netlink_messages (GNetworkMonitorNetlink *nl,
|
|||||||
len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1,
|
len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1,
|
||||||
NULL, NULL, &flags, NULL, &local_error);
|
NULL, NULL, &flags, NULL, &local_error);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
|
||||||
retval = FALSE;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
iv.buffer = g_malloc (len);
|
iv.buffer = g_malloc (len);
|
||||||
iv.size = len;
|
iv.size = len;
|
||||||
len = g_socket_receive_message (nl->priv->sock, &addr, &iv, 1,
|
len = g_socket_receive_message (nl->priv->sock, &addr, &iv, 1,
|
||||||
NULL, NULL, NULL, NULL, &local_error);
|
NULL, NULL, NULL, NULL, &local_error);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
|
||||||
retval = FALSE;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_socket_address_to_native (addr, &source_sockaddr, sizeof (source_sockaddr), &local_error))
|
if (!g_socket_address_to_native (addr, &source_sockaddr, sizeof (source_sockaddr), &local_error))
|
||||||
{
|
|
||||||
retval = FALSE;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
/* If the sender port id is 0 (not fakeable) then the message is from the kernel */
|
/* If the sender port id is 0 (not fakeable) then the message is from the kernel */
|
||||||
if (source_sockaddr.nl_pid != 0)
|
if (source_sockaddr.nl_pid != 0)
|
||||||
@ -353,7 +343,6 @@ read_netlink_messages (GNetworkMonitorNetlink *nl,
|
|||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_PARTIAL_INPUT,
|
G_IO_ERROR_PARTIAL_INPUT,
|
||||||
"netlink message was truncated; shouldn't happen...");
|
"netlink message was truncated; shouldn't happen...");
|
||||||
retval = FALSE;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +408,6 @@ read_netlink_messages (GNetworkMonitorNetlink *nl,
|
|||||||
"netlink error: %s",
|
"netlink error: %s",
|
||||||
g_strerror (-e->error));
|
g_strerror (-e->error));
|
||||||
}
|
}
|
||||||
retval = FALSE;
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -428,7 +416,6 @@ read_netlink_messages (GNetworkMonitorNetlink *nl,
|
|||||||
G_IO_ERROR_INVALID_DATA,
|
G_IO_ERROR_INVALID_DATA,
|
||||||
"unexpected netlink message %d",
|
"unexpected netlink message %d",
|
||||||
msg->nlmsg_type);
|
msg->nlmsg_type);
|
||||||
retval = FALSE;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,13 +424,18 @@ read_netlink_messages (GNetworkMonitorNetlink *nl,
|
|||||||
g_free (iv.buffer);
|
g_free (iv.buffer);
|
||||||
g_clear_object (&addr);
|
g_clear_object (&addr);
|
||||||
|
|
||||||
if (!retval && nl->priv->dump_networks)
|
if (local_error != NULL && nl->priv->dump_networks)
|
||||||
finish_dump (nl);
|
finish_dump (nl);
|
||||||
|
|
||||||
if (local_error)
|
if (local_error != NULL)
|
||||||
|
{
|
||||||
g_propagate_prefixed_error (error, local_error, "Error on netlink socket: ");
|
g_propagate_prefixed_error (error, local_error, "Error on netlink socket: ");
|
||||||
|
return FALSE;
|
||||||
return retval;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -285,14 +285,10 @@ g_proxy_address_enumerator_next (GSocketAddressEnumerator *enumerator,
|
|||||||
{
|
{
|
||||||
dest_hostname = g_strdup (priv->dest_hostname);
|
dest_hostname = g_strdup (priv->dest_hostname);
|
||||||
}
|
}
|
||||||
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
|
|
||||||
|
|
||||||
if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address))
|
g_assert (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address));
|
||||||
{
|
|
||||||
g_free (dest_hostname);
|
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
|
||||||
g_free (dest_protocol);
|
|
||||||
}
|
|
||||||
g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address), NULL);
|
|
||||||
|
|
||||||
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
|
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
|
||||||
inetaddr = g_inet_socket_address_get_address (inetsaddr);
|
inetaddr = g_inet_socket_address_get_address (inetsaddr);
|
||||||
@ -363,7 +359,6 @@ return_result (GTask *task)
|
|||||||
{
|
{
|
||||||
GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
|
GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task);
|
||||||
GSocketAddress *result;
|
GSocketAddress *result;
|
||||||
gboolean is_inet_socket_address;
|
|
||||||
|
|
||||||
if (strcmp ("direct", priv->proxy_type) == 0)
|
if (strcmp ("direct", priv->proxy_type) == 0)
|
||||||
{
|
{
|
||||||
@ -395,13 +390,7 @@ return_result (GTask *task)
|
|||||||
}
|
}
|
||||||
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
|
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
|
||||||
|
|
||||||
is_inet_socket_address = G_IS_INET_SOCKET_ADDRESS (priv->proxy_address);
|
g_assert (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address));
|
||||||
if (!is_inet_socket_address)
|
|
||||||
{
|
|
||||||
g_free (dest_hostname);
|
|
||||||
g_free (dest_protocol);
|
|
||||||
}
|
|
||||||
g_return_if_fail (is_inet_socket_address);
|
|
||||||
|
|
||||||
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
|
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
|
||||||
inetaddr = g_inet_socket_address_get_address (inetsaddr);
|
inetaddr = g_inet_socket_address_get_address (inetsaddr);
|
||||||
|
@ -285,6 +285,7 @@ g_srv_target_list_sort (GList *targets)
|
|||||||
val = g_random_int_range (0, sum + 1);
|
val = g_random_int_range (0, sum + 1);
|
||||||
for (t = targets; ; t = t->next)
|
for (t = targets; ; t = t->next)
|
||||||
{
|
{
|
||||||
|
g_assert (t != NULL && t->data != NULL);
|
||||||
weight = ((GSrvTarget *)t->data)->weight;
|
weight = ((GSrvTarget *)t->data)->weight;
|
||||||
if (weight >= val)
|
if (weight >= val)
|
||||||
break;
|
break;
|
||||||
|
@ -2079,7 +2079,7 @@ mount_monitor_start (void)
|
|||||||
if (proc_mounts_channel == NULL)
|
if (proc_mounts_channel == NULL)
|
||||||
proc_mounts_channel = g_io_channel_new_file (mtab_path, "r", &error);
|
proc_mounts_channel = g_io_channel_new_file (mtab_path, "r", &error);
|
||||||
|
|
||||||
if (proc_mounts_channel == NULL)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
g_warning ("Error creating IO channel for %s: %s (%s, %d)", mtab_path,
|
g_warning ("Error creating IO channel for %s: %s (%s, %d)", mtab_path,
|
||||||
error->message, g_quark_to_string (error->domain), error->code);
|
error->message, g_quark_to_string (error->domain), error->code);
|
||||||
|
@ -543,7 +543,7 @@ get_and_check_serialization (GVariant *value)
|
|||||||
/* First check that the serialization to the D-Bus wire format is correct - do this for both byte orders */
|
/* First check that the serialization to the D-Bus wire format is correct - do this for both byte orders */
|
||||||
for (n = 0; n < 2; n++)
|
for (n = 0; n < 2; n++)
|
||||||
{
|
{
|
||||||
GDBusMessageByteOrder byte_order;
|
GDBusMessageByteOrder byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
|
||||||
switch (n)
|
switch (n)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -245,10 +245,15 @@ cache_magic_compare_to_data (XdgMimeCache *cache,
|
|||||||
size_t len,
|
size_t len,
|
||||||
int *prio)
|
int *prio)
|
||||||
{
|
{
|
||||||
xdg_uint32_t priority = GET_UINT32 (cache->buffer, offset);
|
xdg_uint32_t priority, mimetype_offset, n_matchlets, matchlet_offset;
|
||||||
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, offset + 4);
|
|
||||||
xdg_uint32_t n_matchlets = GET_UINT32 (cache->buffer, offset + 8);
|
assert (cache->buffer != NULL);
|
||||||
xdg_uint32_t matchlet_offset = GET_UINT32 (cache->buffer, offset + 12);
|
|
||||||
|
priority = GET_UINT32 (cache->buffer, offset);
|
||||||
|
mimetype_offset = GET_UINT32 (cache->buffer, offset + 4);
|
||||||
|
n_matchlets = GET_UINT32 (cache->buffer, offset + 8);
|
||||||
|
matchlet_offset = GET_UINT32 (cache->buffer, offset + 12);
|
||||||
|
|
||||||
if (OUT_OF_BOUNDS (matchlet_offset, n_matchlets, 32, cache->size))
|
if (OUT_OF_BOUNDS (matchlet_offset, n_matchlets, 32, cache->size))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -280,6 +285,8 @@ cache_magic_lookup_data (XdgMimeCache *cache,
|
|||||||
|
|
||||||
xdg_uint32_t j;
|
xdg_uint32_t j;
|
||||||
|
|
||||||
|
assert (cache->buffer != NULL);
|
||||||
|
|
||||||
*prio = 0;
|
*prio = 0;
|
||||||
|
|
||||||
list_offset = GET_UINT32 (cache->buffer, 24);
|
list_offset = GET_UINT32 (cache->buffer, 24);
|
||||||
|
@ -670,6 +670,9 @@ parse_type_internal (GIIrModule *module,
|
|||||||
type->is_pointer = TRUE;
|
type->is_pointer = TRUE;
|
||||||
str += strlen ("Error");
|
str += strlen ("Error");
|
||||||
|
|
||||||
|
/* Silence a scan-build false positive */
|
||||||
|
g_assert (str != NULL);
|
||||||
|
|
||||||
if (*str == '<')
|
if (*str == '<')
|
||||||
{
|
{
|
||||||
char *tmp, *end;
|
char *tmp, *end;
|
||||||
|
@ -3104,7 +3104,7 @@ format_number (GString *str,
|
|||||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
|
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
|
||||||
};
|
};
|
||||||
const gchar * const *digits = ascii_digits;
|
const gchar * const *digits = ascii_digits;
|
||||||
const gchar *tmp[10];
|
const gchar *tmp[10] = { '\0', };
|
||||||
gint i = 0;
|
gint i = 0;
|
||||||
#ifdef HAVE_LANGINFO_OUTDIGIT
|
#ifdef HAVE_LANGINFO_OUTDIGIT
|
||||||
static GMutex alt_digits_mutex;
|
static GMutex alt_digits_mutex;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "garray.h"
|
#include "garray.h"
|
||||||
#include "gmem.h"
|
#include "gmem.h"
|
||||||
|
#include "gmessages.h"
|
||||||
#include "gstring.h"
|
#include "gstring.h"
|
||||||
#include "gstrfuncs.h"
|
#include "gstrfuncs.h"
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
@ -667,6 +668,8 @@ g_hostname_to_unicode (const gchar *hostname)
|
|||||||
gssize llen;
|
gssize llen;
|
||||||
gsize hostname_max_length_bytes = get_hostname_max_length_bytes ();
|
gsize hostname_max_length_bytes = get_hostname_max_length_bytes ();
|
||||||
|
|
||||||
|
g_return_val_if_fail (hostname != NULL, NULL);
|
||||||
|
|
||||||
/* See the comment at the top of g_hostname_to_ascii(). */
|
/* See the comment at the top of g_hostname_to_ascii(). */
|
||||||
if (hostname_max_length_bytes <= G_MAXSIZE / 4 &&
|
if (hostname_max_length_bytes <= G_MAXSIZE / 4 &&
|
||||||
strlen_greater_than (hostname, 4 * MAX (255, hostname_max_length_bytes)))
|
strlen_greater_than (hostname, 4 * MAX (255, hostname_max_length_bytes)))
|
||||||
|
@ -1732,6 +1732,7 @@ node_get_by_pos (GSequenceNode *node,
|
|||||||
{
|
{
|
||||||
node = node->left;
|
node = node->left;
|
||||||
}
|
}
|
||||||
|
g_assert (node != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
@ -4308,7 +4308,9 @@ g_test_log_dump (GTestLogMsg *msg,
|
|||||||
gstring_append_int (gstring, 0); /* reserved */
|
gstring_append_int (gstring, 0); /* reserved */
|
||||||
for (ui = 0; ui < msg->n_strings; ui++)
|
for (ui = 0; ui < msg->n_strings; ui++)
|
||||||
{
|
{
|
||||||
guint l = strlen (msg->strings[ui]);
|
guint l;
|
||||||
|
g_assert (msg->strings[ui] != NULL);
|
||||||
|
l = strlen (msg->strings[ui]);
|
||||||
gstring_append_int (gstring, l);
|
gstring_append_int (gstring, l);
|
||||||
g_string_append_len (gstring, msg->strings[ui], l);
|
g_string_append_len (gstring, msg->strings[ui], l);
|
||||||
}
|
}
|
||||||
|
@ -280,6 +280,7 @@ again:
|
|||||||
GTimeZone *
|
GTimeZone *
|
||||||
g_time_zone_ref (GTimeZone *tz)
|
g_time_zone_ref (GTimeZone *tz)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (tz != NULL, NULL);
|
||||||
g_assert (tz->ref_count > 0);
|
g_assert (tz->ref_count > 0);
|
||||||
|
|
||||||
g_atomic_int_inc (&tz->ref_count);
|
g_atomic_int_inc (&tz->ref_count);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "gunicode.h"
|
#include "gunicode.h"
|
||||||
#include "gunidecomp.h"
|
#include "gunidecomp.h"
|
||||||
#include "gmem.h"
|
#include "gmem.h"
|
||||||
|
#include "gtestutils.h"
|
||||||
#include "gunicomp.h"
|
#include "gunicomp.h"
|
||||||
#include "gunicodeprivate.h"
|
#include "gunicodeprivate.h"
|
||||||
|
|
||||||
@ -428,8 +429,9 @@ _g_utf8_normalize_wc (const gchar *str,
|
|||||||
wc_buffer[n_wc++] = wc;
|
wc_buffer[n_wc++] = wc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n_wc > 0)
|
/* Each code path above *must* have appended at least gunichar to wc_buffer. */
|
||||||
{
|
g_assert (n_wc > old_n_wc);
|
||||||
|
|
||||||
cc = COMBINING_CLASS (wc_buffer[old_n_wc]);
|
cc = COMBINING_CLASS (wc_buffer[old_n_wc]);
|
||||||
|
|
||||||
if (cc == 0)
|
if (cc == 0)
|
||||||
@ -437,7 +439,6 @@ _g_utf8_normalize_wc (const gchar *str,
|
|||||||
g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start);
|
g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start);
|
||||||
last_start = old_n_wc;
|
last_start = old_n_wc;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
p = g_utf8_next_char (p);
|
p = g_utf8_next_char (p);
|
||||||
}
|
}
|
||||||
|
@ -904,6 +904,8 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
|
|||||||
if (value.size != 0 && offsets.length == 0)
|
if (value.size != 0 && offsets.length == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
g_assert (value.size != 0 || offsets.length == 0);
|
||||||
|
|
||||||
child.type_info = g_variant_type_info_element (value.type_info);
|
child.type_info = g_variant_type_info_element (value.type_info);
|
||||||
g_variant_type_info_query (child.type_info, &alignment, NULL);
|
g_variant_type_info_query (child.type_info, &alignment, NULL);
|
||||||
child.depth = value.depth + 1;
|
child.depth = value.depth + 1;
|
||||||
|
@ -4620,7 +4620,7 @@ g_variant_format_string_scan_type (const gchar *string,
|
|||||||
const gchar **endptr)
|
const gchar **endptr)
|
||||||
{
|
{
|
||||||
const gchar *my_end;
|
const gchar *my_end;
|
||||||
gchar *dest;
|
gsize i;
|
||||||
gchar *new;
|
gchar *new;
|
||||||
|
|
||||||
if (endptr == NULL)
|
if (endptr == NULL)
|
||||||
@ -4629,16 +4629,19 @@ g_variant_format_string_scan_type (const gchar *string,
|
|||||||
if (!g_variant_format_string_scan (string, limit, endptr))
|
if (!g_variant_format_string_scan (string, limit, endptr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dest = new = g_malloc (*endptr - string + 1);
|
new = g_malloc (*endptr - string + 1);
|
||||||
|
i = 0;
|
||||||
while (string != *endptr)
|
while (string != *endptr)
|
||||||
{
|
{
|
||||||
if (*string != '@' && *string != '&' && *string != '^')
|
if (*string != '@' && *string != '&' && *string != '^')
|
||||||
*dest++ = *string;
|
new[i++] = *string;
|
||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
*dest = '\0';
|
new[i++] = '\0';
|
||||||
|
|
||||||
return (GVariantType *) G_VARIANT_TYPE (new);
|
g_assert (g_variant_type_string_is_valid (new));
|
||||||
|
|
||||||
|
return (GVariantType *) new;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -106,7 +106,7 @@ typedef union {
|
|||||||
gint vint;
|
gint vint;
|
||||||
} ClosureInt;
|
} ClosureInt;
|
||||||
|
|
||||||
#define CHANGE_FIELD(_closure, _field, _OP, _value, _must_set, _SET_OLD, _SET_NEW) \
|
#define ATOMIC_CHANGE_FIELD(_closure, _field, _OP, _value, _must_set, _SET_OLD, _SET_NEW) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
ClosureInt *cunion = (ClosureInt*) _closure; \
|
ClosureInt *cunion = (ClosureInt*) _closure; \
|
||||||
gint new_int, old_int, success; \
|
gint new_int, old_int, success; \
|
||||||
@ -123,21 +123,12 @@ G_STMT_START {
|
|||||||
while (!success && _must_set); \
|
while (!success && _must_set); \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
#define SWAP(_closure, _field, _value, _oldv) CHANGE_FIELD (_closure, _field, =, _value, TRUE, *(_oldv) =, (void) )
|
#define ATOMIC_SWAP(_closure, _field, _value, _oldv) ATOMIC_CHANGE_FIELD (_closure, _field, =, _value, TRUE, *(_oldv) =, (void) )
|
||||||
#define SET(_closure, _field, _value) CHANGE_FIELD (_closure, _field, =, _value, TRUE, (void), (void) )
|
#define ATOMIC_SET(_closure, _field, _value) ATOMIC_CHANGE_FIELD (_closure, _field, =, _value, TRUE, (void), (void) )
|
||||||
#define INC(_closure, _field) CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), (void) )
|
#define ATOMIC_INC(_closure, _field) ATOMIC_CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), (void) )
|
||||||
#define INC_ASSIGN(_closure, _field, _newv) CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), *(_newv) = )
|
#define ATOMIC_INC_ASSIGN(_closure, _field, _newv) ATOMIC_CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), *(_newv) = )
|
||||||
#define DEC(_closure, _field) CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), (void) )
|
#define ATOMIC_DEC(_closure, _field) ATOMIC_CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), (void) )
|
||||||
#define DEC_ASSIGN(_closure, _field, _newv) CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), *(_newv) = )
|
#define ATOMIC_DEC_ASSIGN(_closure, _field, _newv) ATOMIC_CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), *(_newv) = )
|
||||||
|
|
||||||
#if 0 /* for non-thread-safe closures */
|
|
||||||
#define SWAP(cl,f,v,o) (void) (*(o) = cl->f, cl->f = v)
|
|
||||||
#define SET(cl,f,v) (void) (cl->f = v)
|
|
||||||
#define INC(cl,f) (void) (cl->f += 1)
|
|
||||||
#define INC_ASSIGN(cl,f,n) (void) (cl->f += 1, *(n) = cl->f)
|
|
||||||
#define DEC(cl,f) (void) (cl->f -= 1)
|
|
||||||
#define DEC_ASSIGN(cl,f,n) (void) (cl->f -= 1, *(n) = cl->f)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FNOTIFY,
|
FNOTIFY,
|
||||||
@ -225,8 +216,8 @@ g_closure_new_simple (guint sizeof_closure,
|
|||||||
|
|
||||||
closure = (GClosure *) (allocated + private_size);
|
closure = (GClosure *) (allocated + private_size);
|
||||||
|
|
||||||
SET (closure, ref_count, 1);
|
ATOMIC_SET (closure, ref_count, 1);
|
||||||
SET (closure, floating, TRUE);
|
ATOMIC_SET (closure, floating, TRUE);
|
||||||
closure->data = data;
|
closure->data = data;
|
||||||
|
|
||||||
return closure;
|
return closure;
|
||||||
@ -261,7 +252,7 @@ closure_invoke_notifiers (GClosure *closure,
|
|||||||
while (closure->n_fnotifiers)
|
while (closure->n_fnotifiers)
|
||||||
{
|
{
|
||||||
guint n;
|
guint n;
|
||||||
DEC_ASSIGN (closure, n_fnotifiers, &n);
|
ATOMIC_DEC_ASSIGN (closure, n_fnotifiers, &n);
|
||||||
|
|
||||||
ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + n;
|
ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + n;
|
||||||
closure->marshal = (GClosureMarshal) ndata->notify;
|
closure->marshal = (GClosureMarshal) ndata->notify;
|
||||||
@ -272,11 +263,11 @@ closure_invoke_notifiers (GClosure *closure,
|
|||||||
closure->data = NULL;
|
closure->data = NULL;
|
||||||
break;
|
break;
|
||||||
case INOTIFY:
|
case INOTIFY:
|
||||||
SET (closure, in_inotify, TRUE);
|
ATOMIC_SET (closure, in_inotify, TRUE);
|
||||||
while (closure->n_inotifiers)
|
while (closure->n_inotifiers)
|
||||||
{
|
{
|
||||||
guint n;
|
guint n;
|
||||||
DEC_ASSIGN (closure, n_inotifiers, &n);
|
ATOMIC_DEC_ASSIGN (closure, n_inotifiers, &n);
|
||||||
|
|
||||||
ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + n;
|
ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + n;
|
||||||
closure->marshal = (GClosureMarshal) ndata->notify;
|
closure->marshal = (GClosureMarshal) ndata->notify;
|
||||||
@ -285,7 +276,7 @@ closure_invoke_notifiers (GClosure *closure,
|
|||||||
}
|
}
|
||||||
closure->marshal = NULL;
|
closure->marshal = NULL;
|
||||||
closure->data = NULL;
|
closure->data = NULL;
|
||||||
SET (closure, in_inotify, FALSE);
|
ATOMIC_SET (closure, in_inotify, FALSE);
|
||||||
break;
|
break;
|
||||||
case PRE_NOTIFY:
|
case PRE_NOTIFY:
|
||||||
i = closure->n_guards;
|
i = closure->n_guards;
|
||||||
@ -429,7 +420,7 @@ g_closure_add_marshal_guards (GClosure *closure,
|
|||||||
closure->notifiers[i].notify = pre_marshal_notify;
|
closure->notifiers[i].notify = pre_marshal_notify;
|
||||||
closure->notifiers[i + 1].data = post_marshal_data;
|
closure->notifiers[i + 1].data = post_marshal_data;
|
||||||
closure->notifiers[i + 1].notify = post_marshal_notify;
|
closure->notifiers[i + 1].notify = post_marshal_notify;
|
||||||
INC (closure, n_guards);
|
ATOMIC_INC (closure, n_guards);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -466,7 +457,7 @@ g_closure_add_finalize_notifier (GClosure *closure,
|
|||||||
i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers;
|
i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers;
|
||||||
closure->notifiers[i].data = notify_data;
|
closure->notifiers[i].data = notify_data;
|
||||||
closure->notifiers[i].notify = notify_func;
|
closure->notifiers[i].notify = notify_func;
|
||||||
INC (closure, n_fnotifiers);
|
ATOMIC_INC (closure, n_fnotifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -497,7 +488,7 @@ g_closure_add_invalidate_notifier (GClosure *closure,
|
|||||||
i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers;
|
i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers;
|
||||||
closure->notifiers[i].data = notify_data;
|
closure->notifiers[i].data = notify_data;
|
||||||
closure->notifiers[i].notify = notify_func;
|
closure->notifiers[i].notify = notify_func;
|
||||||
INC (closure, n_inotifiers);
|
ATOMIC_INC (closure, n_inotifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
@ -511,7 +502,7 @@ closure_try_remove_inotify (GClosure *closure,
|
|||||||
for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++)
|
for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++)
|
||||||
if (ndata->notify == notify_func && ndata->data == notify_data)
|
if (ndata->notify == notify_func && ndata->data == notify_data)
|
||||||
{
|
{
|
||||||
DEC (closure, n_inotifiers);
|
ATOMIC_DEC (closure, n_inotifiers);
|
||||||
if (ndata < nlast)
|
if (ndata < nlast)
|
||||||
*ndata = *nlast;
|
*ndata = *nlast;
|
||||||
|
|
||||||
@ -531,7 +522,7 @@ closure_try_remove_fnotify (GClosure *closure,
|
|||||||
for (ndata = nlast + 1 - closure->n_fnotifiers; ndata <= nlast; ndata++)
|
for (ndata = nlast + 1 - closure->n_fnotifiers; ndata <= nlast; ndata++)
|
||||||
if (ndata->notify == notify_func && ndata->data == notify_data)
|
if (ndata->notify == notify_func && ndata->data == notify_data)
|
||||||
{
|
{
|
||||||
DEC (closure, n_fnotifiers);
|
ATOMIC_DEC (closure, n_fnotifiers);
|
||||||
if (ndata < nlast)
|
if (ndata < nlast)
|
||||||
*ndata = *nlast;
|
*ndata = *nlast;
|
||||||
if (closure->n_inotifiers)
|
if (closure->n_inotifiers)
|
||||||
@ -561,12 +552,23 @@ g_closure_ref (GClosure *closure)
|
|||||||
g_return_val_if_fail (closure->ref_count > 0, NULL);
|
g_return_val_if_fail (closure->ref_count > 0, NULL);
|
||||||
g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL);
|
g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL);
|
||||||
|
|
||||||
INC_ASSIGN (closure, ref_count, &new_ref_count);
|
ATOMIC_INC_ASSIGN (closure, ref_count, &new_ref_count);
|
||||||
g_return_val_if_fail (new_ref_count > 1, NULL);
|
g_return_val_if_fail (new_ref_count > 1, NULL);
|
||||||
|
|
||||||
return closure;
|
return closure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
closure_invalidate_internal (GClosure *closure)
|
||||||
|
{
|
||||||
|
gboolean was_invalid;
|
||||||
|
|
||||||
|
ATOMIC_SWAP (closure, is_invalid, TRUE, &was_invalid);
|
||||||
|
/* invalidate only once */
|
||||||
|
if (!was_invalid)
|
||||||
|
closure_invoke_notifiers (closure, INOTIFY);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_closure_invalidate:
|
* g_closure_invalidate:
|
||||||
* @closure: #GClosure to invalidate
|
* @closure: #GClosure to invalidate
|
||||||
@ -594,12 +596,8 @@ g_closure_invalidate (GClosure *closure)
|
|||||||
|
|
||||||
if (!closure->is_invalid)
|
if (!closure->is_invalid)
|
||||||
{
|
{
|
||||||
gboolean was_invalid;
|
|
||||||
g_closure_ref (closure); /* preserve floating flag */
|
g_closure_ref (closure); /* preserve floating flag */
|
||||||
SWAP (closure, is_invalid, TRUE, &was_invalid);
|
closure_invalidate_internal (closure);
|
||||||
/* invalidate only once */
|
|
||||||
if (!was_invalid)
|
|
||||||
closure_invoke_notifiers (closure, INOTIFY);
|
|
||||||
g_closure_unref (closure);
|
g_closure_unref (closure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,10 +620,11 @@ g_closure_unref (GClosure *closure)
|
|||||||
g_return_if_fail (closure != NULL);
|
g_return_if_fail (closure != NULL);
|
||||||
g_return_if_fail (closure->ref_count > 0);
|
g_return_if_fail (closure->ref_count > 0);
|
||||||
|
|
||||||
if (closure->ref_count == 1) /* last unref, invalidate first */
|
/* last unref, invalidate first */
|
||||||
g_closure_invalidate (closure);
|
if (closure->ref_count == 1 && !closure->is_invalid)
|
||||||
|
closure_invalidate_internal (closure);
|
||||||
|
|
||||||
DEC_ASSIGN (closure, ref_count, &new_ref_count);
|
ATOMIC_DEC_ASSIGN (closure, ref_count, &new_ref_count);
|
||||||
|
|
||||||
if (new_ref_count == 0)
|
if (new_ref_count == 0)
|
||||||
{
|
{
|
||||||
@ -719,7 +718,7 @@ g_closure_sink (GClosure *closure)
|
|||||||
if (closure->floating)
|
if (closure->floating)
|
||||||
{
|
{
|
||||||
gboolean was_floating;
|
gboolean was_floating;
|
||||||
SWAP (closure, floating, FALSE, &was_floating);
|
ATOMIC_SWAP (closure, floating, FALSE, &was_floating);
|
||||||
/* unref floating flag only once */
|
/* unref floating flag only once */
|
||||||
if (was_floating)
|
if (was_floating)
|
||||||
g_closure_unref (closure);
|
g_closure_unref (closure);
|
||||||
@ -818,7 +817,7 @@ g_closure_invoke (GClosure *closure,
|
|||||||
|
|
||||||
g_return_if_fail (closure->marshal || real_closure->meta_marshal);
|
g_return_if_fail (closure->marshal || real_closure->meta_marshal);
|
||||||
|
|
||||||
SET (closure, in_marshal, TRUE);
|
ATOMIC_SET (closure, in_marshal, TRUE);
|
||||||
if (real_closure->meta_marshal)
|
if (real_closure->meta_marshal)
|
||||||
{
|
{
|
||||||
marshal_data = real_closure->meta_marshal_data;
|
marshal_data = real_closure->meta_marshal_data;
|
||||||
@ -838,7 +837,7 @@ g_closure_invoke (GClosure *closure,
|
|||||||
marshal_data);
|
marshal_data);
|
||||||
if (!in_marshal)
|
if (!in_marshal)
|
||||||
closure_invoke_notifiers (closure, POST_NOTIFY);
|
closure_invoke_notifiers (closure, POST_NOTIFY);
|
||||||
SET (closure, in_marshal, in_marshal);
|
ATOMIC_SET (closure, in_marshal, in_marshal);
|
||||||
}
|
}
|
||||||
g_closure_unref (closure);
|
g_closure_unref (closure);
|
||||||
}
|
}
|
||||||
@ -881,7 +880,7 @@ _g_closure_invoke_va (GClosure *closure,
|
|||||||
|
|
||||||
g_return_if_fail (closure->marshal || real_closure->meta_marshal);
|
g_return_if_fail (closure->marshal || real_closure->meta_marshal);
|
||||||
|
|
||||||
SET (closure, in_marshal, TRUE);
|
ATOMIC_SET (closure, in_marshal, TRUE);
|
||||||
if (real_closure->va_meta_marshal)
|
if (real_closure->va_meta_marshal)
|
||||||
{
|
{
|
||||||
marshal_data = real_closure->meta_marshal_data;
|
marshal_data = real_closure->meta_marshal_data;
|
||||||
@ -901,7 +900,7 @@ _g_closure_invoke_va (GClosure *closure,
|
|||||||
n_params, param_types);
|
n_params, param_types);
|
||||||
if (!in_marshal)
|
if (!in_marshal)
|
||||||
closure_invoke_notifiers (closure, POST_NOTIFY);
|
closure_invoke_notifiers (closure, POST_NOTIFY);
|
||||||
SET (closure, in_marshal, in_marshal);
|
ATOMIC_SET (closure, in_marshal, in_marshal);
|
||||||
}
|
}
|
||||||
g_closure_unref (closure);
|
g_closure_unref (closure);
|
||||||
}
|
}
|
||||||
@ -1011,7 +1010,7 @@ g_cclosure_new_swap (GCallback callback_func,
|
|||||||
if (destroy_data)
|
if (destroy_data)
|
||||||
g_closure_add_finalize_notifier (closure, user_data, destroy_data);
|
g_closure_add_finalize_notifier (closure, user_data, destroy_data);
|
||||||
((GCClosure*) closure)->callback = (gpointer) callback_func;
|
((GCClosure*) closure)->callback = (gpointer) callback_func;
|
||||||
SET (closure, derivative_flag, TRUE);
|
ATOMIC_SET (closure, derivative_flag, TRUE);
|
||||||
|
|
||||||
return closure;
|
return closure;
|
||||||
}
|
}
|
||||||
|
@ -5606,6 +5606,7 @@ _weak_ref_set (GWeakRef *weak_ref,
|
|||||||
if (new_object)
|
if (new_object)
|
||||||
{
|
{
|
||||||
#if G_ENABLE_DEBUG
|
#if G_ENABLE_DEBUG
|
||||||
|
g_assert (new_wrdata != NULL);
|
||||||
g_assert (weak_ref_data_list_find (new_wrdata, weak_ref) < 0);
|
g_assert (weak_ref_data_list_find (new_wrdata, weak_ref) < 0);
|
||||||
#endif
|
#endif
|
||||||
if (g_atomic_int_get (&new_object->ref_count) < 1)
|
if (g_atomic_int_get (&new_object->ref_count) < 1)
|
||||||
|
@ -1197,13 +1197,13 @@ type_data_make_W (TypeNode *node,
|
|||||||
if (value_table->lcopy_format)
|
if (value_table->lcopy_format)
|
||||||
strcat (p, value_table->lcopy_format);
|
strcat (p, value_table->lcopy_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
node->data->common.value_table = vtable;
|
node->data->common.value_table = vtable;
|
||||||
|
g_assert (node->data->common.value_table != NULL); /* paranoid */
|
||||||
node->mutatable_check_cache = (node->data->common.value_table->value_init != NULL &&
|
node->mutatable_check_cache = (node->data->common.value_table->value_init != NULL &&
|
||||||
!((G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_ABSTRACT) &
|
!((G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_ABSTRACT) &
|
||||||
GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))));
|
GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))));
|
||||||
|
|
||||||
g_assert (node->data->common.value_table != NULL); /* paranoid */
|
|
||||||
|
|
||||||
g_atomic_int_set ((int *) &node->ref_count, 1);
|
g_atomic_int_set ((int *) &node->ref_count, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user