proxygen
folly::AsyncPipeWriter Class Reference

#include <AsyncPipe.h>

Inheritance diagram for folly::AsyncPipeWriter:
folly::EventHandler folly::AsyncWriter folly::DelayedDestruction folly::DelayedDestructionBase

Public Types

typedef std::unique_ptr< AsyncPipeWriter, folly::DelayedDestruction::DestructorUniquePtr
 
- Public Types inherited from folly::EventHandler
enum  EventFlags {
  NONE = 0, READ = EV_READ, WRITE = EV_WRITE, READ_WRITE = (READ | WRITE),
  PERSIST = EV_PERSIST
}
 

Public Member Functions

 AsyncPipeWriter (folly::EventBase *eventBase, int pipeFd)
 
void write (std::unique_ptr< folly::IOBuf > iob, AsyncWriter::WriteCallback *wcb=nullptr)
 
void setCloseCallback (std::function< void(int)> closeCb)
 
bool closed () const
 
void closeOnEmpty ()
 
void closeNow ()
 
bool hasPendingWrites () const
 
void write (folly::AsyncWriter::WriteCallback *callback, const void *buf, size_t bytes, WriteFlags flags=WriteFlags::NONE) override
 
void writev (folly::AsyncWriter::WriteCallback *, const iovec *, size_t, WriteFlags=WriteFlags::NONE) override
 
void writeChain (folly::AsyncWriter::WriteCallback *callback, std::unique_ptr< folly::IOBuf > &&buf, WriteFlags flags=WriteFlags::NONE) override
 
- Public Member Functions inherited from folly::EventHandler
 EventHandler (EventBase *eventBase, int fd)
 
 EventHandler (EventBase *eventBase=nullptr, NetworkSocket fd=NetworkSocket())
 
virtual ~EventHandler ()
 
bool registerHandler (uint16_t events)
 
void unregisterHandler ()
 
bool isHandlerRegistered () const
 
void attachEventBase (EventBase *eventBase)
 
void detachEventBase ()
 
void changeHandlerFD (int fd)
 
void changeHandlerFD (NetworkSocket fd)
 
void initHandler (EventBase *eventBase, int fd)
 
void initHandler (EventBase *eventBase, NetworkSocket fd)
 
uint16_t getRegisteredEvents () const
 
bool registerInternalHandler (uint16_t events)
 
bool isPending () const
 
- Public Member Functions inherited from folly::DelayedDestruction
virtual void destroy ()
 
bool getDestroyPending () const
 
- Public Member Functions inherited from folly::DelayedDestructionBase
virtual ~DelayedDestructionBase ()=default
 

Static Public Member Functions

template<typename... Args>
static UniquePtr newWriter (Args &&...args)
 

Private Member Functions

void handlerReady (uint16_t events) noexceptoverride
 
void handleWrite ()
 
void failAllWrites (const AsyncSocketException &ex)
 
 ~AsyncPipeWriter () override
 

Private Attributes

int fd_
 
std::list< std::pair< folly::IOBufQueue, AsyncWriter::WriteCallback * > > queue_
 
bool closeOnEmpty_ {false}
 
std::function< void(int)> closeCb_
 

Additional Inherited Members

- Protected Member Functions inherited from folly::AsyncWriter
virtual ~AsyncWriter ()=default
 
- Protected Member Functions inherited from folly::DelayedDestruction
 ~DelayedDestruction () override=default
 
 DelayedDestruction ()
 
- Protected Member Functions inherited from folly::DelayedDestructionBase
 DelayedDestructionBase ()
 
uint32_t getDestructorGuardCount () const
 

Detailed Description

Write to a pipe in an async manner.

Definition at line 95 of file AsyncPipe.h.

Member Typedef Documentation

Constructor & Destructor Documentation

folly::AsyncPipeWriter::AsyncPipeWriter ( folly::EventBase eventBase,
int  pipeFd 
)
inline

Definition at line 108 of file AsyncPipe.h.

References fizz::detail::write().

109  : EventHandler(eventBase, pipeFd), fd_(pipeFd) {}
EventHandler(EventBase *eventBase, int fd)
Definition: EventHandler.h:65
folly::AsyncPipeWriter::~AsyncPipeWriter ( )
inlineoverrideprivate

