mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-14 19:55:12 +01:00
Merge branch 'steal-handle-id' into 'main'
utils: Add g_steal_handle_id() to complement g_clear_handle_id() See merge request GNOME/glib!4308
This commit is contained in:
commit
766f3414eb
@ -184,6 +184,11 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
* Since: 2.80
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline gboolean g_unix_pipe_open (GUnixPipe *self,
|
||||
int flags,
|
||||
GError **error);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline gboolean
|
||||
g_unix_pipe_open (GUnixPipe *self,
|
||||
int flags,
|
||||
@ -212,6 +217,10 @@ g_unix_pipe_open (GUnixPipe *self,
|
||||
* Since: 2.80
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline int g_unix_pipe_get (GUnixPipe *self,
|
||||
GUnixPipeEnd end);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline int
|
||||
g_unix_pipe_get (GUnixPipe *self,
|
||||
GUnixPipeEnd end)
|
||||
@ -241,6 +250,10 @@ g_unix_pipe_get (GUnixPipe *self,
|
||||
* Since: 2.80
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline int g_unix_pipe_steal (GUnixPipe *self,
|
||||
GUnixPipeEnd end);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline int
|
||||
g_unix_pipe_steal (GUnixPipe *self,
|
||||
GUnixPipeEnd end)
|
||||
@ -276,6 +289,11 @@ g_unix_pipe_steal (GUnixPipe *self,
|
||||
* Since: 2.80
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline gboolean g_unix_pipe_close (GUnixPipe *self,
|
||||
GUnixPipeEnd end,
|
||||
GError **error);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline gboolean
|
||||
g_unix_pipe_close (GUnixPipe *self,
|
||||
GUnixPipeEnd end,
|
||||
@ -304,6 +322,9 @@ g_unix_pipe_close (GUnixPipe *self,
|
||||
*
|
||||
* Since: 2.80
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline void g_unix_pipe_clear (GUnixPipe *self);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
|
||||
static inline void
|
||||
g_unix_pipe_clear (GUnixPipe *self)
|
||||
|
21
glib/gmain.c
21
glib/gmain.c
@ -6571,24 +6571,3 @@ g_get_worker_context (void)
|
||||
return glib_worker_context;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_steal_fd:
|
||||
* @fd_ptr: (not optional) (inout): A pointer to a file descriptor
|
||||
*
|
||||
* Sets @fd_ptr to `-1`, returning the value that was there before.
|
||||
*
|
||||
* Conceptually, this transfers the ownership of the file descriptor
|
||||
* from the referenced variable to the caller of the function (i.e.
|
||||
* ‘steals’ the reference). This is very similar to [func@GLib.steal_pointer],
|
||||
* but for file descriptors.
|
||||
*
|
||||
* On POSIX platforms, this function is async-signal safe
|
||||
* (see [`signal(7)`](man:signal(7)) and
|
||||
* [`signal-safety(7)`](man:signal-safety(7))), making it safe to call from a
|
||||
* signal handler or a #GSpawnChildSetupFunc.
|
||||
*
|
||||
* This function preserves the value of `errno`.
|
||||
*
|
||||
* Returns: the value that @fd_ptr previously had
|
||||
* Since: 2.70
|
||||
*/
|
||||
|
78
glib/gmain.h
78
glib/gmain.h
@ -634,6 +634,9 @@ typedef void GMainContextPusher GLIB_AVAILABLE_TYPE_IN_2_64;
|
||||
* Since: 2.64
|
||||
*/
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_64
|
||||
static inline GMainContextPusher *g_main_context_pusher_new (GMainContext *main_context);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_64
|
||||
static inline GMainContextPusher *
|
||||
g_main_context_pusher_new (GMainContext *main_context)
|
||||
@ -656,6 +659,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
* Since: 2.64
|
||||
*/
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_64
|
||||
static inline void g_main_context_pusher_free (GMainContextPusher *pusher);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_64
|
||||
static inline void
|
||||
g_main_context_pusher_free (GMainContextPusher *pusher)
|
||||
@ -866,6 +872,54 @@ void g_clear_handle_id (guint *tag_ptr,
|
||||
} G_STMT_END \
|
||||
GLIB_AVAILABLE_MACRO_IN_2_56
|
||||
|
||||
/**
|
||||
* g_steal_handle_id:
|
||||
* @handle_pointer: (inout) (not optional): a pointer to a handle ID
|
||||
*
|
||||
* Sets @handle_pointer to `0`, returning the value that was there before.
|
||||
*
|
||||
* Conceptually, this transfers the ownership of the handle ID from the
|
||||
* referenced variable to the ‘caller’ of the macro (ie: ‘steals’ the
|
||||
* handle ID).
|
||||
*
|
||||
* This can be very useful to make ownership transfer explicit, or to prevent
|
||||
* a handle from being released multiple times. For example:
|
||||
*
|
||||
* ```c
|
||||
* void
|
||||
* maybe_unsubscribe_signal (ContextStruct *data)
|
||||
* {
|
||||
* if (some_complex_logic (data))
|
||||
* {
|
||||
* g_dbus_connection_signal_unsubscribe (data->connection,
|
||||
* g_steal_handle_id (&data->subscription_id));
|
||||
* // now data->subscription_id isn’t a dangling handle
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* While [func@GLib.clear_handle_id] can be used in many of the same situations
|
||||
* as `g_steal_handle_id()`, this is one situation where it cannot be used, as
|
||||
* there is no way to pass the `GDBusConnection` to a
|
||||
* [type@GLib.ClearHandleFunc].
|
||||
*
|
||||
* Since: 2.84
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_84
|
||||
static inline unsigned int g_steal_handle_id (unsigned int *handle_pointer);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_84
|
||||
static inline unsigned int
|
||||
g_steal_handle_id (unsigned int *handle_pointer)
|
||||
{
|
||||
unsigned int handle;
|
||||
|
||||
handle = *handle_pointer;
|
||||
*handle_pointer = 0;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
/* Idles, child watchers and timeouts */
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
guint g_timeout_add_full (gint priority,
|
||||
@ -930,6 +984,30 @@ void g_main_context_invoke (GMainContext *context,
|
||||
GSourceFunc function,
|
||||
gpointer data);
|
||||
|
||||
/**
|
||||
* g_steal_fd:
|
||||
* @fd_ptr: (not optional) (inout): A pointer to a file descriptor
|
||||
*
|
||||
* Sets @fd_ptr to `-1`, returning the value that was there before.
|
||||
*
|
||||
* Conceptually, this transfers the ownership of the file descriptor
|
||||
* from the referenced variable to the caller of the function (i.e.
|
||||
* ‘steals’ the reference). This is very similar to [func@GLib.steal_pointer],
|
||||
* but for file descriptors.
|
||||
*
|
||||
* On POSIX platforms, this function is async-signal safe
|
||||
* (see [`signal(7)`](man:signal(7)) and
|
||||
* [`signal-safety(7)`](man:signal-safety(7))), making it safe to call from a
|
||||
* signal handler or a #GSpawnChildSetupFunc.
|
||||
*
|
||||
* This function preserves the value of `errno`.
|
||||
*
|
||||
* Returns: the value that @fd_ptr previously had
|
||||
* Since: 2.70
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_70
|
||||
static inline int g_steal_fd (int *fd_ptr);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_70
|
||||
static inline int
|
||||
g_steal_fd (int *fd_ptr)
|
||||
|
@ -229,6 +229,9 @@ void g_aligned_free_sized (gpointer mem,
|
||||
*
|
||||
* Since: 2.44
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
|
||||
static inline gpointer g_steal_pointer (gpointer pp);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
|
||||
static inline gpointer
|
||||
g_steal_pointer (gpointer pp)
|
||||
|
@ -1841,68 +1841,6 @@ g_close (gint fd,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_clear_fd: (skip)
|
||||
* @fd_ptr: (not optional) (inout) (transfer full): a pointer to a file descriptor
|
||||
* @error: Used to return an error on failure
|
||||
*
|
||||
* If @fd_ptr points to a file descriptor, close it and return
|
||||
* whether closing it was successful, like g_close().
|
||||
* If @fd_ptr points to a negative number, return %TRUE without closing
|
||||
* anything.
|
||||
* In both cases, set @fd_ptr to `-1` before returning.
|
||||
*
|
||||
* Like g_close(), if closing the file descriptor fails, the error is
|
||||
* stored in both %errno and @error. If this function succeeds,
|
||||
* %errno is undefined.
|
||||
*
|
||||
* On POSIX platforms, this function is async-signal safe
|
||||
* if @error is %NULL and @fd_ptr points to either a negative number or a
|
||||
* valid open file descriptor.
|
||||
* This makes it safe to call from a signal handler or a #GSpawnChildSetupFunc
|
||||
* under those conditions.
|
||||
* See [`signal(7)`](man:signal(7)) and
|
||||
* [`signal-safety(7)`](man:signal-safety(7)) for more details.
|
||||
*
|
||||
* It is a programming error for @fd_ptr to point to a non-negative
|
||||
* number that is not a valid file descriptor.
|
||||
*
|
||||
* A typical use of this function is to clean up a file descriptor at
|
||||
* the end of its scope, whether it has been set successfully or not:
|
||||
*
|
||||
* |[
|
||||
* gboolean
|
||||
* operate_on_fd (GError **error)
|
||||
* {
|
||||
* gboolean ret = FALSE;
|
||||
* int fd = -1;
|
||||
*
|
||||
* fd = open_a_fd (error);
|
||||
*
|
||||
* if (fd < 0)
|
||||
* goto out;
|
||||
*
|
||||
* if (!do_something (fd, error))
|
||||
* goto out;
|
||||
*
|
||||
* if (!g_clear_fd (&fd, error))
|
||||
* goto out;
|
||||
*
|
||||
* ret = TRUE;
|
||||
*
|
||||
* out:
|
||||
* // OK to call even if fd was never opened or was already closed
|
||||
* g_clear_fd (&fd, NULL);
|
||||
* return ret;
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* This function is also useful in conjunction with #g_autofd.
|
||||
*
|
||||
* Returns: %TRUE on success
|
||||
* Since: 2.76
|
||||
*/
|
||||
|
||||
/**
|
||||
* g_autofd: (skip)
|
||||
*
|
||||
|
@ -179,6 +179,71 @@ GLIB_AVAILABLE_IN_2_36
|
||||
gboolean g_close (gint fd,
|
||||
GError **error);
|
||||
|
||||
/**
|
||||
* g_clear_fd: (skip)
|
||||
* @fd_ptr: (not optional) (inout) (transfer full): a pointer to a file descriptor
|
||||
* @error: Used to return an error on failure
|
||||
*
|
||||
* If @fd_ptr points to a file descriptor, close it and return
|
||||
* whether closing it was successful, like g_close().
|
||||
* If @fd_ptr points to a negative number, return %TRUE without closing
|
||||
* anything.
|
||||
* In both cases, set @fd_ptr to `-1` before returning.
|
||||
*
|
||||
* Like g_close(), if closing the file descriptor fails, the error is
|
||||
* stored in both %errno and @error. If this function succeeds,
|
||||
* %errno is undefined.
|
||||
*
|
||||
* On POSIX platforms, this function is async-signal safe
|
||||
* if @error is %NULL and @fd_ptr points to either a negative number or a
|
||||
* valid open file descriptor.
|
||||
* This makes it safe to call from a signal handler or a #GSpawnChildSetupFunc
|
||||
* under those conditions.
|
||||
* See [`signal(7)`](man:signal(7)) and
|
||||
* [`signal-safety(7)`](man:signal-safety(7)) for more details.
|
||||
*
|
||||
* It is a programming error for @fd_ptr to point to a non-negative
|
||||
* number that is not a valid file descriptor.
|
||||
*
|
||||
* A typical use of this function is to clean up a file descriptor at
|
||||
* the end of its scope, whether it has been set successfully or not:
|
||||
*
|
||||
* |[
|
||||
* gboolean
|
||||
* operate_on_fd (GError **error)
|
||||
* {
|
||||
* gboolean ret = FALSE;
|
||||
* int fd = -1;
|
||||
*
|
||||
* fd = open_a_fd (error);
|
||||
*
|
||||
* if (fd < 0)
|
||||
* goto out;
|
||||
*
|
||||
* if (!do_something (fd, error))
|
||||
* goto out;
|
||||
*
|
||||
* if (!g_clear_fd (&fd, error))
|
||||
* goto out;
|
||||
*
|
||||
* ret = TRUE;
|
||||
*
|
||||
* out:
|
||||
* // OK to call even if fd was never opened or was already closed
|
||||
* g_clear_fd (&fd, NULL);
|
||||
* return ret;
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* This function is also useful in conjunction with #g_autofd.
|
||||
*
|
||||
* Returns: %TRUE on success
|
||||
* Since: 2.76
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_76
|
||||
static inline gboolean g_clear_fd (int *fd_ptr,
|
||||
GError **error);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_76
|
||||
static inline gboolean
|
||||
g_clear_fd (int *fd_ptr,
|
||||
|
@ -476,6 +476,10 @@ gboolean g_ascii_string_to_unsigned (const gchar *str,
|
||||
* Since: 2.76
|
||||
*/
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_76
|
||||
static inline gboolean g_set_str (char **str_pointer,
|
||||
const char *new_str);
|
||||
|
||||
GLIB_AVAILABLE_STATIC_INLINE_IN_2_76
|
||||
static inline gboolean
|
||||
g_set_str (char **str_pointer,
|
||||
const char *new_str)
|
||||
|
@ -1322,6 +1322,20 @@ test_clear_slist (void)
|
||||
g_assert_null (slist);
|
||||
}
|
||||
|
||||
static void
|
||||
test_steal_handle_id (void)
|
||||
{
|
||||
unsigned int handle_id = 0;
|
||||
|
||||
g_assert_cmpuint (g_steal_handle_id (&handle_id), ==, 0);
|
||||
g_assert_cmpuint (handle_id, ==, 0);
|
||||
|
||||
handle_id = 5; /* pretend this is a meaningful handle */
|
||||
|
||||
g_assert_cmpuint (g_steal_handle_id (&handle_id), ==, 5);
|
||||
g_assert_cmpuint (handle_id, ==, 0);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
@ -1382,6 +1396,7 @@ main (int argc,
|
||||
g_test_add_func ("/utils/int-limits", test_int_limits);
|
||||
g_test_add_func ("/utils/clear-list", test_clear_list);
|
||||
g_test_add_func ("/utils/clear-slist", test_clear_slist);
|
||||
g_test_add_func ("/utils/steal-handle-id", test_steal_handle_id);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user