diff --git a/src/libsysprof-capture/mapped-ring-buffer.c b/src/libsysprof-capture/mapped-ring-buffer.c index 061656ed..b051a54d 100644 --- a/src/libsysprof-capture/mapped-ring-buffer.c +++ b/src/libsysprof-capture/mapped-ring-buffer.c @@ -36,8 +36,9 @@ #define BUFFER_MAX_SIZE ((G_MAXUINT32/2)-_sysprof_getpagesize()) enum { - MODE_READER = 1, - MODE_WRITER = 2, + MODE_READER = 1, + MODE_WRITER = 2, + MODE_READWRITE = 3, }; /* @@ -209,6 +210,17 @@ mapped_ring_buffer_new_reader (gsize buffer_size) return g_steal_pointer (&self); } +MappedRingBuffer * +mapped_ring_buffer_new_readwrite (gsize buffer_size) +{ + MappedRingBuffer *self; + + if ((self = mapped_ring_buffer_new_reader (buffer_size))) + self->mode = MODE_READWRITE; + + return self; +} + /** * mapped_ring_buffer_new_writer: * @fd: a FD to map @@ -363,7 +375,7 @@ mapped_ring_buffer_allocate (MappedRingBuffer *self, gsize tailpos; g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (self->mode == MODE_WRITER, NULL); + g_return_val_if_fail (self->mode & MODE_WRITER, NULL); g_return_val_if_fail (length > 0, NULL); g_return_val_if_fail (length < self->body_size, NULL); g_return_val_if_fail ((length & 0x7) == 0, NULL); @@ -419,7 +431,7 @@ mapped_ring_buffer_advance (MappedRingBuffer *self, guint32 tail; g_return_if_fail (self != NULL); - g_return_if_fail (self->mode == MODE_WRITER); + g_return_if_fail (self->mode & MODE_WRITER); g_return_if_fail (length > 0); g_return_if_fail (length < self->body_size); g_return_if_fail ((length & 0x7) == 0); @@ -464,7 +476,7 @@ mapped_ring_buffer_drain (MappedRingBuffer *self, gsize tailpos; g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (self->mode == MODE_READER, FALSE); + g_return_val_if_fail (self->mode & MODE_READER, FALSE); g_return_val_if_fail (callback != NULL, FALSE); header = get_header (self); diff --git a/src/libsysprof-capture/mapped-ring-buffer.h b/src/libsysprof-capture/mapped-ring-buffer.h index 8530cedc..45387c35 100644 --- a/src/libsysprof-capture/mapped-ring-buffer.h +++ b/src/libsysprof-capture/mapped-ring-buffer.h @@ -56,6 +56,8 @@ typedef gboolean (*MappedRingBufferCallback) (gconstpointer data, G_GNUC_INTERNAL MappedRingBuffer *mapped_ring_buffer_new_reader (gsize buffer_size); G_GNUC_INTERNAL +MappedRingBuffer *mapped_ring_buffer_new_readwrite (gsize buffer_size); +G_GNUC_INTERNAL MappedRingBuffer *mapped_ring_buffer_new_writer (gint fd); G_GNUC_INTERNAL gint mapped_ring_buffer_get_fd (MappedRingBuffer *self); diff --git a/src/tests/test-mapped-ring-buffer.c b/src/tests/test-mapped-ring-buffer.c index 596109fa..5c6c0144 100644 --- a/src/tests/test-mapped-ring-buffer.c +++ b/src/tests/test-mapped-ring-buffer.c @@ -164,12 +164,33 @@ test_threaded_movements (void) g_thread_join (thread2); } +static void +test_readwrite (void) +{ + MappedRingBuffer *ring; + gint64 *ptr; + + ring = mapped_ring_buffer_new_readwrite (4096*16); + g_assert_nonnull (ring); + + real_count = 0; + while ((ptr = mapped_ring_buffer_allocate (ring, sizeof *ptr))) + { + static gint64 count; + g_assert ((GPOINTER_TO_SIZE(ptr) & 0x7) == 0); + *ptr = ++count; + mapped_ring_buffer_advance (ring, sizeof *ptr); + } + mapped_ring_buffer_drain (ring, drain_count_cb, NULL); +} + gint main (gint argc, gchar *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/MappedRingBuffer/basic_movements", test_basic_movements); + g_test_add_func ("/MappedRingBuffer/readwrite", test_readwrite); g_test_add_func ("/MappedRingBuffer/threaded_movements", test_threaded_movements); return g_test_run (); }