Files
utun2/tools/chatgui/transport/utun_node.h
T

86 lines
5.8 KiB
C++

/* Desktop-владелец единственного встроенного ядра: читает INI, создаёт uasync и запускает core/chat в std::thread.
* [gui] utun_enabled=yes дополнительно запускает UTUN; tun_enabled управляет только созданием TUN.
* start подтверждает готовность сервисов и медиапривязок перед входом в poll.
* start/stop/настройки принадлежат GUI-потоку; настройки менять при остановленном узле.
* requestStop допускается из другого потока, stop ждёт worker и освобождает uasync вне callbacks.
* Worker уничтожает instance; идентичность и NTP читаются через защищённую копию состояния,
* обновляемую перед подтверждением старта и после каждого poll. instance — только заимствованный
* указатель для кода ядра: использовать в uasync, согласовав время жизни с stop/restart.
* Logger общий для процесса; путь файла принадлежит объекту до закрытия лога. */
#ifndef UTUN_NODE_H
#define UTUN_NODE_H
#include <QObject>
#include <QByteArray>
#include <QString>
#include <atomic>
#include <cstdint>
#include <future>
#include <mutex>
#include <thread>
struct UTUN_INSTANCE;
class UtunNode : public QObject {
Q_OBJECT
public:
// QObject принадлежит GUI; деструктор выполняет stop и закрывает собственный файл лога.
explicit UtunNode(QObject* parent = nullptr);
~UtunNode();
// Запускает сервисы по INI configPath; ждёт готовности. false — ошибка/уже запущен; см. startupError.
bool start(const QString& configPath);
// Причина последнего отказа start; читается в GUI-потоке после возврата start.
QString startupError() const { return m_startupError; }
void requestStop(); // Попросить выход из poll и разбудить его; не ждёт уничтожения ядра.
void stop(); // Идемпотентно запросить остановку, join worker и очистить опубликованное состояние.
// true от начала start до stop/отката; самостоятельный выход worker сначала сообщает stopped.
bool isRunning() const { return m_running; }
void setDebugFile(const QString& path); // Файл общего logger-а, append; пустой — файл задаёт конфиг ядра.
void setDbPath(const QString& path); // Переопределить db_path INI; создать каталог, ошибку записать в лог.
void setDebugLevel(const QString& level); // Общий уровень; пустой/неизвестный — info.
void setDebugCategories(const QString& categories); // Overrides cat=level,... поверх sys=info,bgp=info.
struct UTUN_INSTANCE* instance() const { return m_instance.load(); }
// Копии данных ядра, безопасны вне uasync; до старта/после stop — пустые строки, 0/false.
QString nodeIdHex() const;
QString pubKeyHex() const;
int64_t ntpOffsetUs() const;
bool ntpSynced() const;
bool ntpEnabled() const;
signals:
void started(); // Синхронно в GUI после успешного start.
void stopped(); // Через Qt-очередь после освобождения ядра; событие прежнего запуска отсекается.
void error(const QString& msg); // Ошибка start; stopped при отказе запуска не посылается.
private:
void runLoop(std::promise<QString> startup);
void finalize(); // Только GUI после join: сброс моста, уничтожение uasync, очистка копии состояния.
void updateSnapshot(const UTUN_INSTANCE* inst); // uasync читает ядро; NULL сбрасывает копию при finalize.
struct Snapshot {
QString nodeId, publicKey;
int64_t ntpOffsetUs = 0;
bool ntpSynced = false, ntpEnabled = false;
} m_snapshot; // Копия для GUI; доступ под m_snapshotMutex, указателей ядра не содержит.
mutable std::mutex m_snapshotMutex;
std::atomic<UTUN_INSTANCE*> m_instance{nullptr}; // Публикуется после готовности; не продлевает жизнь ядра.
struct UASYNC* m_ua = nullptr; // Живёт до join; m_uaMutex защищает wakeup и откат неудачного старта.
std::mutex m_uaMutex;
std::thread m_thread; // Присоединяется GUI до повторного старта и уничтожения объекта.
std::atomic<bool> m_running{false}; // Узел владеет запущенным/останавливаемым worker.
std::atomic<bool> m_stop{false}; // Потокобезопасный запрос остановки.
uint64_t m_generation = 0; // Поколение запуска; GUI отбрасывает поздний stopped прежнего worker.
QString m_configPath;
QString m_startupError;
QString m_debugFile;
QByteArray m_debugLogPath; // Стабильный UTF-8 путь, заимствованный общим logger-ом.
QString m_dbPath;
QString m_debugLevel;
QString m_debugCategories;
};
#endif // UTUN_NODE_H