úÎ!VºUb  Safe@AHVT¯ concurrent-resource-mapA map of shared resources r keyed by k.concurrent-resource-mapYResource maps should implement this small set of operations that we expect maps to have.bThis allows you to use whatever fast underlying map type you'd like, depending on your resources. concurrent-resource-map;Some resource with a count of the users (threads) using it.>Internal invariant: if users = 0 then resource = Uninitialisedconcurrent-resource-mapCreate an empty resource map.concurrent-resource-mapýUse a resource that can be accessed concurrently via multiple threads but is only initialised and destroyed on as-needed basis. If number of users falls to 0, the resource is destroyed. If a new user joins and resource is not available, it's created. Calls to c can even be nested if you need access to resources with different keys in the same map. Calling U in a nested matter on same resource key should have no real adverse effects either. concurrent-resource-map This is like Õ but will only execute the user action if the resource already exists. This is useful if you create your resources in one place but would like to use them conditionally in another place if they are still alive.NAction is given Nothing if the resource does not exist or is not initialised. concurrent-resource-mapNAdds a user at given key. If it's the first user, creates the underlying map.)Should be used as initialising action in   along with  .concurrent-resource-mapCAdds a user at given key but only if the given key already exists..)Should be used as initialising action in   along with  . concurrent-resource-maplRemove user for the given key. If it's the last user, removes the counted resource from the map completely.$Should be used as cleanup action in   along with  .concurrent-resource-mapResource map. Create with .concurrent-resource-mapçKey for the resource. This allows you to have many of the same type of resource but separated: for example, one group of threads could be holding onto a logging handle to syslog while another could be holding a handle to a file.concurrent-resource-mapŸInitialise resource. Only ran if the resource is not yet initialised. Does not run in masked context so if you need to stop async exceptions, you should use \ yourself. If the action fails (throws an exception), the user fails and we enter cleanup.concurrent-resource-mapÿDestroy the resource if it was initialised. Ran by last alive user when it's exiting. Unlike initialisation, this _is_ ran in masked context. If this action fails (by throwing an exception itself), the resource will be assumed to be uninitialised and the exception will be re-thrown.„Therefore, if your cleanup can fail in a way that you have to know about/recover from, you should catch exceptions coming out out /. As you get reference to the resource in the actÙ, you're able to store it/monitor it yourself and decide to take any appropriate actions in the future such as blocking other threads from running initialisation again until you've cleaned up the resource yourself.concurrent-resource-mapÿRun an action with the initialised resource. Note that the availability of this resource only ensures that the user-given initialisers/destructors have been ran appropriate number of times: it of course makes no guarantees as to what the resource represents. For example, if it's a á or a database connection, there's no guarantee that the process is alive or that the database connection is still available. For resources that can dynamically fail, you should implement some sort of monitoring yourself. concurrent-resource-mapResource map. Create with .concurrent-resource-mapçKey for the resource. This allows you to have many of the same type of resource but separated: for example, one group of threads could be holding onto a logging handle to syslog while another could be holding a handle to a file.concurrent-resource-mapÿDestroy the resource if it was initialised. Ran by last alive user when it's exiting. Unlike initialisation, this _is_ ran in masked context. If this action fails (by throwing an exception itself), the resource will be assumed to be uninitialised and the exception will be re-thrown.„Therefore, if your cleanup can fail in a way that you have to know about/recover from, you should catch exceptions coming out out /. As you get reference to the resource in the actÙ, you're able to store it/monitor it yourself and decide to take any appropriate actions in the future such as blocking other threads from running initialisation again until you've cleaned up the resource yourself.concurrent-resource-mapÿRun an action with the resource. Note that the availability of this resource only ensures that the user-given initialisers/destructors have been ran appropriate number of times: it of course makes no guarantees as to what the resource represents. For example, if it's a á or a database connection, there's no guarantee that the process is alive or that the database connection is still available. For resources that can dynamically fail, you should implement some sort of monitoring yourself. concurrent-resource-map!The resource from inside the map.concurrent-resource-mapDestroy resource.concurrent-resource-map Internal ref   SafeU=      6concurrent-resource-map-0.2.0.0-AqwL59jlrxA94mkvYsyrdXData.ConcurrentResourceMapSystem.Process ProcessHandlePaths_concurrent_resource_mapConcurrentResourceMap ResourceMapKeyemptydeleteinsertlookupnewResourceMapwithSharedResourcewithInitialisedResourceCountedResourceaddUserbaseControl.Exception.Basebracket removeUseraddUserIfPresentGHC.IOmaskversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName