Make ServiceScope IAsyncDisposable

ServiceScope.Dispose was not waiting for scoped services to complete
disposing. This had an effect of letting a new plugin instance register
a DtrBar entry before previous plugin instance's entry got unregistered.

This change also cleans up unloading procedure in LocalPlugin.
This commit is contained in:
Soreepeong 2024-08-18 07:58:45 +09:00
parent fdfdee1fcb
commit 0a8f9b73fb
7 changed files with 375 additions and 184 deletions

View file

@ -114,10 +114,42 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
{
if (existingEntry.Title == title)
{
existingEntry.ShouldBeRemoved = false;
if (existingEntry.ShouldBeRemoved)
{
if (plugin == existingEntry.OwnerPlugin)
{
Log.Debug(
"Reviving entry: {what}; owner: {plugin}({pluginId})",
title,
plugin?.InternalName,
plugin?.EffectiveWorkingPluginId);
}
else
{
Log.Debug(
"Reviving entry: {what}; old owner: {old}({oldId}); new owner: {new}({newId})",
title,
existingEntry.OwnerPlugin?.InternalName,
existingEntry.OwnerPlugin?.EffectiveWorkingPluginId,
plugin?.InternalName,
plugin?.EffectiveWorkingPluginId);
existingEntry.OwnerPlugin = plugin;
}
existingEntry.ShouldBeRemoved = false;
}
this.entriesLock.ExitUpgradeableReadLock();
if (plugin == existingEntry.OwnerPlugin)
return existingEntry;
Log.Debug(
"Entry already has a different owner: {what}; owner: {old}({oldId}); requester: {new}({newId})",
title,
existingEntry.OwnerPlugin?.InternalName,
existingEntry.OwnerPlugin?.EffectiveWorkingPluginId,
plugin?.InternalName,
plugin?.EffectiveWorkingPluginId);
throw new ArgumentException("An entry with the same title already exists.");
}
}
@ -125,6 +157,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
this.entriesLock.EnterWriteLock();
var entry = new DtrBarEntry(this.configuration, title, null) { Text = text, OwnerPlugin = plugin };
this.entries.Add(entry);
Log.Debug("Adding entry: {what}; owner: {owner}", title, plugin);
// Add the entry to the end of the order list, if it's not there already.
var dtrOrder = this.configuration.DtrOrder ??= [];
@ -159,14 +192,23 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
{
if (!entry.Added)
{
Log.Debug("Removing entry immediately because it is not added yet: {what}", entry.Title);
this.entriesLock.EnterWriteLock();
this.RemoveEntry(entry);
this.entries.Remove(entry);
this.entriesReadOnlyCopy = null;
this.entriesLock.ExitWriteLock();
}
else if (!entry.ShouldBeRemoved)
{
Log.Debug("Queueing entry for removal: {what}", entry.Title);
entry.Remove();
}
else
{
Log.Debug("Entry is already marked for removal: {what}", entry.Title);
}
entry.Remove();
break;
}
}
@ -313,6 +355,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
var data = this.entries[i];
if (data.ShouldBeRemoved)
{
Log.Debug("Removing entry from Framework.Update: {what}", data.Title);
this.entriesLock.EnterWriteLock();
this.entries.RemoveAt(i);
this.RemoveEntry(data);