lokinet/llarp/router/outbound_session_maker.hpp
Jason Rhinelander b4440094b0 De-abseil, part 2: mutex, locks, (most) time
- util::Mutex is now a std::shared_timed_mutex, which is capable of
  exclusive and shared locks.

- util::Lock is still present as a std::lock_guard<util::Mutex>.

- the locking annotations are preserved, but updated to the latest
  supported by clang rather than using abseil's older/deprecated ones.

- ACQUIRE_LOCK macro is gone since we don't pass mutexes by pointer into
  locks anymore (WTF abseil).

- ReleasableLock is gone.  Instead there are now some llarp::util helper
  methods to obtain unique and/or shared locks:
    - `auto lock = util::unique_lock(mutex);` gets an RAII-but-also
      unlockable object (std::unique_lock<T>, with T inferred from
      `mutex`).
    - `auto lock = util::shared_lock(mutex);` gets an RAII shared (i.e.
      "reader") lock of the mutex.
    - `auto lock = util::unique_locks(mutex1, mutex2, mutex3);` can be
      used to atomically lock multiple mutexes at once (returning a
      tuple of the locks).
  This are templated on the mutex which makes them a bit more flexible
  than using a concrete type: they can be used for any type of lockable
  mutex, not only util::Mutex.  (Some of the code here uses them for
  getting locks around a std::mutex).  Until C++17, using the RAII types
  is painfully verbose:

  ```C++
  // pre-C++17 - needing to figure out the mutex type here is annoying:
  std::unique_lock<util::Mutex> lock(mutex);
  // pre-C++17 and even more verbose (but at least the type isn't needed):
  std::unique_lock<decltype(mutex)> lock(mutex);
  // our compromise:
  auto lock = util::unique_lock(mutex);
  // C++17:
  std::unique_lock lock(mutex);
  ```

  All of these functions will also warn (under gcc or clang) if you
  discard the return value.  You can also do fancy things like
  `auto l = util::unique_lock(mutex, std::adopt_lock)` (which lets a
  lock take over an already-locked mutex).

- metrics code is gone, which also removes a big pile of code that was
  only used by metrics:
  - llarp::util::Scheduler
  - llarp:🧵:TimerQueue
  - llarp::util::Stopwatch
2020-02-21 23:22:47 -04:00

126 lines
3.2 KiB
C++

#ifndef LLARP_ROUTER_OUTBOUND_SESSION_MAKER_HPP
#define LLARP_ROUTER_OUTBOUND_SESSION_MAKER_HPP
#include <router/i_outbound_session_maker.hpp>
#include <router/i_rc_lookup_handler.hpp>
#include <util/thread/logic.hpp>
#include <util/thread/threading.hpp>
#include <util/thread/thread_pool.hpp>
#include <profiling.hpp>
#include <unordered_map>
#include <list>
#include <memory>
struct llarp_nodedb;
namespace llarp
{
struct PendingSession;
struct ILinkManager;
struct I_RCLookupHandler;
struct OutboundSessionMaker final : public IOutboundSessionMaker
{
using CallbacksQueue = std::list< RouterCallback >;
public:
~OutboundSessionMaker() override = default;
bool
OnSessionEstablished(ILinkSession *session) override;
void
OnConnectTimeout(ILinkSession *session) override;
void
CreateSessionTo(const RouterID &router, RouterCallback on_result) override
EXCLUDES(_mutex);
void
CreateSessionTo(const RouterContact &rc, RouterCallback on_result) override
EXCLUDES(_mutex);
bool
HavePendingSessionTo(const RouterID &router) const override
EXCLUDES(_mutex);
void
ConnectToRandomRouters(int numDesired) override;
util::StatusObject
ExtractStatus() const override;
bool
ShouldConnectTo(const RouterID &router) const override EXCLUDES(_mutex);
void
Init(ILinkManager *linkManager, I_RCLookupHandler *rcLookup,
Profiling *profiler, std::shared_ptr< Logic > logic,
llarp_nodedb *nodedb,
std::shared_ptr< llarp::thread::ThreadPool > threadpool);
void
SetOurRouter(RouterID r)
{
us = std::move(r);
}
/// always maintain this many connections to other routers
size_t minConnectedRouters = 4;
/// hard upperbound limit on the number of router to router connections
size_t maxConnectedRouters = 6;
private:
void
DoEstablish(const RouterID &router) EXCLUDES(_mutex);
void
GotRouterContact(const RouterID &router, const RouterContact &rc)
EXCLUDES(_mutex);
void
InvalidRouter(const RouterID &router);
void
RouterNotFound(const RouterID &router);
void
OnRouterContactResult(const RouterID &router, const RouterContact *const rc,
const RCRequestResult result);
void
VerifyRC(const RouterContact rc);
void
CreatePendingSession(const RouterID &router) EXCLUDES(_mutex);
void
FinalizeRequest(const RouterID &router, const SessionResult type)
EXCLUDES(_mutex);
mutable util::Mutex _mutex; // protects pendingSessions, pendingCallbacks
std::unordered_map< RouterID, std::shared_ptr< PendingSession >,
RouterID::Hash >
pendingSessions GUARDED_BY(_mutex);
std::unordered_map< RouterID, CallbacksQueue, RouterID::Hash >
pendingCallbacks GUARDED_BY(_mutex);
ILinkManager *_linkManager = nullptr;
I_RCLookupHandler *_rcLookup = nullptr;
Profiling *_profiler = nullptr;
llarp_nodedb *_nodedb = nullptr;
std::shared_ptr< Logic > _logic;
std::shared_ptr< llarp::thread::ThreadPool > _threadpool;
RouterID us;
};
} // namespace llarp
#endif // LLARP_ROUTER_OUTBOUND_SESSION_MAKER_HPP