Stop Cobalt 将无限期挂起(阻塞)
Stop Cobalt will hang(block) indefinitely
Cobalt调用ApplicationDirectFB::Get()->Stop()
函数后会无限期挂起(阻塞),无法退出,挂起时的backtrace如下,谁能帮忙看看?
<unknown> [0xb5d988f4]
SbConditionVariableWait [0xbd598]
base::WaitableEvent::TimedWait() [0xa0f1c]
base::WaitableEvent::Wait() [0xa0ff8]
cobalt::storage::StorageManager::FinishIO() [0x374454]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
如果我在src/cobalt/storage/storage_manager.cc
中注释StorageManager::FinishIO
中的no_flushes_pending_.Wait();
,它不会挂起(阻塞),并且可以成功退出
void StorageManager::FinishIO() {
TRACE_EVENT0("cobalt::storage", __FUNCTION__);
DCHECK(!sql_message_loop_->BelongsToCurrentThread());
// The SQL thread may be communicating with the savegame I/O thread still,
// flushing all pending updates. This process can require back and forth
// communication. This method exists to wait for that communication to
// finish and for all pending flushes to complete.
// Start by finishing all commands currently in the sql message loop queue.
// This method is called by the destructor, so the only new tasks posted
// after this one will be generated internally. We need to do this because
// it is possible that there are no flushes pending at this instant, but there
// are tasks queued on |sql_message_loop_| that will begin a flush, and so
// we make sure that these are executed first.
base::WaitableEvent current_queue_finished_event_(true, false);
sql_message_loop_->PostTask(
FROM_HERE,
base::Bind(&base::WaitableEvent::Signal,
base::Unretained(¤t_queue_finished_event_)));
current_queue_finished_event_.Wait();
// Now wait for all pending flushes to wrap themselves up. This may involve
// the savegame I/O thread and the SQL thread posting tasks to each other.
//no_flushes_pending_.Wait(); -->Comment it
}
这不是最佳答案,因为我只是依稀记得以前遇到过这个问题,但我找不到任何地方可以确认对它的引用。我相信当其中一个 SbStorage API 没有 return 正确的值时会发生这种情况,可能是因为错误?
根本原因是它会写数据到$HOME/.starboard.storage
(在starboard/shared/linux/get_home_directory.cc
中设置),但是在某些平台上,该分区是只读的,会导致写入失败并无限期挂起,因此需要将 .starboard.storage
的文件路径更改为某个可写分区。
Cobalt调用ApplicationDirectFB::Get()->Stop()
函数后会无限期挂起(阻塞),无法退出,挂起时的backtrace如下,谁能帮忙看看?
<unknown> [0xb5d988f4]
SbConditionVariableWait [0xbd598]
base::WaitableEvent::TimedWait() [0xa0f1c]
base::WaitableEvent::Wait() [0xa0ff8]
cobalt::storage::StorageManager::FinishIO() [0x374454]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
cobalt::storage::StorageManager::~StorageManager() [0x374750]
如果我在src/cobalt/storage/storage_manager.cc
中注释StorageManager::FinishIO
中的no_flushes_pending_.Wait();
,它不会挂起(阻塞),并且可以成功退出
void StorageManager::FinishIO() {
TRACE_EVENT0("cobalt::storage", __FUNCTION__);
DCHECK(!sql_message_loop_->BelongsToCurrentThread());
// The SQL thread may be communicating with the savegame I/O thread still,
// flushing all pending updates. This process can require back and forth
// communication. This method exists to wait for that communication to
// finish and for all pending flushes to complete.
// Start by finishing all commands currently in the sql message loop queue.
// This method is called by the destructor, so the only new tasks posted
// after this one will be generated internally. We need to do this because
// it is possible that there are no flushes pending at this instant, but there
// are tasks queued on |sql_message_loop_| that will begin a flush, and so
// we make sure that these are executed first.
base::WaitableEvent current_queue_finished_event_(true, false);
sql_message_loop_->PostTask(
FROM_HERE,
base::Bind(&base::WaitableEvent::Signal,
base::Unretained(¤t_queue_finished_event_)));
current_queue_finished_event_.Wait();
// Now wait for all pending flushes to wrap themselves up. This may involve
// the savegame I/O thread and the SQL thread posting tasks to each other.
//no_flushes_pending_.Wait(); -->Comment it
}
这不是最佳答案,因为我只是依稀记得以前遇到过这个问题,但我找不到任何地方可以确认对它的引用。我相信当其中一个 SbStorage API 没有 return 正确的值时会发生这种情况,可能是因为错误?
根本原因是它会写数据到$HOME/.starboard.storage
(在starboard/shared/linux/get_home_directory.cc
中设置),但是在某些平台上,该分区是只读的,会导致写入失败并无限期挂起,因此需要将 .starboard.storage
的文件路径更改为某个可写分区。