withWorker :: Manager -> HANDLE -> (Enqueue -> IO a) -> IO a
withWorker mgr@Manager{..} h cb =
    mask $ \restore -> do
        (enqueue, releaseF) <- atomicModifyIORef mgrWorkerMap grabF
        let release = atomicModifyIORef mgrWorkerMap releaseF
                  >>= evaluate
        a <- restore (cb enqueue) `onException` release
        release
        return a
  where
    key = (fromIntegral . ptrToIntPtr) h :: Int

    grabF :: WorkerMap -> (WorkerMap, (Enqueue, ReleaseF))
    grabF m =
        case IM.lookup key m of
            Nothing ->
                let !pool = Pool False mgrWorkers 1
                    !m'   = IM.insert key pool m
                 in (m', (postIO mgr, releaseCP))
            Just Pool{..}
              | pCompletionPort ->
                let !pool = Pool False pWorkers (pRefCount + 1)
                    !m'   = IM.insert key pool m
                 in (m', (postIO mgr, releaseCP))
              | WL w ws <- pWorkers ->
                let !pool = Pool pCompletionPort ws (pRefCount + 1)
                    !m'   = IM.insert key pool m
                 in (m', (Worker.enqueue w, releaseWorker w))

    releaseCP :: ReleaseF
    releaseCP = releaseWith $ \Pool{..} ->
        Pool True pWorkers (pRefCount - 1)

    releaseWorker :: Worker -> ReleaseF
    releaseWorker w = releaseWith $ \Pool{..} ->
        Pool pCompletionPort (WL w pWorkers) (pRefCount - 1)

    releaseWith :: (Pool -> Pool) -> ReleaseF
    releaseWith f m =
        case IM.lookup key m of
            Nothing -> (m, ())  -- should never happen
            Just pool
              | pRefCount pool <= 1 ->
                let !m' = IM.delete key m
                 in (m', ())
              | otherwise ->
                let !pool' = f pool
                    !m'    = IM.insert key pool' m
                 in (m', ())
withWorker :: Manager -> HANDLE -> (Enqueue -> IO a) -> IO a
withWorker mgr@Manager{..} h cb =
    mask $ \restore -> do
        (enqueue, releaseF) <- atomicModifyIORef mgrWorkerMap grabF
        let release = atomicModifyIORef mgrWorkerMap releaseF
                  >>= evaluate
        a <- restore (cb enqueue) `onException` release
        release
        return a
  where
    key = (fromIntegral . ptrToIntPtr) h :: Int

    grabF :: WorkerMap -> (WorkerMap, (Enqueue, ReleaseF))
    grabF m =
        case IM.lookup key m of
            Nothing ->
                let !pool = Pool False mgrWorkers 1
                    !m'   = IM.insert key pool m
                 in (m', (postIO mgr, releaseCP))
            Just Pool{..}
              | pCompletionPort ->
                let !pool = Pool False pWorkers (pRefCount + 1)
                    !m'   = IM.insert key pool m
                 in (m', (postIO mgr, releaseCP))
              | WL w ws <- pWorkers ->
                let !pool = Pool pCompletionPort ws (pRefCount + 1)
                    !m'   = IM.insert key pool m
                 in (m', (Worker.enqueue w, releaseWorker w))

    releaseCP :: ReleaseF
    releaseCP = releaseWith $ \Pool{..} ->
        Pool True pWorkers (pRefCount - 1)

    releaseWorker :: Worker -> ReleaseF
    releaseWorker w = releaseWith $ \Pool{..} ->
        Pool pCompletionPort (WL w pWorkers) (pRefCount - 1)

    releaseWith :: (Pool -> Pool) -> ReleaseF
    releaseWith f m =
        case IM.lookup key m of
            Nothing -> (m, ())  -- should never happen
            Just pool
              | pRefCount pool <= 1 ->
                let !m' = IM.delete key m
                 in (m', ())
              | otherwise ->
                let !pool' = f pool
                    !m'    = IM.insert key pool' m
                 in (m', ())
withWorker mgr@Manager{..} h cb =
    mask $ \restore -> do
        (enqueue, releaseF) <- atomicModifyIORef mgrWorkerMap grabF
        let release = atomicModifyIORef mgrWorkerMap releaseF
                  >>= evaluate
        a <- restore (cb enqueue) `onException` release
        release
        return a
  where
    key = (fromIntegral . ptrToIntPtr) h :: Int

    grabF :: WorkerMap -> (WorkerMap, (Enqueue, ReleaseF))
    grabF m =
        case IM.lookup key m of
            Nothing ->
                let !pool = Pool False mgrWorkers 1
                    !m'   = IM.insert key pool m
                 in (m', (postIO mgr, releaseCP))
            Just Pool{..}
              | pCompletionPort ->
                let !pool = Pool False pWorkers (pRefCount + 1)
                    !m'   = IM.insert key pool m
                 in (m', (postIO mgr, releaseCP))
              | WL w ws <- pWorkers ->
                let !pool = Pool pCompletionPort ws (pRefCount + 1)
                    !m'   = IM.insert key pool m
                 in (m', (Worker.enqueue w, releaseWorker w))

    releaseCP :: ReleaseF
    releaseCP = releaseWith $ \Pool{..} ->
        Pool True pWorkers (pRefCount - 1)

    releaseWorker :: Worker -> ReleaseF
    releaseWorker w = releaseWith $ \Pool{..} ->
        Pool pCompletionPort (WL w pWorkers) (pRefCount - 1)

    releaseWith :: (Pool -> Pool) -> ReleaseF
    releaseWith f m =
        case IM.lookup key m of
            Nothing -> (m, ())  -- should never happen
            Just pool
              | pRefCount pool <= 1 ->
                let !m' = IM.delete key m
                 in (m', ())
              | otherwise ->
                let !pool' = f pool
                    !m'    = IM.insert key pool' m
                 in (m', ())