Fix memory leak in new counter implementation

Since we're allocating memory for use outside Haskell, we're
responsible for freeing it. Switched to ForeignPtr to automate this.
This commit is contained in:
Johan Tibell 2014-04-10 15:21:07 +02:00
parent 308768c5b1
commit 52bc89f474
3 changed files with 19 additions and 10 deletions

View file

@ -10,11 +10,17 @@ module System.Remote.Counter
, add , add
) where ) where
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (Ptr)
import System.Remote.Counter.Internal import System.Remote.Counter.Internal
-- | Increase the counter by one. -- | Increase the counter by one.
inc :: Counter -> IO () inc :: Counter -> IO ()
inc counter = add counter 1 inc counter = add counter 1
add :: Counter -> Int -> IO ()
add (C fp) n = withForeignPtr fp $ \ p -> cAdd p n
-- | Increase the counter by the given amount. -- | Increase the counter by the given amount.
foreign import ccall unsafe "hs_counter_add" add :: Counter -> Int -> IO () foreign import ccall unsafe "hs_counter_add" cAdd :: Ptr Int -> Int -> IO ()

View file

@ -8,13 +8,22 @@ module System.Remote.Counter.Internal
) where ) where
import Data.Int import Data.Int
import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr) import Foreign.Ptr (Ptr)
import Foreign.Storable (poke)
import Prelude hiding (read) import Prelude hiding (read)
-- | A mutable, integer-valued counter. -- | A mutable, integer-valued counter.
newtype Counter = C { unC :: Ptr Int64 } newtype Counter = C { unC :: ForeignPtr Int }
-- | Create a new, zero initialized, counter. -- | Create a new, zero initialized, counter.
foreign import ccall unsafe "hs_counter_new" new :: IO Counter new :: IO Counter
new = do
fp <- mallocForeignPtr
withForeignPtr fp $ \ p -> poke p 0
return $ C fp
foreign import ccall unsafe "hs_counter_read" read :: Counter -> IO Int read :: Counter -> IO Int
read (C fp) = withForeignPtr fp cRead
foreign import ccall unsafe "hs_counter_read" cRead :: Ptr Int -> IO Int

View file

@ -1,11 +1,5 @@
#include <stdlib.h>
#include "HsFFI.h" #include "HsFFI.h"
StgInt* hs_counter_new(void) {
StgInt* counter = malloc(sizeof(StgInt));
*counter = 0;
return counter;
}
void hs_counter_add(volatile StgInt* counter, StgInt n) { void hs_counter_add(volatile StgInt* counter, StgInt n) {
__sync_fetch_and_add(counter, n); __sync_fetch_and_add(counter, n);
} }