Beispiel #1
0
Range<AsyncIO::Op**> AsyncIO::doWait(size_t minRequests, size_t maxRequests) {
  io_event events[pending_];
  int count;
  do {
    // Wait forever
    count = io_getevents(ctx_, minRequests, maxRequests, events, nullptr);
  } while (count == -EINTR);
  checkKernelError(count, "AsyncIO: io_getevents failed");
  DCHECK_GE(count, minRequests);  // the man page says so
  DCHECK_LE(count, pending_);

  completed_.clear();
  if (count == 0) {
    return folly::Range<Op**>();
  }

  for (size_t i = 0; i < count; ++i) {
    DCHECK(events[i].obj);
    Op* op = boost::intrusive::get_parent_from_member(
        events[i].obj, &AsyncIOOp::iocb_);
    --pending_;
    op->complete(events[i].res);
    completed_.push_back(op);
  }

  return folly::Range<Op**>(&completed_.front(), count);
}
Beispiel #2
0
Range<AsyncIO::Op**> AsyncIO::doWait(size_t minRequests, size_t maxRequests) {
  io_event events[maxRequests];

  size_t count = 0;
  do {
    int ret;
    do {
      // GOTCHA: io_getevents() may returns less than min_nr results if
      // interrupted after some events have been read (if before, -EINTR
      // is returned).
      ret = io_getevents(ctx_,
                         minRequests - count,
                         maxRequests - count,
                         events + count,
                         /* timeout */ nullptr);  // wait forever
    } while (ret == -EINTR);
    // Check as may not be able to recover without leaking events.
    CHECK_GE(ret, 0)
      << "AsyncIO: io_getevents failed with error " << errnoStr(-ret);
    count += ret;
  } while (count < minRequests);
  DCHECK_LE(count, maxRequests);

  completed_.clear();
  if (count == 0) {
    return folly::Range<Op**>();
  }

  for (size_t i = 0; i < count; ++i) {
    DCHECK(events[i].obj);
    Op* op = boost::intrusive::get_parent_from_member(
        events[i].obj, &AsyncIOOp::iocb_);
    decrementPending();
    op->complete(events[i].res);
    completed_.push_back(op);
  }

  return folly::Range<Op**>(&completed_.front(), count);
}