Compare commits
1 Commits
master
...
fix-timeou
Author | SHA1 | Date |
---|---|---|
![]() |
f5dd2d4811 |
|
@ -57,6 +57,12 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (NSArray<id<OTRProtocol>>*) allProtocols {
|
||||
@synchronized (self) {
|
||||
return [self.protocolManagers allValues];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeProtocolForAccount:(OTRAccount *)account
|
||||
{
|
||||
NSParameterAssert(account);
|
||||
|
@ -159,47 +165,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)disconnectAllAccountsSocketOnly:(BOOL)socketOnly timeout:(NSTimeInterval)timeout completionBlock:(nullable void (^)())completionBlock
|
||||
{
|
||||
@synchronized (self) {
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
NSMutableDictionary<NSString*, NSObject<OTRProtocol>*> *observingManagersForTokens = [NSMutableDictionary new];
|
||||
for (NSObject<OTRProtocol> *manager in self.protocolManagers.allValues) {
|
||||
OTRXMPPManager *xmpp = (OTRXMPPManager*)manager;
|
||||
NSParameterAssert([xmpp isKindOfClass:OTRXMPPManager.class]);
|
||||
if (![xmpp isKindOfClass:OTRXMPPManager.class]) {
|
||||
DDLogError(@"Wrong protocol class for manager %@", manager);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xmpp.loginStatus != OTRLoginStatusDisconnected) {
|
||||
dispatch_group_enter(group);
|
||||
NSString *token = [xmpp addObserverForKeyPath:NSStringFromSelector(@selector(loginStatus))
|
||||
options:0
|
||||
block:^(NSString *keyPath, OTRXMPPManager *mgr, NSDictionary *change) {
|
||||
if (mgr.loginStatus == OTRLoginStatusDisconnected) {
|
||||
dispatch_group_leave(group);
|
||||
}
|
||||
}];
|
||||
observingManagersForTokens[token] = manager;
|
||||
[manager disconnectSocketOnly:socketOnly];
|
||||
}
|
||||
}
|
||||
if (timeout > 0) {
|
||||
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t) (timeout * NSEC_PER_SEC)));
|
||||
}
|
||||
for (NSString *token in observingManagersForTokens.allKeys) {
|
||||
[observingManagersForTokens[token] removeObserverForToken:token];
|
||||
}
|
||||
if (completionBlock != nil) {
|
||||
completionBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)disconnectAllAccounts
|
||||
{
|
||||
[self disconnectAllAccountsSocketOnly:NO timeout:0 completionBlock:nil];
|
||||
[self disconnectAllAccountsSocketOnly:NO timeout:1 completionBlock:nil];
|
||||
}
|
||||
|
||||
- (void)protocolDidChange:(NSDictionary *)change
|
||||
|
|
|
@ -21,3 +21,36 @@ extension OTRProtocolManager {
|
|||
|
||||
@objc public static let pushController = PushController(baseURL: OTRProtocolManager.pushApiEndpoint, sessionConfiguration: URLSessionConfiguration.ephemeral)
|
||||
}
|
||||
|
||||
extension OTRProtocolManager {
|
||||
@objc(disconnectAllAccountsSocketOnly:timeout:completionBlock:)
|
||||
public func disconnectAllAccounts(socketOnly: Bool, timeout: TimeInterval, completion: (()->Void)? = nil) {
|
||||
let group = DispatchGroup()
|
||||
let tokens: [NSKeyValueObservation] = allProtocols
|
||||
.compactMap { $0 as? XMPPManager }
|
||||
.filter { $0.loginStatus != .disconnected }
|
||||
.map {
|
||||
group.enter()
|
||||
let token = $0.observe(\.loginStatus) { xmppManager, change in
|
||||
if xmppManager.loginStatus == .disconnected {
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
$0.disconnectSocketOnly(socketOnly)
|
||||
return token
|
||||
}
|
||||
DispatchQueue.global(qos: .default).async {
|
||||
let result = group.wait(timeout: .now() + timeout)
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .timedOut:
|
||||
DDLogWarn("Exceeded max time for disconnect")
|
||||
}
|
||||
tokens.forEach { $0.invalidate() }
|
||||
DispatchQueue.main.async {
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ extension OTRAppDelegate {
|
|||
OTRProtocolManager.shared.loginAccounts(OTRAccountsManager.allAutoLoginAccounts())
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 8, execute: {
|
||||
let timeout = 1.0
|
||||
OTRProtocolManager.shared.disconnectAllAccountsSocketOnly(true, timeout: timeout) {
|
||||
OTRProtocolManager.shared.disconnectAllAccounts(socketOnly: true, timeout: timeout) {
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.removeExtraForegroundNotifications()
|
||||
switch type {
|
||||
|
|
|
@ -35,6 +35,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property (atomic, readonly) NSUInteger numberOfConnectedProtocols;
|
||||
@property (atomic, readonly) NSUInteger numberOfConnectingProtocols;
|
||||
|
||||
@property (atomic, readonly) NSArray<id<OTRProtocol>>* allProtocols;
|
||||
|
||||
- (BOOL)existsProtocolForAccount:(OTRAccount *)account;
|
||||
- (nullable id <OTRProtocol>)protocolForAccount:(OTRAccount *)account;
|
||||
- (nullable OTRXMPPManager*)xmppManagerForAccount:(OTRAccount *)account;
|
||||
|
@ -48,7 +50,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
- (void)loginAccounts:(NSArray<OTRAccount*> *)accounts;
|
||||
- (void)goAwayForAllAccounts;
|
||||
- (void)disconnectAllAccounts;
|
||||
- (void)disconnectAllAccountsSocketOnly:(BOOL)socketOnly timeout:(NSTimeInterval)timeout completionBlock:(nullable void (^)())completionBlock;
|
||||
|
||||
- (void)sendMessage:(OTROutgoingMessage *)message;
|
||||
|
||||
|
|
Loading…
Reference in New Issue