from threading import Lock

_lock_table_lock = Lock()
_lock_table = {}


# decorate drops method attributes like .im_class? bleah
def synchronized_module_function():
    """ Synchronization decorator. """
    def decorate(f):
        def new_func(*args, **kw):
            lock = _get_lock_for_method(f)
            lock.acquire()
            try:
                return f(*args, **kw)
            finally:
                lock.release()
        return new_func
    return decorate

def _get_lock_for_method(f):
    # key from module class is from, func name -- would like class name but not available?
    _lock_table_lock.acquire()
    try:
        key = "%s%s" % (f.__module__, f.__name__)
        lock = None
        try:
            lock = _lock_table[key]
        except KeyError:
            lock = _lock_table[key] = Lock()
    finally:
        _lock_table_lock.release()
    return lock