public void Dispose() { lock (_singletonAccessLock) { _profiledThreadInfoProvider.Dispose(); _profiledAppDomainProvider.Dispose(); UnregisterReversePInvokeCallbacks(); if (GenerateProfilesInManagedCode()) { _resolveAndExportStacksBackgroundLoop.Dispose(); } _pprofBuilder.Dispose(); StackSnapshotsBufferSegmentCollection completedStackSnapshots = GetCompletedStackSnapshots(); if (completedStackSnapshots != null) { _completedStackSnapshots = null; completedStackSnapshots.Dispose(); } if (_currentEngine == this) { _currentEngine = null; } } }
internal StackSnapshotsBufferSegmentCollection GetResetCompletedStackSnapshots() { var newCompletedStackSnapshots = new StackSnapshotsBufferSegmentCollection(); StackSnapshotsBufferSegmentCollection prevCompletedStackSnapshots = Interlocked.Exchange(ref _completedStackSnapshots, newCompletedStackSnapshots); prevCompletedStackSnapshots.MakeReadonly(); return(prevCompletedStackSnapshots); }
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); }
private ProfilerEngine(IProductConfiguration config) { Validate.NotNull(config, nameof(config)); _versionInfo = ProfilerEngineVersionInfo.CreateNewInstance(); _profiledThreadInfoProvider = new ProfiledThreadInfoProvider(); _profiledAppDomainProvider = new ProfiledAppDomainProvider(); _enqueueStackSnapshotBufferSegmentForExport = NativeCallback_EnqueueStackSnapshotBufferSegmentForExport; _tryShutdownCurrentManagedProfilerEngine = NativeCallback_TryShutdownCurrentManagedProfilerEngine; _completedStackSnapshots = new StackSnapshotsBufferSegmentCollection(); _pprofBuilder = new PProfBuilder(); RegisterReversePInvokeCallbacks(); _resolveAndExportStacksBackgroundLoop = new ResolveAndExportStacksBackgroundLoop(this, config); _resolveAndExportStacksBackgroundLoop.Start(); }
internal StackSnapshotsBufferSegmentCollection GetCompletedStackSnapshots() { StackSnapshotsBufferSegmentCollection completedStackSnapshots = Volatile.Read(ref _completedStackSnapshots); return(completedStackSnapshots); }