[sysprof] capture: fix sysprof_capture_reader_list_files()
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] capture: fix sysprof_capture_reader_list_files()
- Date: Mon, 28 Sep 2020 22:54:03 +0000 (UTC)
commit 28bb526603e9f7d0bb55bf2137938ea131308392
Author: Christian Hergert <chergert redhat com>
Date: Mon Sep 28 15:53:54 2020 -0700
capture: fix sysprof_capture_reader_list_files()
This needs to stash the string pointers internally so that we can maintain
ABI and still fix the issue at hand.
Fixes #50
src/libsysprof-capture/sysprof-capture-reader.c | 65 +++++++++++++++++--------
1 file changed, 44 insertions(+), 21 deletions(-)
---
diff --git a/src/libsysprof-capture/sysprof-capture-reader.c b/src/libsysprof-capture/sysprof-capture-reader.c
index 9a5aa91..ce48d7b 100644
--- a/src/libsysprof-capture/sysprof-capture-reader.c
+++ b/src/libsysprof-capture/sysprof-capture-reader.c
@@ -88,6 +88,8 @@ struct _SysprofCaptureReader
int64_t end_time;
SysprofCaptureStat st_buf;
unsigned int st_buf_set : 1;
+ char **list_files;
+ size_t n_list_files;
};
/* Sets @errno on failure. Sets @errno to EBADMSG if the file magic doesn’t
@@ -1276,7 +1278,7 @@ array_append (const char ***files,
*files = new_files;
}
- (*files)[*n_files] = new_element;
+ (*files)[*n_files] = new_element ? strdup (new_element) : NULL;
*n_files = *n_files + 1;
assert (*n_files <= *n_files_allocated);
@@ -1304,6 +1306,16 @@ array_deduplicate (const char **files,
*n_files = last_written + 1;
}
+static int
+compare_strings (const void *a,
+ const void *b)
+{
+ const char * const *astr = a;
+ const char * const *bstr = b;
+
+ return strcmp (*astr, *bstr);
+}
+
const char **
sysprof_capture_reader_list_files (SysprofCaptureReader *self)
{
@@ -1313,39 +1325,50 @@ sysprof_capture_reader_list_files (SysprofCaptureReader *self)
assert (self != NULL);
- while (sysprof_capture_reader_peek_type (self, &type))
+ /* Only generate the list of files once */
+ if (self->list_files == NULL)
{
- const SysprofCaptureFileChunk *file;
-
- if (type != SYSPROF_CAPTURE_FRAME_FILE_CHUNK)
+ while (sysprof_capture_reader_peek_type (self, &type))
{
- sysprof_capture_reader_skip (self);
- continue;
+ const SysprofCaptureFileChunk *file;
+
+ if (type != SYSPROF_CAPTURE_FRAME_FILE_CHUNK)
+ {
+ sysprof_capture_reader_skip (self);
+ continue;
+ }
+
+ if (!(file = sysprof_capture_reader_read_file (self)))
+ break;
+
+ if (!array_append (&files, &n_files, &n_files_allocated, file->path))
+ {
+ free (files);
+ errno = ENOMEM;
+ return NULL;
+ }
}
- if (!(file = sysprof_capture_reader_read_file (self)))
- break;
+ /* Sort and deduplicate the files array. */
+ qsort (files, n_files, sizeof (*files), compare_strings);
+ array_deduplicate (files, &n_files);
- if (!array_append (&files, &n_files, &n_files_allocated, file->path))
+ /* Add a null terminator */
+ if (!array_append (&files, &n_files, &n_files_allocated, NULL))
{
free (files);
errno = ENOMEM;
return NULL;
}
- }
-
- /* Sort and deduplicate the files array. */
- qsort (files, n_files, sizeof (*files), (int (*)(const void *, const void *)) strcmp);
- array_deduplicate (files, &n_files);
- /* Add a null terminator */
- if (!array_append (&files, &n_files, &n_files_allocated, NULL))
- {
- free (files);
- errno = ENOMEM;
- return NULL;
+ self->list_files = (char **)sysprof_steal_pointer (&files);
+ self->n_list_files = n_files; /* including NULL */
}
+ /* Now copy the list but not the strings */
+ files = malloc (sizeof (char *) * self->n_list_files);
+ memcpy (files, self->list_files, sizeof (char *) * self->n_list_files);
+
return sysprof_steal_pointer (&files);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]