105 lines
2.3 KiB
Objective-C
105 lines
2.3 KiB
Objective-C
//
|
|
// Copyright 2019 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
#import "SDSCrossProcess.h"
|
|
#import "DarwinNotificationCenter.h"
|
|
#import <SignalCoreKit/OWSAsserts.h>
|
|
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
// NOTE: CFNotificationCenterGetDarwinNotifyCenter() might offer a better / equivalent solution,
|
|
// but it wasn't working for me and so I moved on.
|
|
|
|
static pid_t localPid(void)
|
|
{
|
|
static dispatch_once_t onceToken;
|
|
static pid_t pid;
|
|
dispatch_once(&onceToken, ^{ pid = getpid(); });
|
|
return pid;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
@interface SDSCrossProcess ()
|
|
|
|
@property (nonatomic) int notifyToken;
|
|
|
|
@end
|
|
|
|
#pragma mark -
|
|
|
|
@implementation SDSCrossProcess
|
|
|
|
- (id)init
|
|
{
|
|
if (self = [super init]) {
|
|
self.notifyToken = DarwinNotificationInvalidObserver;
|
|
|
|
[self start];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[self stop];
|
|
}
|
|
|
|
- (void)start
|
|
{
|
|
[self stop];
|
|
|
|
__weak SDSCrossProcess *weakSelf = self;
|
|
self.notifyToken =
|
|
[DarwinNotificationCenter addObserverForName:DarwinNotificationName.sdsCrossProcess
|
|
queue:dispatch_get_main_queue()
|
|
usingBlock:^(int token) { [weakSelf handleNotification:token]; }];
|
|
}
|
|
|
|
- (void)handleNotification:(int)token
|
|
{
|
|
OWSAssertIsOnMainThread();
|
|
|
|
uint64_t fromPid = [DarwinNotificationCenter getStateForObserver:token];
|
|
BOOL isLocal = fromPid == (uint64_t)localPid();
|
|
if (isLocal) {
|
|
return;
|
|
}
|
|
|
|
if (self.callback) {
|
|
self.callback();
|
|
}
|
|
}
|
|
|
|
- (void)stop
|
|
{
|
|
if ([DarwinNotificationCenter isValidObserver:self.notifyToken]) {
|
|
[DarwinNotificationCenter removeObserver:self.notifyToken];
|
|
}
|
|
self.notifyToken = DarwinNotificationInvalidObserver;
|
|
}
|
|
|
|
- (void)notifyChangedAsync
|
|
{
|
|
dispatch_async(dispatch_get_main_queue(), ^{ [self notifyChanged]; });
|
|
}
|
|
|
|
- (void)notifyChanged
|
|
{
|
|
OWSAssertIsOnMainThread();
|
|
|
|
if (![DarwinNotificationCenter isValidObserver:self.notifyToken]) {
|
|
[self start];
|
|
}
|
|
|
|
[DarwinNotificationCenter setState:(uint64_t)localPid() forObserver:self.notifyToken];
|
|
[DarwinNotificationCenter postNotificationName:DarwinNotificationName.sdsCrossProcess];
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|