When a file is opened that has multiple traces inside, there is a race condition with how the metadata is maintained with the PlaybackMetadataCustomization and how it is reused.
This change avoids that problem by instead making sure that the objects have a copy of their metadata directly on their thread so they do not need to reference the current in the PlaybackMetadata. More full explanation below.
As part of a more robust fix, this also moves further from explicitly typed/casting of explicit types and instead uses the interfaces extensively (leaving explicit types when it provides a notable perf optimization with a fallback to the interface).
This additionally fixes a math error if the trace is a multiple of 8 bytes
Race condition:
When we open a file, we start in CtfPlayback.GeneratePlaybackStreams which creates the MetadataParser itself for the stream. As part of this, we may start a CtfStreamReadAhead which will try to parse the file on a worker thread. After reading enough packets from the current stream, we will move onto the next stream and do the same.
Since these streams exist within the same playback, we will share the PlaybackCustomization and it will make a new MetadataParser. This means that PlaybackCustomization.Metadata will change at that point (while the background threads can still be running). This means that at that point, any of the worker threads may not be able to find metadata like clocks or event ids because they are looking at a different and possibly empty metadata.
When a file is opened that has multiple traces inside, there is a race condition with how the metadata is maintained with the PlaybackMetadataCustomization and how it is reused. This change avoids that problem by instead making sure that the objects have a copy of their metadata directly on their thread so they do not need to reference the current in the PlaybackMetadata. More full explanation below.
As part of a more robust fix, this also moves further from explicitly typed/casting of explicit types and instead uses the interfaces extensively (leaving explicit types when it provides a notable perf optimization with a fallback to the interface).
This additionally fixes a math error if the trace is a multiple of 8 bytes
Race condition: When we open a file, we start in CtfPlayback.GeneratePlaybackStreams which creates the MetadataParser itself for the stream. As part of this, we may start a CtfStreamReadAhead which will try to parse the file on a worker thread. After reading enough packets from the current stream, we will move onto the next stream and do the same. Since these streams exist within the same playback, we will share the PlaybackCustomization and it will make a new MetadataParser. This means that PlaybackCustomization.Metadata will change at that point (while the background threads can still be running). This means that at that point, any of the worker threads may not be able to find metadata like clocks or event ids because they are looking at a different and possibly empty metadata.