Definition at line 181 of file AsyncPipe.h.

181  {
182  closeNow();
183  }

Member Function Documentation

bool folly::AsyncPipeWriter::closed ( ) const
inline

Returns true if the pipe is closed

Definition at line 129 of file AsyncPipe.h.

References folly::AsyncPipeReader::fd_.

129  {
130  return (fd_ < 0 || closeOnEmpty_);
131  }
void folly::AsyncPipeWriter::closeNow ( )

Close the pipe immediately, and fail all pending writes

Definition at line 187 of file AsyncPipe.cpp.

References folly::EventHandler::changeHandlerFD(), folly::AsyncPipeReader::close(), folly::AsyncPipeReader::closeCb_, folly::AsyncPipeReader::fd_, folly::AsyncSocketException::NOT_OPEN, and folly::EventHandler::unregisterHandler().

187  {
188  VLOG(5) << "close now";
189  if (!queue_.empty()) {
190  failAllWrites(AsyncSocketException(
191  AsyncSocketException::NOT_OPEN, "closed with pending writes"));
192  }
193  if (fd_ >= 0) {
195  changeHandlerFD(-1);
196  if (closeCb_) {
197  closeCb_(fd_);
198  } else {
199  close(fd_);
200  }
201  fd_ = -1;
202  }
203 }
void failAllWrites(const AsyncSocketException &ex)
Definition: AsyncPipe.cpp:205
std::list< std::pair< folly::IOBufQueue, AsyncWriter::WriteCallback * > > queue_
Definition: AsyncPipe.h:177
void changeHandlerFD(int fd)
Definition: EventHandler.h:143
int close(NetworkSocket s)
Definition: NetOps.cpp:90
std::function< void(int)> closeCb_
Definition: AsyncPipe.h:179
void folly::AsyncPipeWriter::closeOnEmpty ( )

Notify the pipe to close as soon as all pending writes complete

Definition at line 177 of file AsyncPipe.cpp.

References folly::EventHandler::isHandlerRegistered().

177  {
178  VLOG(5) << "close on empty";
179  if (queue_.empty()) {
180  closeNow();
181  } else {
182  closeOnEmpty_ = true;
183  CHECK(isHandlerRegistered());
184  }
185 }
std::list< std::pair< folly::IOBufQueue, AsyncWriter::WriteCallback * > > queue_
Definition: AsyncPipe.h:177
bool isHandlerRegistered() const
Definition: EventHandler.h:112
void folly::AsyncPipeWriter::failAllWrites ( const AsyncSocketException ex)
private

Definition at line 205 of file AsyncPipe.cpp.

205  {
206  DestructorGuard dg(this);
207  while (!queue_.empty()) {
208  // the first entry of the queue could have had a partial write, but needs to
209  // be tracked.
210  if (queue_.front().second) {
211  queue_.front().second->writeErr(0, ex);
212  }
213  queue_.pop_front();
214  }
215 }
std::list< std::pair< folly::IOBufQueue, AsyncWriter::WriteCallback * > > queue_
Definition: AsyncPipe.h:177
void folly::AsyncPipeWriter::handlerReady ( uint16_t  events)
overrideprivatevirtualnoexcept

handlerReady() is invoked when the handler is ready.

Parameters
eventsA bitset indicating the events that are ready.

Implements folly::EventHandler.

Definition at line 217 of file AsyncPipe.cpp.

References folly::EventHandler::WRITE.

217  {
218  CHECK(events & EventHandler::WRITE);
219 
220  handleWrite();
221 }
void folly::AsyncPipeWriter::handleWrite ( )
private

Definition at line 223 of file AsyncPipe.cpp.

References folly::IOBufQueue::empty(), folly::AsyncPipeReader::fd_, folly::IOBufQueue::front(), folly::AsyncSocketException::INTERNAL_ERROR, folly::EventHandler::registerHandler(), folly::IOBufQueue::trimStart(), folly::EventHandler::unregisterHandler(), folly::EventHandler::WRITE, and folly::writeNoInt().

