|
|
nono 1.6.0
//
// nono
// Copyright (C) 2021 nono project
// Licensed under nono-license.txt
//
//
// ホストデバイス (基本クラス)
//
#pragma once
#include "thread.h"
#include "autofd.h"
#include "kevent.h"
#include "rwlock.h"
using DeviceCallback_t = void (Device::*)(uint32);
#define ToDeviceCallback(f) static_cast<DeviceCallback_t>(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; // 待受ソケット着信
protected:
HostDevice(Device *parent_, uint objid_, const std::string& portname_);
public:
~HostDevice() 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 AddListen(int ls, int action);
int DelListen(int ls);
// ドライバの再選択を指示。(他スレッドから呼ばれる)
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;
virtual void Dispatch(int udata);
// ドライバから読み込み。キューに投入したデータ数を返す。
virtual int Read() = 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 からの送信用パイプ
autofd rpipe {};
autofd wpipe {};
// 各種通知コールバック
DeviceCallback_t rx_func {};
uint32 rx_arg {};
DeviceCallback_t accept_func {};
std::string errmsg {};
// スレッド終了フラグ
bool exit_requested {};
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.