mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
Fixed double release of item event objects
This commit is contained in:
parent
a450f6e616
commit
4307e4a0f7
@ -38,14 +38,14 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
if (o == null)
|
if (o == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
IBase wrapper = CreateWrapper(o);
|
IBase wrapper = CreateWrapper(o, mustRelease);
|
||||||
if (wrapper != null)
|
if (wrapper != null)
|
||||||
wrapper.MustRelease = mustRelease;
|
wrapper.MustRelease = mustRelease;
|
||||||
ComRelease.LogWrapper(o, wrapper);
|
ComRelease.LogWrapper(o, wrapper);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBase CreateWrapper(object o)
|
private static IBase CreateWrapper(object o, bool mustRelease)
|
||||||
{
|
{
|
||||||
// TODO: switch on o.Class
|
// TODO: switch on o.Class
|
||||||
if (o is NSOutlook.MailItem)
|
if (o is NSOutlook.MailItem)
|
||||||
@ -64,9 +64,11 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
return new TaskItemWrapper((NSOutlook.TaskItem)o);
|
return new TaskItemWrapper((NSOutlook.TaskItem)o);
|
||||||
|
|
||||||
// TODO: support others?
|
// TODO: support others?
|
||||||
// The caller assumes a wrapper will be returned, so any lingering object here will never be released.
|
if (mustRelease)
|
||||||
// TODO: do this only if caller has mustRelease
|
{
|
||||||
ComRelease.Release(o);
|
// The caller assumes a wrapper will be returned, so any lingering object here will never be released.
|
||||||
|
ComRelease.Release(o);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +77,7 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
{
|
{
|
||||||
return (Type)Wrap(o, mustRelease);
|
return (Type)Wrap(o, mustRelease);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: are these not the same now? Differ only on wrong type?
|
// TODO: are these not the same now? Differ only on wrong type?
|
||||||
public static Type WrapOrDefault<Type>(object o, bool mustRelease = true)
|
public static Type WrapOrDefault<Type>(object o, bool mustRelease = true)
|
||||||
where Type : IBase
|
where Type : IBase
|
||||||
|
@ -73,7 +73,7 @@ namespace Acacia.Utils
|
|||||||
Logger.Instance.TraceExtra(typeof(ComRelease), "Releasing object: {0:X} @ {1}", GetObjAddress(o),
|
Logger.Instance.TraceExtra(typeof(ComRelease), "Releasing object: {0:X} @ {1}", GetObjAddress(o),
|
||||||
new System.Diagnostics.StackTrace());
|
new System.Diagnostics.StackTrace());
|
||||||
}
|
}
|
||||||
Marshal.ReleaseComObject(o);
|
Marshal.FinalReleaseComObject(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long GetObjAddress(object o)
|
private static long GetObjAddress(object o)
|
||||||
|
@ -208,6 +208,8 @@ namespace Acacia.Utils
|
|||||||
|
|
||||||
#region Implementation
|
#region Implementation
|
||||||
|
|
||||||
|
private readonly HashSet<MailEventHooker> _keepAlives = new HashSet<MailEventHooker>();
|
||||||
|
|
||||||
public MailEvents(IAddIn app)
|
public MailEvents(IAddIn app)
|
||||||
{
|
{
|
||||||
app.ItemLoad += OnItemLoad;
|
app.ItemLoad += OnItemLoad;
|
||||||
@ -219,21 +221,25 @@ namespace Acacia.Utils
|
|||||||
NSOutlook.ItemEvents_10_Event hasEvents = item as NSOutlook.ItemEvents_10_Event;
|
NSOutlook.ItemEvents_10_Event hasEvents = item as NSOutlook.ItemEvents_10_Event;
|
||||||
if (hasEvents != null)
|
if (hasEvents != null)
|
||||||
{
|
{
|
||||||
new MailEventHooker(hasEvents, this);
|
_keepAlives.Add(new MailEventHooker(item, hasEvents, this));
|
||||||
}
|
}
|
||||||
|
else ComRelease.Release(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MailEventHooker : ComWrapper
|
private class MailEventHooker : ComWrapper
|
||||||
{
|
{
|
||||||
private NSOutlook.ItemEvents_10_Event _item;
|
private object _item;
|
||||||
|
private NSOutlook.ItemEvents_10_Event _itemEvents;
|
||||||
private readonly MailEvents _events;
|
private readonly MailEvents _events;
|
||||||
|
// TODO: remove id and debug logging
|
||||||
private int _id;
|
private int _id;
|
||||||
private static int nextId;
|
private static int nextId;
|
||||||
|
|
||||||
public MailEventHooker(NSOutlook.ItemEvents_10_Event item, MailEvents events)
|
public MailEventHooker(object item, NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events)
|
||||||
{
|
{
|
||||||
this._id = ++nextId;
|
this._id = ++nextId;
|
||||||
this._item = item;
|
this._item = item;
|
||||||
|
this._itemEvents = itemEvents;
|
||||||
this._events = events;
|
this._events = events;
|
||||||
HookEvents(true);
|
HookEvents(true);
|
||||||
}
|
}
|
||||||
@ -241,57 +247,67 @@ namespace Acacia.Utils
|
|||||||
protected override void DoRelease()
|
protected override void DoRelease()
|
||||||
{
|
{
|
||||||
Logger.Instance.Debug(this, "DoRelease: {0}", _id);
|
Logger.Instance.Debug(this, "DoRelease: {0}", _id);
|
||||||
|
|
||||||
|
_events._keepAlives.Remove(this);
|
||||||
|
|
||||||
ComRelease.Release(_item);
|
ComRelease.Release(_item);
|
||||||
_item = null;
|
_item = null;
|
||||||
|
ComRelease.Release(_itemEvents);
|
||||||
|
_itemEvents = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HookEvents(bool add)
|
private void HookEvents(bool add)
|
||||||
{
|
{
|
||||||
if (add)
|
if (add)
|
||||||
{
|
{
|
||||||
_item.BeforeDelete += HandleBeforeDelete;
|
_itemEvents.BeforeDelete += HandleBeforeDelete;
|
||||||
_item.Forward += HandleForward;
|
_itemEvents.Forward += HandleForward;
|
||||||
_item.Read += HandleRead;
|
_itemEvents.Read += HandleRead;
|
||||||
_item.Reply += HandleReply;
|
_itemEvents.Reply += HandleReply;
|
||||||
_item.ReplyAll += HandleReplyAll;
|
_itemEvents.ReplyAll += HandleReplyAll;
|
||||||
_item.Unload += HandleUnload;
|
_itemEvents.Unload += HandleUnload;
|
||||||
_item.Write += HandleWrite;
|
_itemEvents.Write += HandleWrite;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_item.BeforeDelete -= HandleBeforeDelete;
|
_itemEvents.BeforeDelete -= HandleBeforeDelete;
|
||||||
_item.Forward -= HandleForward;
|
_itemEvents.Forward -= HandleForward;
|
||||||
_item.Read -= HandleRead;
|
_itemEvents.Read -= HandleRead;
|
||||||
_item.Reply -= HandleReply;
|
_itemEvents.Reply -= HandleReply;
|
||||||
_item.ReplyAll -= HandleReplyAll;
|
_itemEvents.ReplyAll -= HandleReplyAll;
|
||||||
_item.Unload -= HandleUnload;
|
_itemEvents.Unload -= HandleUnload;
|
||||||
_item.Write -= HandleWrite;
|
_itemEvents.Write -= HandleWrite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleBeforeDelete(object item, ref bool cancel)
|
private void HandleBeforeDelete(object item, ref bool cancel)
|
||||||
{
|
{
|
||||||
|
Logger.Instance.Debug(this, "HandleBeforeDelete: {0}", _id);
|
||||||
_events.OnBeforeDelete(item, ref cancel);
|
_events.OnBeforeDelete(item, ref cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleForward(object response, ref bool cancel)
|
private void HandleForward(object response, ref bool cancel)
|
||||||
{
|
{
|
||||||
_events.OnForward(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
Logger.Instance.Debug(this, "HandleForward: {0}", _id);
|
||||||
|
_events.OnForward(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleRead()
|
private void HandleRead()
|
||||||
{
|
{
|
||||||
_events.OnRead(_item as NSOutlook.MailItem);
|
Logger.Instance.Debug(this, "HandleRead: {0}", _id);
|
||||||
|
_events.OnRead(_itemEvents as NSOutlook.MailItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleReply(object response, ref bool cancel)
|
private void HandleReply(object response, ref bool cancel)
|
||||||
{
|
{
|
||||||
_events.OnReply(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
Logger.Instance.Debug(this, "HandleReply: {0}", _id);
|
||||||
|
_events.OnReply(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleReplyAll(object response, ref bool cancel)
|
private void HandleReplyAll(object response, ref bool cancel)
|
||||||
{
|
{
|
||||||
_events.OnReplyAll(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id);
|
||||||
|
_events.OnReplyAll(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleUnload()
|
private void HandleUnload()
|
||||||
@ -305,7 +321,7 @@ namespace Acacia.Utils
|
|||||||
private void HandleWrite(ref bool cancel)
|
private void HandleWrite(ref bool cancel)
|
||||||
{
|
{
|
||||||
Logger.Instance.Debug(this, "HandleWrite: {0}", _id);
|
Logger.Instance.Debug(this, "HandleWrite: {0}", _id);
|
||||||
_events.OnWrite(_item, ref cancel);
|
_events.OnWrite(_itemEvents, ref cancel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user