docs: def critical_section_dynamic_lock(lock_fn, blocking=True, timeout=None, raise_exception=True):
  	""" Protect a function with a lock, that was get from the specified function. If a lock can not be acquire, then
  	no function call will be made
  
  	:param lock_fn: callable that returns a lock, with which a function may be protected
  	:param blocking: whenever to block operations with lock acquiring
  	:param timeout: timeout with which a lock acquiring will be made
  	:param raise_exception: whenever to raise an WCriticalSectionError exception if lock can not be acquired
  
  	:return: decorator with which a target function may be protected
  	"""
  
  	if blocking is False or timeout is None:
  		timeout = -1
  
  	def first_level_decorator(decorated_function):
  		def second_level_decorator(original_function, *args, **kwargs):
  			lock = lock_fn(*args, **kwargs)
  			if lock.acquire(blocking=blocking, timeout=timeout) is True:
  				try:
  					result = original_function(*args, **kwargs)
  					return result
  				finally:
  					lock.release()
  			elif raise_exception is True:
  				raise WCriticalSectionError('Unable to lock critical section\n')
  
  		return decorator(second_level_decorator)(decorated_function)
  	return first_level_decorator