bool low_latency_iocp_context::io_operation::start_read()

in source/win32/low_latency_iocp_context.cpp [488:551]


  bool low_latency_iocp_context::io_operation::start_read(
      span<std::byte> buffer) noexcept {
    UNIFEX_ASSERT(context.is_running_on_io_thread());
    UNIFEX_ASSERT(ioState != nullptr);
    UNIFEX_ASSERT(ioState->operationCount < max_vectored_io_size);

    std::size_t offset = 0;
    while (offset < buffer.size()) {
      ntapi::IO_STATUS_BLOCK& iosb =
          ioState->operations[ioState->operationCount];
      ++ioState->operationCount;

      iosb.Status = STATUS_PENDING;
      iosb.Information = 0;

      // Truncate over-large chunks to a number of bytes that will still
      // preserve alignment requirements of the underlying device if this
      // happens to be an unbuffered storage device.
      // In this case we truncate to the largest multiple of 64k less than
      // 2^32 to allow for up to 64k alignment.
      // TODO: Ideally we'd just use the underlying alignment of the
      // file-handle.
      static constexpr std::size_t truncatedChunkSize = 0xFFFF0000u;
      static constexpr std::size_t maxChunkSize = 0xFFFFFFFFu;

      std::size_t chunkSize = buffer.size() - offset;
      if (chunkSize > maxChunkSize) {
        chunkSize = truncatedChunkSize;
      }

      ntapi::NTSTATUS status = ntapi::NtReadFile(
          fileHandle,
          NULL,                                  // Event
          NULL,                                  // ApcRoutine
          &iosb,                                 // ApcContext
          &iosb,                                 // IoStatusBlock
          buffer.data() + offset,                // Buffer
          static_cast<ntapi::ULONG>(chunkSize),  // Length
          nullptr,                               // ByteOffset
          nullptr);                              // Key
      if (status == STATUS_PENDING) {
        ++ioState->pendingCompletionNotifications;
      } else if (ntapi::ntstatus_success(status)) {
        // Succeeded synchronously.
        if (!skipNotificationOnSuccess) {
          ++ioState->pendingCompletionNotifications;
        }
      } else {
        // Immediate failure.
        // Don't launch any more operations.
        // TODO: Should we cancel any prior launched operations?
        return false;
      }

      if (ioState->operationCount == max_vectored_io_size) {
        // We've launched as many operations as we can.
        return false;
      }

      offset += chunkSize;
    }

    return true;
  }