
Hello, I am also testing my aio support. The aio_write binding seems to work ok .. as well as aio_error, Aio_return is a problem child. I think I wrote a really simple binding. I always receive nbytes as 0. I have been staring at the code hoping to catch a stupid mistake. I put putStrLn's in the code. .....Here is the code ... aioReturn :: AIOCB -> IO (AIOCB, ByteCount) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) aiocb <- peek p_aiocb return (aiocb, fromIntegral count) foreign import ccall safe "aio.h aio_return" c_aio_return :: Ptr AIOCB -> IO CInt Maybe someone can spot something that I haven't. Thanks, Vasili

Hello Vasili, Tuesday, July 1, 2008, 11:42:26 AM, you wrote: looks ok, show us your peek/poke code
Hello,
I am also testing my aio support. The aio_write binding seems to work ok .. as well as aio_error, Aio_return is a problem child. I think I wrote a really simple binding. I always receive nbytes as 0. I have been staring at the code hoping to catch a stupid mistake. I put putStrLn's in the code. .....Here is the code ...
aioReturn :: AIOCB -> IO (AIOCB, ByteCount) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) aiocb <- peek p_aiocb return (aiocb, fromIntegral count)
foreign import ccall safe "aio.h aio_return" c_aio_return :: Ptr AIOCB -> IO CInt
Maybe someone can spot something that I haven't.
Thanks, Vasili
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

