This is an automated email from the ASF dual-hosted git repository.
kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 1d3cf6f1820 GH-44349: [GLib] Keep GBytes alive in GBytes based buffers
(#55333)
1d3cf6f1820 is described below
commit 1d3cf6f18205870b88b2beecabc92a6567dfefb0
Author: Sutou Kouhei <[email protected]>
AuthorDate: Sun Nov 1 23:06:50 2026 +0900
GH-44349: [GLib] Keep GBytes alive in GBytes based buffers (#55333)
### Rationale for this change
If a `GArrowBuffer` is freed but the underlying `arrow::Buffer` is still
alive, the `arrow::Buffer` still refers invalidated data.
### What changes are included in this PR?
Create our `arrow::Buffer` subclass that refers `GBytes` and use it.
### Are these changes tested?
Yes.
### Are there any user-facing changes?
No.
### Was AI used for this PR?
In accordance to the [AI generation
guidelines](https://arrow.apache.org/docs/dev/developers/overview.html#ai-generated-code),
please disclose below whether and how AI was used in this PR.
**PR code and description written by:**
- [x] Human
- [x] AI
**Reviewed before submission by:**
- [x] Human
- [x] AI
- [ ] Not reviewed
* GitHub Issue: #44349
Authored-by: Sutou Kouhei <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
c_glib/arrow-glib/buffer.cpp | 48 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/c_glib/arrow-glib/buffer.cpp b/c_glib/arrow-glib/buffer.cpp
index 8681ab4efa6..cd751d73203 100644
--- a/c_glib/arrow-glib/buffer.cpp
+++ b/c_glib/arrow-glib/buffer.cpp
@@ -20,6 +20,34 @@
#include <arrow-glib/buffer.hpp>
#include <arrow-glib/error.hpp>
+namespace garrow {
+ class GBytesBuffer : public arrow::Buffer {
+ public:
+ GBytesBuffer(GBytes *bytes, const uint8_t *data, int64_t size)
+ : arrow::Buffer(data, size),
+ bytes_(g_bytes_ref(bytes))
+ {
+ }
+ ~GBytesBuffer() override { g_bytes_unref(bytes_); }
+
+ private:
+ GBytes *bytes_;
+ };
+
+ class GBytesMutableBuffer : public arrow::MutableBuffer {
+ public:
+ GBytesMutableBuffer(GBytes *bytes, uint8_t *data, int64_t size)
+ : arrow::MutableBuffer(data, size),
+ bytes_(g_bytes_ref(bytes))
+ {
+ }
+ ~GBytesMutableBuffer() override { g_bytes_unref(bytes_); }
+
+ private:
+ GBytes *bytes_;
+ };
+} // namespace garrow
+
G_BEGIN_DECLS
/**
@@ -191,7 +219,8 @@ garrow_buffer_new(const guint8 *data, gint64 size)
/**
* garrow_buffer_new_bytes:
- * @data: Data for the buffer.
+ * @data: Data for the buffer. The data isn't copied. The buffer keeps
+ * @data alive.
*
* Returns: A newly created #GArrowBuffer.
*
@@ -202,8 +231,10 @@ garrow_buffer_new_bytes(GBytes *data)
{
size_t data_size;
auto raw_data = g_bytes_get_data(data, &data_size);
- auto arrow_buffer =
- std::make_shared<arrow::Buffer>(static_cast<const uint8_t *>(raw_data),
data_size);
+ std::shared_ptr<arrow::Buffer> arrow_buffer =
+ std::make_shared<garrow::GBytesBuffer>(data,
+ static_cast<const uint8_t
*>(raw_data),
+ data_size);
return garrow_buffer_new_raw_bytes(&arrow_buffer, data);
}
@@ -453,7 +484,8 @@ garrow_mutable_buffer_new(guint8 *data, gint64 size)
/**
* garrow_mutable_buffer_new_bytes:
- * @data: Data for the buffer.
+ * @data: Data for the buffer. The data isn't copied. The buffer keeps
+ * @data alive.
*
* Returns: A newly created #GArrowMutableBuffer.
*
@@ -465,9 +497,11 @@ garrow_mutable_buffer_new_bytes(GBytes *data)
size_t data_size;
auto raw_data = g_bytes_get_data(data, &data_size);
auto mutable_raw_data = const_cast<gpointer>(raw_data);
- auto arrow_buffer =
- std::make_shared<arrow::MutableBuffer>(static_cast<uint8_t
*>(mutable_raw_data),
- data_size);
+ std::shared_ptr<arrow::MutableBuffer> arrow_buffer =
+ std::make_shared<garrow::GBytesMutableBuffer>(
+ data,
+ static_cast<uint8_t *>(mutable_raw_data),
+ data_size);
return garrow_mutable_buffer_new_raw_bytes(&arrow_buffer, data);
}