code: def atomic(fn: Callable) -> Callable:
      
      msg = {
          Msgs.cmd: Cmds.run_fn_atomically,
          Msgs.info: serializer.dumps_fn(fn),
          Msgs.args: (),
          Msgs.kwargs: {},
      }
  
      @wraps(fn)
      def wrapper(state: State, *args, **kwargs):
          msg[Msgs.args] = args
          msg[Msgs.kwargs] = kwargs
          return state._s_request_reply(msg)
  
      return wrapper
docs: Wraps a function, to create an atomic operation out of it.
  
      This contract guarantees, that while an atomic ``fn`` is running -
  
      - No one, except the "callee" may access the state.
      - If an ``Exception`` occurs while the ``fn`` is running, the state remains unaffected.
      - | If a signal is sent to the "callee", the ``fn`` remains unaffected.
        | (The state is not left in an incoherent state.)
  
      .. note::
          - The first argument to the wrapped function *must* be a :py:class:`State` object.
          - The wrapped ``fn`` receives a frozen version (snapshot) of state,
            which is a ``dict`` object, not a :py:class:`State` object.
          - It is not possible to call one atomic function from other.
  
      Please read :ref:`atomicity` for a detailed explanation.
  
      :param fn:
          The function to be wrapped, as an atomic function.
  
      :returns:
          A wrapper function.
  
          The wrapper function returns the value returned by the wrapped ``fn``.
  
      >>> import zproc
      >>>
      >>> @zproc.atomic
      ... def increment(snapshot):
      ...     return snapshot['count'] + 1
      ...
      >>>
      >>> ctx = zproc.Context()
      >>> state = ctx.create_state({'count': 0})
      >>>
      >>> increment(state)
      1