diff --git a/libs/base/Data/IORef.idr b/libs/base/Data/IORef.idr index 6231967c48..3467fdcf8b 100644 --- a/libs/base/Data/IORef.idr +++ b/libs/base/Data/IORef.idr @@ -17,33 +17,47 @@ export data IORef : Type -> Type where MkRef : Mut a -> IORef a +||| Create a new IORef. export newIORef : HasIO io => a -> io (IORef a) newIORef val = do m <- primIO (prim__newIORef val) pure (MkRef m) +||| Read the value of an IORef. %inline export readIORef : HasIO io => IORef a -> io a readIORef (MkRef m) = primIO (prim__readIORef m) +||| Write a new value into an IORef. +||| This function does not create a memory barrier and can be reordered with other independent reads and writes within a thread, +||| which may cause issues for multithreaded execution. %inline export writeIORef : HasIO io => IORef a -> (val : a) -> io () writeIORef (MkRef m) val = primIO (prim__writeIORef m val) +||| Write a new value into an IORef. +||| This function does not create a memory barrier and can be reordered with other independent reads and writes within a thread, +||| which may cause issues for multithreaded execution. %inline export writeIORef1 : HasLinearIO io => IORef a -> (1 val : a) -> io () writeIORef1 (MkRef m) val = primIO1 (prim__writeIORef m val) +||| Mutate the contents of an IORef, combining readIORef and writeIORef. +||| This is not an atomic update, consider using atomicModifyIORef when operating in a multithreaded environment. export modifyIORef : HasIO io => IORef a -> (a -> a) -> io () modifyIORef ref f = do val <- readIORef ref writeIORef ref (f val) +||| This function atomically modifies the contents of an IORef. +||| This function is useful for using IORef in a safe way in a multithreaded program. +||| If you only have one IORef, then using atomicModifyIORef to access and modify it will prevent race conditions. +||| Any backend other than the default (chez) will perform modifyIORef (non-atomic). export atomicModifyIORef : HasIO io => IORef a -> (a -> a) -> io () atomicModifyIORef ref f @@ -53,4 +67,4 @@ atomicModifyIORef ref f val <- readIORef ref () <- writeIORef ref (f val) mutexRelease mutex - _ => pure () + _ => modifyIORef ref f