XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using XFESystem.Collections;
namespace XFESystem.Browser;

public sealed partial class BrowserService
{
    public BrowserDomLifetime? ReadLifetimeDiagnostics()=>WithGate(()=>dom?.Lifetime);
    public WeakCollectionLifetime? ReadWeakCollectionLifetime()=>WithGate(()=>runtime?.WeakCollectionLifetime);
    /// <summary>Only the current owner calls this. Background proxies schedule
    /// it on their worker after any indivisible script callback returns.</summary>
    public void Release()=>WithGate(()=>
    {
        ReleasePageOwners("Release");
        dom=null;runtime=null;document=null;displayList=null;metricCanvas=null;textMetrics=new BrowserFallbackTextMetrics();
        layoutEngine.ReleaseDocument();
        linkedStyles.Clear();pendingResources.Clear();scheduledResources.Clear();executedScripts.Clear();
        hoveredNode=pointerDownNode=null;resourceLoader=null;pageDiagnostics=null;ResetDocumentLoading();
        return 0;
    });

    // All callers already execute on the page's exclusive owner. Keep this
    // common path explicit: native cleanup cannot depend on finally/finalizers.
    private void ReleasePageOwners(string reason)
    {
        var previousDom=dom;var previousRuntime=runtime;
        var domBefore=previousDom?.Lifetime;
        var weakBefore=previousRuntime?.WeakCollectionLifetime;
        previousDom?.ReleaseRetainedState();previousRuntime?.Release();
        var domAfter=previousDom?.Lifetime;
        var weakAfter=previousRuntime?.WeakCollectionLifetime;
        // Drop each released owner before diagnostics. A throwing observer
        // must not leave a dead engine published or interrupt navigation.
        dom=null;runtime=null;
        string records="";
        if(domBefore is not null&&domAfter is not null)
            records="XFE_BROWSER_RELEASE|HandlesBefore|"+domBefore.OutstandingHandles+
                "|HandlesAfter|"+domAfter.OutstandingHandles+"\n";
        if(weakBefore is not null&&weakAfter is not null)
            records+="XFE_BROWSER_WEAK_RELEASE|TablesBefore|"+weakBefore.Tables+
                "|EntriesBefore|"+weakBefore.Entries+"|TablesAfter|"+weakAfter.Tables+
                "|EntriesAfter|"+weakAfter.Entries+"|Created|"+weakAfter.Created+
                "|Disposed|"+weakAfter.Disposed+"|OwnerHandlesCreated|"+weakAfter.TableHandlesCreated+
                "|OwnerHandlesDisposed|"+weakAfter.TableHandlesDisposed+"|Page|"+paintIdentity+"|Reason|"+reason+"\n";
        if(records.Length!=0)TraceReleasedOwner(records);
    }
    private void TraceReleasedOwner(string text)
    {
        try { Trace?.Invoke(text); }
        catch(Exception error)when(error is not OutOfMemoryException and not StackOverflowException)
        { /* Diagnostic observers do not own page cleanup. */ }
    }
}