machinebase: fully initialize devices registered by other devices

postinit_devices() may cause additional devices to be registered
(e.g. PCI hosts will register their cards). We were not calling
device_postinit on those devices, because the iterator over the
device map was set up at the start of the loop.

Keep looping until we've actually initialized all devices in the map.
This commit is contained in:
Mihai Parparita 2023-11-08 00:08:41 -08:00
parent 351ac78e4b
commit e5c50640e3
1 changed files with 13 additions and 3 deletions

View File

@ -24,6 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <machines/machinebase.h>
#include <map>
#include <set>
#include <string>
std::unique_ptr<MachineBase> gMachineObj = 0;
@ -79,9 +80,18 @@ HWComponent* MachineBase::get_comp_by_type(HWCompType type) {
int MachineBase::postinit_devices()
{
for (auto it = this->device_map.begin(); it != this->device_map.end(); it++) {
if (it->second->device_postinit()) {
return -1;
// Allow additional devices to be registered by device_postinit, in which
// case we'll initialize them too.
std::set<std::string> initialized_devices;
while (initialized_devices.size() < this->device_map.size()) {
for (auto it = this->device_map.begin(); it != this->device_map.end(); it++) {
if (initialized_devices.find(it->first) == initialized_devices.end()) {
if (it->second->device_postinit()) {
LOG_F(ERROR, "Could not initialize device %s", it->first.c_str());
return -1;
}
initialized_devices.insert(it->first);
}
}
}