* Implemented a basic notification mechanism. Right now, only media changes and

device additions/removals can be monitored.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29582 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-03-18 08:55:49 +00:00
parent d95f6cac87
commit 3f78b216ad
6 changed files with 136 additions and 60 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2007, Haiku, Inc. All rights reserved. * Copyright 2004-2009, Haiku, Inc. All rights reserved.
* Copyright 2003-2004, Ingo Weinhold, [email protected]. All rights reserved. * Copyright 2003-2004, Ingo Weinhold, [email protected]. All rights reserved.
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -10,6 +10,7 @@
#include <disk_device_manager.h> #include <disk_device_manager.h>
#include <Locker.h> #include <Locker.h>
#include <Notifications.h>
namespace BPrivate { namespace BPrivate {
@@ -40,6 +41,9 @@ public:
// Disk Device / Partition Management // Disk Device / Partition Management
DefaultUserNotificationService& Notifications();
void Notify(const KMessage& event, uint32 eventMask);
// manager must be locked // manager must be locked
KDiskDevice *FindDevice(const char *path); KDiskDevice *FindDevice(const char *path);
KDiskDevice *FindDevice(partition_id id, bool deviceOnly = true); KDiskDevice *FindDevice(partition_id id, bool deviceOnly = true);
@@ -104,6 +108,7 @@ private:
struct PartitionSet; struct PartitionSet;
class DiskSystemWatcher; class DiskSystemWatcher;
class DeviceWatcher; class DeviceWatcher;
class DiskNotifications;
static status_t _CheckMediaStatusDaemon(void* self); static status_t _CheckMediaStatusDaemon(void* self);
status_t _CheckMediaStatus(); status_t _CheckMediaStatus();
@@ -126,6 +131,8 @@ private:
status_t _AddRemoveMonitoring(const char *path, bool add); status_t _AddRemoveMonitoring(const char *path, bool add);
void _NotifyDeviceEvent(KDiskDevice* device, int32 event, uint32 mask);
BLocker fLock; BLocker fLock;
DeviceMap *fDevices; DeviceMap *fDevices;
PartitionMap *fPartitions; PartitionMap *fPartitions;
@@ -135,6 +142,7 @@ private:
volatile bool fTerminating; volatile bool fTerminating;
DiskSystemWatcher *fDiskSystemWatcher; DiskSystemWatcher *fDiskSystemWatcher;
DeviceWatcher *fDeviceWatcher; DeviceWatcher *fDeviceWatcher;
DiskNotifications* fNotifications;
static KDiskDeviceManager *sDefaultManager; static KDiskDeviceManager *sDefaultManager;
}; };
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2008, Haiku Inc. * Copyright 2003-2009, Haiku Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -90,6 +90,10 @@ status_t _user_delete_child_partition(partition_id partitionID,
int32* changeCounter, partition_id childID, int32* changeCounter, partition_id childID,
int32 childChangeCounter); int32 childChangeCounter);
// change notification
status_t _user_start_watching_disks(uint32 eventMask, port_id port, int32 token);
status_t _user_stop_watching_disks(port_id port, int32 token);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
+5 -10
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2008, Haiku Inc. All rights reserved. * Copyright 2004-2009, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _SYSTEM_SYSCALLS_H #ifndef _SYSTEM_SYSCALLS_H
@@ -512,15 +512,10 @@ extern status_t _kern_delete_child_partition(partition_id partitionID,
int32* changeCounter, partition_id childID, int32* changeCounter, partition_id childID,
int32 childChangeCounter); int32 childChangeCounter);
#if 0 // disk change notification
extern status_t _kern_start_watching_disks(uint32 eventMask, port_id port,
// watching int32 token);
status_t start_disk_device_watching(port_id, int32 token, uint32 flags); extern status_t _kern_stop_watching_disks(port_id port, int32 token);
status_t start_disk_device_job_watching(disk_job_id job, port_id, int32 token,
uint32 flags);
status_t stop_disk_device_watching(port_id, int32 token);
#endif // 0
// The end mark for gensyscallinfos. // The end mark for gensyscallinfos.
@@ -22,6 +22,8 @@
#include <Path.h> #include <Path.h>
#include <Volume.h> #include <Volume.h>
#include <MessengerPrivate.h>
#include <syscalls.h> #include <syscalls.h>
#include <ddm_userland_interface_defs.h> #include <ddm_userland_interface_defs.h>
@@ -511,8 +513,14 @@ BDiskDeviceRoster::GetFileDeviceForPath(const char* filename,
status_t status_t
BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask) BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask)
{ {
// not implemented if (eventMask == 0)
return B_ERROR; return B_BAD_VALUE;
BMessenger::Private messengerPrivate(target);
port_id port = messengerPrivate.Port();
int32 token = messengerPrivate.Token();
return _kern_start_watching_disks(eventMask, port, token);
} }
@@ -525,8 +533,11 @@ BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask)
status_t status_t
BDiskDeviceRoster::StopWatching(BMessenger target) BDiskDeviceRoster::StopWatching(BMessenger target)
{ {
// not implemented BMessenger::Private messengerPrivate(target);
return B_ERROR; port_id port = messengerPrivate.Port();
int32 token = messengerPrivate.Token();
return _kern_stop_watching_disks(port, token);
} }
#if 0 #if 0
@@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2008, Haiku, Inc. All rights reserved. * Copyright 2004-2009, Haiku, Inc. All rights reserved.
* Copyright 2003-2004, Ingo Weinhold, [email protected]. All rights reserved. * Copyright 2003-2004, Ingo Weinhold, [email protected]. All rights reserved.
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -20,6 +20,7 @@
#include <VectorMap.h> #include <VectorMap.h>
#include <VectorSet.h> #include <VectorSet.h>
#include <DiskDeviceRoster.h>
#include <KernelExport.h> #include <KernelExport.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
@@ -183,19 +184,42 @@ private:
}; };
class KDiskDeviceManager::DiskNotifications
: public DefaultUserNotificationService {
public:
DiskNotifications()
: DefaultUserNotificationService("disk devices")
{
}
virtual ~DiskNotifications()
{
}
protected:
status_t _ToFlags(const KMessage& eventSpecifier, uint32& flags)
{
flags = eventSpecifier.GetInt32("flags", 0);
return B_OK;
}
};
// #pragma mark - // #pragma mark -
KDiskDeviceManager::KDiskDeviceManager() KDiskDeviceManager::KDiskDeviceManager()
: fLock("disk device manager"), :
fDevices(new(nothrow) DeviceMap), fLock("disk device manager"),
fPartitions(new(nothrow) PartitionMap), fDevices(new(nothrow) DeviceMap),
fDiskSystems(new(nothrow) DiskSystemMap), fPartitions(new(nothrow) PartitionMap),
fObsoletePartitions(new(nothrow) PartitionSet), fDiskSystems(new(nothrow) DiskSystemMap),
fMediaChecker(-1), fObsoletePartitions(new(nothrow) PartitionSet),
fTerminating(false), fMediaChecker(-1),
fDiskSystemWatcher(NULL), fTerminating(false),
fDeviceWatcher(new(nothrow) DeviceWatcher(this)) fDiskSystemWatcher(NULL),
fDeviceWatcher(new(nothrow) DeviceWatcher(this)),
fNotifications(new(nothrow) DiskNotifications)
{ {
if (InitCheck() != B_OK) if (InitCheck() != B_OK)
return; return;
@@ -267,7 +291,8 @@ KDiskDeviceManager::~KDiskDeviceManager()
status_t status_t
KDiskDeviceManager::InitCheck() const KDiskDeviceManager::InitCheck() const
{ {
if (!fPartitions || !fDevices || !fDiskSystems || !fObsoletePartitions) if (fPartitions == NULL || fDevices == NULL || fDiskSystems == NULL
|| fObsoletePartitions == NULL || fNotifications == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
return fLock.Sem() >= 0 ? B_OK : fLock.Sem(); return fLock.Sem() >= 0 ? B_OK : fLock.Sem();
@@ -323,6 +348,20 @@ KDiskDeviceManager::Unlock()
} }
DefaultUserNotificationService&
KDiskDeviceManager::Notifications()
{
return *fNotifications;
}
void
KDiskDeviceManager::Notify(const KMessage& event, uint32 eventMask)
{
fNotifications->Notify(event, eventMask);
}
KDiskDevice* KDiskDevice*
KDiskDeviceManager::FindDevice(const char* path) KDiskDeviceManager::FindDevice(const char* path)
{ {
@@ -637,6 +676,9 @@ KDiskDeviceManager::CreateDevice(const char* path, bool* newlyCreated)
_ScanPartition(device, false); _ScanPartition(device, false);
device->UnmarkBusy(true); device->UnmarkBusy(true);
_NotifyDeviceEvent(device, B_DEVICE_ADDED,
B_DEVICE_REQUEST_DEVICE_LIST);
if (newlyCreated) if (newlyCreated)
*newlyCreated = true; *newlyCreated = true;
@@ -709,6 +751,9 @@ KDiskDeviceManager::CreateFileDevice(const char* filePath, bool* newlyCreated)
_ScanPartition(device, false); _ScanPartition(device, false);
device->UnmarkBusy(true); device->UnmarkBusy(true);
_NotifyDeviceEvent(device, B_DEVICE_ADDED,
B_DEVICE_REQUEST_DEVICE_LIST);
if (newlyCreated) if (newlyCreated)
*newlyCreated = true; *newlyCreated = true;
@@ -765,6 +810,7 @@ KDiskDeviceManager::NextDevice(int32* cookie)
{ {
if (!cookie) if (!cookie)
return NULL; return NULL;
DeviceMap::Iterator it = fDevices->FindClose(*cookie, false); DeviceMap::Iterator it = fDevices->FindClose(*cookie, false);
if (it != fDevices->End()) { if (it != fDevices->End()) {
KDiskDevice* device = it->Value(); KDiskDevice* device = it->Value();
@@ -787,7 +833,7 @@ KDiskDeviceManager::PartitionRemoved(KPartition* partition)
{ {
if (partition && partition->PrepareForRemoval() if (partition && partition->PrepareForRemoval()
&& fPartitions->Remove(partition->ID())) { && fPartitions->Remove(partition->ID())) {
// If adding the partition to the obsolete list fails (due to lack // TODO: If adding the partition to the obsolete list fails (due to lack
// of memory), we can't do anything about it. We will leak memory then. // of memory), we can't do anything about it. We will leak memory then.
fObsoletePartitions->Insert(partition); fObsoletePartitions->Insert(partition);
partition->MarkObsolete(); partition->MarkObsolete();
@@ -1091,8 +1137,14 @@ KDiskDeviceManager::_AddDevice(KDiskDevice* device)
bool bool
KDiskDeviceManager::_RemoveDevice(KDiskDevice* device) KDiskDeviceManager::_RemoveDevice(KDiskDevice* device)
{ {
return (device && fDevices->Remove(device->ID()) if (device != NULL && fDevices->Remove(device->ID())
&& PartitionRemoved(device)); && PartitionRemoved(device)) {
_NotifyDeviceEvent(device, B_DEVICE_REMOVED,
B_DEVICE_REQUEST_DEVICE_LIST);
return true;
}
return false;
} }
@@ -1433,6 +1485,8 @@ KDiskDeviceManager::_CheckMediaStatus()
dprintf("Media changed from %s\n", device->Path()); dprintf("Media changed from %s\n", device->Path());
device->UpdateGeometry(); device->UpdateGeometry();
_ScanPartition(device, false); _ScanPartition(device, false);
_NotifyDeviceEvent(device, B_DEVICE_MEDIA_CHANGED,
B_DEVICE_REQUEST_DEVICE);
} else if (!device->HasMedia() && hadMedia) { } else if (!device->HasMedia() && hadMedia) {
dprintf("Media removed from %s\n", device->Path()); dprintf("Media removed from %s\n", device->Path());
} }
@@ -1452,3 +1506,19 @@ KDiskDeviceManager::_CheckMediaStatusDaemon(void* self)
{ {
return ((KDiskDeviceManager*)self)->_CheckMediaStatus(); return ((KDiskDeviceManager*)self)->_CheckMediaStatus();
} }
void
KDiskDeviceManager::_NotifyDeviceEvent(KDiskDevice* device, int32 event,
uint32 mask)
{
char messageBuffer[512];
KMessage message;
message.SetTo(messageBuffer, sizeof(messageBuffer), B_DEVICE_UPDATE);
message.AddInt32("event", event);
message.AddInt32("id", device->ID());
message.AddString("device", device->Path());
fNotifications->Notify(message, mask);
}
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2008, Haiku, Inc. All Rights Reserved. * Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -40,7 +40,6 @@ using namespace BPrivate::DiskDevice;
// TODO: Add user address checks and check return values of user_memcpy()! // TODO: Add user address checks and check return values of user_memcpy()!
// ddm_strlcpy
/*! \brief Wrapper around user_strlcpy() that returns a status_t /*! \brief Wrapper around user_strlcpy() that returns a status_t
indicating appropriate success or failure. indicating appropriate success or failure.
@@ -61,7 +60,6 @@ ddm_strlcpy(char *to, const char *from, size_t size,
} }
// copy_from_user_value
template<typename Type> template<typename Type>
static inline status_t static inline status_t
copy_from_user_value(Type& value, const Type* userValue) copy_from_user_value(Type& value, const Type* userValue)
@@ -76,7 +74,6 @@ copy_from_user_value(Type& value, const Type* userValue)
} }
// copy_to_user_value
template<typename Type> template<typename Type>
static inline status_t static inline status_t
copy_to_user_value(Type* userValue, const Type& value) copy_to_user_value(Type* userValue, const Type& value)
@@ -91,7 +88,6 @@ copy_to_user_value(Type* userValue, const Type& value)
} }
// UserStringParameter
template<bool kAllowsNull> template<bool kAllowsNull>
struct UserStringParameter { struct UserStringParameter {
char* value; char* value;
@@ -144,7 +140,6 @@ struct UserStringParameter {
}; };
// UserMemoryParameter
template<typename Type, bool kAllowsNull> template<typename Type, bool kAllowsNull>
struct UserMemoryParameter { struct UserMemoryParameter {
Type* value; Type* value;
@@ -190,7 +185,6 @@ struct UserMemoryParameter {
#if 0 #if 0
// move_descendants
static void static void
move_descendants(KPartition *partition, off_t moveBy) move_descendants(KPartition *partition, off_t moveBy)
{ {
@@ -203,7 +197,6 @@ move_descendants(KPartition *partition, off_t moveBy)
} }
// move_descendants_contents
static status_t static status_t
move_descendants_contents(KPartition *partition) move_descendants_contents(KPartition *partition)
{ {
@@ -228,7 +221,6 @@ move_descendants_contents(KPartition *partition)
#endif // 0 #endif // 0
// _user_get_next_disk_device_id
partition_id partition_id
_user_get_next_disk_device_id(int32 *_cookie, size_t *neededSize) _user_get_next_disk_device_id(int32 *_cookie, size_t *neededSize)
{ {
@@ -262,7 +254,6 @@ _user_get_next_disk_device_id(int32 *_cookie, size_t *neededSize)
} }
// _user_find_disk_device
partition_id partition_id
_user_find_disk_device(const char *_filename, size_t *neededSize) _user_find_disk_device(const char *_filename, size_t *neededSize)
{ {
@@ -293,7 +284,6 @@ _user_find_disk_device(const char *_filename, size_t *neededSize)
} }
// _user_find_partition
partition_id partition_id
_user_find_partition(const char *_filename, size_t *neededSize) _user_find_partition(const char *_filename, size_t *neededSize)
{ {
@@ -362,7 +352,6 @@ _user_find_file_disk_device(const char *_filename, size_t *neededSize)
} }
// _user_get_disk_device_data
/*! \brief Writes data describing the disk device identified by ID and all /*! \brief Writes data describing the disk device identified by ID and all
its partitions into the supplied buffer. its partitions into the supplied buffer.
@@ -454,7 +443,6 @@ _user_get_disk_device_data(partition_id id, bool deviceOnly,
} }
// _user_register_file_device
partition_id partition_id
_user_register_file_device(const char *_filename) _user_register_file_device(const char *_filename)
{ {
@@ -475,7 +463,6 @@ _user_register_file_device(const char *_filename)
} }
// _user_unregister_file_device
status_t status_t
_user_unregister_file_device(partition_id deviceID, const char *_filename) _user_unregister_file_device(partition_id deviceID, const char *_filename)
{ {
@@ -520,7 +507,6 @@ _user_get_file_disk_device_path(partition_id id, char* buffer,
} }
// _user_get_disk_system_info
status_t status_t
_user_get_disk_system_info(disk_system_id id, user_disk_system_info *_info) _user_get_disk_system_info(disk_system_id id, user_disk_system_info *_info)
{ {
@@ -539,7 +525,6 @@ _user_get_disk_system_info(disk_system_id id, user_disk_system_info *_info)
} }
// _user_get_next_disk_system_info
status_t status_t
_user_get_next_disk_system_info(int32 *_cookie, user_disk_system_info *_info) _user_get_next_disk_system_info(int32 *_cookie, user_disk_system_info *_info)
{ {
@@ -562,7 +547,6 @@ _user_get_next_disk_system_info(int32 *_cookie, user_disk_system_info *_info)
} }
// _user_find_disk_system
status_t status_t
_user_find_disk_system(const char *_name, user_disk_system_info *_info) _user_find_disk_system(const char *_name, user_disk_system_info *_info)
{ {
@@ -585,7 +569,6 @@ _user_find_disk_system(const char *_name, user_disk_system_info *_info)
} }
// _user_defragment_partition
status_t status_t
_user_defragment_partition(partition_id partitionID, int32* _changeCounter) _user_defragment_partition(partition_id partitionID, int32* _changeCounter)
{ {
@@ -640,7 +623,6 @@ _user_defragment_partition(partition_id partitionID, int32* _changeCounter)
} }
// _user_repair_partition
status_t status_t
_user_repair_partition(partition_id partitionID, int32* _changeCounter, _user_repair_partition(partition_id partitionID, int32* _changeCounter,
bool checkOnly) bool checkOnly)
@@ -696,7 +678,6 @@ _user_repair_partition(partition_id partitionID, int32* _changeCounter,
} }
// _user_resize_partition
status_t status_t
_user_resize_partition(partition_id partitionID, int32* _changeCounter, _user_resize_partition(partition_id partitionID, int32* _changeCounter,
partition_id childID, int32* _childChangeCounter, off_t size, partition_id childID, int32* _childChangeCounter, off_t size,
@@ -792,7 +773,6 @@ _user_resize_partition(partition_id partitionID, int32* _changeCounter,
} }
// _user_move_partition
status_t status_t
_user_move_partition(partition_id partitionID, int32* changeCounter, _user_move_partition(partition_id partitionID, int32* changeCounter,
partition_id childID, int32* childChangeCounter, off_t newOffset, partition_id childID, int32* childChangeCounter, off_t newOffset,
@@ -834,7 +814,6 @@ return B_BAD_VALUE;
} }
// _user_set_partition_name
status_t status_t
_user_set_partition_name(partition_id partitionID, int32* _changeCounter, _user_set_partition_name(partition_id partitionID, int32* _changeCounter,
partition_id childID, int32* _childChangeCounter, const char* _name) partition_id childID, int32* _childChangeCounter, const char* _name)
@@ -915,7 +894,6 @@ _user_set_partition_name(partition_id partitionID, int32* _changeCounter,
} }
// _user_set_partition_content_name
status_t status_t
_user_set_partition_content_name(partition_id partitionID, _user_set_partition_content_name(partition_id partitionID,
int32* _changeCounter, const char* _name) int32* _changeCounter, const char* _name)
@@ -975,7 +953,6 @@ _user_set_partition_content_name(partition_id partitionID,
} }
// _user_set_partition_type
status_t status_t
_user_set_partition_type(partition_id partitionID, int32* _changeCounter, _user_set_partition_type(partition_id partitionID, int32* _changeCounter,
partition_id childID, int32* _childChangeCounter, const char* _type) partition_id childID, int32* _childChangeCounter, const char* _type)
@@ -1056,7 +1033,6 @@ _user_set_partition_type(partition_id partitionID, int32* _changeCounter,
} }
// _user_set_partition_parameters
status_t status_t
_user_set_partition_parameters(partition_id partitionID, int32* _changeCounter, _user_set_partition_parameters(partition_id partitionID, int32* _changeCounter,
partition_id childID, int32* _childChangeCounter, const char* _parameters, partition_id childID, int32* _childChangeCounter, const char* _parameters,
@@ -1139,7 +1115,6 @@ _user_set_partition_parameters(partition_id partitionID, int32* _changeCounter,
} }
// _user_set_partition_content_parameters
status_t status_t
_user_set_partition_content_parameters(partition_id partitionID, _user_set_partition_content_parameters(partition_id partitionID,
int32* _changeCounter, const char* _parameters, size_t parametersSize) int32* _changeCounter, const char* _parameters, size_t parametersSize)
@@ -1201,7 +1176,6 @@ _user_set_partition_content_parameters(partition_id partitionID,
} }
// _user_initialize_partition
status_t status_t
_user_initialize_partition(partition_id partitionID, int32* _changeCounter, _user_initialize_partition(partition_id partitionID, int32* _changeCounter,
const char* _diskSystemName, const char* _name, const char* _parameters, const char* _diskSystemName, const char* _name, const char* _parameters,
@@ -1276,7 +1250,6 @@ _user_initialize_partition(partition_id partitionID, int32* _changeCounter,
} }
// _user_uninitialize_partition
status_t status_t
_user_uninitialize_partition(partition_id partitionID, int32* _changeCounter) _user_uninitialize_partition(partition_id partitionID, int32* _changeCounter)
{ {
@@ -1328,7 +1301,6 @@ _user_uninitialize_partition(partition_id partitionID, int32* _changeCounter)
} }
// _user_create_child_partition
status_t status_t
_user_create_child_partition(partition_id partitionID, int32* _changeCounter, _user_create_child_partition(partition_id partitionID, int32* _changeCounter,
off_t offset, off_t size, const char* _type, const char* _name, off_t offset, off_t size, const char* _type, const char* _name,
@@ -1404,7 +1376,6 @@ _user_create_child_partition(partition_id partitionID, int32* _changeCounter,
} }
// _user_delete_child_partition
status_t status_t
_user_delete_child_partition(partition_id partitionID, int32* _changeCounter, _user_delete_child_partition(partition_id partitionID, int32* _changeCounter,
partition_id childID, int32 childChangeCounter) partition_id childID, int32 childChangeCounter)
@@ -1473,3 +1444,20 @@ _user_delete_child_partition(partition_id partitionID, int32* _changeCounter,
return B_OK; return B_OK;
} }
status_t
_user_start_watching_disks(uint32 eventMask, port_id port, int32 token)
{
KDiskDeviceManager* manager = KDiskDeviceManager::Default();
return manager->Notifications().UpdateUserListener(eventMask, port, token);
}
status_t
_user_stop_watching_disks(port_id port, int32 token)
{
KDiskDeviceManager* manager = KDiskDeviceManager::Default();
return manager->Notifications().RemoveUserListeners(port, token);
}