223  {
224  DestructorGuard dg(this);
225  assert(!queue_.empty());
226  do {
227  auto& front = queue_.front();
228  folly::IOBufQueue& curQueue = front.first;
229  DCHECK(!curQueue.empty());
230  // someday, support writev. The logic for partial writes is a bit complex
231  const IOBuf* head = curQueue.front();
232  CHECK(head->length());
233  ssize_t rc = folly::writeNoInt(fd_, head->data(), head->length());
234  if (rc < 0) {
235  if (errno == EAGAIN || errno == EWOULDBLOCK) {
236  // pipe is full
237  VLOG(5) << "write blocked";
239  return;
240  } else {
241  failAllWrites(AsyncSocketException(
242  AsyncSocketException::INTERNAL_ERROR, "write failed", errno));
243  closeNow();
244  return;
245  }
246  } else if (rc == 0) {
248  return;
249  }
250  curQueue.trimStart(size_t(rc));
251  if (curQueue.empty()) {
252  auto cb = front.second;
253  queue_.pop_front();
254  if (cb) {
255  cb->writeSuccess();
256  }
257  } else {
258  VLOG(5) << "partial write blocked";
259  }
260  } while (!queue_.empty());
261 
262  if (closeOnEmpty_) {
263  closeNow();
264  } else {
266  }
267 }
const folly::IOBuf * front() const
Definition: IOBufQueue.h:476
bool empty() const
Definition: IOBufQueue.h:503
void failAllWrites(const AsyncSocketException &ex)
Definition: AsyncPipe.cpp:205
std::list< std::pair< folly::IOBufQueue, AsyncWriter::WriteCallback * > > queue_
Definition: AsyncPipe.h:177
ssize_t writeNoInt(int fd, const void *buf, size_t count)
Definition: FileUtil.cpp:114
void trimStart(size_t amount)
Definition: IOBufQueue.cpp:255
bool registerHandler(uint16_t events)
Definition: EventHandler.h:100
bool folly::AsyncPipeWriter::hasPendingWrites ( ) const
inline

Return true if there are currently writes pending (eg: the pipe is blocked for writing)

Definition at line 147 of file AsyncPipe.h.

147  {
148  return !queue_.empty();
149  }
std::list< std::pair< folly::IOBufQueue, AsyncWriter::WriteCallback * > > queue_
Definition: AsyncPipe.h:177
template<typename... Args>
static UniquePtr folly::AsyncPipeWriter::newWriter ( Args &&...  args)
inlinestatic

Definition at line 104 of file AsyncPipe.h.

Referenced by folly::TEST().

104  {
105  return UniquePtr(new AsyncPipeWriter(std::forward<Args>(args)...));
106  }
std::unique_ptr< AsyncPipeWriter, folly::DelayedDestruction::Destructor > UniquePtr
Definition: AsyncPipe.h:101
AsyncPipeWriter(folly::EventBase *eventBase, int pipeFd)
Definition: AsyncPipe.h:108
void folly::AsyncPipeWriter::setCloseCallback ( std::function< void(int)>  closeCb)
inline

Set a special hook to close the socket (otherwise, will call close())

Definition at line 122 of file AsyncPipe.h.

References folly::AsyncPipeReader::closeCb_.

122  {
123  closeCb_ = closeCb;
124  }
std::function< void(int)> closeCb_
Definition: AsyncPipe.h:179
void folly::AsyncPipeWriter::write ( std::unique_ptr< folly::IOBuf iob,
AsyncWriter::WriteCallback wcb = nullptr 
)

Asynchronously write the given iobuf to this pipe, and invoke the callback on success/error.

Definition at line 145 of file AsyncPipe.cpp.

References folly::IOBufQueue::append(), folly::EventHandler::isHandlerRegistered(), folly::gen::move, folly::AsyncSocketException::NOT_OPEN, and folly::AsyncWriter::WriteCallback::writeErr().

