EventRepository is locked for all the time an event is dispatched

The change in TROCustomSessionManager.DeleteSession has been working steadily for the past two months, we are happy with it.
However, it is not enough as there is another potential deadlock when the timer in TROCustomSessionManager elapses. At that point, it calls TROCustomSessionManager.ClearSessions that starts by locking itself (fCritical.Enter) and then calls DoClearSessions
In my case, this goes into TROInMemorySessionManager that then calls TROCustomSessionManager.DeleteSession with an already locked session manager. This means that the call to DoNotifySessionsChangesListener is made with a locked session manager, which is exactly what we tried to avoid by doing the change mentioned above.
And in my case, sure enough, the event repository is locked, waiting for an event reply to come back. But this reply comes back in a thread that waits for the session manager to be free, effectively leading to a deadlock.

Now, the event repository is locked because we set BlockingEvents to true back in 2011 when it seemed to be required. The situation might have changed, I’ll evaluate reverting it back to its default value.
But still, even if this is no longer blocking, it may happen that the event repository is locked while the session manager is also from ClearSessions which is why I suggest the following change:

procedure DoClearSessions(aSessionIds: TROSessionIDs; OnlyExpired : boolean); virtual; abstract;

procedure TROCustomSessionManager.ClearSessions(OnlyExpired : boolean);
var
  lRetry: Boolean;
begin
  CreateTimerByRequest;
  try
    fClearing := True;
    lRetry := True;
    while lRetry do begin
      lRetry := False;
      try
        DoClearSessions(GetAllSessions, OnlyExpired);
      except
        on e: Exception do begin
          if assigned(fOnException) then fOnException(EmptyGUID, e, lRetry);
          if not lRetry then raise;
        end;
      end;
    end;
  finally
    fClearing := False;
  end;
end;

procedure TROInMemorySessionManager.DoClearSessions(aSessionIds: TROSessionIDs; OnlyExpired: boolean);
var
  i : integer;
begin
  if OnlyExpired then begin
    for i := Low(aSessionIds) to High(aSessionIds) do
      if CheckSessionIsExpired(aSessionIds[i]) then  DeleteSession(aSessionIds[i], True);
  end
  else begin
    for i := Low(aSessionIds) to High(aSessionIds) do
      DeleteSession(aSessionIds[i], True);
  end;
end;

Basically, remove the lock in TROCustomSessionManager.ClearSessions and pass the list of session IDs to DoClearSessions so that it can work on them without being locked.