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:
Rene Gollent 2013-04-19 23:00:00 -04:00
parent be573dcd88
commit c24adb2950
9 changed files with 42 additions and 4 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -78,10 +78,12 @@ IOSchedulerRoster::IOSchedulerRoster()
fNotificationService("I/O")
{
mutex_init(&fLock, "IOSchedulerRoster");
fNotificationService.Register();
}
IOSchedulerRoster::~IOSchedulerRoster()
{
mutex_destroy(&fLock);
fNotificationService.Unregister();
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -2771,6 +2771,8 @@ team_init(kernel_args* args)
new(&sNotificationService) TeamNotificationService();
sNotificationService.Register();
return B_OK;
}

View File

@ -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");