Skip to content

Commit

Permalink
Address potential races in recent event changes (#882)
Browse files Browse the repository at this point in the history
* Change ordering of delegate registration.

* Fix potential race.

* Address PR feedback.
  • Loading branch information
manodasanW authored Jun 17, 2021
1 parent ea43282 commit d607f3e
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 9 deletions.
5 changes: 3 additions & 2 deletions src/cswinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -6488,11 +6488,12 @@ bind<write_type_name>(type, typedef_name_type::CCW, true)
{
handler = (%) =>
{
if (_state.del == null)
var localDel = _state.del;
if (localDel == null)
{
return %;
}
%_state.del.Invoke(%);
%localDel.Invoke(%);
};
}
return handler;
Expand Down
17 changes: 10 additions & 7 deletions src/cswinrt/strings/WinRT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,10 @@ public void Subscribe(TDelegate del)
{
lock (this)
{
if (_state.del is null)
bool registerHandler = _state.del is null;

_state.del = (TDelegate)global::System.Delegate.Combine(_state.del, del);
if (registerHandler)
{
var marshaler = CreateMarshaler((TDelegate)EventInvoke);
try
Expand All @@ -385,7 +388,6 @@ public void Subscribe(TDelegate del)
DisposeMarshaler(marshaler);
}
}
_state.del = (TDelegate)global::System.Delegate.Combine(_state.del, del);
}
}

Expand Down Expand Up @@ -445,10 +447,10 @@ private class Cache
}

private IWeakReference target;
private ConcurrentDictionary<int, EventSource<TDelegate>.State> states = new ConcurrentDictionary<int, EventSource<TDelegate>.State>();
private readonly ConcurrentDictionary<int, EventSource<TDelegate>.State> states = new ConcurrentDictionary<int, EventSource<TDelegate>.State>();

private static ReaderWriterLockSlim cachesLock = new ReaderWriterLockSlim();
private static ConcurrentDictionary<IntPtr, Cache> caches = new ConcurrentDictionary<IntPtr, Cache>();
private static readonly ReaderWriterLockSlim cachesLock = new ReaderWriterLockSlim();
private static readonly ConcurrentDictionary<IntPtr, Cache> caches = new ConcurrentDictionary<IntPtr, Cache>();

private Cache Update(IWeakReference target, EventSource<TDelegate> source, int index)
{
Expand Down Expand Up @@ -579,8 +581,9 @@ override protected System.Delegate EventInvoke
{
handler = (System.Object obj, T e) =>
{
if (_state.del != null)
_state.del.Invoke(obj, e);
var localDel = _state.del;
if (localDel != null)
localDel.Invoke(obj, e);
};
}
return handler;
Expand Down

0 comments on commit d607f3e

Please sign in to comment.