Skip to content

Commit 995c7eb

Browse files
6.4.19-rc1 (#1600)
- Accelerated connection establishment - Fixed joining of groups/channels after a longer period of being offline IOS_ONLY - Fixed long delay when sometimes answering an incoming call
2 parents 38a10a7 + 9b46360 commit 995c7eb

File tree

14 files changed

+485
-266
lines changed

14 files changed

+485
-266
lines changed

Monal/Classes/DataLayer.m

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -357,19 +357,11 @@ -(NSMutableDictionary*) readStateForAccount:(NSNumber*) accountNo
357357
return nil;
358358
NSString* query = @"SELECT state from account where account_id=?";
359359
NSArray* params = @[accountNo];
360-
DDLogVerbose(@"Outside of transaction: Reading account state: %@", accountNo);
361-
[MLSQLite debugTransactions];
362360
NSData* data = (NSData*)[self.db idReadTransaction:^{
363-
DDLogVerbose(@"Inside of transaction: Reading account state: %@", accountNo);
364361
return [self.db executeScalar:query andArguments:params];
365362
}];
366-
DDLogVerbose(@"After transaction: Reading account state: %@ --> %@", accountNo, data);
367363
if(data)
368-
{
369-
NSMutableDictionary* retval = [HelperTools unserializeData:data];
370-
DDLogVerbose(@"After unserializeData: Reading account state: %@", accountNo);
371-
return retval;
372-
}
364+
return [HelperTools unserializeData:data];
373365
return nil;
374366
}
375367

