hooks should use their own IOService instance and register it with the main IOService
related to #3308 (closed)
to properly load and run IOService poll so that configuration errors are detected before configuration is applied and to unload hooks and safely call all close callbacks, a "local" IOService instance should be used by each hook. this guarantees that there can be no handlers referencing objects created in the hook that are called after hook unload.
hooks that use main io service:
premium:
- gss_tsig
- forensic_log
- lease_query
- ping_check
- radius
core:
- high_availability
- mysql_cb
- pbsql_cb
- run_script
all hooks requiring IOService should do the following:
int unload() {
if (getMainIOService()) {
getMainIOService()->unregisterExternalIOService(getIOService());
}
getIOService()->stop();
getIOService()->restart();
try {
getIOService()->poll();
} catch (...) {
}
...
}
int dhcp4_srv_configured(CalloutHandle& handle) {
handle.getArgument("io_context", getMainIOService());
if (!getMainIOService()) {
// Should not happen!
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
const string error("Error: io_context is null");
handle.setArgument("error", error);
return (1);
}
...
getMainIOService()->registerExternalIOService(getIOService());
...
}
int dhcp6_srv_configured(CalloutHandle& handle) {
handle.getArgument("io_context", getMainIOService());
if (!getMainIOService()) {
// Should not happen!
handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
const string error("Error: io_context is null");
handle.setArgument("error", error);
return (1);
}
...
getMainIOService()->registerExternalIOService(getIOService());
...
}
void
IOService::registerExternalIOService(IOServicePtr io_service) {
external_io_services_.push_back(io_service);
}
void
IOService::unregisterExternalIOService(IOServicePtr io_service) {
auto it = std::find(external_io_services_.begin(), external_io_services_.end(), io_service);
if (it != external_io_services_.end()) {
external_io_services_.erase(it);
}
}
void
IOService::pollExternalIO() {
for (auto& io_service : external_io_services_) {
io_service->poll();
}
}
built on top of #3281 (closed)
I confirm it fixes the crash in #3308 (closed)
Edited by Razvan Becheriu