InitXLogReaderState(XLogRecPtr lsn, XLogRecPtr *first_record)
 {
    XLogReaderState *xlogreader;
+   ReadLocalXLogPageNoWaitPrivate *private_data;
 
    /*
     * Reading WAL below the first page of the first segments isn't allowed.
                (errmsg("could not read WAL at LSN %X/%X",
                        LSN_FORMAT_ARGS(lsn))));
 
+   private_data = (ReadLocalXLogPageNoWaitPrivate *)
+                       palloc0(sizeof(ReadLocalXLogPageNoWaitPrivate));
+
    xlogreader = XLogReaderAllocate(wal_segment_size, NULL,
                                    XL_ROUTINE(.page_read = &read_local_xlog_page_no_wait,
                                               .segment_open = &wal_segment_open,
                                               .segment_close = &wal_segment_close),
-                                   NULL);
+                                   private_data);
 
    if (xlogreader == NULL)
        ereport(ERROR,
  *
  * We guard against ordinary errors trying to read WAL that hasn't been
  * written yet by limiting end_lsn to the flushed WAL, but that can also
- * encounter errors if the flush pointer falls in the middle of a record.
+ * encounter errors if the flush pointer falls in the middle of a record. In
+ * that case we'll return NULL.
  */
 static XLogRecord *
 ReadNextXLogRecord(XLogReaderState *xlogreader, XLogRecPtr first_record)
 
    if (record == NULL)
    {
+       ReadLocalXLogPageNoWaitPrivate *private_data;
+
+       /* return NULL, if end of WAL is reached */
+       private_data = (ReadLocalXLogPageNoWaitPrivate *)
+                           xlogreader->private_data;
+
+       if (private_data->end_of_wal)
+           return NULL;
+
        if (errormsg)
            ereport(ERROR,
                    (errcode_for_file_access(),
 
    xlogreader = InitXLogReaderState(lsn, &first_record);
 
-   (void) ReadNextXLogRecord(xlogreader, first_record);
+   if (!ReadNextXLogRecord(xlogreader, first_record))
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("could not read WAL at %X/%X",
+                       LSN_FORMAT_ARGS(first_record))));
 
    MemSet(values, 0, sizeof(values));
    MemSet(nulls, 0, sizeof(nulls));
    GetWALRecordInfo(xlogreader, first_record, values, nulls,
                     PG_GET_WAL_RECORD_INFO_COLS);
 
+   pfree(xlogreader->private_data);
    XLogReaderFree(xlogreader);
 
    tuple = heap_form_tuple(tupdesc, values, nulls);
    MemSet(values, 0, sizeof(values));
    MemSet(nulls, 0, sizeof(nulls));
 
-   for (;;)
+   while (ReadNextXLogRecord(xlogreader, first_record) &&
+          xlogreader->EndRecPtr <= end_lsn)
    {
-       (void) ReadNextXLogRecord(xlogreader, first_record);
-
-       if (xlogreader->EndRecPtr <= end_lsn)
-       {
-           GetWALRecordInfo(xlogreader, xlogreader->currRecPtr, values, nulls,
-                            PG_GET_WAL_RECORDS_INFO_COLS);
+       GetWALRecordInfo(xlogreader, xlogreader->currRecPtr, values, nulls,
+                        PG_GET_WAL_RECORDS_INFO_COLS);
 
-           tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
-                                values, nulls);
-       }
-
-       /* if we read up to end_lsn, we're done */
-       if (xlogreader->EndRecPtr >= end_lsn)
-           break;
+       tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
+                            values, nulls);
 
        CHECK_FOR_INTERRUPTS();
    }
 
+   pfree(xlogreader->private_data);
    XLogReaderFree(xlogreader);
 
 #undef PG_GET_WAL_RECORDS_INFO_COLS
 
    MemSet(&stats, 0, sizeof(stats));
 
-   for (;;)
+   while (ReadNextXLogRecord(xlogreader, first_record) &&
+          xlogreader->EndRecPtr <= end_lsn)
    {
-       (void) ReadNextXLogRecord(xlogreader, first_record);
-
-       if (xlogreader->EndRecPtr <= end_lsn)
-           XLogRecStoreStats(&stats, xlogreader);
-
-       /* if we read up to end_lsn, we're done */
-       if (xlogreader->EndRecPtr >= end_lsn)
-           break;
+       XLogRecStoreStats(&stats, xlogreader);
 
        CHECK_FOR_INTERRUPTS();
    }
 
+   pfree(xlogreader->private_data);
    XLogReaderFree(xlogreader);
 
    MemSet(values, 0, sizeof(values));