1
0
mirror of https://gitlab.gnome.org/GNOME/glib.git synced 2026-10-24 00:49:00 +03:00
Files
glib/gio/goutputstream.h
Sam James 016829559e Drop G_GNUC_CONST for *_get_type
g_type_ensure has a large comment saying _get_type shouldn't be
marked with G_GNUC_CONST because it has side-effects on the first
run, but it's OK if you consistently call g_type_ensure first.

Unfortunately, this isn't accurate. GCC trunk (observed at r17-1725-ge259a182e1f100)
now analyses points-to information more effectively and propagates its
findings, so it sees the function modifies some global state, concludes
that can't be possible (because of the const attribute), and deletes
the stores.

pure unfortunately is unsuitable for *_get_type too as it has a side-effect
(writes to global memory).

Mesa had a similar issue which I fixed recently [0]. glib and glibmm likely
want the (not-yet-implemented) 'idempotent' attribute instead [1]. In fact,
this exact problem is what motivated that request! :)

ebassi mentions an alternative to the current setup as well, using
atomics [2].

This problem has gone back many years but the compiler has finally
fully outsmarted us here, so give in.

[0] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42361
[1] https://gcc.gnu.org/PR32911
[2] https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4249#note_2583110

Fixes: https://gitlab.gnome.org/GNOME/glib/-/work_items/3984
Signed-off-by: Sam James <sam@gentoo.org>
2026-06-25 17:23:46 +01:00

326 lines
15 KiB
C

