mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 14:45:24 +00:00
client rpc: Separate call creation from running IO loop
This makes it possible to create and queue new calls while we are running IO loop.
This commit is contained in:
parent
28c75382b0
commit
c57103e567
@ -1642,6 +1642,60 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static virNetClientCallPtr
|
||||||
|
virNetClientCallNew(virNetMessagePtr msg,
|
||||||
|
bool expectReply,
|
||||||
|
bool nonBlock)
|
||||||
|
{
|
||||||
|
virNetClientCallPtr call = NULL;
|
||||||
|
|
||||||
|
if (expectReply &&
|
||||||
|
(msg->bufferLength != 0) &&
|
||||||
|
(msg->header.status == VIR_NET_CONTINUE)) {
|
||||||
|
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Attempt to send an asynchronous message with"
|
||||||
|
" a synchronous reply"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectReply && nonBlock) {
|
||||||
|
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Attempt to send a non-blocking message with"
|
||||||
|
" a synchronous reply"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC(call) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virCondInit(&call->cond) < 0) {
|
||||||
|
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("cannot initialize condition variable"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->donefds = 0;
|
||||||
|
if (msg->bufferLength)
|
||||||
|
call->mode = VIR_NET_CLIENT_MODE_WAIT_TX;
|
||||||
|
else
|
||||||
|
call->mode = VIR_NET_CLIENT_MODE_WAIT_RX;
|
||||||
|
call->msg = msg;
|
||||||
|
call->expectReply = expectReply;
|
||||||
|
call->nonBlock = nonBlock;
|
||||||
|
|
||||||
|
VIR_DEBUG("New call %p: msg=%p, expectReply=%d, nonBlock=%d",
|
||||||
|
call, msg, expectReply, nonBlock);
|
||||||
|
|
||||||
|
return call;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_FREE(call);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns 1 if the call was queued and will be completed later (only
|
* Returns 1 if the call was queued and will be completed later (only
|
||||||
* for nonBlock==true), 0 if the call was completed and -1 on error.
|
* for nonBlock==true), 0 if the call was completed and -1 on error.
|
||||||
@ -1660,47 +1714,18 @@ static int virNetClientSendInternal(virNetClientPtr client,
|
|||||||
msg->header.prog, msg->header.vers, msg->header.proc,
|
msg->header.prog, msg->header.vers, msg->header.proc,
|
||||||
msg->header.type, msg->header.status, msg->header.serial);
|
msg->header.type, msg->header.status, msg->header.serial);
|
||||||
|
|
||||||
if (expectReply &&
|
if (!client->sock || client->wantClose) {
|
||||||
(msg->bufferLength != 0) &&
|
|
||||||
(msg->header.status == VIR_NET_CONTINUE)) {
|
|
||||||
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Attempt to send an asynchronous message with a synchronous reply"));
|
_("client socket is closed"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectReply && nonBlock) {
|
if (!(call = virNetClientCallNew(msg, expectReply, nonBlock))) {
|
||||||
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("Attempt to send a non-blocking message with a synchronous reply"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VIR_ALLOC(call) < 0) {
|
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!client->sock || client->wantClose) {
|
|
||||||
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("client socket is closed"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virCondInit(&call->cond) < 0) {
|
|
||||||
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("cannot initialize condition variable"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg->donefds = 0;
|
|
||||||
if (msg->bufferLength)
|
|
||||||
call->mode = VIR_NET_CLIENT_MODE_WAIT_TX;
|
|
||||||
else
|
|
||||||
call->mode = VIR_NET_CLIENT_MODE_WAIT_RX;
|
|
||||||
call->msg = msg;
|
|
||||||
call->expectReply = expectReply;
|
|
||||||
call->nonBlock = nonBlock;
|
|
||||||
call->haveThread = true;
|
call->haveThread = true;
|
||||||
|
|
||||||
ret = virNetClientIO(client, call);
|
ret = virNetClientIO(client, call);
|
||||||
|
|
||||||
/* If queued, the call will be finished and freed later by another thread;
|
/* If queued, the call will be finished and freed later by another thread;
|
||||||
@ -1709,8 +1734,6 @@ static int virNetClientSendInternal(virNetClientPtr client,
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ignore_value(virCondDestroy(&call->cond));
|
ignore_value(virCondDestroy(&call->cond));
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VIR_FREE(call);
|
VIR_FREE(call);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user