Repository: neovim/neovim
File: src/nvim/msgpack_rpc/channel.c (C)

Code before:

  if (ERROR_SET(err)) {
    // error represented by a [type, message] array
    mpack_array(&packer.ptr, 2);
    mpack_integer(&packer.ptr, err->type);
    mpack_str(cstr_as_string(err->msg), &packer);
    // Nil result
    mpack_nil(&packer.ptr);
  } else {
    // Nil error
    mpack_nil(&packer.ptr);
    // Return value
    mpack_object(arg, &packer);
  }

  packer_buffer_finish_channels(&packer);

  log_response(SEND, channel->id, ERROR_SET(err) ? ERR : RES, response_id);
}

static void packer_buffer_init_channels(Channel **chans, size_t nchans, PackerBuffer *packer)
{
  packer->startptr = alloc_block();
  packer->ptr = packer->startptr;
  packer->endptr = packer->startptr + ARENA_BLOCK_SIZE;
  packer->packer_flush = channel_flush_callback;
  packer->anydata = chans;
  packer->anyint = (int64_t)nchans;
}

static void packer_buffer_finish_channels(PackerBuffer *packer)
{
  size_t len = (size_t)(packer->ptr - packer->startptr);
  if (len > 0) {
    WBuffer *buf = wstream_new_buffer(packer->startptr, len, (size_t)packer->anyint, free_block);
    Channel **chans = packer->anydata;
    for (int64_t i = 0; i < packer->anyint; i++) {
      channel_write(chans[i], buf);
    }
  } else {
    free_block(packer->startptr);
  }
}

static void channel_flush_callback(PackerBuffer *packer)
{
  packer_buffer_finish_channels(packer);
  packer_buffer_init_channels(packer->anydata, (size_t)packer->anyint, packer);
}

void rpc_set_client_info(uint64_t id, Dict info)

Review comment (performance):
Why not always call `remote_ui_flush_pending_data`? Why only do it when `incomplete_event=true` ?

Also, can we find the UI here instead of storing it on the `ui` field? Is that a performance concern?

Code after:

  if (ERROR_SET(err)) {
    // error represented by a [type, message] array
    mpack_array(&packer.ptr, 2);
    mpack_integer(&packer.ptr, err->type);
    mpack_str(cstr_as_string(err->msg), &packer);
    // Nil result
    mpack_nil(&packer.ptr);
  } else {
    // Nil error
    mpack_nil(&packer.ptr);
    // Return value
    mpack_object(arg, &packer);
  }

  packer_buffer_finish_channels(&packer);

  log_response(SEND, channel->id, ERROR_SET(err) ? ERR : RES, response_id);
}

static void packer_buffer_init_channels(Channel **chans, size_t nchans, PackerBuffer *packer)
{
  for (size_t i = 0; i < nchans; i++) {
    Channel *chan = chans[i];
    if (chan->rpc.ui && chan->rpc.ui->incomplete_event) {
      remote_ui_flush_pending_data(chan->rpc.ui);
    }
  }
  packer->startptr = alloc_block();
  packer->ptr = packer->startptr;
  packer->endptr = packer->startptr + ARENA_BLOCK_SIZE;
  packer->packer_flush = channel_flush_callback;
  packer->anydata = chans;
  packer->anyint = (int64_t)nchans;
}

static void packer_buffer_finish_channels(PackerBuffer *packer)
{
  size_t len = (size_t)(packer->ptr - packer->startptr);
  if (len > 0) {
    WBuffer *buf = wstream_new_buffer(packer->startptr, len, (size_t)packer->anyint, free_block);
    Channel **chans = packer->anydata;
    for (int64_t i = 0; i < packer->anyint; i++) {
      channel_write(chans[i], buf);
    }
  } else {
    free_block(packer->startptr);
  }
}

static void channel_flush_callback(PackerBuffer *packer)