/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
*
* 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/>.
*
* Author: Alexander Larsson <alexl@redhat.com>
*/
#ifndef __G_OUTPUT_STREAM_H__
#define __G_OUTPUT_STREAM_H__
#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
#error "Only <gio/gio.h> can be included directly."
#endif
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_OUTPUT_STREAM (g_output_stream_get_type ())
#define G_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_OUTPUT_STREAM, GOutputStream))
#define G_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_OUTPUT_STREAM, GOutputStreamClass))
#define G_IS_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_OUTPUT_STREAM))
#define G_IS_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_OUTPUT_STREAM))
#define G_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_OUTPUT_STREAM, GOutputStreamClass))
typedef struct _GOutputStreamClass GOutputStreamClass;
typedef struct _GOutputStreamPrivate GOutputStreamPrivate;
struct _GOutputStream
{
GObject parent_instance;
/*< private >*/
GOutputStreamPrivate *priv;
};
struct _GOutputStreamClass
{
GObjectClass parent_class;
/* Sync ops: */
gssize (* write_fn) (GOutputStream *stream,
const void *buffer,
gsize count,
GCancellable *cancellable,
GError **error);
gssize (* splice) (GOutputStream *stream,
GInputStream *source,
GOutputStreamSpliceFlags flags,
GCancellable *cancellable,
GError **error);
gboolean (* flush) (GOutputStream *stream,
GCancellable *cancellable,
GError **error);
gboolean (* close_fn) (GOutputStream *stream,
GCancellable *cancellable,
GError **error);
/* Async ops: (optional in derived classes) */
void (* write_async) (GOutputStream *stream,
const void *buffer,
gsize count,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gssize (* write_finish) (GOutputStream *stream,
GAsyncResult *result,
GError **error);
void (* splice_async) (GOutputStream *stream,
GInputStream *source,
GOutputStreamSpliceFlags flags,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gssize (* splice_finish) (GOutputStream *stream,
GAsyncResult *result,
GError **error);
void (* flush_async) (GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (* flush_finish) (GOutputStream *stream,
GAsyncResult *result,
GError **error);
void (* close_async) (GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (* close_finish) (GOutputStream *stream,
GAsyncResult *result,
GError **error);
gboolean (* writev_fn) (GOutputStream *stream,
const GOutputVector *vectors,
gsize n_vectors,
gsize *bytes_written,
GCancellable *cancellable,
GError **error);
void (* writev_async) (GOutputStream *stream,
const GOutputVector *vectors,
gsize n_vectors,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (* writev_finish) (GOutputStream *stream,
GAsyncResult *result,
gsize *bytes_written,
GError **error);
/*< private >*/
/* Padding for future expansion */
void (*_g_reserved4) (void);
void (*_g_reserved5) (void);
void (*_g_reserved6) (void);
void (*_g_reserved7) (void);
void (*_g_reserved8) (void);
};
GIO_AVAILABLE_IN_ALL
GType g_output_stream_get_type (void);
GIO_AVAILABLE_IN_ALL
gssize g_output_stream_write (GOutputStream *stream,
const void *buffer,
gsize count,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_write_all (GOutputStream *stream,
const void *buffer,
gsize count,
gsize *bytes_written,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_2_60
gboolean g_output_stream_writev (GOutputStream *stream,
const GOutputVector *vectors,
gsize n_vectors,
gsize *bytes_written,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_2_60
gboolean g_output_stream_writev_all (GOutputStream *stream,
GOutputVector *vectors,
gsize n_vectors,
gsize *bytes_written,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_2_40
gboolean g_output_stream_printf (GOutputStream *stream,
gsize *bytes_written,
GCancellable *cancellable,
GError **error,
const gchar *format,
...) G_GNUC_PRINTF (5, 6);
GIO_AVAILABLE_IN_2_40
gboolean g_output_stream_vprintf (GOutputStream *stream,
gsize *bytes_written,
GCancellable *cancellable,
GError **error,
const gchar *format,
va_list args) G_GNUC_PRINTF (5, 0);
GIO_AVAILABLE_IN_2_34
gssize g_output_stream_write_bytes (GOutputStream *stream,
GBytes *bytes,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_ALL
gssize g_output_stream_splice (GOutputStream *stream,
GInputStream *source,
GOutputStreamSpliceFlags flags,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_flush (GOutputStream *stream,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_close (GOutputStream *stream,
GCancellable *cancellable,
GError **error);
GIO_AVAILABLE_IN_ALL
void g_output_stream_write_async (GOutputStream *stream,
const void *buffer,
gsize count,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_ALL
gssize g_output_stream_write_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error);
GIO_AVAILABLE_IN_2_44
void g_output_stream_write_all_async (GOutputStream *stream,
const void *buffer,
gsize count,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_2_44
gboolean g_output_stream_write_all_finish (GOutputStream *stream,
GAsyncResult *result,
gsize *bytes_written,
GError **error);
GIO_AVAILABLE_IN_2_60
void g_output_stream_writev_async (GOutputStream *stream,
const GOutputVector *vectors,
gsize n_vectors,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_2_60
gboolean g_output_stream_writev_finish (GOutputStream *stream,
GAsyncResult *result,
gsize *bytes_written,
GError **error);
GIO_AVAILABLE_IN_2_60
void g_output_stream_writev_all_async (GOutputStream *stream,
GOutputVector *vectors,
gsize n_vectors,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_2_60
gboolean g_output_stream_writev_all_finish (GOutputStream *stream,
GAsyncResult *result,
gsize *bytes_written,
GError **error);
GIO_AVAILABLE_IN_2_34
void g_output_stream_write_bytes_async (GOutputStream *stream,
GBytes *bytes,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_2_34
gssize g_output_stream_write_bytes_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error);
GIO_AVAILABLE_IN_ALL
void g_output_stream_splice_async (GOutputStream *stream,
GInputStream *source,
GOutputStreamSpliceFlags flags,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_ALL
gssize g_output_stream_splice_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error);
GIO_AVAILABLE_IN_ALL
void g_output_stream_flush_async (GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_flush_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error);
GIO_AVAILABLE_IN_ALL
void g_output_stream_close_async (GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_close_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_is_closed (GOutputStream *stream);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_is_closing (GOutputStream *stream);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_has_pending (GOutputStream *stream);
GIO_AVAILABLE_IN_ALL
gboolean g_output_stream_set_pending (GOutputStream *stream,
GError **error);
GIO_AVAILABLE_IN_ALL
void g_output_stream_clear_pending (GOutputStream *stream);
G_END_DECLS
#endif /* __G_OUTPUT_STREAM_H__ */