Skip to content

Calling "destroyResource" multiple times on the same resource causes "inUse" count to be incorrect, which allows exceeding the maxResources limit #32

Description

@mgsloan

The definition of destroyResource is:

destroyResource::Poola->LocalPoola->a->IO()
destroyResource Pool{..} LocalPool{..} resource =do
destroy resource `E.catch`\(_::SomeException) ->return()
atomically (modifyTVar_ inUse (subtract1))

inUse always gets decremented, regardless of if this function has been called multiple times for the same resource. Here is a demonstration of the issue:

#!/usr/bin/env stack
-- stack script --resolver lts-11.4 --package resource-pool --package stmimportControl.Concurrent.STMimportControl.Concurrent.STM.TVarimportControl.MonadimportData.Poolmain::IO()
main =do
counter <- newTVarIO 0let acquire =do
k <- atomically $do
k <- readTVar counter
writeTVar counter (k +1)
return k
putStrLn$"acquire "++show k
return k
release k =putStrLn$"release "++show k
pool <- createPool acquire release 1601
(k, localPool) <- takeResource pool
destroyResource pool localPool k
destroyResource pool localPool k
void $ takeResource pool
void $ takeResource pool
putStrLn"Bug: acquired two resources despite the pool having a limit of 1. Next resource acquire will block."
void $ takeResource pool

Output:

acquire 0
release 0
release 0
acquire 1
acquire 2
Bug: acquired two resources despite the pool having a limit of 1. Next resource acquire will block.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions