Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
imjiangjun
pbrt-v4
提交
4fa5af5e
P
pbrt-v4
项目概览
imjiangjun
/
pbrt-v4
11 个月 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
pbrt-v4
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4fa5af5e
编写于
8月 26, 2021
作者:
M
Matt Pharr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
BasicScene: use Future::TryGet() to fix deadlocks.
上级
4990b921
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
49 addition
and
38 deletion
+49
-38
src/pbrt/scene.cpp
src/pbrt/scene.cpp
+31
-20
src/pbrt/scene.h
src/pbrt/scene.h
+18
-18
未找到文件。
src/pbrt/scene.cpp
浏览文件 @
4fa5af5e
...
...
@@ -761,32 +761,43 @@ Medium BasicScene::GetMedium(const std::string &name, const FileLoc *loc) {
if
(
name
.
empty
())
return
nullptr
;
std
::
lock_guard
<
std
::
mutex
>
lock
(
mediaMutex
);
if
(
auto
iter
=
mediaMap
.
find
(
name
);
iter
!=
mediaMap
.
end
())
return
iter
->
second
;
else
{
auto
fiter
=
mediumFutures
.
find
(
name
);
if
(
fiter
==
mediumFutures
.
end
())
ErrorExit
(
loc
,
"%s: medium is not defined."
,
name
);
Medium
m
=
fiter
->
second
.
Get
();
mediaMap
[
name
]
=
m
;
mediumFutures
.
erase
(
fiter
);
return
m
;
mediaMutex
.
lock
();
while
(
true
)
{
if
(
auto
iter
=
mediaMap
.
find
(
name
);
iter
!=
mediaMap
.
end
())
{
Medium
m
=
iter
->
second
;
mediaMutex
.
unlock
();
return
m
;
}
else
{
auto
fiter
=
mediumFutures
.
find
(
name
);
if
(
fiter
==
mediumFutures
.
end
())
ErrorExit
(
loc
,
"%s: medium is not defined."
,
name
);
pstd
::
optional
<
Medium
>
m
=
fiter
->
second
.
TryGet
(
&
mediaMutex
);
if
(
m
)
{
mediaMap
[
name
]
=
*
m
;
mediumFutures
.
erase
(
fiter
);
mediaMutex
.
unlock
();
return
*
m
;
}
}
}
}
std
::
map
<
std
::
string
,
Medium
>
BasicScene
::
CreateMedia
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
mediaMutex
);
if
(
mediumFutures
.
empty
())
return
mediaMap
;
// Consume futures for asynchronously-created _Medium_ objects
LOG_VERBOSE
(
"Consume media futures start"
);
for
(
auto
&
m
:
mediumFutures
)
{
CHECK
(
mediaMap
.
find
(
m
.
first
)
==
mediaMap
.
end
());
mediaMap
[
m
.
first
]
=
m
.
second
.
Get
();
mediaMutex
.
lock
();
if
(
!
mediumFutures
.
empty
())
{
// Consume futures for asynchronously-created _Medium_ objects
LOG_VERBOSE
(
"Consume media futures start"
);
for
(
auto
&
m
:
mediumFutures
)
{
while
(
mediaMap
.
find
(
m
.
first
)
==
mediaMap
.
end
())
{
pstd
::
optional
<
Medium
>
med
=
m
.
second
.
TryGet
(
&
mediaMutex
);
if
(
med
)
mediaMap
[
m
.
first
]
=
*
med
;
}
}
}
mediumFutures
.
clear
();
mediaMutex
.
unlock
();
LOG_VERBOSE
(
"Consume media futures finished"
);
return
mediaMap
;
...
...
src/pbrt/scene.h
浏览文件 @
4fa5af5e
...
...
@@ -283,35 +283,35 @@ class BasicScene {
void
Done
();
Camera
GetCamera
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
cameraFutureMutex
);
if
(
!
camera
)
{
if
(
!
cameraFuture
.
IsReady
())
LOG_VERBOSE
(
"Waiting for camera future"
);
camera
=
cameraFuture
.
Get
();
LOG_VERBOSE
(
"Got camera future"
);
cameraFutureMutex
.
lock
();
while
(
!
camera
)
{
pstd
::
optional
<
Camera
>
c
=
cameraFuture
.
TryGet
(
&
cameraFutureMutex
);
if
(
c
)
camera
=
*
c
;
}
cameraFutureMutex
.
unlock
();
return
camera
;
}
Film
GetFilm
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
filmFutureMutex
);
if
(
!
film
)
{
if
(
!
filmFuture
.
IsReady
())
LOG_VERBOSE
(
"Waiting for film future"
);
film
=
filmFuture
.
Get
();
LOG_VERBOSE
(
"Got film future"
);
filmFutureMutex
.
lock
();
while
(
!
film
)
{
pstd
::
optional
<
Film
>
f
=
filmFuture
.
TryGet
(
&
filmFutureMutex
);
if
(
f
)
film
=
*
f
;
}
filmFutureMutex
.
unlock
();
return
film
;
}
Sampler
GetSampler
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
samplerFutureMutex
);
if
(
!
sampler
)
{
if
(
!
samplerFuture
.
IsReady
())
LOG_VERBOSE
(
"Waiting for sampler future"
);
sampler
=
samplerFuture
.
Get
();
LOG_VERBOSE
(
"Got sampler future"
);
samplerFutureMutex
.
lock
();
while
(
!
sampler
)
{
pstd
::
optional
<
Sampler
>
s
=
samplerFuture
.
TryGet
(
&
samplerFutureMutex
);
if
(
s
)
sampler
=
*
s
;
}
samplerFutureMutex
.
unlock
();
return
sampler
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录