Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
adminstrot
TDengine
提交
4e45a4fd
TDengine
项目概览
adminstrot
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4e45a4fd
编写于
10月 11, 2019
作者:
H
hjxilinx
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix race condition in release cache resource.
上级
c214e229
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
44 addition
and
70 deletion
+44
-70
src/util/src/tcache.c
src/util/src/tcache.c
+44
-70
未找到文件。
src/util/src/tcache.c
浏览文件 @
4e45a4fd
...
...
@@ -89,7 +89,6 @@ typedef struct {
_hashFunc
hashFp
;
int
numOfElemsInTrash
;
// number of element in trash
int16_t
deleting
;
// set the deleting flag to stop refreshing asap.
int16_t
refreshing
;
// if refreshing is invoked, it will be set 1
#if defined LINUX
pthread_rwlock_t
lock
;
...
...
@@ -500,7 +499,7 @@ static SDataNode *taosUpdateCacheImpl(SCacheObj *pObj, SDataNode *pNode, char *k
// only a node is not referenced by any other object, in-place update it
if
(
pNode
->
refCount
==
0
)
{
size_t
newSize
=
sizeof
(
SDataNode
)
+
dataSize
+
(
keyLen
+
1
)
;
size_t
newSize
=
sizeof
(
SDataNode
)
+
dataSize
+
keyLen
;
pNewNode
=
(
SDataNode
*
)
realloc
(
pNode
,
newSize
);
if
(
pNewNode
==
NULL
)
{
...
...
@@ -725,6 +724,34 @@ void *taosUpdateDataFromCache(void *handle, char *key, char *pData, int size, in
return
(
pNew
!=
NULL
)
?
pNew
->
data
:
NULL
;
}
static
void
doCleanUpDataCache
(
SCacheObj
*
pObj
)
{
SDataNode
*
pNode
,
*
pNext
;
__cache_wr_lock
(
pObj
);
if
(
pObj
->
hashList
&&
pObj
->
size
>
0
)
{
for
(
int
i
=
0
;
i
<
pObj
->
capacity
;
++
i
)
{
pNode
=
pObj
->
hashList
[
i
];
while
(
pNode
)
{
pNext
=
pNode
->
next
;
free
(
pNode
);
pNode
=
pNext
;
}
}
tfree
(
pObj
->
hashList
);
}
__cache_unlock
(
pObj
);
taosClearCacheTrash
(
pObj
,
true
);
__cache_lock_destroy
(
pObj
);
memset
(
pObj
,
0
,
sizeof
(
SCacheObj
));
free
(
pObj
);
}
/**
* refresh cache to remove data in both hash list and trash, if any nodes' refcount == 0, every pObj->refreshTime
* @param handle Cache object handle
...
...
@@ -733,21 +760,13 @@ void taosRefreshDataCache(void *handle, void *tmrId) {
SDataNode
*
pNode
,
*
pNext
;
SCacheObj
*
pObj
=
(
SCacheObj
*
)
handle
;
if
(
pObj
==
NULL
||
pObj
->
capacity
<=
0
||
pObj
->
deleting
==
1
)
{
if
(
pObj
==
NULL
||
pObj
->
capacity
<=
0
)
{
pTrace
(
"object is destroyed. no refresh retry"
);
return
;
}
pObj
->
refreshing
=
1
;
#if defined LINUX
__sync_synchronize
();
#else
MemoryBarrier
();
#endif
if
(
pObj
->
deleting
==
1
)
{
pObj
->
refreshing
=
0
;
doCleanUpDataCache
(
pObj
)
;
return
;
}
...
...
@@ -760,8 +779,7 @@ void taosRefreshDataCache(void *handle, void *tmrId) {
for
(
int
i
=
0
;
i
<
pObj
->
capacity
;
++
i
)
{
// in deleting process, quit refreshing immediately
if
(
pObj
->
deleting
==
1
)
{
pObj
->
refreshing
=
0
;
return
;
break
;
}
__cache_wr_lock
(
pObj
);
...
...
@@ -786,12 +804,8 @@ void taosRefreshDataCache(void *handle, void *tmrId) {
__cache_unlock
(
pObj
);
}
int16_t
isDeleting
=
pObj
->
deleting
;
pObj
->
refreshing
=
0
;
// the SCacheObj may have been released now.
if
(
isDeleting
==
1
)
{
return
;
if
(
pObj
->
deleting
==
1
)
{
// clean up resources and abort
doCleanUpDataCache
(
pObj
);
}
else
{
taosClearCacheTrash
(
pObj
,
false
);
taosTmrReset
(
taosRefreshDataCache
,
pObj
->
refreshTime
,
pObj
,
pObj
->
tmrCtrl
,
&
pObj
->
pTimer
);
...
...
@@ -829,8 +843,7 @@ void taosClearDataCache(void *handle) {
}
/**
*
* @param capacity maximum slots available for hash elements
* @param capacity maximum slots available for hash elements
* @param tmrCtrl timer ctrl
* @param refreshTime refresh operation interval time, the maximum survival time when one element is expired and
* not referenced by other objects
...
...
@@ -877,61 +890,22 @@ void *taosInitDataCache(int capacity, void *tmrCtrl, int64_t refreshTime) {
}
/**
* release all allocated memory and destroy the cache object
* release all allocated memory and destroy the cache object.
*
* This function only set the deleting flag, and the specific work of clean up cache is delegated to
* taosRefreshDataCache function, which will executed every SCacheObj->refreshTime sec.
*
* If the value of SCacheObj->refreshTime is too large, the taosRefreshDataCache function may not be invoked
* before the main thread terminated, in which case all allocated resources are simply recycled by OS.
*
* @param handle
*/
void
taosCleanUpDataCache
(
void
*
handle
)
{
SCacheObj
*
pObj
;
SDataNode
*
pNode
,
*
pNext
;
pObj
=
(
SCacheObj
*
)
handle
;
SCacheObj
*
pObj
=
(
SCacheObj
*
)
handle
;
if
(
pObj
==
NULL
)
{
return
;
}
if
(
pObj
->
capacity
<=
0
)
{
__cache_lock_destroy
(
pObj
);
free
(
pObj
);
return
;
}
taosTmrStopA
(
&
pObj
->
pTimer
);
pObj
->
deleting
=
1
;
#if defined LINUX
__sync_synchronize
();
#else
MemoryBarrier
();
#endif
while
(
pObj
->
refreshing
==
1
)
{
taosMsleep
(
0
);
}
__cache_wr_lock
(
pObj
);
if
(
pObj
->
hashList
&&
pObj
->
size
>
0
)
{
for
(
int
i
=
0
;
i
<
pObj
->
capacity
;
++
i
)
{
pNode
=
pObj
->
hashList
[
i
];
while
(
pNode
)
{
pNext
=
pNode
->
next
;
free
(
pNode
);
pNode
=
pNext
;
}
}
tfree
(
pObj
->
hashList
);
}
__cache_unlock
(
pObj
);
taosClearCacheTrash
(
pObj
,
true
);
__cache_lock_destroy
(
pObj
);
memset
(
pObj
,
0
,
sizeof
(
SCacheObj
));
free
(
pObj
);
return
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录