Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
673adba5
L
libvirt
项目概览
openeuler
/
libvirt
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
libvirt
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
673adba5
编写于
13年前
作者:
J
Jiri Denemark
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for async close of client RPC socket
上级
f4324e32
无相关合并请求
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
90 addition
and
9 deletion
+90
-9
src/rpc/virnetclient.c
src/rpc/virnetclient.c
+90
-9
未找到文件。
src/rpc/virnetclient.c
浏览文件 @
673adba5
...
...
@@ -101,9 +101,13 @@ struct _virNetClient {
size_t
nstreams
;
virNetClientStreamPtr
*
streams
;
bool
wantClose
;
};
void
virNetClientRequestClose
(
virNetClientPtr
client
);
static
void
virNetClientLock
(
virNetClientPtr
client
)
{
virMutexLock
(
&
client
->
lock
);
...
...
@@ -409,12 +413,14 @@ void virNetClientFree(virNetClientPtr client)
}
void
virNetClientClose
(
virNetClientPtr
client
)
static
void
virNetClientCloseLocked
(
virNetClientPtr
client
)
{
if
(
!
client
)
VIR_DEBUG
(
"client=%p, sock=%p"
,
client
,
client
->
sock
);
if
(
!
client
->
sock
)
return
;
virNetClientLock
(
client
);
virNetSocketRemoveIOCallback
(
client
->
sock
);
virNetSocketFree
(
client
->
sock
);
client
->
sock
=
NULL
;
...
...
@@ -424,6 +430,41 @@ void virNetClientClose(virNetClientPtr client)
virNetSASLSessionFree
(
client
->
sasl
);
client
->
sasl
=
NULL
;
#endif
client
->
wantClose
=
false
;
}
void
virNetClientClose
(
virNetClientPtr
client
)
{
if
(
!
client
)
return
;
virNetClientLock
(
client
);
virNetClientCloseLocked
(
client
);
virNetClientUnlock
(
client
);
}
void
virNetClientRequestClose
(
virNetClientPtr
client
)
{
VIR_DEBUG
(
"client=%p"
,
client
);
virNetClientLock
(
client
);
/* If there is a thread polling for data on the socket, set wantClose flag
* and wake the thread up or just immediately close the socket when no-one
* is polling on it.
*/
if
(
client
->
waitDispatch
)
{
char
ignore
=
1
;
size_t
len
=
sizeof
(
ignore
);
client
->
wantClose
=
true
;
if
(
safewrite
(
client
->
wakeupSendFD
,
&
ignore
,
len
)
!=
len
)
VIR_ERROR
(
_
(
"failed to wake up polling thread"
));
}
else
{
virNetClientCloseLocked
(
client
);
}
virNetClientUnlock
(
client
);
}
...
...
@@ -1096,6 +1137,26 @@ static bool virNetClientIOEventLoopRemoveNonBlocking(virNetClientCallPtr call,
}
static
void
virNetClientIOEventLoopRemoveAll
(
virNetClientPtr
client
,
virNetClientCallPtr
thiscall
)
{
if
(
!
client
->
waitDispatch
)
return
;
if
(
client
->
waitDispatch
==
thiscall
)
{
/* just pretend nothing was sent and the caller will free the call */
thiscall
->
sentSomeData
=
false
;
}
else
{
virNetClientCallPtr
call
=
client
->
waitDispatch
;
virNetClientCallRemove
(
&
client
->
waitDispatch
,
call
);
ignore_value
(
virCondDestroy
(
&
call
->
cond
));
VIR_FREE
(
call
->
msg
);
VIR_FREE
(
call
);
}
}
static
void
virNetClientIOEventLoopPassTheBuck
(
virNetClientPtr
client
,
virNetClientCallPtr
thiscall
)
{
VIR_DEBUG
(
"Giving up the buck %p"
,
thiscall
);
...
...
@@ -1110,7 +1171,12 @@ static void virNetClientIOEventLoopPassTheBuck(virNetClientPtr client, virNetCli
}
tmp
=
tmp
->
next
;
}
VIR_DEBUG
(
"No thread to pass the buck to"
);
if
(
client
->
wantClose
)
{
virNetClientCloseLocked
(
client
);
virNetClientIOEventLoopRemoveAll
(
client
,
thiscall
);
}
}
...
...
@@ -1141,11 +1207,12 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
sigset_t
oldmask
,
blockedsigs
;
int
timeout
=
-
1
;
/* If we have existing SASL decoded data we
* don't want to sleep in the poll(), just
* check if any other FDs are also ready
/* If we have existing SASL decoded data we don't want to sleep in
* the poll(), just check if any other FDs are also ready.
* If the connection is going to be closed, we don't want to sleep in
* poll() either.
*/
if
(
virNetSocketHasCachedData
(
client
->
sock
))
if
(
virNetSocketHasCachedData
(
client
->
sock
)
||
client
->
wantClose
)
timeout
=
0
;
/* If there are any non-blocking calls in the queue,
...
...
@@ -1208,6 +1275,11 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
fds
[
0
].
revents
|=
POLLIN
;
}
/* If wantClose flag is set, pretend there was an error on the socket
*/
if
(
client
->
wantClose
)
fds
[
0
].
revents
=
POLLERR
;
if
(
fds
[
1
].
revents
)
{
VIR_DEBUG
(
"Woken up from poll by other thread"
);
if
(
saferead
(
client
->
wakeupReadFD
,
&
ignore
,
sizeof
(
ignore
))
!=
sizeof
(
ignore
))
{
...
...
@@ -1441,7 +1513,8 @@ static int virNetClientIO(virNetClientPtr client,
virResetLastError
();
rv
=
virNetClientIOEventLoop
(
client
,
thiscall
);
virNetClientIOUpdateCallback
(
client
,
true
);
if
(
client
->
sock
)
virNetClientIOUpdateCallback
(
client
,
true
);
if
(
rv
==
0
&&
virGetLastError
())
...
...
@@ -1467,7 +1540,7 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
goto
done
;
/* This should be impossible, but it doesn't hurt to check */
if
(
client
->
haveTheBuck
)
if
(
client
->
haveTheBuck
||
client
->
wantClose
)
goto
done
;
VIR_DEBUG
(
"Event fired %p %d"
,
sock
,
events
);
...
...
@@ -1528,6 +1601,12 @@ static int virNetClientSendInternal(virNetClientPtr client,
virNetClientLock
(
client
);
if
(
!
client
->
sock
||
client
->
wantClose
)
{
virNetError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"client socket is closed"
));
goto
unlock
;
}
if
(
virCondInit
(
&
call
->
cond
)
<
0
)
{
virNetError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot initialize condition variable"
));
...
...
@@ -1554,6 +1633,8 @@ cleanup:
ignore_value
(
virCondDestroy
(
&
call
->
cond
));
VIR_FREE
(
call
);
}
unlock:
virNetClientUnlock
(
client
);
return
ret
;
}
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部