Source code
Revision control
Copy as Markdown
Other Tools
/* -*- 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
#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<nsIAsyncOutputStream> mOutput;
Atomic<bool> mStopped{false};
nsTArray<uint8_t> 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<nsIRunnable>&& aCallback);
bool IsPipeClosed() const { return mPipeClosed; }
NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream* aStream) override;
private:
~SerialPortWritePump() = default;
nsString mPortId;
nsCOMPtr<nsIAsyncInputStream> mInput;
Atomic<bool> mStopped{false};
// Only accessed from the SerialPlatformService's IO thread
bool mPipeClosed = false;
nsCOMPtr<nsIRunnable> mClosedCallback;
};
} // namespace mozilla::dom::webserial
#endif // mozilla_dom_SerialPortPumps_h