LCOV - code coverage report
Current view: top level - src/include/port - pg_iovec.h (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 8 8 100.0 %
Date: 2024-11-21 08:14:44 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * pg_iovec.h
       4             :  *    Header for vectored I/O functions, to use in place of <sys/uio.h>.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  * src/include/port/pg_iovec.h
      10             :  *
      11             :  *-------------------------------------------------------------------------
      12             :  */
      13             : #ifndef PG_IOVEC_H
      14             : #define PG_IOVEC_H
      15             : 
      16             : #ifndef WIN32
      17             : 
      18             : #include <limits.h>
      19             : #include <sys/uio.h>
      20             : #include <unistd.h>
      21             : 
      22             : #else
      23             : 
      24             : /* POSIX requires at least 16 as a maximum iovcnt. */
      25             : #define IOV_MAX 16
      26             : 
      27             : /* Define our own POSIX-compatible iovec struct. */
      28             : struct iovec
      29             : {
      30             :     void       *iov_base;
      31             :     size_t      iov_len;
      32             : };
      33             : 
      34             : #endif
      35             : 
      36             : /* Define a reasonable maximum that is safe to use on the stack. */
      37             : #define PG_IOV_MAX Min(IOV_MAX, 32)
      38             : 
      39             : /*
      40             :  * Like preadv(), but with a prefix to remind us of a side-effect: on Windows
      41             :  * this changes the current file position.
      42             :  */
      43             : static inline ssize_t
      44     2900776 : pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
      45             : {
      46             : #if HAVE_DECL_PREADV
      47             :     /*
      48             :      * Avoid a small amount of argument copying overhead in the kernel if
      49             :      * there is only one iovec.
      50             :      */
      51     2900776 :     if (iovcnt == 1)
      52     2899474 :         return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
      53             :     else
      54        1302 :         return preadv(fd, iov, iovcnt, offset);
      55             : #else
      56             :     ssize_t     sum = 0;
      57             :     ssize_t     part;
      58             : 
      59             :     for (int i = 0; i < iovcnt; ++i)
      60             :     {
      61             :         part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
      62             :         if (part < 0)
      63             :         {
      64             :             if (i == 0)
      65             :                 return -1;
      66             :             else
      67             :                 return sum;
      68             :         }
      69             :         sum += part;
      70             :         offset += part;
      71             :         if ((size_t) part < iov[i].iov_len)
      72             :             return sum;
      73             :     }
      74             :     return sum;
      75             : #endif
      76             : }
      77             : 
      78             : /*
      79             :  * Like pwritev(), but with a prefix to remind us of a side-effect: on Windows
      80             :  * this changes the current file position.
      81             :  */
      82             : static inline ssize_t
      83     1838074 : pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
      84             : {
      85             : #if HAVE_DECL_PWRITEV
      86             :     /*
      87             :      * Avoid a small amount of argument copying overhead in the kernel if
      88             :      * there is only one iovec.
      89             :      */
      90     1838074 :     if (iovcnt == 1)
      91     1665844 :         return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
      92             :     else
      93      172230 :         return pwritev(fd, iov, iovcnt, offset);
      94             : #else
      95             :     ssize_t     sum = 0;
      96             :     ssize_t     part;
      97             : 
      98             :     for (int i = 0; i < iovcnt; ++i)
      99             :     {
     100             :         part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
     101             :         if (part < 0)
     102             :         {
     103             :             if (i == 0)
     104             :                 return -1;
     105             :             else
     106             :                 return sum;
     107             :         }
     108             :         sum += part;
     109             :         offset += part;
     110             :         if ((size_t) part < iov[i].iov_len)
     111             :             return sum;
     112             :     }
     113             :     return sum;
     114             : #endif
     115             : }
     116             : 
     117             : #endif                          /* PG_IOVEC_H */

Generated by: LCOV version 1.14