/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_SerialPortPumps_h #define mozilla_dom_SerialPortPumps_h #include "mozilla/dom/SerialPlatformService.h" #include "nsIAsyncInputStream.h" #include "nsIAsyncOutputStream.h" #include "nsThreadUtils.h" namespace mozilla::dom { constexpr uint32_t kMinSerialPortPumpSize = 16384; } // namespace mozilla::dom namespace mozilla::dom::webserial { // Reads data from the serial device and writes it into a local nsIPipe. // Runs on the IO thread. An NS_AsyncCopy bridges the nsIPipe to the // DataPipeSender on a separate thread (DataPipeSender::Write() can block). // Uses AsyncWait for backpressure when the local pipe is full. class SerialPortReadPump final : public Runnable, public nsIOutputStreamCallback { public: NS_DECL_ISUPPORTS_INHERITED SerialPortReadPump(const nsString& aPortId, nsIAsyncOutputStream* aOutput); void Stop(); NS_IMETHOD Run() override; NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream* aStream) override; private: ~SerialPortReadPump() = default; nsString mPortId; nsCOMPtr mOutput; Atomic mStopped{false}; nsTArray mPendingData; uint32_t mPendingOffset = 0; }; // Reads data from a DataPipeReceiver (JS writes) and writes it to the serial // device. Runs on the IO thread. Uses AsyncWait to be notified when data is // available in the pipe. class SerialPortWritePump final : public nsIInputStreamCallback { public: NS_DECL_THREADSAFE_ISUPPORTS SerialPortWritePump(const nsString& aPortId, nsIAsyncInputStream* aInput); void Start(); void Stop(); // Register a runnable to invoke when the input pipe is fully closed (all // data consumed and written to the device). If the pipe is already closed // the runnable fires synchronously. Only one callback may be registered; // a second call replaces the previous one. void OnPipeClosed(nsCOMPtr&& aCallback); bool IsPipeClosed() const { return mPipeClosed; } NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream* aStream) override; private: ~SerialPortWritePump() = default; nsString mPortId; nsCOMPtr mInput; Atomic mStopped{false}; // Only accessed from the SerialPlatformService's IO thread bool mPipeClosed = false; nsCOMPtr mClosedCallback; }; } // namespace mozilla::dom::webserial #endif // mozilla_dom_SerialPortPumps_h