| t | class LockDescriptor: | t | class LockDescriptor: | 
            |  | _semaphores = {} |  | _semaphores = {} | 
            |  | _waiting_queues = {} |  | _waiting_queues = {} | 
            |  | _temp = {} |  | _temp = {} | 
            |  |  |  |  | 
            |  | def __get__(self, instance, owner): |  | def __get__(self, instance, owner): | 
            |  | instance_id = id(instance) |  | instance_id = id(instance) | 
            |  | name = self._temp.get(instance_id, None) |  | name = self._temp.get(instance_id, None) | 
            |  | if name is not None and name not in self._semaphores.values(): |  | if name is not None and name not in self._semaphores.values(): | 
            |  | self._semaphores[instance_id] = name |  | self._semaphores[instance_id] = name | 
            |  | return self._semaphores.get(id(instance), None) |  | return self._semaphores.get(id(instance), None) | 
            |  |  |  |  | 
            |  | def __set__(self, instance, name): |  | def __set__(self, instance, name): | 
            |  | instance_id = id(instance) |  | instance_id = id(instance) | 
            |  | current_lock = self._semaphores.get(instance_id) |  | current_lock = self._semaphores.get(instance_id) | 
            |  | if current_lock == name: |  | if current_lock == name: | 
            |  | self.__delete__(instance) |  | self.__delete__(instance) | 
            |  | if self._waiting_queues.get(name): |  | if self._waiting_queues.get(name): | 
            |  | next_instance = self._waiting_queues[name].pop(0) |  | next_instance = self._waiting_queues[name].pop(0) | 
            |  | self._temp[id(next_instance)] = name |  | self._temp[id(next_instance)] = name | 
            |  | elif (instance_id, name) not in self._temp.items() and name not in self._semaphores.values(): |  | elif (instance_id, name) not in self._temp.items() and name not in self._semaphores.values(): | 
            |  | self._temp[instance_id] = name |  | self._temp[instance_id] = name | 
            |  | else: |  | else: | 
            |  | if current_lock is not None and current_lock != name: |  | if current_lock is not None and current_lock != name: | 
            |  | del self._semaphores[instance_id] |  | del self._semaphores[instance_id] | 
            |  | del self._temp[instance_id] |  | del self._temp[instance_id] | 
            |  | self._waiting_queues.setdefault(name, []).append(instance) |  | self._waiting_queues.setdefault(name, []).append(instance) | 
            |  |  |  |  | 
            |  | def __delete__(self, instance): |  | def __delete__(self, instance): | 
            |  | instance_id = id(instance) |  | instance_id = id(instance) | 
            |  | semaphore_to_release = self._semaphores.pop(instance_id, None) |  | semaphore_to_release = self._semaphores.pop(instance_id, None) | 
            |  | self._temp.pop(instance_id, None) |  | self._temp.pop(instance_id, None) | 
            |  | if semaphore_to_release: |  | if semaphore_to_release: | 
            |  | if semaphore_to_release in self._waiting_queues: |  | if semaphore_to_release in self._waiting_queues: | 
            |  | waiting_instances = self._waiting_queues[semaphore_to_release] |  | waiting_instances = self._waiting_queues[semaphore_to_release] | 
            |  | if waiting_instances: |  | if waiting_instances: | 
            |  | next_instance = waiting_instances.pop(0) |  | next_instance = waiting_instances.pop(0) | 
            |  | self._temp[id(next_instance)] = semaphore_to_release |  | self._temp[id(next_instance)] = semaphore_to_release | 
            |  |  |  |  | 
            |  | @classmethod |  | @classmethod | 
            |  | def release_all(cls, instance): |  | def release_all(cls, instance): | 
            |  | instance_id = id(instance) |  | instance_id = id(instance) | 
            |  | semaphore_to_release = cls._semaphores.pop(instance_id, None) |  | semaphore_to_release = cls._semaphores.pop(instance_id, None) | 
            |  | cls._temp.pop(instance_id, None) |  | cls._temp.pop(instance_id, None) | 
            |  | if semaphore_to_release and semaphore_to_release in cls._waiting_queues: |  | if semaphore_to_release and semaphore_to_release in cls._waiting_queues: | 
            |  | waiting_instances = cls._waiting_queues[semaphore_to_release] |  | waiting_instances = cls._waiting_queues[semaphore_to_release] | 
            |  | if waiting_instances: |  | if waiting_instances: | 
            |  | next_instance = waiting_instances.pop(0) |  | next_instance = waiting_instances.pop(0) | 
            |  | cls._temp[id(next_instance)] = semaphore_to_release |  | cls._temp[id(next_instance)] = semaphore_to_release | 
            |  |  |  |  | 
            |  | class Lock: |  | class Lock: | 
            |  |  |  |  | 
            |  | @staticmethod |  | @staticmethod | 
            |  | def locked(cls): |  | def locked(cls): | 
            |  |  |  |  | 
            |  | class Wrapped(cls): |  | class Wrapped(cls): | 
            |  | lock = LockDescriptor() |  | lock = LockDescriptor() | 
            |  |  |  |  | 
            |  | def __del__(self): |  | def __del__(self): | 
            |  | try: |  | try: | 
            |  | LockDescriptor.release_all(self) |  | LockDescriptor.release_all(self) | 
            |  | except AttributeError: |  | except AttributeError: | 
            |  | pass |  | pass | 
            |  | super_del = getattr(super(), '__del__', None) |  | super_del = getattr(super(), '__del__', None) | 
            |  | if callable(super_del): |  | if callable(super_del): | 
            |  | super_del(self) |  | super_del(self) | 
            |  | return Wrapped |  | return Wrapped |