Monal/Classes/HelperTools.m

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -702,16 +702,18 @@ +(NSRunLoop*) getExtraRunloopWithIdentifier:(MLRunLoopIdentifier) identifier
702702
NSCondition* condition = [NSCondition new];
703703
[condition lock];
704704
NSThread* newRunloopThread = [[NSThread alloc] initWithBlock:^{
705-
//we don't need an @synchronized block around this because the @synchronized block of the outer thread
706-
//waits until we signal our condition (e.g. no other thread can race with us)
707-
NSRunLoop* localLoop = runloops[@(identifier)] = [NSRunLoop currentRunLoop];
708-
[condition lock];
709-
[condition signal];
710-
[condition unlock];
711-
while(YES)
712-
{
713-
[localLoop run];
714-
usleep(10000); //sleep 10ms if we ever return from our runloop to not consume too much cpu
705+
@autoreleasepool {
706+
//we don't need an @synchronized block around this because the @synchronized block of the outer thread
707+
//waits until we signal our condition (e.g. no other thread can race with us)
708+
NSRunLoop* localLoop = runloops[@(identifier)] = [NSRunLoop currentRunLoop];
709+
[condition lock];
710+
[condition signal];
711+
[condition unlock];
712+
while(YES)
713+
{
714+
[localLoop run];
715+
usleep(10000); //sleep 10ms if we ever return from our runloop to not consume too much cpu
716+
}
715717
}
716718
}];
717719
//configure and start thread

Monal/Classes/IPC.m

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -199,56 +199,58 @@ -(id) initWithProcessName:(NSString*) processName
199199

200200
-(void) serverThreadMain
201201
{
202-
DDLogInfo(@"Now running IPC server for '%@' with thread priority %f...", _processName, [NSThread threadPriority]);
203-
//register darwin notification handler for "im.monal.ipc.wakeup:<process name>" which is used to wake up readNextMessage using the NSCondition
204-
CFNotificationCenterAddObserver(_darwinNotificationCenterRef, (__bridge void*) self, &darwinNotificationCenterCallback, (__bridge CFNotificationName)[NSString stringWithFormat:@"im.monal.ipc.wakeup:%@", _processName], NULL, 0);
205-
CFNotificationCenterAddObserver(_darwinNotificationCenterRef, (__bridge void*) self, &darwinNotificationCenterCallback, (__bridge CFNotificationName)@"im.monal.ipc.wakeup:*", NULL, 0);
206-
while(![[NSThread currentThread] isCancelled])
207-
{
208-
NSDictionary* message = [self readNextMessage]; //this will be blocking
209-
if(!message)
210-
continue;
211-
DDLogDebug(@"Got IPC message: %@", message);
212-
213-
//use a dedicated serial queue for every IPC receiver to maintain IPC message ordering while not blocking other receivers or this serverThread)
214-
NSArray* parts = [message[@"name"] componentsSeparatedByString:@"."];
215-
NSString* queueName = [parts objectAtIndex:0];
216-
if(!queueName || [parts count]<2)
217-
queueName = @"_default";
218-
queueName = [NSString stringWithFormat:@"ipc.queue:%@", queueName];
219-
if(!_ipcQueues[queueName])
220-
_ipcQueues[queueName] = dispatch_queue_create([queueName cStringUsingEncoding:NSUTF8StringEncoding], dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0));
221-
222-
//handle all responses (don't trigger a kMonalIncomingIPC for responses)
223-
if(message[@"response_to"] && [message[@"response_to"] intValue] > 0)
202+
@autoreleasepool {
203+
DDLogInfo(@"Now running IPC server for '%@' with thread priority %f...", _processName, [NSThread threadPriority]);
204+
//register darwin notification handler for "im.monal.ipc.wakeup:<process name>" which is used to wake up readNextMessage using the NSCondition
205+
CFNotificationCenterAddObserver(_darwinNotificationCenterRef, (__bridge void*) self, &darwinNotificationCenterCallback, (__bridge CFNotificationName)[NSString stringWithFormat:@"im.monal.ipc.wakeup:%@", _processName], NULL, 0);
206+
CFNotificationCenterAddObserver(_darwinNotificationCenterRef, (__bridge void*) self, &darwinNotificationCenterCallback, (__bridge CFNotificationName)@"im.monal.ipc.wakeup:*", NULL, 0);
207+
while(![[NSThread currentThread] isCancelled])
224208
{
225-
//call response handler if one is present (ignore the spurious response otherwise)
226-
if(_responseHandlers[message[@"response_to"]])
209+
NSDictionary* message = [self readNextMessage]; //this will be blocking
210+
if(!message)
211+
continue;
212+
DDLogDebug(@"Got IPC message: %@", message);
213+
214+
//use a dedicated serial queue for every IPC receiver to maintain IPC message ordering while not blocking other receivers or this serverThread)
215+
NSArray* parts = [message[@"name"] componentsSeparatedByString:@"."];
216+
NSString* queueName = [parts objectAtIndex:0];
217+
if(!queueName || [parts count]<2)
218+
queueName = @"_default";
219+
queueName = [NSString stringWithFormat:@"ipc.queue:%@", queueName];
220+
if(!_ipcQueues[queueName])
221+
_ipcQueues[queueName] = dispatch_queue_create([queueName cStringUsingEncoding:NSUTF8StringEncoding], dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0));
222+
223+
//handle all responses (don't trigger a kMonalIncomingIPC for responses)
224+
if(message[@"response_to"] && [message[@"response_to"] intValue] > 0)
227225
{
228-
IPC_response_handler_t responseHandler = (IPC_response_handler_t)_responseHandlers[message[@"response_to"]];
229-
if(responseHandler)
226+
//call response handler if one is present (ignore the spurious response otherwise)
227+
if(_responseHandlers[message[@"response_to"]])
230228
{
231-
//responses handlers are only valid for the maximum RTT of messages (+ some safety margin)
232-
createTimer(MSG_TIMEOUT*2 + 1, (^{
233-
[_responseHandlers removeObjectForKey:message[@"response_to"]];
234-
}));
235-
dispatch_async(_ipcQueues[queueName], ^{
236-
responseHandler(message);
237-
});
229+
IPC_response_handler_t responseHandler = (IPC_response_handler_t)_responseHandlers[message[@"response_to"]];
230+
if(responseHandler)
231+
{
232+
//responses handlers are only valid for the maximum RTT of messages (+ some safety margin)
233+
createTimer(MSG_TIMEOUT*2 + 1, (^{
234+
[_responseHandlers removeObjectForKey:message[@"response_to"]];
235+
}));
236+
dispatch_async(_ipcQueues[queueName], ^{
237+
responseHandler(message);
238+
});
239+
}
238240
}
239241
}
242+
else //publish all non-responses (using the message name as object allows for filtering by ipc message name)
243+
dispatch_async(_ipcQueues[queueName], ^{
244+
[[NSNotificationCenter defaultCenter] postNotificationName:kMonalIncomingIPC object:message[@"name"] userInfo:message];
245+
});
246+
247+
DDLogDebug(@"Handled IPC message: %@", message);
240248
}
241-
else //publish all non-responses (using the message name as object allows for filtering by ipc message name)
242-
dispatch_async(_ipcQueues[queueName], ^{
243-
[[NSNotificationCenter defaultCenter] postNotificationName:kMonalIncomingIPC object:message[@"name"] userInfo:message];
244-
});
245-
246-
DDLogDebug(@"Handled IPC message: %@", message);
249+
//unregister darwin notification handler
250+
CFNotificationCenterRemoveObserver(_darwinNotificationCenterRef, (__bridge void*) self, (__bridge CFNotificationName)[NSString stringWithFormat:@"im.monal.ipc.wakeup:%@", _processName], NULL);
251+
CFNotificationCenterRemoveObserver(_darwinNotificationCenterRef, (__bridge void*) self, (__bridge CFNotificationName)@"im.monal.ipc.wakeup:*", NULL);
252+
DDLogInfo(@"IPC server for '%@' now terminated", _processName);
247253
}
248-
//unregister darwin notification handler
249-
CFNotificationCenterRemoveObserver(_darwinNotificationCenterRef, (__bridge void*) self, (__bridge CFNotificationName)[NSString stringWithFormat:@"im.monal.ipc.wakeup:%@", _processName], NULL);
250-
CFNotificationCenterRemoveObserver(_darwinNotificationCenterRef, (__bridge void*) self, (__bridge CFNotificationName)@"im.monal.ipc.wakeup:*", NULL);
251-
DDLogInfo(@"IPC server for '%@' now terminated", _processName);
252254
}
253255

254256
-(void) incomingDarwinNotification:(NSString*) name

Monal/Classes/MLDelayedDealloc.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// MLDelayedDealloc.h
3+
// monalxmpp
4+
//
5+
// Created by Thilo Molitor on 04.03.26.
6+
// Copyright © 2026 Monal.im. All rights reserved.
7+
//
8+
9+
NS_ASSUME_NONNULL_BEGIN
10+
11+
@interface MLDelayedDealloc : NSObject
12+
13+
+(void) delayFor:(id) obj;
14+
15+
@end
16+
17+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)