On Sep13, 2011, at 13:07 , Florian Pflug wrote:
> Here's my suggested implementation for pg_write_nointr. pg_read_nointr should 
> be similar
> (but obviously without the ENOSPC handling)
> 
> <wrong pg_write_nointr implementation snipped>

Sorry for the self-reply. I realized only after hitting send that I
got the ENOSPC handling wrong again - we probably ought to check for
ENOSPC as well as ret == 0. Also, it seems preferable to return the
number of bytes actually written instead of -1 if we hit an error during
retry.

With this version, any return value other than <amount> signals an
error, the number of actually written bytes is reported even in the
case of an error (to the best of pg_write_nointr's knowledge), and
errno always indicates the kind of error.

int pg_write_nointr(int fd, const void *bytes, Size amount)
{
 int written = 0;

 while (amount > 0)
 {
   int ret;

   ret = write(fd, bytes, amount);

   if ((ret < 0) && (errno == EINTR))
   {
     /* interrupted by signal before first byte was written. Retry */

     /* XXX: Is it safe to call CHECK_FOR_INTERRUPTS here? */
     CHECK_FOR_INTERRUPTS();

     continue;
   }
   else if (ret < 1)
   {
     /* error occurred. Abort */

     if (ret == 0)
       /* out of disk space */
       errno = ENOSPC;

     if (written == 0)
       return -1;
     else
       return written;
   }

   /* made progress */
   written += ret;
   amount -= ret;
   bytes = (const char *) bytes + ret;
   
   /* XXX: Is it safe to call CHECK_FOR_INTERRUPTS here? */
   CHECK_FOR_INTERRUPTS();
 }
}

best regards,
Florian Pflug


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to