|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2021 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // ホストデバイス (基本クラス)
9: //
10:
11: #pragma once
12:
13: #include "thread.h"
14: #include "autofd.h"
15: #include "kevent.h"
1.1.1.8 root 16: #include "rwlock.h"
1.1 root 17:
1.1.1.7 root 18: using DeviceCallback_t = void (Device::*)(uint32);
1.1 root 19: #define ToDeviceCallback(f) static_cast<DeviceCallback_t>(f)
20:
21: class HostDevice : public ThreadDevice
22: {
23: using inherited = ThreadDevice;
24:
1.1.1.7 root 25: protected:
26: static constexpr uint8 PIPE_TX = 0; // データ送信通知
27: static constexpr uint8 PIPE_RESELECT = 1; // ドライバ再選択通知
28:
1.1 root 29: public:
30: static const int DONE = 0; // 処理終了
31: static const int DATA_FROM_VM = 1; // VM からの着信
32: static const int DATA_FROM_OUTER = 2; // 外部からの着信
33: static const int LISTEN_SOCKET = 3; // 待受ソケット着信
34:
35: protected:
1.1.1.7 root 36: HostDevice(Device *parent_, uint objid_, const std::string& portname_);
1.1 root 37: public:
1.1.1.4 root 38: ~HostDevice() override;
1.1 root 39:
1.1.1.6 root 40: bool Create2() override;
1.1 root 41:
42: void Terminate() override;
43:
44: // 設定ファイルキーのプレフィックス ("hostcomX-" とか) を返す
45: std::string GetConfigKey() const;
46:
1.1.1.7 root 47: // 表示用の親デバイスのポート名 ("SIO(uPD7201) Ch.A" とか) を返す。
48: std::string GetPortName() const { return portname; }
49: void SetPortName(const std::string& portname_) { portname = portname_; }
50:
1.1 root 51: // NetDriver からのディスクリプタの登録
52: int AddOuter(int fd);
53: int DelOuter(int fd);
54: int AddListen(int ls, int action);
1.1.1.7 root 55: int DelListen(int ls);
1.1 root 56:
1.1.1.7 root 57: // ドライバの再選択を指示。(他スレッドから呼ばれる)
58: bool NotifyReselectDriver() {
59: return WritePipe(PIPE_RESELECT);
60: }
61:
62: void ResetRxCallback();
63: void SetRxCallback(DeviceCallback_t func, uint32 arg);
1.1 root 64: void SetAcceptCallback(DeviceCallback_t func);
65:
1.1.1.7 root 66: // 直近のエラーメッセージを返す。
67: const std::string& GetErrmsg() const { return errmsg; }
68:
1.1 root 69: protected:
70: void ThreadRun() override;
71:
72: virtual void Dispatch(int udata);
73:
74: // ドライバから読み込み。キューに投入したデータ数を返す。
75: virtual int Read() = 0;
76:
77: // ドライバに書き出し。
1.1.1.7 root 78: virtual void Write() = 0;
79:
80: // ドライバの(再)選択。
81: virtual bool SelectDriver(bool startup) = 0;
1.1 root 82:
83: bool WritePipe(uint32 data);
84:
85: // ログ出力
86: void putlogn(const char *fmt, ...) const override __printflike(2, 3);
87:
1.1.1.3 root 88: // 親デバイス
89: Device *parent {};
90:
1.1.1.7 root 91: // 親デバイスのポート名 (UI 表示用)
92: std::string portname {};
93:
1.1.1.8 root 94: // ドライバ切り替えから保護するため。
95: // 使うほうは読み書きに関わらず Read ロック。
96: // ドライバの切り替えが Write ロック。
97: RWLock driverlock {};
1.1.1.7 root 98:
1.1 root 99: autofd kq {};
100:
101: // VM からの送信用パイプ
102: autofd rpipe {};
103: autofd wpipe {};
104:
105: // 各種通知コールバック
106: DeviceCallback_t rx_func {};
1.1.1.7 root 107: uint32 rx_arg {};
1.1 root 108: DeviceCallback_t accept_func {};
109:
1.1.1.7 root 110: std::string errmsg {};
111:
1.1 root 112: // スレッド終了フラグ
113: bool exit_requested {};
114: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.