{- Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. -} module Glean.Util.Mutex ( Mutex, newMutex, withMutex, withMutexSafe, withMutex_, tryWithMutex, tryWithMutexSafe, ) where import Control.Concurrent.MVar import Control.Exception (bracket) newtype Mutex a = Mutex (MVar a) newMutex :: a -> IO (Mutex a) newMutex x = Mutex <$> newMVar x withMutex :: Mutex a -> (a -> IO b) -> IO b withMutex (Mutex v) = withMVar v withMutexSafe :: Mutex (f a) -> (forall s . f s -> IO b) -> IO b withMutexSafe (Mutex v) = withMVar v withMutex_ :: Mutex a -> IO b -> IO b withMutex_ m = withMutex m . const tryWithMutex :: Mutex a -> (a -> IO b) -> IO (Maybe b) tryWithMutex (Mutex v) f = bracket (tryTakeMVar v) (maybe (return ()) $ putMVar v) (traverse f) tryWithMutexSafe :: Mutex (f a) -> (forall s . f s -> IO b) -> IO (Maybe b) tryWithMutexSafe = tryWithMutex