Repository: neovim
Issue: In channel1->nvim->channel2 nested rpcrequest, closing channel2 after responding can return error on channel1
Labels: bug,channels-rpc

### Problem

I set up a scenario in which I have two RPC channels (the first one is over stdio as I'm running an embedded Neovim, but I don't think that's relevant) and on the first channel I send a request asking Neovim to send a request to the second. I then return a response to the second channel and immediately close the connection. Sometimes, the first channel will receive an error saying that the channel closed even though the response was sent on the second channel before it was closed.

Here is some traffic demonstrating this behavior:
```
------------------------------------  client1  ------------------------------------
Plugin -> Neovim:
[ 0
, 0
, "nvim_set_client_info"
, [ "177a9549-74af-3924-5dee-38abdd3623d9", {}, "remote", {}, {} ]
]
Neovim -> Plugin: [ 1, 0, nil, nil ]
Plugin -> Neovim: [ 0, 1, "nvim_list_chans", [] ]
Neovim -> Plugin:
[ 1
, 1
, nil
, [ { "id": 1
    , "stream": "stdio"
    , "client":
          { "name": "177a9549-74af-3924-5dee-38abdd3623d9"
          , "version": { "major": 0 }
          , "type": "remote"
          , "methods": {}
          , "attributes": {}
          }
    , "mode": "rpc"
    }
  , { "id": 2, "stream": "stderr", "mode": "bytes" }
  ]
]
Plugin -> Neovim:
[ 0, 2, "nvim_set_client_info", [ "client1", {}, "remote", {}, {} ] ]
Neovim -> Plugin: [ 1, 2, nil, nil ]
Plugin -> Neovim:
[ 0, 3, "nvim_call_function", [ "rpcrequest", [ 3, "rpc" ] ] ]
Neovim -> Plugin:
[ 1
, 3
, [ 0
  , "Vim:Error invoking 'rpc' on channel 3 (client2):\nch 3 was closed by the client"
  ]
, nil
]
("Neovim -> Plugin: Connection closed" (angstrom_exit_status (Ok ())))
("Plugin -> Neovim: Connection closed" (angstrom_exit_status (Ok ())))
-----------------------------------------------------------------------------------
------------------------------------  client2  ------------------------------------
Plugin -> Neovim:
[ 0
, 0
, "nvim_set_client_info"
, [ "f0beaf41-b871-3984-ab44-2ba3e44e48fc", {}, "remote", {}, {} ]
]
Neovim -> Plugin: [ 1, 0, nil, nil ]
Plugin -> Neovim: [ 0, 1, "nvim_list_chans", [] ]
Neovim -> Plugin:
[ 1
, 1
, nil
, [ { "id": 1
    , "stream": "stdio"
    , "client":
          { "name": "client1"
          , "version": { "major": 0 }
          , "type": "remote"
          , "methods": {}
          , "attributes": {}
          }
    , "mode": "rpc"
    }
  , { "id": 2, "stream": "stderr", "mode": "bytes" }
  , { "id": 3
    , "stream": "socket"
    , "client":
          { "name": "f0beaf41-b871-3984-ab44-2ba3e44e48fc"
          , "version": { "major": 0 }
          , "type": "remote"
          , "methods": {}
          , "attributes": {}
          }
    , "mode": "rpc"
    }
  ]
]
Plugin -> Neovim:
[ 0, 2, "nvim_set_client_info", [ "client2", {}, "remote", {}, {} ] ]
Neovim -> Plugin: [ 1, 2, nil, nil ]
Neovim -> Plugin: [ 0, 1, "rpc", [] ]
Plugin -> Neovim: [ 2, "nvim_eval", [ "0" ] ]
Plugin -> Neovim: [ 0, 3, "nvim_get_current_buf", [] ]
Neovim -> Plugin: [ 1, 3, nil, 1 ]
Plugin -> Neovim: [ 0, 4, "nvim_get_current_buf", [] ]
Neovim -> Plugin: [ 1, 4, nil, 1 ]
Plugin -> Neovim: [ 1, 1, nil, nil ]
("Plugin -> Neovim: Connection closed" (angstrom_exit_status (Ok ())))
("Neovim -> Plugin: Connection closed" (angstrom_exit_status (Ok ())))
-----------------------------------------------------------------------------------
```
The key line is at the end of the `client2` log: `Plugin -> Neovim: [1, 1, nil, nil]`, which tells us that the plugin did send the response to Neovim before closing the connection.

### Steps to reproduce
Run the script below - it will probably repro within the first 2K runs. `vim.schedule` is used to delay closing until after Neovim has responded to the request.

```lua
function test()
  local nvim = vim.fn.jobstart({ vim.v.progpath, "--embed", "--headless", "--clean", "-n" }, { rpc = true })
  vim.rpcrequest(nvim, "nvim_exec_lua", "vim.schedule(function() vim.cmd \"quit\" end)", {})
  local jobwait_result = vim.fn.jobwait({nvim}, 1000)[1]
  if jobwait_result < 0 then
    vim.fn.jobstop(nvim)
    error("Unexpected jobwait result: "..jobwait_result)
  end
end

function run(num_tests)
  for i = 1, (num_tests or 10000) do
    local succeeded, message = pcall(test)
    if not succeeded then
      error("Failure on run "..i..":\n"..message)
    end
  end
  print("All "..num_tests.." runs succeeded")
end
```

### Expected behavior

No error. The response was returned on channel2 successfully, so channel1 should receive a successful response.

### Neovim version (nvim -v)

0.9.1

### Vim (not Nvim) behaves the same?

N/A

### Operating system/version

CentOS 7.9

### Terminal name/version

xfce4-terminal 1.0.4

### $TERM environment variable

tmux-256color

### Installation

build from repo