Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: add zooSetAcl #12

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
allocating memory for acl vectors
Yu-zh committed Apr 6, 2021
commit 23a4c29670d8bb453a1e3a7b7b25314c9c7a83f8
45 changes: 43 additions & 2 deletions src/ZooKeeper.hs
Original file line number Diff line number Diff line change
@@ -19,6 +19,8 @@ module ZooKeeper
, zooWatchExists
, zooGetAcl
, zooSetAcl
, unsafeAllocaZooAcl
, fromAclList

, zooMulti
, zooCreateOpInit
@@ -38,13 +40,14 @@ module ZooKeeper
import Control.Concurrent (forkIO, myThreadId, newEmptyMVar,
takeMVar, threadCapability)
import Control.Exception (mask_, onException)
import Control.Monad (void, when, zipWithM, (<=<))
import Control.Monad (void, when, zipWithM, (<=<), forM_)
import Data.Bifunctor (first)
import Data.Maybe (fromMaybe)
import Foreign.C (CInt)
import Foreign.ForeignPtr (mallocForeignPtrBytes,
touchForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr, nullPtr, plusPtr)
import Foreign (Word8, Storable(pokeByteOff, peekByteOff, sizeOf, peek))
import GHC.Conc (newStablePtrPrimMVar)
import GHC.Stack (HasCallStack, callStack)
import Z.Data.CBytes (CBytes)
@@ -527,6 +530,44 @@ zooSetAcl zh path m_acl m_version = CBytes.withCBytesUnsafe path $ \path' -> do
let cfunc = I.c_hs_zoo_aset_acl' zh path' version nullPtr
E.throwZooErrorIfLeft =<< I.withZKAsync csize I.peekRet I.peekData cfunc

unsafeAllocaZooAcl :: I.ZooAcl -> IO Z.ByteArray
unsafeAllocaZooAcl (I.ZooAcl perms scheme id) = do
mba <- Z.newPinnedByteArray I.sizeOfZooAcl
mba_scheme@(Z.MutableByteArray mba_scheme#) <- Z.newPinnedByteArray (CBytes.length scheme)
mba_id@(Z.MutableByteArray mba_id#) <- Z.newPinnedByteArray (CBytes.length id)
let ptr_scheme = Z.mutableByteArrayContents mba_scheme
ptr_id = Z.mutableByteArrayContents mba_id
-- ptr = Z.mutableByteArrayContents mba
_ <- CBytes.pokeMBACBytes mba_scheme# 0 scheme
_ <- CBytes.pokeMBACBytes mba_id# 0 id
_ <- Z.writeByteArray mba 0 $ I.fromZooPerms perms
_ <- Z.writeByteArray mba 1 ptr_scheme
-- equivalently, we could poke the pointer
-- _ <- pokeByteOff ptr 8 ptr_scheme
-- peek_scheme_ptr <- peekByteOff ptr 8
-- peek_scheme <- CBytes.fromCString peek_scheme_ptr
-- print peek_scheme
_ <- Z.writeByteArray mba 2 ptr_id
Z.freezeByteArray mba 0 I.sizeOfZooAcl

fromAclList :: [I.ZooAcl] -> IO I.AclVector
fromAclList acls = do
let len = length acls
mba_data@(Z.MutableByteArray mba_data#) <- Z.newPinnedByteArray (I.sizeOfZooAcl * len)
forM_ (zip [0..len-1] acls) $ \(idx, acl) -> do
ba_acl <- unsafeAllocaZooAcl acl
Z.copyByteArray mba_data (idx * I.sizeOfZooAcl) ba_acl 0 I.sizeOfZooAcl
-- let ptr_acl = Z.byteArrayContents ba_acl
-- _ <- Z.writeByteArray mba_data idx ptr_acl
return ()
let ptr_data = Z.mutableByteArrayContents mba_data
mba@(Z.MutableByteArray mba#) <- Z.newPinnedByteArray (sizeOf len + sizeOf ptr_data)
Z.writeByteArray mba 0 len -- should be 8 bytes
-- writeByteArray calculates the offset based on the type of the elements to write instead of bytes
-- so we rely on the fact that pointers and integers have the same length
Z.writeByteArray mba 1 ptr_data
return . I.AclVector . Z.castPtr . Z.mutableByteArrayContents $ mba

-------------------------------------------------------------------------------

-- | Atomically commits multiple zookeeper operations.
@@ -538,7 +579,7 @@ zooMulti
=> T.ZHandle
-- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
-> [T.ZooOp]
-- ^ An list of operations to commit
-- ^ A list of operations to commit
-> IO [T.ZooOpResult]
zooMulti zh ops = do
let len = length ops
9 changes: 6 additions & 3 deletions src/ZooKeeper/Internal/Types.hsc
Original file line number Diff line number Diff line change
@@ -88,7 +88,7 @@ data ZooAcl = ZooAcl
{ aclPerms :: [ZooPerm]
, aclIdScheme :: CBytes
, aclId :: CBytes
} deriving Show
} deriving (Show, Eq)

{-# INLINE sizeOfZooAcl #-}
sizeOfZooAcl :: Int
@@ -99,8 +99,11 @@ peekZooAcl ptr = do
perms <- toZooPerms <$> (#peek acl_t, perms) ptr
scheme_ptr <- (#peek acl_t, id.scheme) ptr
id_ptr <- (#peek acl_t, id.id) ptr
scheme <- CBytes.fromCString scheme_ptr <* free scheme_ptr
acl_id <- CBytes.fromCString id_ptr <* free id_ptr
-- scheme <- CBytes.fromCString scheme_ptr <* free scheme_ptr
-- acl_id <- CBytes.fromCString id_ptr <* free id_ptr
-- we can't do the free for some reason I don't know
scheme <- CBytes.fromCString scheme_ptr
acl_id <- CBytes.fromCString id_ptr
return $ ZooAcl perms scheme acl_id

-- TODO
2 changes: 2 additions & 0 deletions src/ZooKeeper/Types.hs
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@ module ZooKeeper.Types
, I.zooReadAclUnsafe
, I.zooCreatorAllAcl
, I.ZooAcl (..)
, I.toAclList
, I.peekZooAcl

, I.HsWatcherCtx (..)