2019-01-11 01:19:36 +00:00
|
|
|
#include <path/pathset.hpp>
|
|
|
|
|
2018-12-12 00:48:54 +00:00
|
|
|
#include <dht/messages/pubintro.hpp>
|
2019-01-11 01:19:36 +00:00
|
|
|
#include <path/path.hpp>
|
2019-06-15 14:55:13 +00:00
|
|
|
#include <routing/dht_message.hpp>
|
2019-11-05 16:58:53 +00:00
|
|
|
#include <router/abstractrouter.hpp>
|
2018-06-25 15:12:08 +00:00
|
|
|
|
2020-05-21 14:25:46 +00:00
|
|
|
#include <random>
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace path
|
|
|
|
{
|
2019-07-18 16:28:17 +00:00
|
|
|
PathSet::PathSet(size_t num) : numPaths(num)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2018-10-29 16:48:36 +00:00
|
|
|
PathSet::ShouldBuildMore(llarp_time_t now) const
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2019-04-23 16:13:22 +00:00
|
|
|
(void)now;
|
2019-04-22 19:15:07 +00:00
|
|
|
const auto building = NumInStatus(ePathBuilding);
|
2020-04-07 18:38:56 +00:00
|
|
|
if (building >= numPaths)
|
2019-04-22 19:15:07 +00:00
|
|
|
return false;
|
|
|
|
const auto established = NumInStatus(ePathEstablished);
|
2019-11-05 16:58:53 +00:00
|
|
|
return established < numPaths;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
|
2018-11-14 18:02:27 +00:00
|
|
|
bool
|
|
|
|
PathSet::ShouldBuildMoreForRoles(llarp_time_t now, PathRole roles) const
|
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-11-14 18:02:27 +00:00
|
|
|
const size_t required = MinRequiredForRoles(roles);
|
2020-04-07 18:38:56 +00:00
|
|
|
size_t has = 0;
|
|
|
|
for (const auto& item : m_Paths)
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (item.second->SupportsAnyRoles(roles))
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!item.second->ExpiresSoon(now))
|
2018-11-14 18:02:27 +00:00
|
|
|
++has;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return has < required;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
PathSet::MinRequiredForRoles(PathRole roles) const
|
|
|
|
{
|
2018-11-19 16:48:35 +00:00
|
|
|
(void)roles;
|
|
|
|
return 0;
|
2018-11-14 18:02:27 +00:00
|
|
|
}
|
|
|
|
|
2018-11-26 13:30:03 +00:00
|
|
|
size_t
|
|
|
|
PathSet::NumPathsExistingAt(llarp_time_t futureTime) const
|
2018-11-25 16:58:27 +00:00
|
|
|
{
|
|
|
|
size_t num = 0;
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2020-04-07 18:38:56 +00:00
|
|
|
for (const auto& item : m_Paths)
|
2018-11-25 16:58:27 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (item.second->IsReady() && !item.second->Expired(futureTime))
|
2018-11-25 16:58:27 +00:00
|
|
|
++num;
|
|
|
|
}
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
2018-06-29 16:02:39 +00:00
|
|
|
void
|
2019-11-05 16:58:53 +00:00
|
|
|
PathSet::TickPaths(AbstractRouter* r)
|
2018-06-29 16:02:39 +00:00
|
|
|
{
|
2019-11-05 16:58:53 +00:00
|
|
|
const auto now = llarp::time_now_ms();
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2020-04-07 18:38:56 +00:00
|
|
|
for (auto& item : m_Paths)
|
2018-06-29 16:02:39 +00:00
|
|
|
{
|
2018-09-13 16:41:53 +00:00
|
|
|
item.second->Tick(now, r);
|
2018-06-29 16:02:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
void
|
2019-11-07 18:23:06 +00:00
|
|
|
PathSet::ExpirePaths(llarp_time_t now, AbstractRouter* router)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2020-04-07 18:38:56 +00:00
|
|
|
if (m_Paths.size() == 0)
|
2018-08-17 19:49:58 +00:00
|
|
|
return;
|
2018-06-26 14:52:19 +00:00
|
|
|
auto itr = m_Paths.begin();
|
2020-04-07 18:38:56 +00:00
|
|
|
while (itr != m_Paths.end())
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->Expired(now))
|
2019-11-05 16:58:53 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
router->outboundMessageHandler().QueueRemoveEmptyPath(itr->second->TXID());
|
2018-06-26 14:52:19 +00:00
|
|
|
itr = m_Paths.erase(itr);
|
2019-11-05 16:58:53 +00:00
|
|
|
}
|
2018-06-26 14:52:19 +00:00
|
|
|
else
|
|
|
|
++itr;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr
|
2018-12-18 18:36:19 +00:00
|
|
|
PathSet::GetEstablishedPathClosestTo(RouterID id, PathRole roles) const
|
2018-08-01 22:10:38 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr path = nullptr;
|
2020-04-07 18:38:56 +00:00
|
|
|
AlignedBuffer<32> dist;
|
|
|
|
AlignedBuffer<32> to = id;
|
2018-08-01 22:10:38 +00:00
|
|
|
dist.Fill(0xff);
|
2020-04-07 18:38:56 +00:00
|
|
|
for (const auto& item : m_Paths)
|
2018-08-01 22:10:38 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!item.second->IsReady())
|
2018-08-02 00:48:43 +00:00
|
|
|
continue;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!item.second->SupportsAnyRoles(roles))
|
2018-11-14 18:02:27 +00:00
|
|
|
continue;
|
2020-04-07 18:38:56 +00:00
|
|
|
AlignedBuffer<32> localDist = item.second->Endpoint() ^ to;
|
|
|
|
if (localDist < dist)
|
2018-08-01 22:10:38 +00:00
|
|
|
{
|
|
|
|
dist = localDist;
|
|
|
|
path = item.second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr
|
2018-12-18 18:36:19 +00:00
|
|
|
PathSet::GetNewestPathByRouter(RouterID id, PathRole roles) const
|
2018-09-18 23:56:26 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr chosen = nullptr;
|
2020-04-07 18:38:56 +00:00
|
|
|
auto itr = m_Paths.begin();
|
|
|
|
while (itr != m_Paths.end())
|
2018-09-18 23:56:26 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
|
2018-09-18 23:56:26 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->Endpoint() == id)
|
2018-09-18 23:56:26 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (chosen == nullptr)
|
2018-09-18 23:56:26 +00:00
|
|
|
chosen = itr->second;
|
2020-04-07 18:38:56 +00:00
|
|
|
else if (chosen->intro.expiresAt < itr->second->intro.expiresAt)
|
2018-09-18 23:56:26 +00:00
|
|
|
chosen = itr->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return chosen;
|
|
|
|
}
|
|
|
|
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr
|
2018-12-18 18:36:19 +00:00
|
|
|
PathSet::GetPathByRouter(RouterID id, PathRole roles) const
|
2018-07-22 23:14:29 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr chosen = nullptr;
|
2020-04-07 18:38:56 +00:00
|
|
|
auto itr = m_Paths.begin();
|
|
|
|
while (itr != m_Paths.end())
|
2018-07-22 23:14:29 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
|
2018-07-23 07:38:29 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->Endpoint() == id)
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (chosen == nullptr)
|
2018-09-13 16:41:53 +00:00
|
|
|
chosen = itr->second;
|
2020-04-07 18:38:56 +00:00
|
|
|
else if (chosen->intro.latency > itr->second->intro.latency)
|
2018-09-13 16:41:53 +00:00
|
|
|
chosen = itr->second;
|
|
|
|
}
|
2018-07-23 07:38:29 +00:00
|
|
|
}
|
2018-07-22 23:14:29 +00:00
|
|
|
++itr;
|
|
|
|
}
|
2018-09-13 16:41:53 +00:00
|
|
|
return chosen;
|
2018-07-22 23:14:29 +00:00
|
|
|
}
|
|
|
|
|
2020-05-21 14:25:46 +00:00
|
|
|
Path_ptr
|
|
|
|
PathSet::GetRandomPathByRouter(RouterID id, PathRole roles) const
|
|
|
|
{
|
|
|
|
Lock_t l(m_PathsMutex);
|
|
|
|
std::vector<Path_ptr> chosen;
|
|
|
|
auto itr = m_Paths.begin();
|
|
|
|
while (itr != m_Paths.end())
|
|
|
|
{
|
|
|
|
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
|
|
|
|
{
|
|
|
|
if (itr->second->Endpoint() == id)
|
|
|
|
{
|
|
|
|
chosen.emplace_back(itr->second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
if (chosen.empty())
|
|
|
|
return nullptr;
|
|
|
|
size_t idx = 0;
|
|
|
|
if (chosen.size() >= 2)
|
|
|
|
{
|
|
|
|
idx = rand() % chosen.size();
|
|
|
|
}
|
|
|
|
return chosen[idx];
|
|
|
|
}
|
|
|
|
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr
|
2019-03-08 17:26:29 +00:00
|
|
|
PathSet::GetByEndpointWithID(RouterID ep, PathID_t id) const
|
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2019-03-08 17:26:29 +00:00
|
|
|
auto itr = m_Paths.begin();
|
2020-04-07 18:38:56 +00:00
|
|
|
while (itr != m_Paths.end())
|
2019-03-08 17:26:29 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->IsEndpoint(ep, id))
|
2019-03-08 17:26:29 +00:00
|
|
|
{
|
|
|
|
return itr->second;
|
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr
|
2018-12-18 18:36:19 +00:00
|
|
|
PathSet::GetPathByID(PathID_t id) const
|
2018-08-10 21:34:11 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-08-10 21:34:11 +00:00
|
|
|
auto itr = m_Paths.begin();
|
2020-04-07 18:38:56 +00:00
|
|
|
while (itr != m_Paths.end())
|
2018-08-10 21:34:11 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->RXID() == id)
|
2018-08-10 21:34:11 +00:00
|
|
|
return itr->second;
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-11-16 14:06:50 +00:00
|
|
|
size_t
|
|
|
|
PathSet::AvailablePaths(PathRole roles) const
|
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-11-16 14:06:50 +00:00
|
|
|
size_t count = 0;
|
2020-04-07 18:38:56 +00:00
|
|
|
auto itr = m_Paths.begin();
|
|
|
|
while (itr != m_Paths.end())
|
2018-11-16 14:06:50 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->Status() == ePathEstablished && itr->second->SupportsAnyRoles(roles))
|
2018-11-16 14:06:50 +00:00
|
|
|
++count;
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
size_t
|
|
|
|
PathSet::NumInStatus(PathStatus st) const
|
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-06-25 15:12:08 +00:00
|
|
|
size_t count = 0;
|
2020-04-07 18:38:56 +00:00
|
|
|
auto itr = m_Paths.begin();
|
|
|
|
while (itr != m_Paths.end())
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->Status() == st)
|
2018-06-25 15:12:08 +00:00
|
|
|
++count;
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-04-23 14:28:59 +00:00
|
|
|
PathSet::AddPath(Path_ptr path)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2019-11-05 16:58:53 +00:00
|
|
|
const auto upstream = path->Upstream(); // RouterID
|
2020-04-07 18:38:56 +00:00
|
|
|
const auto RXID = path->RXID(); // PathID
|
|
|
|
if (not m_Paths.emplace(std::make_pair(upstream, RXID), path).second)
|
2019-11-05 16:58:53 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
LogError(
|
|
|
|
Name(),
|
|
|
|
" failed to add own path, duplicate info wtf? upstream=",
|
|
|
|
upstream,
|
|
|
|
" rxid=",
|
|
|
|
RXID);
|
2019-11-05 16:58:53 +00:00
|
|
|
}
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-04-23 14:28:59 +00:00
|
|
|
PathSet::RemovePath(Path_ptr path)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-06-26 14:52:19 +00:00
|
|
|
m_Paths.erase({path->Upstream(), path->RXID()});
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr
|
2018-12-18 18:36:19 +00:00
|
|
|
PathSet::GetByUpstream(RouterID remote, PathID_t rxid) const
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-06-26 14:52:19 +00:00
|
|
|
auto itr = m_Paths.find({remote, rxid});
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr == m_Paths.end())
|
2018-06-26 14:52:19 +00:00
|
|
|
return nullptr;
|
|
|
|
return itr->second;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
|
2018-10-01 14:18:17 +00:00
|
|
|
bool
|
|
|
|
PathSet::GetCurrentIntroductionsWithFilter(
|
2020-04-07 18:38:56 +00:00
|
|
|
std::set<service::Introduction>& intros,
|
|
|
|
std::function<bool(const service::Introduction&)> filter) const
|
2018-10-01 14:18:17 +00:00
|
|
|
{
|
|
|
|
intros.clear();
|
|
|
|
size_t count = 0;
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-12-02 18:07:07 +00:00
|
|
|
auto itr = m_Paths.begin();
|
2020-04-07 18:38:56 +00:00
|
|
|
while (itr != m_Paths.end())
|
2018-10-01 14:18:17 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->IsReady() && filter(itr->second->intro))
|
2018-10-01 14:18:17 +00:00
|
|
|
{
|
|
|
|
intros.insert(itr->second->intro);
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return count > 0;
|
|
|
|
}
|
|
|
|
|
2018-07-09 17:32:11 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
PathSet::GetCurrentIntroductions(std::set<service::Introduction>& intros) const
|
2018-07-11 16:11:19 +00:00
|
|
|
{
|
2018-07-17 06:17:13 +00:00
|
|
|
intros.clear();
|
2018-07-11 16:11:19 +00:00
|
|
|
size_t count = 0;
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-12-02 18:07:07 +00:00
|
|
|
auto itr = m_Paths.begin();
|
2020-04-07 18:38:56 +00:00
|
|
|
while (itr != m_Paths.end())
|
2018-07-11 16:11:19 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->IsReady())
|
2018-07-11 16:11:19 +00:00
|
|
|
{
|
2018-07-19 04:58:39 +00:00
|
|
|
intros.insert(itr->second->intro);
|
2018-07-11 16:11:19 +00:00
|
|
|
++count;
|
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return count > 0;
|
|
|
|
}
|
|
|
|
|
2018-09-26 13:04:25 +00:00
|
|
|
void
|
2019-04-23 14:28:59 +00:00
|
|
|
PathSet::HandlePathBuildTimeout(Path_ptr p)
|
2018-09-26 13:04:25 +00:00
|
|
|
{
|
2020-02-20 21:37:39 +00:00
|
|
|
LogWarn(Name(), " path build ", p->ShortName(), " timed out");
|
2019-07-01 13:44:25 +00:00
|
|
|
m_BuildStats.timeouts++;
|
|
|
|
}
|
|
|
|
|
2019-07-31 12:51:24 +00:00
|
|
|
void
|
|
|
|
PathSet::HandlePathBuildFailed(Path_ptr p)
|
|
|
|
{
|
2020-02-20 21:37:39 +00:00
|
|
|
LogWarn(Name(), " path build ", p->ShortName(), " failed");
|
2019-08-02 03:25:48 +00:00
|
|
|
m_BuildStats.fails++;
|
2019-07-31 12:51:24 +00:00
|
|
|
}
|
|
|
|
|
2019-07-01 13:44:25 +00:00
|
|
|
void
|
|
|
|
PathSet::PathBuildStarted(Path_ptr p)
|
|
|
|
{
|
2020-02-20 21:37:39 +00:00
|
|
|
LogInfo(Name(), " path build ", p->ShortName(), " started");
|
2019-07-01 13:44:25 +00:00
|
|
|
m_BuildStats.attempts++;
|
|
|
|
}
|
|
|
|
|
|
|
|
util::StatusObject
|
|
|
|
BuildStats::ExtractStatus() const
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
return util::StatusObject{
|
|
|
|
{"success", success}, {"attempts", attempts}, {"timeouts", timeouts}, {"fails", fails}};
|
2019-07-01 13:44:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
|
|
|
BuildStats::ToString() const
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
2020-02-26 02:27:34 +00:00
|
|
|
ss << (SuccessRatio() * 100.0) << " percent success ";
|
2019-07-01 13:44:25 +00:00
|
|
|
ss << "(success=" << success << " ";
|
|
|
|
ss << "attempts=" << attempts << " ";
|
|
|
|
ss << "timeouts=" << timeouts << " ";
|
|
|
|
ss << "fails=" << fails << ")";
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
double
|
2020-02-26 02:27:34 +00:00
|
|
|
BuildStats::SuccessRatio() const
|
2019-07-01 13:44:25 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (attempts)
|
2019-07-01 14:56:56 +00:00
|
|
|
return double(success) / double(attempts);
|
|
|
|
return 0.0;
|
2018-09-26 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
2018-09-27 10:51:30 +00:00
|
|
|
bool
|
|
|
|
PathSet::GetNewestIntro(service::Introduction& intro) const
|
|
|
|
{
|
2018-09-27 11:03:01 +00:00
|
|
|
intro.Clear();
|
2018-09-27 10:51:30 +00:00
|
|
|
bool found = false;
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-12-02 18:07:07 +00:00
|
|
|
auto itr = m_Paths.begin();
|
2020-04-07 18:38:56 +00:00
|
|
|
while (itr != m_Paths.end())
|
2018-09-27 10:51:30 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->IsReady() && itr->second->intro.expiresAt > intro.expiresAt)
|
2018-09-27 10:51:30 +00:00
|
|
|
{
|
|
|
|
intro = itr->second->intro;
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2019-04-23 14:28:59 +00:00
|
|
|
Path_ptr
|
2018-11-14 18:02:27 +00:00
|
|
|
PathSet::PickRandomEstablishedPath(PathRole roles) const
|
2018-07-11 16:11:19 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
std::vector<Path_ptr> established;
|
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::thread::TimerQueue
- llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
|
|
|
Lock_t l(m_PathsMutex);
|
2018-07-11 16:11:19 +00:00
|
|
|
auto itr = m_Paths.begin();
|
2020-04-07 18:38:56 +00:00
|
|
|
while (itr != m_Paths.end())
|
2018-07-11 16:11:19 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
|
2018-07-11 16:11:19 +00:00
|
|
|
established.push_back(itr->second);
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
auto sz = established.size();
|
2020-04-07 18:38:56 +00:00
|
|
|
if (sz)
|
2018-07-11 16:11:19 +00:00
|
|
|
{
|
2019-02-18 10:35:16 +00:00
|
|
|
return established[randint() % sz];
|
2018-07-11 16:11:19 +00:00
|
|
|
}
|
2019-07-06 17:03:40 +00:00
|
|
|
|
|
|
|
return nullptr;
|
2018-07-11 16:11:19 +00:00
|
|
|
}
|
|
|
|
|
2019-09-05 17:39:09 +00:00
|
|
|
void
|
2019-09-16 16:12:05 +00:00
|
|
|
PathSet::UpstreamFlush(AbstractRouter* r)
|
2019-09-16 10:21:12 +00:00
|
|
|
{
|
|
|
|
ForEachPath([r](const Path_ptr& p) { p->FlushUpstream(r); });
|
|
|
|
}
|
2019-09-05 17:39:09 +00:00
|
|
|
|
2019-09-16 10:21:12 +00:00
|
|
|
void
|
2019-09-16 16:12:05 +00:00
|
|
|
PathSet::DownstreamFlush(AbstractRouter* r)
|
2019-09-05 17:39:09 +00:00
|
|
|
{
|
2019-09-16 10:21:12 +00:00
|
|
|
ForEachPath([r](const Path_ptr& p) { p->FlushDownstream(r); });
|
2019-09-05 17:39:09 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
} // namespace path
|
2018-08-17 19:49:58 +00:00
|
|
|
} // namespace llarp
|