-- | Drop a previous file descriptor registration, without waking the
-- event manager thread.  The return value indicates whether the event
-- manager ought to be woken.
unregisterFd_ :: EventManager -> FdKey -> IO Bool
unregisterFd_ mgr@(EventManager{..}) (FdKey fd u) =
  withMVar (callbackTableVar mgr fd) $ \tbl -> do
    let dropReg = nullToNothing . filter ((/= u) . keyUnique . fdKey)
        fd' = fromIntegral fd
        pairEvents prev = do
          r <- maybe mempty eventsOf `fmap` IT.lookup fd' tbl
          return (eventsOf prev, r)
    (oldEvs, newEvs) <- IT.updateWith dropReg fd' tbl >>=
                        maybe (return (mempty, mempty)) pairEvents
    let modify = oldEvs /= newEvs
    when modify $ failOnInvalidFile "unregisterFd_" fd $
      if haveOneShot && emOneShot && newEvs /= mempty
      then I.modifyFdOnce emBackend fd newEvs
      else I.modifyFd emBackend fd oldEvs newEvs
    return modify

-- | Drop a previous file descriptor registration.
unregisterFd_ :: EventManager -> FdKey -> IO Bool
unregisterFd_ mgr@(EventManager{..}) (FdKey fd u) =
  withMVar (callbackTableVar mgr fd) $ \tbl -> do
    let dropReg = nullToNothing . filter ((/= u) . keyUnique . fdKey)
        fd' = fromIntegral fd
        pairEvents prev = do
          r <- maybe mempty eventsOf `fmap` IT.lookup fd' tbl
          return (eventsOf prev, r)
    (oldEvs, newEvs) <- IT.updateWith dropReg fd' tbl >>=
                        maybe (return (mempty, mempty)) pairEvents
    let modify = oldEvs /= newEvs
    when modify $ failOnInvalidFile "unregisterFd_" fd $
      if haveOneShot && emOneShot && newEvs /= mempty
      then I.modifyFdOnce emBackend fd newEvs
      else I.modifyFd emBackend fd oldEvs newEvs
    return modify

-- | Drop a previous file descriptor registration.
unregisterFd_ mgr@(EventManager{..}) (FdKey fd u) =
  withMVar (callbackTableVar mgr fd) $ \tbl -> do
    let dropReg = nullToNothing . filter ((/= u) . keyUnique . fdKey)
        fd' = fromIntegral fd
        pairEvents prev = do
          r <- maybe mempty eventsOf `fmap` IT.lookup fd' tbl
          return (eventsOf prev, r)
    (oldEvs, newEvs) <- IT.updateWith dropReg fd' tbl >>=
                        maybe (return (mempty, mempty)) pairEvents
    let modify = oldEvs /= newEvs
    when modify $ failOnInvalidFile "unregisterFd_" fd $
      if haveOneShot && emOneShot && newEvs /= mempty
      then I.modifyFdOnce emBackend fd newEvs
      else I.modifyFd emBackend fd oldEvs newEvs
    return modify

-- | Drop a previous file descriptor registration.