Files
flipper/iOS/SonarKit/SonarClient.mm
John Knox cebc409da6 Change SonarInitConfig to take two EventBases
Summary:
We currently give sonar one event base from java / obj-c code to use for scheduling tasks.
This causes a problem, because we schedule reconnect tasks on the event base, and then these tasks interact with rsocket which schedules it's own tasks.
The problem is that we're passing rsocket the same event base. So the reconnect code executes and blocks waiting for rsocket to connect.
But rsocket can never connect because it never executes because that thread is blocked, so we get deadlock.

This is the first step which just changes the interface to pass two event bases.
The consumers will be changed to pass in different threads next.

Reviewed By: danielbuechele

Differential Revision: D8748350

fbshipit-source-id: 481d6f23644f28fd0f1c786252605287019c999c
2018-07-09 07:49:07 -07:00

126 lines
3.1 KiB
Plaintext

/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
#if FB_SONARKIT_ENABLED
#import "SonarClient.h"
#import "SonarCppWrapperPlugin.h"
#import <Sonar/SonarClient.h>
#include <folly/io/async/EventBase.h>
#include <folly/io/async/ScopedEventBaseThread.h>
#import <UIKit/UIKit.h>
#if !TARGET_OS_SIMULATOR
//#import "SKPortForwardingServer.h"
#endif
using WrapperPlugin = facebook::sonar::SonarCppWrapperPlugin;
@implementation SonarClient {
facebook::sonar::SonarClient *_cppClient;
folly::ScopedEventBaseThread sonarThread;
#if !TARGET_OS_SIMULATOR
// SKPortForwardingServer *_server;
#endif
}
+ (instancetype)sharedClient
{
static SonarClient *sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedClient = [[self alloc] init];
});
return sharedClient;
}
- (instancetype)init
{
if (self = [super init]) {
UIDevice *device = [UIDevice currentDevice];
NSString *deviceName = [device name];
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey];
NSString *deviceId = [[device identifierForVendor]UUIDString];
NSString *appId = appName;
NSString *privateAppDirectory = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:privateAppDirectory isDirectory:NULL] == NO) {
//TODO: Handle errors properly
[manager createDirectoryAtPath:privateAppDirectory withIntermediateDirectories:YES attributes:nil error:nil];
}
#if TARGET_OS_SIMULATOR
deviceName = [NSString stringWithFormat:@"%@ %@", [[UIDevice currentDevice] model], @"Simulator"];
#endif
facebook::sonar::SonarClient::init({
{
"localhost",
"iOS",
[deviceName UTF8String],
[deviceId UTF8String],
[appName UTF8String],
[appId UTF8String],
[privateAppDirectory UTF8String],
},
sonarThread.getEventBase(),
sonarThread.getEventBase()
});
_cppClient = facebook::sonar::SonarClient::instance();
}
return self;
}
- (void)refreshPlugins
{
_cppClient->refreshPlugins();
}
- (void)addPlugin:(NSObject<SonarPlugin> *)plugin
{
_cppClient->addPlugin(std::make_shared<WrapperPlugin>(plugin));
}
- (void)removePlugin:(NSObject<SonarPlugin> *)plugin
{
_cppClient->removePlugin(std::make_shared<WrapperPlugin>(plugin));
}
- (NSObject<SonarPlugin> *)pluginWithIdentifier:(NSString *)identifier
{
auto cppPlugin = _cppClient->getPlugin([identifier UTF8String]);
if (auto wrapper = dynamic_cast<WrapperPlugin *>(cppPlugin.get())) {
return wrapper->getObjCPlugin();
}
return nil;
}
- (void)start;
{
#if !TARGET_OS_SIMULATOR
// _server = [SKPortForwardingServer new];
// [_server forwardConnectionsFromPort:8088];
// [_server listenForMultiplexingChannelOnPort:8078];
#endif
_cppClient->start();
}
- (void)stop
{
_cppClient->stop();
#if !TARGET_OS_SIMULATOR
// [_server close];
// _server = nil;
#endif
}
@end
#endif