Signal-iOS/SignalServiceKit/Storage/Database/SDSCrossProcess.m
Harry bb083ca39c
Fold SignalCoreKit into SignalServiceKit
Co-authored-by: Adam Sharp <sharplet@signal.org>
2024-06-26 08:44:41 -07:00

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 <SignalServiceKit/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