instance Storable AIOCB where
sizeOf _ = (#const sizeof (struct aiocb))
alignment _ = 1
poke p_AIOCB (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf
aioBytes aioSigevent) = do
(#poke struct aiocb, aio_fildes) p_AIOCB aioFd
(#poke struct aiocb, aio_lio_opcode) p_AIOCB aioLioOpcode
(#poke struct aiocb, aio_reqprio) p_AIOCB aioReqPrio
(#poke struct aiocb, aio_offset) p_AIOCB aioOffset
(#poke struct aiocb, aio_buf) p_AIOCB aioBuf
(#poke struct aiocb, aio_nbytes) p_AIOCB aioBytes
(#poke struct aiocb, aio_sigevent) p_AIOCB aioSigevent
peek p_AIOCB = do
aioFd <- (#peek struct aiocb, aio_fildes) p_AIOCB
aioLioOpcode <- (#peek struct aiocb, aio_lio_opcode) p_AIOCB
aioReqPrio <- (#peek struct aiocb, aio_reqprio) p_AIOCB
aioOffset <- (#peek struct aiocb, aio_offset) p_AIOCB
aioBuf <- (#peek struct aiocb, aio_buf) p_AIOCB
aioBytes <- (#peek struct aiocb, aio_nbytes) p_AIOCB
aioSigevent <- (#peek struct aiocb, aio_sigevent) p_AIOCB
return (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf aioBytes
aioSigevent)
On Tue, Jul 1, 2008 at 2:48 AM, Bulat Ziganshin
Hello Vasili,
Tuesday, July 1, 2008, 11:42:26 AM, you wrote:
looks ok, show us your peek/poke code
Hello,
I am also testing my aio support. The aio_write binding seems to work ok .. as well as aio_error, Aio_return is a problem child. I think I wrote a really simple binding. I always receive nbytes as 0. I have been staring at the code hoping to catch a stupid mistake. I put putStrLn's in the code. .....Here is the code ...
aioReturn :: AIOCB -> IO (AIOCB, ByteCount) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) aiocb <- peek p_aiocb return (aiocb, fromIntegral count)
foreign import ccall safe "aio.h aio_return" c_aio_return :: Ptr AIOCB -> IO CInt
Maybe someone can spot something that I haven't.
Thanks, Vasili
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hello,
Haskell 101 question! I discovered that aio_error returns "errno" rather
-1. Of course, my aio_error binding is called before my aio_return binding
(aio calling sequence "protocol"). I have worked on Posix OS's for quite a
while but am unhappy with non-consistent errno handling ;^(. In any case, I
modified my aio_error binding implementation to have a "AIOCB -> IO Errno"
signature:
aioError :: AIOCB -> IO Errno
aioError aiocb = do
allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
poke p_aiocb aiocb
errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb)
return (errno)
foreign import ccall safe "aio.h aio_error"
c_aio_error :: Ptr AIOCB -> IO Errno
"ghc" thinks that "Errno" should be an instance of "Num":
System/Posix/Aio.hsc:117:15:
No instance for (Num Errno)
Why?
Vasili
On Tue, Jul 1, 2008 at 2:42 AM, Galchin, Vasili
Hello,
I am also testing my aio support. The aio_write binding seems to work ok .. as well as aio_error, Aio_return is a problem child. I think I wrote a really simple binding. I always receive nbytes as 0. I have been staring at the code hoping to catch a stupid mistake. I put putStrLn's in the code. .....Here is the code ...
aioReturn :: AIOCB -> IO (AIOCB, ByteCount) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) aiocb <- peek p_aiocb return (aiocb, fromIntegral count)
foreign import ccall safe "aio.h aio_return" c_aio_return :: Ptr AIOCB -> IO CInt
Maybe someone can spot something that I haven't.
Thanks, Vasili

On 2008 Jul 2, at 1:42, Galchin, Vasili wrote:
errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb)
"ghc" thinks that "Errno" should be an instance of "Num":
System/Posix/Aio.hsc:117:15: No instance for (Num Errno)
I expect so it can compare it to -1(throwErrnoIfMinusOne). But if the return value is actually an errno and not -1 to indicate error (which it is if I read the manpage correctly), you don't want throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value of c_aio_return (which should be IO CInt) in an Errno constructor, then use errnoToIOError if you really want to raise an IOError. (What were you expecting for "count"? I see none, just an errno.) Note that it *never* returns -1; it returns 0 for successful completion for the aiocb, EINPROGRESS if it's still working, and the appropriate errno if it failed. You might want to decide if you want to use the aio_return style interface or something more Haskell-ish before designing this part of the API. If you want to stick close to the C interface: aioReturn :: AIOCB -> IO (AIOCB, Errno) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb err <- c_aio_return p_aiocb aiocb <- peek p_aiocb return (aiocb, Errno err) I'd actually consider something more Haskellish, e.g. a variant of StateT IO where the state is the aiocb and errno, the errno initialized to eINPROGRESS and set by aioReturn and aioError (and once aioReturn is called, it can't be called again so return the cached value if needed). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Wed, 2008-07-02 at 02:07 -0400, Brandon S. Allbery KF8NH wrote:
On 2008 Jul 2, at 1:42, Galchin, Vasili wrote:
errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb)
"ghc" thinks that "Errno" should be an instance of "Num":
System/Posix/Aio.hsc:117:15: No instance for (Num Errno)
I expect so it can compare it to -1(throwErrnoIfMinusOne). But if the return value is actually an errno and not -1 to indicate error (which it is if I read the manpage correctly), you don't want throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value of c_aio_return (which should be IO CInt) in an Errno constructor, then use errnoToIOError if you really want to raise an IOError.
(What were you expecting for "count"? I see none, just an errno.)
Note that it *never* returns -1; it returns 0 for successful completion for the aiocb, EINPROGRESS if it's still working, and the appropriate errno if it failed.
It seems as though it can return -1 if given non-sensical input. But in that case, the nicely type-correct thing to do would still be to have the C binding return a CInt, and wrap that after the call to throwErrnoIfMinus1 (in this case, `errno' still refers to the global errno, set to EINVAL). jcc

On 2008 Jul 2, at 2:15, Jonathan Cast wrote:
It seems as though it can return -1 if given non-sensical input. But in
The POSIX spec says it returns EINVAL in that case. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Wed, 2008-07-02 at 02:17 -0400, Brandon S. Allbery KF8NH wrote:
On 2008 Jul 2, at 2:15, Jonathan Cast wrote:
It seems as though it can return -1 if given non-sensical input. But in
The POSIX spec says it returns EINVAL in that case.
Are you sure? A little googling picks up e.g. HP docs [1] that state RETURN VALUE If the aiocb is invalid or if no asynchronous I/O operation is enqueued for the aiocb, aio_error() returns -1 and errno is set to indicate the error It may be non-POSIX, but I'd like to see some verbiage for which HP/UX's behavior isn't the most natural interpretation. jcc [1] http://docs.hp.com/en/B9106-90009/aio_error.2.html

On 2008 Jul 2, at 2:32, Jonathan Cast wrote:
On Wed, 2008-07-02 at 02:17 -0400, Brandon S. Allbery KF8NH wrote:
On 2008 Jul 2, at 2:15, Jonathan Cast wrote:
It seems as though it can return -1 if given non-sensical input. But in
The POSIX spec says it returns EINVAL in that case.
Are you sure? A little googling picks up e.g. HP docs [1] that state
Hm. I think the manuals I was looking at are ambiguous on the point, and I can't get at the actual standard right now. Probably best to assume -1/EINVAL is a possible return value, then. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

Thanks, Brandon!! I understand most of what you say but let me ponder! Kind regards, Vasili On Wed, Jul 2, 2008 at 1:07 AM, Brandon S. Allbery KF8NH < allbery@ece.cmu.edu> wrote:
On 2008 Jul 2, at 1:42, Galchin, Vasili wrote:
errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb)
"ghc" thinks that "Errno" should be an instance of "Num":
System/Posix/Aio.hsc:117:15: No instance for (Num Errno)
I expect so it can compare it to -1(throwErrnoIfMinusOne). But if the return value is actually an errno and not -1 to indicate error (which it is if I read the manpage correctly), you don't want throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value of c_aio_return (which should be IO CInt) in an Errno constructor, then use errnoToIOError if you really want to raise an IOError.
(What were you expecting for "count"? I see none, just an errno.)
Note that it *never* returns -1; it returns 0 for successful completion for the aiocb, EINPROGRESS if it's still working, and the appropriate errno if it failed.
You might want to decide if you want to use the aio_return style interface or something more Haskell-ish before designing this part of the API. If you want to stick close to the C interface:
aioReturn :: AIOCB -> IO (AIOCB, Errno) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb err <- c_aio_return p_aiocb aiocb <- peek p_aiocb return (aiocb, Errno err) I'd actually consider something more Haskellish, e.g. a variant of StateT IO where the state is the aiocb and errno, the errno initialized to eINPROGRESS and set by aioReturn and aioError (and once aioReturn is called, it can't be called again so return the cached value if needed).
-- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

Hi Brandon, Most of what you say makes sense. However, at some places in your narrative aren't you mixing up my aioError and aioReturn?(or aio_error and aio_return, respectively). E.g. aioReturn should return the byte count and not errno? If you want to stick close to the C interface: aioReturn :: AIOCB -> IO (AIOCB, Errno) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb err <- c_aio_return p_aiocb aiocb <- peek p_aiocb return (aiocb, Errno err) Vasili On Wed, Jul 2, 2008 at 1:07 AM, Brandon S. Allbery KF8NH < allbery@ece.cmu.edu> wrote:
On 2008 Jul 2, at 1:42, Galchin, Vasili wrote:
errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb)
"ghc" thinks that "Errno" should be an instance of "Num":
System/Posix/Aio.hsc:117:15: No instance for (Num Errno)
I expect so it can compare it to -1(throwErrnoIfMinusOne). But if the return value is actually an errno and not -1 to indicate error (which it is if I read the manpage correctly), you don't want throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value of c_aio_return (which should be IO CInt) in an Errno constructor, then use errnoToIOError if you really want to raise an IOError.
(What were you expecting for "count"? I see none, just an errno.)
Note that it *never* returns -1; it returns 0 for successful completion for the aiocb, EINPROGRESS if it's still working, and the appropriate errno if it failed.
You might want to decide if you want to use the aio_return style interface or something more Haskell-ish before designing this part of the API. If you want to stick close to the C interface:
aioReturn :: AIOCB -> IO (AIOCB, Errno) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb err <- c_aio_return p_aiocb aiocb <- peek p_aiocb return (aiocb, Errno err) I'd actually consider something more Haskellish, e.g. a variant of StateT IO where the state is the aiocb and errno, the errno initialized to eINPROGRESS and set by aioReturn and aioError (and once aioReturn is called, it can't be called again so return the cached value if needed).
-- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
participants (4)
-
Brandon S. Allbery KF8NH
-
Bulat Ziganshin
-
Galchin, Vasili
-
Jonathan Cast