NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/45441: aio_write and aio_read connected to one pipe don't make progress



>Number:         45441
>Category:       kern
>Synopsis:       aio_write and aio_read connected to one pipe don't make 
>progress
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Oct 07 22:55:00 +0000 2011
>Originator:     Alexander Nasonov
>Release:        NetBSD 5.99.56
>Organization:
home sweet home
>Environment:
NetBSD nebeda.localdomain 5.99.56 NetBSD 5.99.56 (GENERIC) #0: Thu Oct  6 
13:58:32 UTC 2011  
builds%b6.netbsd.org@localhost:/home/builds/ab/HEAD/amd64/201110061150Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC
 amd64
>Description:
If you initialize two aiocb structs to connect to one pipe and call aio_read 
before aio_write, then aio_error() calls will always be returning EINPROGRESS.

>How-To-Repeat:
#include <err.h>                                                                
                                               
#include <errno.h>                                                              
                                               
#include <limits.h>                                                             
                                               
#include <stdlib.h>                                                             
                                               
#include <string.h>                                                             
                                               
                                                                                
                                               
#include <aio.h>                                                                
                                               
#include <unistd.h>                                                             
                                               
                                                                                
                                               
static void                                                                     
                                               
init_pipe_data(int fd[], struct aiocb cb[], char *buf[], size_t buf_sz)         
                                               
{                                                                               
                                               
        int i;                                                                  
                                               
                                                                                
                                               
        if (pipe(fd) != 0)                                                      
                                               
                err(EXIT_FAILURE, "pipe");                                      
                                               
                                                                                
                                               
        for (i = 0; i < 2; i++) {                                               
                                               
                buf[i] = malloc(buf_sz);                                        
                                               
                if (buf[i] == NULL)                                             
                                               
                        err(EXIT_FAILURE, "malloc");                            
                                               
                buf[i][0] = i;                                                  
                                               
                buf[i][buf_sz-1] = CHAR_MAX - i;                                
                                               
                memset(&cb[i], 0, sizeof(cb[i]));                               
                                               
                cb[i].aio_buf = buf[i];                                         
                                               
                cb[i].aio_fildes = fd[i];                                       
                                               
                cb[i].aio_offset = 0;                                           
                                               
                cb[i].aio_nbytes = buf_sz;                                      
                                               
        }                                                                       
                                               
}

static void                                                                     
                                               
destroy_pipe_data(int fd[], char *buf[])                                        
                                               
{                                                                               
                                               
        int i;                                                                  
                                               
                                                                                
                                               
        for (i = 0; i < 2; i++) {                                               
                                               
                free(buf[i]);                                                   
                                               
                close(fd[i]);                                                   
                                               
        }                                                                       
                                               
}

int main()                                                                      
                                               
{                                                                               
                                               
        const size_t sz = PIPE_BUF + 13;                                        
                                               
                                                                                
                                               
        int res[2] = { EINPROGRESS, EINPROGRESS };                              
                                               
        int fd[2];                                                              
                                               
        struct aiocb cb[2];                                                     
                                               
        char *buf[2];                                                           
                                               
                                                                                
                                               
        init_pipe_data(fd, cb, buf, sz);                                        
                                               
                                                                                
                                               
        if (aio_read(&cb[0]) != 0)                                              
                                               
                err(EXIT_FAILURE, "aio_read");                                  
                                               
                                                                                
                                               
        if (aio_write(&cb[1]) != 0)                                             
                                               
                err(EXIT_FAILURE, "aio_write");                                 
                                               
                                                                                
                                               
        do {                                                                    
                                               
                int i;                                                          
                                               
                for (i = 0; i < 2; i++)                                         
                                               
                        if (res[i] == EINPROGRESS)                              
                                               
                                res[i] = aio_error(&cb[i]);                     
                                               
        } while (res[0] == EINPROGRESS || res[1] == EINPROGRESS);               
                                               
                                                                                
                                               
        destroy_pipe_data(fd, buf);                                             
                                               
                                                                                
                                               
        return EXIT_SUCCESS;                                                    
                                               
}                                                                               
                                      
 
>Fix:
not known



Home | Main Index | Thread Index | Old Index