public SnapshotEnumerator(StackSnapshotsBufferSegment ownerSegment) { _ownerSegment = ownerSegment; _snapshotsCount = ownerSegment.SnapshotsCount; _currentSnapshotIndex = 0; _nextSnapshotDataPtr = (_snapshotsCount < 1) ? IntPtr.Zero : _ownerSegment.SegmentBufferStartAddress; }
private uint NativeCallback_EnqueueStackSnapshotBufferSegmentForExport( IntPtr segmentNativeObjectPtr, IntPtr segmentStartAddress, uint segmentByteCount, uint segmentSnapshotCount, ulong segmentUnixTimeUtcRangeStart, ulong segmentUnixTimeUtcRangeEnd) { StackSnapshotsBufferSegment segment = null; try { segment = new StackSnapshotsBufferSegment( segmentNativeObjectPtr, segmentStartAddress, segmentByteCount, segmentSnapshotCount, segmentUnixTimeUtcRangeStart, segmentUnixTimeUtcRangeEnd); StackSnapshotsBufferSegmentCollection completedStackSnapshots = GetCompletedStackSnapshots(); bool isAdded = completedStackSnapshots != null && completedStackSnapshots.Add(segment); while (!isAdded) { // If we get null, we are in a race on shutdown. There is nothing we can do, except just give up. // We need will dispose the segment without calling native Release // and return a failure code to indicate that we never kept a pointer in the first place. if (completedStackSnapshots == null) { segment.DisposeWithoutNativeRelease(); segment = null; return(HResult.E_CHANGED_STATE); } Thread.Yield(); completedStackSnapshots = GetCompletedStackSnapshots(); isAdded = completedStackSnapshots != null && completedStackSnapshots.Add(segment); } } catch (Exception ex) { Log.Error(LogSourceMoniker, ex); if (segment != null) { segment.DisposeWithoutNativeRelease(); } return(HResult.GetFailureCode(ex)); } return(HResult.S_OK); }
public bool Add(StackSnapshotsBufferSegment segment) { if (_isReadonly) { return(false); } Validate.NotNull(segment, nameof(segment)); lock (_updateLock) { if (_isReadonly) { return(false); } if (_segments.Count == 0) { _totalTimeRangeStart = segment.TimeRangeStart; _totalTimeRangeEnd = segment.TimeRangeEnd; } else { if (segment.TimeRangeStart < _totalTimeRangeStart) { _totalTimeRangeStart = segment.TimeRangeStart; } if (segment.TimeRangeEnd > _totalTimeRangeEnd) { _totalTimeRangeEnd = segment.TimeRangeEnd; } } _totalByteCount += segment.SegmentByteCount; _totalSnapshotsCount += segment.SnapshotsCount; _segments.Add(segment); return(true); } }