--- nono/host/hostdevice.h 2026/04/29 17:05:11 1.1 +++ nono/host/hostdevice.h 2026/04/29 17:05:56 1.1.1.9 @@ -13,43 +13,59 @@ #include "thread.h" #include "autofd.h" #include "kevent.h" +#include "rwlock.h" -using DeviceCallback_t = void (Device::*)(); +using DeviceCallback_t = void (Device::*)(uint32); #define ToDeviceCallback(f) static_cast(f) class HostDevice : public ThreadDevice { using inherited = ThreadDevice; + protected: + static constexpr uint8 PIPE_TX = 0; // データ送信通知 + static constexpr uint8 PIPE_RESELECT = 1; // ドライバ再選択通知 + public: static const int DONE = 0; // 処理終了 static const int DATA_FROM_VM = 1; // VM からの着信 static const int DATA_FROM_OUTER = 2; // 外部からの着信 static const int LISTEN_SOCKET = 3; // 待受ソケット着信 - static const int DATA_FROM_SIGNAL = 4; // シグナル受信 protected: - HostDevice(const std::string& objname_); + HostDevice(Device *parent_, uint objid_, const std::string& portname_); public: - virtual ~HostDevice() override; + ~HostDevice() override; - bool Init() override; + bool Create2() override; void Terminate() override; // 設定ファイルキーのプレフィックス ("hostcomX-" とか) を返す std::string GetConfigKey() const; + // 表示用の親デバイスのポート名 ("SIO(uPD7201) Ch.A" とか) を返す。 + std::string GetPortName() const { return portname; } + void SetPortName(const std::string& portname_) { portname = portname_; } + // NetDriver からのディスクリプタの登録 int AddOuter(int fd); int DelOuter(int fd); - int AddSignal(int rfd, int wfd); int AddListen(int ls, int action); + int DelListen(int ls); - void SetCallbackDevice(Device *); - void SetRxCallback(DeviceCallback_t func); + // ドライバの再選択を指示。(他スレッドから呼ばれる) + bool NotifyReselectDriver() { + return WritePipe(PIPE_RESELECT); + } + + void ResetRxCallback(); + void SetRxCallback(DeviceCallback_t func, uint32 arg); void SetAcceptCallback(DeviceCallback_t func); + // 直近のエラーメッセージを返す。 + const std::string& GetErrmsg() const { return errmsg; } + protected: void ThreadRun() override; @@ -59,13 +75,27 @@ class HostDevice : public ThreadDevice virtual int Read() = 0; // ドライバに書き出し。 - virtual void Write(uint32 data) = 0; + virtual void Write() = 0; + + // ドライバの(再)選択。 + virtual bool SelectDriver(bool startup) = 0; bool WritePipe(uint32 data); // ログ出力 void putlogn(const char *fmt, ...) const override __printflike(2, 3); + // 親デバイス + Device *parent {}; + + // 親デバイスのポート名 (UI 表示用) + std::string portname {}; + + // ドライバ切り替えから保護するため。 + // 使うほうは読み書きに関わらず Read ロック。 + // ドライバの切り替えが Write ロック。 + RWLock driverlock {}; + autofd kq {}; // VM からの送信用パイプ @@ -73,10 +103,12 @@ class HostDevice : public ThreadDevice autofd wpipe {}; // 各種通知コールバック - Device *dev {}; DeviceCallback_t rx_func {}; + uint32 rx_arg {}; DeviceCallback_t accept_func {}; + std::string errmsg {}; + // スレッド終了フラグ bool exit_requested {}; };