Rework DefaultNotificationService registration.
- Instead of implicitly registering and unregistering a service instance on construction/destruction, DefaultNotificationService now exports explicit Register()/Unregister() calls, which subclasses are expected to call when they're ready. - Adjust all implementing subclasses. Resolves an issue with deadlocks when booting a DEBUG=1 build.
This commit is contained in:
parent
be573dcd88
commit
c24adb2950
@ -152,6 +152,9 @@ public:
|
||||
|
||||
virtual const char* Name() { return fName; }
|
||||
|
||||
status_t Register();
|
||||
void Unregister();
|
||||
|
||||
protected:
|
||||
virtual status_t ToEventMask(const KMessage& eventSpecifier,
|
||||
uint32& eventMask);
|
||||
|
@ -130,22 +130,32 @@ notifications_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
{
|
||||
TRACE("init\n");
|
||||
|
||||
new(&sNotificationService) NetNotificationService();
|
||||
status_t result = sNotificationService.Register();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
register_generic_syscall(NET_NOTIFICATIONS_SYSCALLS,
|
||||
net_notifications_control, 1, 0);
|
||||
return B_OK;
|
||||
|
||||
}
|
||||
case B_MODULE_UNINIT:
|
||||
TRACE("uninit\n");
|
||||
|
||||
unregister_generic_syscall(NET_NOTIFICATIONS_SYSCALLS, 1);
|
||||
|
||||
// TODO: due to the way the locking in the notification
|
||||
// manager works, there's a potential race condition here
|
||||
// where someone attempts to add a listener right as
|
||||
// we're uninitializing. Needs to be looked at/resolved.
|
||||
sNotificationService.Unregister();
|
||||
|
||||
// we need to release the reference that was acquired
|
||||
// on our behalf by the NotificationManager.
|
||||
// sNotificationService.ReleaseReference();
|
||||
sNotificationService.ReleaseReference();
|
||||
sNotificationService.~NetNotificationService();
|
||||
return B_OK;
|
||||
|
||||
|
@ -156,13 +156,11 @@ DefaultNotificationService::DefaultNotificationService(const char* name)
|
||||
fName(name)
|
||||
{
|
||||
recursive_lock_init(&fLock, name);
|
||||
NotificationManager::Manager().RegisterService(*this);
|
||||
}
|
||||
|
||||
|
||||
DefaultNotificationService::~DefaultNotificationService()
|
||||
{
|
||||
NotificationManager::Manager().UnregisterService(*this);
|
||||
recursive_lock_destroy(&fLock);
|
||||
}
|
||||
|
||||
@ -253,6 +251,20 @@ DefaultNotificationService::RemoveListener(const KMessage* eventSpecifier,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultNotificationService::Register()
|
||||
{
|
||||
return NotificationManager::Manager().RegisterService(*this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultNotificationService::Unregister()
|
||||
{
|
||||
NotificationManager::Manager().UnregisterService(*this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DefaultNotificationService::ToEventMask(const KMessage& eventSpecifier,
|
||||
uint32& eventMask)
|
||||
|
@ -78,10 +78,12 @@ IOSchedulerRoster::IOSchedulerRoster()
|
||||
fNotificationService("I/O")
|
||||
{
|
||||
mutex_init(&fLock, "IOSchedulerRoster");
|
||||
fNotificationService.Register();
|
||||
}
|
||||
|
||||
|
||||
IOSchedulerRoster::~IOSchedulerRoster()
|
||||
{
|
||||
mutex_destroy(&fLock);
|
||||
fNotificationService.Unregister();
|
||||
}
|
||||
|
@ -254,6 +254,8 @@ KDiskDeviceManager::KDiskDeviceManager()
|
||||
if (InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
fNotifications->Register();
|
||||
|
||||
RescanDiskSystems();
|
||||
|
||||
fMediaChecker = spawn_kernel_thread(_CheckMediaStatusDaemon,
|
||||
@ -310,6 +312,8 @@ KDiskDeviceManager::~KDiskDeviceManager()
|
||||
delete diskSystem;
|
||||
}
|
||||
|
||||
fNotifications->Unregister();
|
||||
|
||||
// delete the containers
|
||||
delete fPartitions;
|
||||
delete fDevices;
|
||||
|
@ -343,6 +343,8 @@ image_init(void)
|
||||
|
||||
new(&sNotificationService) ImageNotificationService();
|
||||
|
||||
sNotificationService.Register();
|
||||
|
||||
#ifdef ADD_DEBUGGER_COMMANDS
|
||||
add_debugger_command("team_images", &dump_images_list, "Dump all registered images from the current team");
|
||||
#endif
|
||||
|
@ -792,6 +792,7 @@ port_init(kernel_args *args)
|
||||
" <condition> - address of the port's read or write condition.\n", 0);
|
||||
|
||||
new(&sNotificationService) PortNotificationService();
|
||||
sNotificationService.Register();
|
||||
sPortsActive = true;
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -2771,6 +2771,8 @@ team_init(kernel_args* args)
|
||||
|
||||
new(&sNotificationService) TeamNotificationService();
|
||||
|
||||
sNotificationService.Register();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -2738,6 +2738,8 @@ thread_init(kernel_args *args)
|
||||
// init the notification service
|
||||
new(&sNotificationService) ThreadNotificationService();
|
||||
|
||||
sNotificationService.Register();
|
||||
|
||||
// start the undertaker thread
|
||||
new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
|
||||
sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");
|
||||
|
Loading…
Reference in New Issue
Block a user