dm.sharedresource
=================

A shared resource is some resource identified by an id
and used concurrently by several threads.
To make the concurrent use safe, calls to resource methods
are synchronized.

A resource is obtained by a call to `get_resource`.
The required resource is identified by an id (an arbitrary
object adequate as a dictionary key).
If a resouce of this id already exists, it is returned.
Otherwise, one is created calling the creator and
the creator parameters provided to `get_resource`.
The returned value is a wrapper around the resource.
The wrapping ensures that calls to the resource's methods
are synchronized.

>>> from dm.sharedresource import get_resource
>>> r = get_resource(1, dict) # a new resource is created with the `dict` creator
>>> r is get_resource(1, dict)
True

The resource behaves quite like the created object. However,
calls to its methods are synchronized (i.e. thread safe).
However, special methods (those the names of which start and and in
`__`) may not be found (Python 2.4 introduced that some methods
must be defined at class creation time and are not longer looked
up in the instance). As a special case, `__getitem__`, `__setitem__`,
`__delitem__`, `__len__`, `__nonzero__` are explicitely delegated.


>>> r[1] = 1
>>> r[1]
1

Parameters and keyword parameters for the creator can be provided
as arguments to `get_resource`.

>>> r = get_resource('with args', dict, {1:1}, a='a', b='b')
>>> sorted(r.items())
[(1, 1), ('a', 'a'), ('b', 'b')]

Now look that normal classes work as creators, too.

>>> class Resource:
...   def __init__(self, v): self.v = v
...   def f(self): return self.v
...
>>> r = get_resource('class', Resource, 1)
>>> r.f()
1
