1 #pragma once 2 3 #include "NVMeContext.hpp" 4 #include "NVMeSensor.hpp" 5 6 #include <boost/asio/io_context.hpp> 7 #include <boost/asio/posix/stream_descriptor.hpp> 8 9 #include <cstddef> 10 #include <memory> 11 #include <thread> 12 13 class NVMeBasicContext : public NVMeContext 14 { 15 public: 16 NVMeBasicContext(boost::asio::io_context& io, int rootBus); 17 ~NVMeBasicContext() override = default; 18 void pollNVMeDevices() override; 19 void readAndProcessNVMeSensor() override; 20 void processResponse(std::shared_ptr<NVMeSensor>& sensor, void* msg, 21 size_t len) override; 22 23 private: 24 NVMeBasicContext(boost::asio::io_context& io, int rootBus, int cmdOut, 25 int streamIn, int streamOut, int cmdIn); 26 boost::asio::io_context& io; 27 28 // The IO thread must be destructed after the stream descriptors, so 29 // initialise it first. http://eel.is/c++draft/class.base.init#note-6 30 // 31 // Providing a stop-source to the thread execution function isn't 32 // particularly useful as it will spend most of its time blocked in a system 33 // call - ioctl() for the actual device communication, or read() and write() 34 // on the pipes associated with reqStream and respStream. Rather than trying 35 // to force a stop, rely on read()/write() failures from closed pipes to 36 // coerce it to exit and thus allow completion of the join(). 37 std::jthread thread; 38 39 // Destruction of the stream descriptors has the effect of issuing cancel(), 40 // destroying the closure of the callback where we might be carrying 41 // weak_ptrs to `this`. 42 // https://www.boost.org/doc/libs/1_79_0/doc/html/boost_asio/reference/posix__basic_descriptor/_basic_descriptor.html 43 boost::asio::posix::stream_descriptor reqStream; 44 boost::asio::posix::stream_descriptor respStream; 45 46 enum 47 { 48 NVME_MI_BASIC_SFLGS_DRIVE_NOT_READY = 0x40, 49 NVME_MI_BASIC_SFLGS_DRIVE_FUNCTIONAL = 0x20, 50 }; 51 }; 52