147  {
148  if (closed()) {
149  if (callback) {
150  AsyncSocketException ex(
151  AsyncSocketException::NOT_OPEN, "attempt to write to closed pipe");
152  callback->writeErr(0, ex);
153  }
154  return;
155  }
156  bool wasEmpty = (queue_.empty());
157  folly::IOBufQueue iobq;
158  iobq.append(std::move(buf));
159  std::pair<folly::IOBufQueue, AsyncWriter::WriteCallback*> p(
160  std::move(iobq), callback);
161  queue_.emplace_back(std::move(p));
162  if (wasEmpty) {
163  handleWrite();
164  } else {
165  CHECK(!queue_.empty());
166  CHECK(isHandlerRegistered());
167  }
168 }
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::list< std::pair< folly::IOBufQueue, AsyncWriter::WriteCallback * > > queue_
Definition: AsyncPipe.h:177
bool closed() const
Definition: AsyncPipe.h:129
bool isHandlerRegistered() const
Definition: EventHandler.h:112
void folly::AsyncPipeWriter::write ( folly::AsyncWriter::WriteCallback callback,
const void *  buf,
size_t  bytes,
WriteFlags  flags = WriteFlags::NONE 
)
inlineoverridevirtual

If you supply a non-null WriteCallback, exactly one of writeSuccess() or writeErr() will be invoked when the write completes. If you supply the same WriteCallback object for multiple write() calls, it will be invoked exactly once per call. The only way to cancel outstanding write requests is to close the socket (e.g., with closeNow() or shutdownWriteNow()). When closing the socket this way, writeErr() will still be invoked once for each outstanding write operation.

Implements folly::AsyncWriter.

Definition at line 152 of file AsyncPipe.h.

References folly::IOBuf::wrapBuffer().

156  {
157  writeChain(callback, IOBuf::wrapBuffer(buf, bytes), flags);
158  }
flags
Definition: http_parser.h:127
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
Definition: IOBuf.cpp:353
void writeChain(folly::AsyncWriter::WriteCallback *callback, std::unique_ptr< folly::IOBuf > &&buf, WriteFlags flags=WriteFlags::NONE) override
Definition: AsyncPipe.cpp:170
void folly::AsyncPipeWriter::writeChain ( folly::AsyncWriter::WriteCallback callback,
std::unique_ptr< folly::IOBuf > &&  buf,
WriteFlags  flags = WriteFlags::NONE 
)
overridevirtual

If you supply a non-null WriteCallback, exactly one of writeSuccess() or writeErr() will be invoked when the write completes. If you supply the same WriteCallback object for multiple write() calls, it will be invoked exactly once per call. The only way to cancel outstanding write requests is to close the socket (e.g., with closeNow() or shutdownWriteNow()). When closing the socket this way, writeErr() will still be invoked once for each outstanding write operation.

Implements folly::AsyncWriter.

Definition at line 170 of file AsyncPipe.cpp.

References folly::gen::move, and fizz::detail::write().

173  {
174  write(std::move(buf), callback);
175 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void write(std::unique_ptr< folly::IOBuf > iob, AsyncWriter::WriteCallback *wcb=nullptr)
Definition: AsyncPipe.cpp:145
void folly::AsyncPipeWriter::writev ( folly::AsyncWriter::WriteCallback callback,
const iovec *  vec,
size_t  count,
WriteFlags  flags = WriteFlags::NONE 
)
inlineoverridevirtual

If you supply a non-null WriteCallback, exactly one of writeSuccess() or writeErr() will be invoked when the write completes. If you supply the same WriteCallback object for multiple write() calls, it will be invoked exactly once per call. The only way to cancel outstanding write requests is to close the socket (e.g., with closeNow() or shutdownWriteNow()). When closing the socket this way, writeErr() will still be invoked once for each outstanding write operation.

Implements folly::AsyncWriter.

Definition at line 159 of file AsyncPipe.h.

References folly::AsyncPipeReader::handlerReady(), folly::pushmi::__adl::noexcept(), folly::NONE, and uint16_t.

163  {
164  throw std::runtime_error("writev is not supported. Please use writeChain.");
165  }

Member Data Documentation

std::function<void(int)> folly::AsyncPipeWriter::closeCb_
private

Definition at line 179 of file AsyncPipe.h.

bool folly::AsyncPipeWriter::closeOnEmpty_ {false}
private

Definition at line 178 of file AsyncPipe.h.

int folly::AsyncPipeWriter::fd_
private

Definition at line 176 of file AsyncPipe.h.

std::list<std::pair<folly::IOBufQueue, AsyncWriter::WriteCallback*> > folly::AsyncPipeWriter::queue_
private

Definition at line 177 of file AsyncPipe.h.


The documentation for this class was generated from the following files: