提交 d4d87744 编写于 作者: J Jiri Denemark 提交者: Cole Robinson

Revert "rpc: Discard non-blocking calls only when necessary"

This reverts commit b1e374a7, which was
rather bad since I failed to consider all sides of the issue. The main
things I didn't consider properly are:

- a thread which sends a non-blocking call waits for the thread with
  the buck to process the call
- the code doesn't expect non-blocking calls to remain in the queue
  unless they were already partially sent

Thus, the reverted patch actually breaks more than what it fixes and
clients (which may even be libvirtd during p2p migrations) will likely
end up in a deadlock.
(cherry picked from commit 63643f67)
上级 3600eec4
...@@ -1257,13 +1257,6 @@ static void virNetClientIOEventLoopPassTheBuck(virNetClientPtr client, virNetCli ...@@ -1257,13 +1257,6 @@ static void virNetClientIOEventLoopPassTheBuck(virNetClientPtr client, virNetCli
} }
client->haveTheBuck = false; client->haveTheBuck = false;
/* Remove non-blocking calls from the dispatch list since there is no
* call with a thread in the list which could take care of them.
*/
virNetClientCallRemovePredicate(&client->waitDispatch,
virNetClientIOEventLoopRemoveNonBlocking,
thiscall);
VIR_DEBUG("No thread to pass the buck to"); VIR_DEBUG("No thread to pass the buck to");
if (client->wantClose) { if (client->wantClose) {
virNetClientCloseLocked(client); virNetClientCloseLocked(client);
...@@ -1307,9 +1300,12 @@ static int virNetClientIOEventLoop(virNetClientPtr client, ...@@ -1307,9 +1300,12 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
if (virNetSocketHasCachedData(client->sock) || client->wantClose) if (virNetSocketHasCachedData(client->sock) || client->wantClose)
timeout = 0; timeout = 0;
/* If we are non-blocking, we don't want to sleep in poll() /* If there are any non-blocking calls in the queue,
* then we don't want to sleep in poll()
*/ */
if (thiscall->nonBlock) if (virNetClientCallMatchPredicate(client->waitDispatch,
virNetClientIOEventLoopWantNonBlock,
NULL))
timeout = 0; timeout = 0;
fds[0].events = fds[0].revents = 0; fds[0].events = fds[0].revents = 0;
...@@ -1414,6 +1410,13 @@ static int virNetClientIOEventLoop(virNetClientPtr client, ...@@ -1414,6 +1410,13 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
virNetClientIOEventLoopRemoveDone, virNetClientIOEventLoopRemoveDone,
thiscall); thiscall);
/* Iterate through waiting calls and if any are
* non-blocking, remove them from the dispatch list...
*/
virNetClientCallRemovePredicate(&client->waitDispatch,
virNetClientIOEventLoopRemoveNonBlocking,
thiscall);
/* Now see if *we* are done */ /* Now see if *we* are done */
if (thiscall->mode == VIR_NET_CLIENT_MODE_COMPLETE) { if (thiscall->mode == VIR_NET_CLIENT_MODE_COMPLETE) {
virNetClientCallRemove(&client->waitDispatch, thiscall); virNetClientCallRemove(&client->waitDispatch, thiscall);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册