--- nono/host/hostdevice.h 2026/04/29 17:05:26 1.1.1.4 +++ nono/host/hostdevice.h 2026/04/29 17:05:51 1.1.1.8 @@ -13,14 +13,19 @@ #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 からの着信 @@ -28,10 +33,11 @@ class HostDevice : public ThreadDevice static const int LISTEN_SOCKET = 3; // 待受ソケット着信 protected: - HostDevice(Device *parent_, int objid_); + HostDevice(Device *parent_, uint objid_, const std::string& portname_); public: ~HostDevice() override; + bool Create2() override; bool Init() override; void Terminate() override; @@ -39,14 +45,28 @@ class HostDevice : public ThreadDevice // 設定ファイルキーのプレフィックス ("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 AddListen(int ls, int action); + int DelListen(int ls); - 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; @@ -56,7 +76,10 @@ 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); @@ -66,6 +89,14 @@ class HostDevice : public ThreadDevice // 親デバイス Device *parent {}; + // 親デバイスのポート名 (UI 表示用) + std::string portname {}; + + // ドライバ切り替えから保護するため。 + // 使うほうは読み書きに関わらず Read ロック。 + // ドライバの切り替えが Write ロック。 + RWLock driverlock {}; + autofd kq {}; // VM からの送信用パイプ @@ -74,8 +105,11 @@ class HostDevice : public ThreadDevice // 各種通知コールバック DeviceCallback_t rx_func {}; + uint32 rx_arg {}; DeviceCallback_t accept_func {}; + std::string errmsg {}; + // スレッド終了フラグ bool exit_requested {}; };