[Haskell-cafe] carry "state" around ....
Galchin, Vasili
vigalchin at gmail.com
Mon Jul 28 01:54:04 EDT 2008
Hi Duncan and Brandon,
I am moving to the ForeignPtr strategy. However, I always try to learn
from where I am before going to a new approach. I have discovered by
debugging that the AIOCB peek is working; however, passing the "peeked"
AIOCB back to the caller(i.e. the test program) is not working .. please let
me try to demonstrate below. I have been staring at my Haskell code many,
many times .... sigh ...
0)
IN PEEK CODE .. aioErrorCode => 115
IN PEEK CODE .. aioReturnValue => 0
aioWrite after aio_write
IN PEEK CODE .. aioErrorCode => 115
IN PEEK CODE .. aioReturnValue => 0
*************aiocb dump***************
fd => 3
opcode => 1
prio => 0
offset => 0
nbytes => 20
next => 0x00000000
absprio => 0
policy => 0
errocode => 115 <<<< correct ... INPROGRESS errno
return value => 0
<<<<<<<<<<<<<<<<<<<< return from call of Haskell function aioWrite here
... below "errocode" has changed from 115 to 0 ... somehow my "return AIOCB"
is corrupting the "state"/value of AIOCB ....
*****************aioWrite dumpAIOCB
*************aiocb dump***************
fd => 3
opcode => 0
prio => 0
offset => 0
nbytes => 20
next => 0x00000000
absprio => 0
policy => 0
errocode => 0 <<<< incorrect "Errno" ... should
still be IN PROGRESS.
return value => 0
1) aioWrite ... the function marshalling(poke) and unmarshalling(peek) an
AIOCB:
aioWrite :: AIOCB -> IO AIOCB
aioWrite aiocb = do
allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
poke p_aiocb aiocb
putStrLn "aioWrite before aio_write"
aiocb1 <- peek p_aiocb
dumpAIOCB aiocb1
throwErrnoIfMinus1 "aioWrite" (c_aio_write p_aiocb)
aiocb <- peek p_aiocb
putStrLn "aioWrite after aio_write"
aiocb <- peek p_aiocb
dumpAIOCB aiocb
-- putStrLn "aioWrite after aio_write"
-- aiocb1 <- peek p_aiocb
-- dumpAIOCB aiocb1
return (aiocb)
foreign import ccall safe "aio.h aio_write"
c_aio_write :: Ptr AIOCB -> IO CInt
2) an AIOCB:
data LioOps = LioRead | LioWrite | LioNop
data AIOCB = AIOCB {
aioFd :: Fd,
aioLioOpcode :: Int,
aioReqPrio :: Int,
aioOffset :: FileOffset,
aioBuf :: Ptr Word8,
aioBytes :: ByteCount,
aioSigevent :: Sigevent,
-- Internal members
aioNext :: Ptr AIOCB,
aioAbsPrio :: Int,
aioPolicy :: Int,
aioErrorCode :: Int,
aioReturnValue :: ByteCount
}
3) poke/peek
instance Storable AIOCB where
sizeOf _ = (#const sizeof (struct aiocb))
alignment _ = 1
poke p_AIOCB (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf
aioBytes aioSigevent aioNext aioAbsPrio aioPolicy aioErrorCode
aioReturnValue) = 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
(#poke struct aiocb, __next_prio) p_AIOCB aioNext
(#poke struct aiocb, __abs_prio) p_AIOCB aioAbsPrio
(#poke struct aiocb, __policy) p_AIOCB aioPolicy
(#poke struct aiocb, __error_code) p_AIOCB aioErrorCode
(#poke struct aiocb, __return_value) p_AIOCB aioReturnValue
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
aioNext <- (#peek struct aiocb, __next_prio) p_AIOCB
aioAbsPrio <- (#peek struct aiocb, __abs_prio) p_AIOCB
aioPolicy <- (#peek struct aiocb, __policy) p_AIOCB
aioErrorCode <- (#peek struct aiocb, __error_code) p_AIOCB
putStrLn ("IN PEEK CODE .. aioErrorCode => " ++ (show aioErrorCode))
aioReturnValue <- (#peek struct aiocb, __return_value) p_AIOCB
putStrLn ("IN PEEK CODE .. aioReturnValue => " ++ (show
aioReturnValue))
return (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf aioBytes
aioSigevent aioNext aioAbsPrio aioPolicy aioErrorCode aioReturnValue)
Kind regards, Vasili
On Sun, Jul 20, 2008 at 6:51 AM, Duncan Coutts
<duncan.coutts at worc.ox.ac.uk>wrote:
>
> On Sat, 2008-07-19 at 23:55 -0500, Galchin, Vasili wrote:
> > yes Duncan I am trying to pass-by-value. I am familiar with
> > ForeignPtr; however, I don't comprehend what you and Brandon are
> > suggesting to do. Could either of you provide a code illustration or
> > point at existing code to illustrate your approach?
>
> Take a look at John Meacham's RSA example.
>
> So at the moment you're using using Storable and a Haskell record, say:
>
> data AIOCB = AIOCB {
> ...
> }
>
> and we're suggesting instead:
>
> newtype AIOCB = AIOCB (ForeignPtr AIOCB)
>
> then to access a member use hsc2hs:
>
> getBlah :: AIOCB -> IO Blah
> getBlah (AIOCB fptr) =
> withForeignPtr fptr $ \ptr -> {# peek aiocb,blah #} ptr
>
> So you only access the parts you need and keep the aiocb C struct
> allocated on the heap (use mallocForeignPtr).
>
> Duncan
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080728/ce8c9b18/attachment.htm
More information about the Haskell-Cafe
mailing list