@@ -1010,7 +1010,7 @@ -(void) disconnectWithStreamError:(MLXMLNode* _Nullable) streamError andExplicit
10101010
10111011 // reset smacks state to sane values (this can be done even if smacks is not supported)
10121012 [self initSM3 ];
1013- self. unAckedStanzas = stanzas;
1013+ [ self replaceUnackedStanzasWith: stanzas] ;
10141014
10151015 // inform all old iq handlers of invalidation and clear _iqHandlers dictionary afterwards
10161016 @synchronized (self->_iqHandlers ) {
@@ -1142,7 +1142,7 @@ -(void) disconnectWithStreamError:(MLXMLNode* _Nullable) streamError andExplicit
11421142
11431143 // reset smacks state to sane values (this can be done even if smacks is not supported)
11441144 [self initSM3 ];
1145- self. unAckedStanzas = stanzas;
1145+ [ self replaceUnackedStanzasWith: stanzas] ;
11461146
11471147 // inform all old iq handlers of invalidation and clear _iqHandlers dictionary afterwards
11481148 @synchronized (self->_iqHandlers ) {
@@ -1670,7 +1670,7 @@ -(void) resendUnackedStanzas
16701670 self.lastOutboundStanza = [NSNumber numberWithInteger: [self .lastOutboundStanza integerValue ] - [self .unAckedStanzas count ]];
16711671 // Send appends to the unacked stanzas. Not removing it now will create an infinite loop.
16721672 // It may also result in mutation on iteration
1673- [self .unAckedStanzas removeAllObjects ];
1673+ [self replaceUnackedStanzasWith: [ NSMutableArray new ] ];
16741674 for (NSDictionary * dic in sendCopy)
16751675 [self send: (XMPPStanza*)[dic objectForKey: kStanza ]];
16761676 DDLogInfo (@" Done resending unacked stanzas..." );
@@ -1804,7 +1804,7 @@ -(BOOL) removeAckedStanzasFromQueue:(NSNumber*) hvalue
18041804 }
18051805
18061806 [iterationArray removeObjectsInArray: discard];
1807- self. unAckedStanzas = iterationArray;
1807+ [ self replaceUnackedStanzasWith: iterationArray] ;
18081808
18091809 // persist these changes (but only if we actually made some changes)
18101810 if ([discard count ])
@@ -3823,6 +3823,7 @@ -(void) realReadState
38233823 NSMutableDictionary * dic = [[DataLayer sharedInstance ] readStateForAccount: self .accountNo];
38243824 if (dic)
38253825 {
3826+ DDLogError (@" Inside dic if..." );
38263827 // check state version
38273828 int oldVersion = [dic[@" VERSION" ] intValue ];
38283829 if (oldVersion != STATE_VERSION)
@@ -3835,150 +3836,188 @@ -(void) realReadState
38353836 self.hasSeenOmemoDeviceListAfterOwnDeviceid = YES ;
38363837 }
38373838
3839+ DDLogError (@" Collecting smacks state..." );
38383840 // collect smacks state
38393841 self.lastHandledInboundStanza = [dic objectForKey: @" lastHandledInboundStanza" ];
38403842 self.lastHandledOutboundStanza = [dic objectForKey: @" lastHandledOutboundStanza" ];
38413843 self.lastOutboundStanza = [dic objectForKey: @" lastOutboundStanza" ];
3844+ DDLogError (@" Collecting stanzas..." );
38423845 NSArray * stanzas = [dic objectForKey: @" unAckedStanzas" ];
3843- self.unAckedStanzas = [stanzas mutableCopy ];
3846+ [self replaceUnackedStanzasWith: [stanzas mutableCopy ]];
3847+ DDLogError (@" Done collecting stanzas..." );
38443848 self.streamID = [dic objectForKey: @" streamID" ];
38453849 if ([dic objectForKey: @" isDoingFullReconnect" ])
38463850 {
3851+ DDLogError (@" Inside is doing full reconnect..." );
38473852 NSNumber * isDoingFullReconnect = [dic objectForKey: @" isDoingFullReconnect" ];
38483853 self.isDoingFullReconnect = isDoingFullReconnect.boolValue ;
38493854 }
38503855
3856+ DDLogError (@" Checking for corrupt smacks state..." );
38513857 // invalidate corrupt smacks states (this could potentially loose messages, but hey, the state is corrupt anyways)
38523858 if (self.lastHandledInboundStanza == nil || self.lastHandledOutboundStanza == nil || self.lastOutboundStanza == nil || !self.unAckedStanzas )
38533859 {
3860+ DDLogError (@" Inside corrupt smacks state..." );
38543861#ifndef IS_ALPHA
38553862 [self initSM3 ];
38563863#else
38573864 @throw [NSException exceptionWithName: @" RuntimeError" reason: @" corrupt smacks state" userInfo: dic];
38583865#endif
38593866 }
38603867
3868+ DDLogError (@" Handling iq handlers..." );
38613869 NSDictionary * persistentIqHandlers = [dic objectForKey: @" iqHandlers" ];
38623870 NSMutableDictionary * persistentIqHandlerDescriptions = [NSMutableDictionary new ];
3871+ DDLogError (@" Before iq handlers @synchronized..." );
38633872 @synchronized (_iqHandlers) {
3873+ DDLogError (@" Inside iq handlers @synchronized..." );
38643874 // remove all current persistent handlers...
38653875 NSMutableDictionary * handlersCopy = [_iqHandlers copy ];
38663876 for (NSString * iqid in handlersCopy)
38673877 if (handlersCopy[iqid][@" handler" ] != nil )
38683878 [_iqHandlers removeObjectForKey: iqid];
3879+ DDLogError (@" all persistent handlers removed..." );
38693880 // ...and replace them with persistent handlers loaded from state
38703881 for (NSString * iqid in persistentIqHandlers)
38713882 {
38723883 _iqHandlers[iqid] = [persistentIqHandlers[iqid] mutableCopy ];
38733884 persistentIqHandlerDescriptions[iqid] = [NSString stringWithFormat: @" %@ : %@ " , persistentIqHandlers[iqid][@" timeout" ], persistentIqHandlers[iqid][@" handler" ]];
38743885 }
3886+ DDLogError (@" replaced persistent handlers from state..." );
38753887 }
38763888
3889+ DDLogError (@" after iq handers @synchronized and before reconnection handlers @synchronized..." );
3890+
38773891 @synchronized (self->_reconnectionHandlers ) {
3892+ DDLogError (@" inside reconnection handlers @synchronized..." );
38783893 [_reconnectionHandlers removeAllObjects ];
38793894 [_reconnectionHandlers addObjectsFromArray: [dic objectForKey: @" reconnectionHandlers" ]];
3895+ DDLogError (@" did work..." );
38803896 }
3897+ DDLogError (@" after reconnection handlers @synchronized..." );
38813898
38823899 self.connectionProperties .serverFeatures = [dic objectForKey: @" serverFeatures" ];
38833900 self.connectionProperties .serverDiscoFeatures = [dic objectForKey: @" serverDiscoFeatures" ];
38843901 self.connectionProperties .accountDiscoFeatures = [dic objectForKey: @" accountDiscoFeatures" ];
3902+ DDLogError (@" after disco update 1..." );
38853903
38863904 self.connectionProperties .discoveredServices = [[dic objectForKey: @" discoveredServices" ] mutableCopy ];
38873905 self.connectionProperties .discoveredStunTurnServers = [[dic objectForKey: @" discoveredStunTurnServers" ] mutableCopy ];
38883906 self.connectionProperties .discoveredAdhocCommands = [[dic objectForKey: @" discoveredAdhocCommands" ] mutableCopy ];
38893907 self.connectionProperties .serverVersion = [dic objectForKey: @" serverVersion" ];
3908+ DDLogError (@" after disco upodate 2..." );
38903909
38913910 self.connectionProperties .uploadServer = [dic objectForKey: @" uploadServer" ];
38923911 self.connectionProperties .conferenceServers = [[dic objectForKey: @" conferenceServers" ] mutableCopy ];
3912+ DDLogError (@" after server update..." );
38933913
38943914 if ([dic objectForKey: @" loggedInOnce" ])
38953915 {
38963916 NSNumber * loggedInOnce = [dic objectForKey: @" loggedInOnce" ];
38973917 _loggedInOnce = loggedInOnce.boolValue ;
38983918 }
3919+ DDLogError (@" after logged in once..." );
38993920
39003921 if ([dic objectForKey: @" usingCarbons2" ])
39013922 {
39023923 NSNumber * carbonsNumber = [dic objectForKey: @" usingCarbons2" ];
39033924 self.connectionProperties .usingCarbons2 = carbonsNumber.boolValue ;
39043925 }
3926+ DDLogError (@" after carbons2..." );
39053927
39063928 if ([dic objectForKey: @" supportsBookmarksCompat" ])
39073929 {
39083930 NSNumber * compatNumber = [dic objectForKey: @" supportsBookmarksCompat" ];
39093931 self.connectionProperties .supportsBookmarksCompat = compatNumber.boolValue ;
39103932 }
3933+ DDLogError (@" after bookmarks compat..." );
39113934
39123935 if ([dic objectForKey: @" pushEnabled" ])
39133936 {
39143937 NSNumber * pushEnabled = [dic objectForKey: @" pushEnabled" ];
39153938 self.connectionProperties .pushEnabled = pushEnabled.boolValue ;
39163939 }
3940+ DDLogError (@" after push enabled..." );
39173941
39183942 if ([dic objectForKey: @" supportsPubSub" ])
39193943 {
39203944 NSNumber * supportsPubSub = [dic objectForKey: @" supportsPubSub" ];
39213945 self.connectionProperties .supportsPubSub = supportsPubSub.boolValue ;
39223946 }
3947+ DDLogError (@" after supports push..." );
39233948
39243949 if ([dic objectForKey: @" supportsPubSubMax" ])
39253950 {
39263951 NSNumber * supportsPubSubMax = [dic objectForKey: @" supportsPubSubMax" ];
39273952 self.connectionProperties .supportsPubSubMax = supportsPubSubMax.boolValue ;
39283953 }
3954+ DDLogError (@" after supports pubsub max..." );
39293955
39303956 if ([dic objectForKey: @" supportsModernPubSub" ])
39313957 {
39323958 NSNumber * supportsModernPubSub = [dic objectForKey: @" supportsModernPubSub" ];
39333959 self.connectionProperties .supportsModernPubSub = supportsModernPubSub.boolValue ;
39343960 }
3961+ DDLogError (@" after supports modern pubsub..." );
39353962
39363963 if ([dic objectForKey: @" supportsHTTPUpload" ])
39373964 {
39383965 NSNumber * supportsHTTPUpload = [dic objectForKey: @" supportsHTTPUpload" ];
39393966 self.connectionProperties .supportsHTTPUpload = supportsHTTPUpload.boolValue ;
39403967 }
3968+ DDLogError (@" after supports http upload..." );
39413969
39423970 if ([dic objectForKey: @" lastInteractionDate" ])
39433971 _lastInteractionDate = [dic objectForKey: @" lastInteractionDate" ];
3972+ DDLogError (@" after last interaction date..." );
39443973
39453974 if ([dic objectForKey: @" accountDiscoDone" ])
39463975 {
39473976 NSNumber * accountDiscoDone = [dic objectForKey: @" accountDiscoDone" ];
39483977 self.connectionProperties .accountDiscoDone = accountDiscoDone.boolValue ;
39493978 }
3979+ DDLogError (@" after account disco done..." );
39503980
39513981 if ([dic objectForKey: @" pubsubData" ])
39523982 [self .pubsub setInternalData: [dic objectForKey: @" pubsubData" ]];
3983+ DDLogError (@" after pubsub data..." );
39533984
39543985 if ([dic objectForKey: @" mucState" ])
39553986 [self .mucProcessor setInternalState: [dic objectForKey: @" mucState" ]];
3987+ DDLogError (@" after muc state..." );
39563988
39573989 if ([dic objectForKey: @" runningCapsQueries" ])
39583990 _runningCapsQueries = [[dic objectForKey: @" runningCapsQueries" ] mutableCopy ];
3991+ DDLogError (@" after running caps queries..." );
39593992
39603993 if ([dic objectForKey: @" runningMamQueries" ])
39613994 _runningMamQueries = [[dic objectForKey: @" runningMamQueries" ] mutableCopy ];
3995+ DDLogError (@" after runing mam queries..." );
39623996
39633997 if ([dic objectForKey: @" inCatchup" ])
39643998 _inCatchup = [[dic objectForKey: @" inCatchup" ] mutableCopy ];
3999+ DDLogError (@" after in catchup..." );
39654000
39664001 if ([dic objectForKey: @" mdsData" ])
39674002 _mdsData = [[dic objectForKey: @" mdsData" ] mutableCopy ];
4003+ DDLogError (@" after mds data..." );
39684004
39694005 if ([dic objectForKey: @" cachedStreamFeaturesBeforeAuth" ])
39704006 _cachedStreamFeaturesBeforeAuth = [dic objectForKey: @" cachedStreamFeaturesBeforeAuth" ];
39714007 if ([dic objectForKey: @" cachedStreamFeaturesAfterAuth" ])
39724008 _cachedStreamFeaturesAfterAuth = [dic objectForKey: @" cachedStreamFeaturesAfterAuth" ];
4009+ DDLogError (@" after cached features..." );
39734010
39744011 if ([dic objectForKey: @" omemoState" ] && self.omemo )
39754012 self.omemo .state = [dic objectForKey: @" omemoState" ];
4013+ DDLogError (@" after omemo state..." );
39764014
39774015 if ([dic objectForKey: @" hasSeenOmemoDeviceListAfterOwnDeviceid" ])
39784016 {
39794017 NSNumber * hasSeenOmemoDeviceListAfterOwnDeviceid = [dic objectForKey: @" hasSeenOmemoDeviceListAfterOwnDeviceid" ];
39804018 self.hasSeenOmemoDeviceListAfterOwnDeviceid = hasSeenOmemoDeviceListAfterOwnDeviceid.boolValue ;
39814019 }
4020+ DDLogError (@" after has seen devicelist after own deviceid..." );
39824021
39834022 // debug output
39844023 DDLogVerbose (@" %@ --> readState(saved at %@ ):\n\t isDoingFullReconnect=%@ ,\n\t lastHandledInboundStanza=%@ ,\n\t lastHandledOutboundStanza=%@ ,\n\t lastOutboundStanza=%@ ,\n\t #unAckedStanzas=%lu%s ,\n\t streamID=%@ ,\n\t lastInteractionDate=%@ \n\t persistentIqHandlers=%@ \n\t supportsHttpUpload=%d \n\t pushEnabled=%d \n\t supportsPubSub=%d \n\t supportsModernPubSub=%d \n\t supportsPubSubMax=%d \n\t supportsBookmarksCompat=%d \n\t accountDiscoDone=%d \n\t _inCatchup=%@ \n\t omemo.state=%@ \n\t hasSeenOmemoDeviceListAfterOwnDeviceid=%@ \n\t _cachedStreamFeaturesBeforeAuth=%@ \n\t _cachedStreamFeaturesAfterAuth=%@ \n " ,
@@ -4005,10 +4044,12 @@ -(void) realReadState
40054044 bool2str (self->_cachedStreamFeaturesBeforeAuth !=nil ),
40064045 bool2str (self->_cachedStreamFeaturesAfterAuth !=nil )
40074046 );
4047+ DDLogError (@" before printing unacked stanzas..." );
40084048 if (self.unAckedStanzas )
40094049 for (NSDictionary * dic in self.unAckedStanzas )
40104050 DDLogDebug (@" readState unAckedStanza %@ : %@ " , [dic objectForKey: kQueueID ], [dic objectForKey: kStanza ]);
40114051 }
4052+ DDLogError (@" after if dic..." );
40124053
40134054 // always reset handler and smacksRequestInFlight when loading smacks state
40144055 _smacksAckHandler = [NSMutableArray new ];
@@ -4074,14 +4115,32 @@ -(void) initSM3
40744115 self.lastHandledInboundStanza = [NSNumber numberWithInteger: 0 ];
40754116 self.lastHandledOutboundStanza = [NSNumber numberWithInteger: 0 ];
40764117 self.lastOutboundStanza = [NSNumber numberWithInteger: 0 ];
4077- self. unAckedStanzas = [NSMutableArray new ];
4118+ [ self replaceUnackedStanzasWith: [NSMutableArray new ] ];
40784119 self.streamID = nil ;
40794120 _smacksAckHandler = [NSMutableArray new ];
40804121 DDLogDebug (@" initSM3 done" );
40814122 }
40824123 DDLogVerbose (@" After @synchronized of _stateLockObject..." );
40834124}
40844125
4126+ -(NSMutableArray *) replaceUnackedStanzasWith : (NSMutableArray *) newUnackedStanzas
4127+ {
4128+ @synchronized (_stateLockObject) {
4129+ // this might take a long time since it throws away all self.unAckedStanzas and thus calls dealloc on each of them in each nesting level
4130+ // --> move deallocation into a background thread
4131+ NSMutableArray * __block oldUnacked = self.unAckedStanzas ;
4132+ self.unAckedStanzas = newUnackedStanzas;
4133+ dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_LOW, 0 ), ^{
4134+ DDLogVerbose (@" Sleeping 500ms before throwing away old unAckedStanzas..." );
4135+ [NSThread sleepForTimeInterval: 0.500 ];
4136+ DDLogVerbose (@" Now throwing away old unAckedStanzas..." );
4137+ oldUnacked = nil ;
4138+ DDLogVerbose (@" All old unAckedStanzas successfully deallocated now..." );
4139+ });
4140+ }
4141+ return newUnackedStanzas;
4142+ }
4143+
40854144-(void ) bindResource : (NSString *) resource
40864145{
40874146 if (resource == nil )
0 commit comments