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-22 18:42:21 -04:00
parent be573dcd88
commit c24adb2950
9 changed files with 42 additions and 4 deletions
+3
View File
@@ -152,6 +152,9 @@ public:
virtual const char* Name() { return fName; } virtual const char* Name() { return fName; }
status_t Register();
void Unregister();
protected: protected:
virtual status_t ToEventMask(const KMessage& eventSpecifier, virtual status_t ToEventMask(const KMessage& eventSpecifier,
uint32& eventMask); uint32& eventMask);
@@ -130,22 +130,32 @@ notifications_std_ops(int32 op, ...)
{ {
switch (op) { switch (op) {
case B_MODULE_INIT: case B_MODULE_INIT:
{
TRACE("init\n"); TRACE("init\n");
new(&sNotificationService) NetNotificationService(); new(&sNotificationService) NetNotificationService();
status_t result = sNotificationService.Register();
if (result != B_OK)
return result;
register_generic_syscall(NET_NOTIFICATIONS_SYSCALLS, register_generic_syscall(NET_NOTIFICATIONS_SYSCALLS,
net_notifications_control, 1, 0); net_notifications_control, 1, 0);
return B_OK; return B_OK;
}
case B_MODULE_UNINIT: case B_MODULE_UNINIT:
TRACE("uninit\n"); TRACE("uninit\n");
unregister_generic_syscall(NET_NOTIFICATIONS_SYSCALLS, 1); 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 // we need to release the reference that was acquired
// on our behalf by the NotificationManager. // on our behalf by the NotificationManager.
// sNotificationService.ReleaseReference(); sNotificationService.ReleaseReference();
sNotificationService.~NetNotificationService(); sNotificationService.~NetNotificationService();
return B_OK; return B_OK;
+14 -2
View File
@@ -156,13 +156,11 @@ DefaultNotificationService::DefaultNotificationService(const char* name)
fName(name) fName(name)
{ {
recursive_lock_init(&fLock, name); recursive_lock_init(&fLock, name);
NotificationManager::Manager().RegisterService(*this);
} }
DefaultNotificationService::~DefaultNotificationService() DefaultNotificationService::~DefaultNotificationService()
{ {
NotificationManager::Manager().UnregisterService(*this);
recursive_lock_destroy(&fLock); 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 status_t
DefaultNotificationService::ToEventMask(const KMessage& eventSpecifier, DefaultNotificationService::ToEventMask(const KMessage& eventSpecifier,
uint32& eventMask) uint32& eventMask)
@@ -78,10 +78,12 @@ IOSchedulerRoster::IOSchedulerRoster()
fNotificationService("I/O") fNotificationService("I/O")
{ {
mutex_init(&fLock, "IOSchedulerRoster"); mutex_init(&fLock, "IOSchedulerRoster");
fNotificationService.Register();
} }
IOSchedulerRoster::~IOSchedulerRoster() IOSchedulerRoster::~IOSchedulerRoster()
{ {
mutex_destroy(&fLock); mutex_destroy(&fLock);
fNotificationService.Unregister();
} }
@@ -254,6 +254,8 @@ KDiskDeviceManager::KDiskDeviceManager()
if (InitCheck() != B_OK) if (InitCheck() != B_OK)
return; return;
fNotifications->Register();
RescanDiskSystems(); RescanDiskSystems();
fMediaChecker = spawn_kernel_thread(_CheckMediaStatusDaemon, fMediaChecker = spawn_kernel_thread(_CheckMediaStatusDaemon,
@@ -310,6 +312,8 @@ KDiskDeviceManager::~KDiskDeviceManager()
delete diskSystem; delete diskSystem;
} }
fNotifications->Unregister();
// delete the containers // delete the containers
delete fPartitions; delete fPartitions;
delete fDevices; delete fDevices;
+2
View File
@@ -343,6 +343,8 @@ image_init(void)
new(&sNotificationService) ImageNotificationService(); new(&sNotificationService) ImageNotificationService();
sNotificationService.Register();
#ifdef ADD_DEBUGGER_COMMANDS #ifdef ADD_DEBUGGER_COMMANDS
add_debugger_command("team_images", &dump_images_list, "Dump all registered images from the current team"); add_debugger_command("team_images", &dump_images_list, "Dump all registered images from the current team");
#endif #endif
+1
View File
@@ -792,6 +792,7 @@ port_init(kernel_args *args)
" <condition> - address of the port's read or write condition.\n", 0); " <condition> - address of the port's read or write condition.\n", 0);
new(&sNotificationService) PortNotificationService(); new(&sNotificationService) PortNotificationService();
sNotificationService.Register();
sPortsActive = true; sPortsActive = true;
return B_OK; return B_OK;
} }
+2
View File
@@ -2771,6 +2771,8 @@ team_init(kernel_args* args)
new(&sNotificationService) TeamNotificationService(); new(&sNotificationService) TeamNotificationService();
sNotificationService.Register();
return B_OK; return B_OK;
} }
+2
View File
@@ -2738,6 +2738,8 @@ thread_init(kernel_args *args)
// init the notification service // init the notification service
new(&sNotificationService) ThreadNotificationService(); new(&sNotificationService) ThreadNotificationService();
sNotificationService.Register();
// start the undertaker thread // start the undertaker thread
new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>(); new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries"); sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");