Files
flipper/xplat/Flipper/FlipperConnectionManagerImpl.h
Matt Galloway d37c64c329 Flipper | Fix potential for deadlock when stopping Flipper
Summary:
There was an interesting problem in Flipper which I encountered. On closing our app we would deadlock. This was happening when joining the Flipper thread.

Upon investigation I found that it happened only when Flipper was not connected to the app. And digging in I found that it's because we are continually trying to connect the `FlipperClient` to the Flipper app when there is no connection. This works great, but it continues even if you have asked Flipper to terminate. So this meant that the `EventBase` never gets chance to shutdown, as it keeps getting new work to do.

The fix is to add a flag to `FlipperConnectionManagerImpl` to say if the conection is started or not. Then, if it's not started and we get a request to retry connection, then we will fail it.

Reviewed By: jknoxville

Differential Revision: D18780622

fbshipit-source-id: cce82cbb5c54e6d92ea16644c8a247bd2578ae26
2019-12-04 07:33:10 -08:00

82 lines
2.0 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <folly/Executor.h>
#include <folly/io/async/EventBase.h>
#include <rsocket/RSocket.h>
#include <mutex>
#include "FlipperConnectionManager.h"
#include "FlipperInitConfig.h"
#include "FlipperState.h"
namespace facebook {
namespace flipper {
class ConnectionEvents;
class ConnectionContextStore;
class FlipperRSocketResponder;
rsocket::Payload toRSocketPayload(folly::dynamic data);
class FlipperConnectionManagerImpl : public FlipperConnectionManager {
friend ConnectionEvents;
public:
FlipperConnectionManagerImpl(
FlipperInitConfig config,
std::shared_ptr<FlipperState> state,
std::shared_ptr<ConnectionContextStore> contextStore);
~FlipperConnectionManagerImpl();
void start() override;
void stop() override;
bool isOpen() const override;
void setCallbacks(Callbacks* callbacks) override;
void sendMessage(const folly::dynamic& message) override;
void onMessageReceived(
const folly::dynamic& message,
std::unique_ptr<FlipperResponder> responder) override;
void reconnect();
private:
bool isOpen_ = false;
bool isStarted_ = false;
Callbacks* callbacks_;
DeviceData deviceData_;
std::shared_ptr<FlipperState> flipperState_;
int insecurePort;
int securePort;
folly::EventBase* flipperEventBase_;
folly::EventBase* connectionEventBase_;
std::unique_ptr<rsocket::RSocketClient> client_;
bool connectionIsTrusted_;
int failedConnectionAttempts_ = 0;
std::shared_ptr<ConnectionContextStore> contextStore_;
void startSync();
void doCertificateExchange();
void connectSecurely();
bool isCertificateExchangeNeeded();
void requestSignedCertFromFlipper();
bool isRunningInOwnThread();
void sendLegacyCertificateRequest(folly::dynamic message);
std::string getDeviceId();
};
} // namespace flipper
} // namespace facebook