code: def run(self, request_cb, notification_cb, setup_cb=None):
          
          self._request_cb = request_cb
          self._notification_cb = notification_cb
          self._is_running = True
          self._setup_exception = None
          self._loop_thread = threading.current_thread()
  
          def on_setup():
              try:
                  setup_cb()
              except Exception as e:
                  self._setup_exception = e
                  self.stop()
  
          if setup_cb:
              # Create a new greenlet to handle the setup function
              gr = greenlet.greenlet(on_setup)
              gr.switch()
  
          if self._setup_exception:
              error('Setup error: {}'.format(self._setup_exception))
              raise self._setup_exception
  
          # Process all pending requests and notifications
          while self._pending_messages:
              msg = self._pending_messages.popleft()
              getattr(self, '_on_{}'.format(msg[0]))(*msg[1:])
          self._async_session.run(self._on_request, self._on_notification)
          self._is_running = False
          self._request_cb = None
          self._notification_cb = None
          self._loop_thread = None
  
          if self._setup_exception:
              raise self._setup_exception
docs: Run the event loop to receive requests and notifications from Nvim.
  
          Like `AsyncSession.run()`, but `request_cb` and `notification_cb` are
          inside greenlets.