提交 4fa5af5e 编写于 作者: M Matt Pharr

BasicScene: use Future::TryGet() to fix deadlocks.

上级 4990b921
......@@ -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;
......
......@@ -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.
先完成此消息的编辑!
想要评论请 注册