vbox6: machine power-down support

Use 'StateChange' event to check for machine's 'PowerOff' state, close
Gui connections and submit exit signal to EP which in turns calls exit.

Fixes #4291
This commit is contained in:
Sebastian Sumpf 2021-10-08 14:12:33 +02:00 committed by Norman Feske
parent c7abc9f983
commit d1461f6a72
3 changed files with 48 additions and 1 deletions

View File

@ -232,6 +232,8 @@ struct Main : Event_handler
}
}
void destruct_rom() { _rom.destruct(); }
void update_guest(bool enabled) { _guest = enabled; }
bool update_from_rom()
@ -262,6 +264,8 @@ struct Main : Event_handler
Mouse_shape _mouse_shape { _env };
Signal_handler<Main> _exit_handler { _env.ep(), *this, &Main::_handle_exit };
Registry<Registered<Gui::Connection>> _gui_connections { };
Signal_handler<Main> _input_handler { _env.ep(), *this, &Main::_handle_input };
@ -324,6 +328,20 @@ struct Main : Event_handler
}
}
void _power_down_machine()
{
_capslock.destruct_rom();
_gui_connections.for_each([&] (Gui::Connection &gui) {
delete &gui;
});
/* signal exit to main entrypoint */
_exit_handler.local_submit();
}
void _handle_exit() { _env.parent().exit(0); }
void handle_vbox_event(VBoxEventType_T, IEvent &) override;
bool const _vbox_event_handler_installed = ( _install_vbox_event_handler(), true );
@ -342,6 +360,7 @@ struct Main : Event_handler
event_types.push_back(VBoxEventType_OnMouseCapabilityChanged);
event_types.push_back(VBoxEventType_OnMousePointerShapeChanged);
event_types.push_back(VBoxEventType_OnKeyboardLedsChanged);
event_types.push_back(VBoxEventType_OnStateChanged);
ievent_source->RegisterListener(listener, ComSafeArrayAsInParam(event_types), true);
}
@ -449,6 +468,17 @@ void Main::handle_vbox_event(VBoxEventType_T ev_type, IEvent &ev)
_capslock.update_guest(!!capslock);
} break;
case VBoxEventType_OnStateChanged:
{
ComPtr<IStateChangedEvent> state_change_ev = &ev;
MachineState_T machineState;
state_change_ev->COMGETTER(State)(&machineState);
if (machineState == MachineState_PoweredOff)
_power_down_machine();
} break;
default: /* ignore other events */ break;
}
}

View File

@ -228,7 +228,7 @@ int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
}
int nemR3NativeTerm(PVM pVM) STOP
int nemR3NativeTerm(PVM pVM) TRACE(VINF_SUCCESS)
/**

View File

@ -631,6 +631,15 @@ static void ioctl(SUPCALLVMMR0 &request)
rc = vmmr0_vmmr0_init_emt(request.u.In.pVMR0, request.u.In.idCpu);
return;
/* XXX ignore ioctls called during poweroff */
case VMMR0_DO_GVMM_DEREGISTER_VMCPU:
case VMMR0_DO_VMMR0_TERM:
case VMMR0_DO_PGM_FLUSH_HANDY_PAGES:
case VMMR0_DO_GMM_BALLOONED_PAGES:
case VMMR0_DO_GMM_RESET_SHARED_MODULES:
rc = VINF_SUCCESS;
return;
default:
error(__func__, " operation=", (int)operation);
rc = VERR_NOT_IMPLEMENTED;
@ -667,6 +676,13 @@ static void ioctl(SUPGETPAGINGMODE &request)
}
static void ioctl(SUPPAGEFREE &request)
{
warning("SUPPAGEFREE called");
request.Hdr.rc = VINF_SUCCESS;
}
static void ioctl(SUPPAGEALLOCEX &request)
{
/*
@ -739,6 +755,7 @@ int suplibOsIOCtl(PSUPLIBDATA pThis, uintptr_t opcode, void *req, size_t len)
case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_GET_PAGING_MODE): ioctl(*(SUPGETPAGINGMODE *)req); break;
case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_PAGE_ALLOC_EX): ioctl(*(SUPPAGEALLOCEX *)req); break;
case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_SET_VM_FOR_FAST): ioctl(*(SUPSETVMFORFAST *)req); break;
case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_PAGE_FREE): ioctl(*(SUPPAGEFREE *)req); break;
default: