* RVolumeList:
- Added locking, listener support.
- Changed message handling from BHandler to MessageHandler interface.
- Fixed bugs.
* RDiskDeviceList:
- Locking uses an external lock now (the same one as the volume list)
- Prepared for message handling (MessageHandler).
* DiskDeviceManager:
- Added priority message queue and message handler thread -- should be
more or less complete now.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2644 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3,28 +3,49 @@
|
|||||||
// by the OpenBeOS license.
|
// by the OpenBeOS license.
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <NodeMonitor.h>
|
||||||
#include <RegistrarDefs.h>
|
#include <RegistrarDefs.h>
|
||||||
|
|
||||||
#include "DiskDeviceManager.h"
|
#include "DiskDeviceManager.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
REQUEST_PRIORITY = 0,
|
||||||
|
NODE_MONITOR_PRIORITY = 10,
|
||||||
|
};
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
DiskDeviceManager::DiskDeviceManager()
|
DiskDeviceManager::DiskDeviceManager()
|
||||||
: BLooper("disk device manager"),
|
: BLooper("disk device manager"),
|
||||||
fDeviceList(),
|
fDeviceListLock(),
|
||||||
fVolumeList()
|
fVolumeList(BMessenger(this), fDeviceListLock),
|
||||||
|
fDeviceList(BMessenger(this), fDeviceListLock, fVolumeList),
|
||||||
|
fMessageQueue(),
|
||||||
|
fWorker(-1),
|
||||||
|
fMessageCounter(-1),
|
||||||
|
fTerminating(false)
|
||||||
{
|
{
|
||||||
AddHandler(&fVolumeList);
|
// set up the device list
|
||||||
|
fVolumeList.Rescan();
|
||||||
fVolumeList.Dump();
|
fVolumeList.Dump();
|
||||||
fDeviceList.Rescan();
|
fDeviceList.Rescan();
|
||||||
fDeviceList.Dump();
|
fDeviceList.Dump();
|
||||||
|
// start the worker thread
|
||||||
|
fMessageCounter = create_sem(0, "disk device manager msgcounter");
|
||||||
|
if (fMessageCounter >= 0) {
|
||||||
|
fWorker = spawn_thread(_WorkerEntry, "disk device manager worker",
|
||||||
|
B_NORMAL_PRIORITY, this);
|
||||||
|
if (fWorker >= 0)
|
||||||
|
resume_thread(fWorker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
DiskDeviceManager::~DiskDeviceManager()
|
DiskDeviceManager::~DiskDeviceManager()
|
||||||
{
|
{
|
||||||
Lock();
|
fTerminating = true;
|
||||||
RemoveHandler(&fVolumeList);
|
delete_sem(fMessageCounter);
|
||||||
Unlock();
|
int32 dummy;
|
||||||
|
wait_for_thread(fWorker, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageReceived
|
// MessageReceived
|
||||||
@@ -37,6 +58,14 @@ DiskDeviceManager::MessageReceived(BMessage *message)
|
|||||||
case B_REG_UPDATE_DISK_DEVICE:
|
case B_REG_UPDATE_DISK_DEVICE:
|
||||||
case B_REG_DEVICE_START_WATCHING:
|
case B_REG_DEVICE_START_WATCHING:
|
||||||
case B_REG_DEVICE_STOP_WATCHING:
|
case B_REG_DEVICE_STOP_WATCHING:
|
||||||
|
DetachCurrentMessage();
|
||||||
|
if (!_PushMessage(message, REQUEST_PRIORITY))
|
||||||
|
delete message;
|
||||||
|
break;
|
||||||
|
case B_NODE_MONITOR:
|
||||||
|
DetachCurrentMessage();
|
||||||
|
if (!_PushMessage(message, NODE_MONITOR_PRIORITY))
|
||||||
|
delete message;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BLooper::MessageReceived(message);
|
BLooper::MessageReceived(message);
|
||||||
@@ -44,3 +73,69 @@ DiskDeviceManager::MessageReceived(BMessage *message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _PushMessage
|
||||||
|
bool
|
||||||
|
DiskDeviceManager::_PushMessage(BMessage *message, int32 priority)
|
||||||
|
{
|
||||||
|
bool result = fMessageQueue.PushMessage(message, priority);
|
||||||
|
if (result)
|
||||||
|
release_sem(fMessageCounter);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _PopMessage
|
||||||
|
BMessage *
|
||||||
|
DiskDeviceManager::_PopMessage()
|
||||||
|
{
|
||||||
|
BMessage *result = NULL;
|
||||||
|
status_t error = acquire_sem(fMessageCounter);
|
||||||
|
if (error == B_OK)
|
||||||
|
result = fMessageQueue.PopMessage();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _WorkerEntry
|
||||||
|
int32
|
||||||
|
DiskDeviceManager::_WorkerEntry(void *parameters)
|
||||||
|
{
|
||||||
|
return static_cast<DiskDeviceManager*>(parameters)->_Worker();
|
||||||
|
}
|
||||||
|
|
||||||
|
// _Worker
|
||||||
|
int32
|
||||||
|
DiskDeviceManager::_Worker()
|
||||||
|
{
|
||||||
|
while (!fTerminating) {
|
||||||
|
if (BMessage *message = _PopMessage()) {
|
||||||
|
// dispatch the message
|
||||||
|
switch (message->what) {
|
||||||
|
case B_REG_NEXT_DISK_DEVICE:
|
||||||
|
case B_REG_GET_DISK_DEVICE:
|
||||||
|
case B_REG_UPDATE_DISK_DEVICE:
|
||||||
|
case B_REG_DEVICE_START_WATCHING:
|
||||||
|
case B_REG_DEVICE_STOP_WATCHING:
|
||||||
|
fDeviceList.HandleMessage(message);
|
||||||
|
break;
|
||||||
|
case B_NODE_MONITOR:
|
||||||
|
{
|
||||||
|
int32 opcode = 0;
|
||||||
|
if (message->FindInt32("opcode", &opcode) == B_OK) {
|
||||||
|
if (opcode == B_DEVICE_MOUNTED
|
||||||
|
|| opcode == B_DEVICE_UNMOUNTED) {
|
||||||
|
fVolumeList.HandleMessage(message);
|
||||||
|
} else {
|
||||||
|
fDeviceList.HandleMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// error
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,11 @@
|
|||||||
#ifndef DISK_DEVICE_MANAGER_H
|
#ifndef DISK_DEVICE_MANAGER_H
|
||||||
#define DISK_DEVICE_MANAGER_H
|
#define DISK_DEVICE_MANAGER_H
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
#include <Looper.h>
|
#include <Looper.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
#include "PriorityMessageQueue.h"
|
||||||
#include "RDiskDeviceList.h"
|
#include "RDiskDeviceList.h"
|
||||||
#include "RVolumeList.h"
|
#include "RVolumeList.h"
|
||||||
|
|
||||||
@@ -19,8 +22,20 @@ public:
|
|||||||
virtual void MessageReceived(BMessage *message);
|
virtual void MessageReceived(BMessage *message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RDiskDeviceList fDeviceList;
|
bool _PushMessage(BMessage *message, int32 priority);
|
||||||
RVolumeList fVolumeList;
|
BMessage *_PopMessage();
|
||||||
|
|
||||||
|
static int32 _WorkerEntry(void *parameters);
|
||||||
|
int32 _Worker();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BLocker fDeviceListLock;
|
||||||
|
RVolumeList fVolumeList;
|
||||||
|
RDiskDeviceList fDeviceList;
|
||||||
|
PriorityMessageQueue fMessageQueue;
|
||||||
|
thread_id fWorker;
|
||||||
|
sem_id fMessageCounter;
|
||||||
|
bool fTerminating;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DISK_DEVICE_MANAGER_H
|
#endif // DISK_DEVICE_MANAGER_H
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
//#include <ObjectLocker.h>
|
#include <Locker.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
|
||||||
#include "RDiskDeviceList.h"
|
#include "RDiskDeviceList.h"
|
||||||
@@ -72,12 +72,18 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
RDiskDeviceList::RDiskDeviceList()
|
RDiskDeviceList::RDiskDeviceList(BMessenger target, BLocker &lock,
|
||||||
: fLock(),
|
RVolumeList &volumeList)
|
||||||
|
: MessageHandler(),
|
||||||
|
RVolumeListListener(),
|
||||||
|
fLock(lock),
|
||||||
|
fTarget(target),
|
||||||
|
fVolumeList(volumeList),
|
||||||
fDevices(20, true),
|
fDevices(20, true),
|
||||||
fSessions(40, false),
|
fSessions(40, false),
|
||||||
fPartitions(80, false)
|
fPartitions(80, false)
|
||||||
{
|
{
|
||||||
|
fVolumeList.SetListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
@@ -85,6 +91,34 @@ RDiskDeviceList::~RDiskDeviceList()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleMessage
|
||||||
|
void
|
||||||
|
RDiskDeviceList::HandleMessage(BMessage *message)
|
||||||
|
{
|
||||||
|
if (Lock()) {
|
||||||
|
switch (message->what) {
|
||||||
|
default:
|
||||||
|
MessageHandler::HandleMessage(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// VolumeMounted
|
||||||
|
void
|
||||||
|
RDiskDeviceList::VolumeMounted(const RVolume *volume)
|
||||||
|
{
|
||||||
|
PRINT(("RDiskDeviceList::VolumeMounted(%ld)\n", volume->ID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// VolumeUnmounted
|
||||||
|
void
|
||||||
|
RDiskDeviceList::VolumeUnmounted(const RVolume *volume)
|
||||||
|
{
|
||||||
|
PRINT(("RDiskDeviceList::VolumeUnmounted(%ld)\n", volume->ID()));
|
||||||
|
}
|
||||||
|
|
||||||
// AddDevice
|
// AddDevice
|
||||||
bool
|
bool
|
||||||
RDiskDeviceList::AddDevice(RDiskDevice *device)
|
RDiskDeviceList::AddDevice(RDiskDevice *device)
|
||||||
|
|||||||
@@ -6,21 +6,30 @@
|
|||||||
#ifndef DISK_DEVICE_LIST_H
|
#ifndef DISK_DEVICE_LIST_H
|
||||||
#define DISK_DEVICE_LIST_H
|
#define DISK_DEVICE_LIST_H
|
||||||
|
|
||||||
#include <Locker.h>
|
#include <Messenger.h>
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
#include "MessageHandler.h"
|
||||||
|
#include "RVolumeList.h"
|
||||||
|
|
||||||
class BDirectory;
|
class BDirectory;
|
||||||
class BEntry;
|
class BEntry;
|
||||||
|
class BLocker;
|
||||||
|
|
||||||
class RDiskDevice;
|
class RDiskDevice;
|
||||||
class RPartition;
|
class RPartition;
|
||||||
class RSession;
|
class RSession;
|
||||||
|
|
||||||
class RDiskDeviceList {
|
class RDiskDeviceList : public MessageHandler, public RVolumeListListener {
|
||||||
public:
|
public:
|
||||||
RDiskDeviceList();
|
RDiskDeviceList(BMessenger target, BLocker &lock, RVolumeList &volumeList);
|
||||||
~RDiskDeviceList();
|
~RDiskDeviceList();
|
||||||
|
|
||||||
|
virtual void HandleMessage(BMessage *message);
|
||||||
|
|
||||||
|
void RDiskDeviceList::VolumeMounted(const RVolume *volume);
|
||||||
|
void RDiskDeviceList::VolumeUnmounted(const RVolume *volume);
|
||||||
|
|
||||||
bool AddDevice(RDiskDevice *device);
|
bool AddDevice(RDiskDevice *device);
|
||||||
bool RemoveDevice(int32 index);
|
bool RemoveDevice(int32 index);
|
||||||
bool RemoveDevice(RDiskDevice *device);
|
bool RemoveDevice(RDiskDevice *device);
|
||||||
@@ -59,7 +68,9 @@ private:
|
|||||||
status_t _ScanDevice(const char *path);
|
status_t _ScanDevice(const char *path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BLocker fLock;
|
mutable BLocker &fLock;
|
||||||
|
BMessenger fTarget;
|
||||||
|
RVolumeList &fVolumeList;
|
||||||
BObjectList<RDiskDevice> fDevices; // sorted by ID
|
BObjectList<RDiskDevice> fDevices; // sorted by ID
|
||||||
BObjectList<RSession> fSessions; //
|
BObjectList<RSession> fSessions; //
|
||||||
BObjectList<RPartition> fPartitions; //
|
BObjectList<RPartition> fPartitions; //
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <NodeMonitor.h>
|
#include <NodeMonitor.h>
|
||||||
#include <Volume.h>
|
#include <Volume.h>
|
||||||
@@ -79,66 +80,84 @@ RVolume::Unset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// RVolumeListListener
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
RVolumeListListener::RVolumeListListener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
RVolumeListListener::~RVolumeListListener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// VolumeMounted
|
||||||
|
void
|
||||||
|
RVolumeListListener::VolumeMounted(const RVolume *volume)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// VolumeUnmounted
|
||||||
|
void
|
||||||
|
RVolumeListListener::VolumeUnmounted(const RVolume *volume)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// RVolumeList
|
// RVolumeList
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
RVolumeList::RVolumeList()
|
RVolumeList::RVolumeList(BMessenger target, BLocker &lock)
|
||||||
: BHandler(),
|
: MessageHandler(),
|
||||||
|
fLock(lock),
|
||||||
|
fTarget(target),
|
||||||
fVolumes(20, true),
|
fVolumes(20, true),
|
||||||
fRoster()
|
fRoster(),
|
||||||
|
fListener(NULL)
|
||||||
{
|
{
|
||||||
|
// TODO: Remove work-around. At this time R5 libbe's watching functions don't
|
||||||
|
// work for us. We have an own implementation in `NodeMonitoring.cpp'.
|
||||||
|
// fRoster.StartWatching(BMessenger(this));
|
||||||
|
watch_node(NULL, B_WATCH_MOUNT, fTarget);
|
||||||
|
Rescan();
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
RVolumeList::~RVolumeList()
|
RVolumeList::~RVolumeList()
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
// MessageReceived
|
|
||||||
void
|
|
||||||
RVolumeList::MessageReceived(BMessage *message)
|
|
||||||
{
|
|
||||||
switch (message->what) {
|
|
||||||
case B_NODE_MONITOR:
|
|
||||||
{
|
|
||||||
int32 opcode = 0;
|
|
||||||
if (message->FindInt32("opcode", &opcode) == B_OK) {
|
|
||||||
switch (opcode) {
|
|
||||||
case B_DEVICE_MOUNTED:
|
|
||||||
_DeviceMounted(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_UNMOUNTED:
|
|
||||||
_DeviceUnmounted(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
BHandler::MessageReceived(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNextHandler
|
|
||||||
void
|
|
||||||
RVolumeList::SetNextHandler(BHandler *handler)
|
|
||||||
{
|
|
||||||
// stop watching volumes, if removed from looper
|
|
||||||
if (!handler) {
|
|
||||||
// TODO: Remove work-around. At this time R5 libbe's watching functions don't
|
// TODO: Remove work-around. At this time R5 libbe's watching functions don't
|
||||||
// work for us. We have an own implementation in `NodeMonitoring.cpp'.
|
// work for us. We have an own implementation in `NodeMonitoring.cpp'.
|
||||||
// fRoster.StopWatching();
|
// fRoster.StopWatching();
|
||||||
stop_watching(BMessenger(this));
|
stop_watching(fTarget);
|
||||||
}
|
}
|
||||||
BHandler::SetNextHandler(handler);
|
|
||||||
// start watching volumes and rescan list, if added to looper
|
// HandleMessage
|
||||||
if (handler) {
|
void
|
||||||
// TODO: Remove work-around. At this time R5 libbe's watching functions don't
|
RVolumeList::HandleMessage(BMessage *message)
|
||||||
// work for us. We have an own implementation in `NodeMonitoring.cpp'.
|
{
|
||||||
// fRoster.StartWatching(BMessenger(this));
|
if (Lock()) {
|
||||||
watch_node(NULL, B_WATCH_MOUNT, BMessenger(this));
|
switch (message->what) {
|
||||||
Rescan();
|
case B_NODE_MONITOR:
|
||||||
|
{
|
||||||
|
int32 opcode = 0;
|
||||||
|
if (message->FindInt32("opcode", &opcode) == B_OK) {
|
||||||
|
switch (opcode) {
|
||||||
|
case B_DEVICE_MOUNTED:
|
||||||
|
_DeviceMounted(message);
|
||||||
|
break;
|
||||||
|
case B_DEVICE_UNMOUNTED:
|
||||||
|
_DeviceUnmounted(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
MessageHandler::HandleMessage(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,23 +177,37 @@ RVolumeList::Rescan()
|
|||||||
const RVolume *
|
const RVolume *
|
||||||
RVolumeList::VolumeForDevicePath(const char *devicePath) const
|
RVolumeList::VolumeForDevicePath(const char *devicePath) const
|
||||||
{
|
{
|
||||||
// TODO: ...
|
const RVolume *volume = NULL;
|
||||||
return NULL;
|
if (devicePath && fLock.Lock()) {
|
||||||
|
bool found = false;
|
||||||
|
int32 index = fVolumes.FindBinaryInsertionIndex(
|
||||||
|
CompareDevicePathPredicate(devicePath), &found);
|
||||||
|
if (found)
|
||||||
|
volume = fVolumes.ItemAt(index);
|
||||||
|
fLock.Unlock();
|
||||||
|
}
|
||||||
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
bool
|
bool
|
||||||
RVolumeList::Lock()
|
RVolumeList::Lock()
|
||||||
{
|
{
|
||||||
// TODO: ...
|
return fLock.Lock();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock
|
// Unlock
|
||||||
void
|
void
|
||||||
RVolumeList::Unlock()
|
RVolumeList::Unlock()
|
||||||
{
|
{
|
||||||
// TODO: ...
|
fLock.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetListener
|
||||||
|
void
|
||||||
|
RVolumeList::SetListener(RVolumeListListener *listener)
|
||||||
|
{
|
||||||
|
fListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump
|
// Dump
|
||||||
@@ -189,21 +222,24 @@ RVolumeList::Dump() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// _AddVolume
|
// _AddVolume
|
||||||
void
|
RVolume *
|
||||||
RVolumeList::_AddVolume(dev_t id)
|
RVolumeList::_AddVolume(dev_t id)
|
||||||
{
|
{
|
||||||
if (RVolume *volume = new RVolume) {
|
RVolume *volume = new RVolume;
|
||||||
|
if (volume) {
|
||||||
status_t error = volume->SetTo(id);
|
status_t error = volume->SetTo(id);
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
fVolumes.BinaryInsert(volume,
|
fVolumes.BinaryInsert(volume,
|
||||||
CompareDevicePathPredicate(volume->DevicePath()));
|
CompareDevicePathPredicate(volume->DevicePath()));
|
||||||
} else {
|
} else {
|
||||||
delete volume;
|
delete volume;
|
||||||
|
volume = NULL;
|
||||||
PRINT(("RVolumeList::_AddVolume(): initializing RVolume failed: "
|
PRINT(("RVolumeList::_AddVolume(): initializing RVolume failed: "
|
||||||
"%s\n", strerror(error)));
|
"%s\n", strerror(error)));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
PRINT(("RVolumeList::_AddVolume(): no memory!\n"));
|
PRINT(("RVolumeList::_AddVolume(): no memory!\n"));
|
||||||
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _DeviceMounted
|
// _DeviceMounted
|
||||||
@@ -213,7 +249,10 @@ RVolumeList::_DeviceMounted(BMessage *message)
|
|||||||
dev_t device;
|
dev_t device;
|
||||||
if (message->FindInt32("new device", &device) == B_OK) {
|
if (message->FindInt32("new device", &device) == B_OK) {
|
||||||
PRINT(("RVolumeList::_DeviceMounted(%ld)\n", device));
|
PRINT(("RVolumeList::_DeviceMounted(%ld)\n", device));
|
||||||
_AddVolume(device);
|
if (RVolume *volume = _AddVolume(device)) {
|
||||||
|
if (fListener)
|
||||||
|
fListener->VolumeMounted(volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,8 +263,12 @@ RVolumeList::_DeviceUnmounted(BMessage *message)
|
|||||||
dev_t device;
|
dev_t device;
|
||||||
if (message->FindInt32("device", &device) == B_OK) {
|
if (message->FindInt32("device", &device) == B_OK) {
|
||||||
PRINT(("RVolumeList::_DeviceUnmounted(%ld)\n", device));
|
PRINT(("RVolumeList::_DeviceUnmounted(%ld)\n", device));
|
||||||
if (RVolume *volume = fVolumes.FindIf(CompareIDPredicate(volume)))
|
if (RVolume *volume = fVolumes.FindIf(CompareIDPredicate(device))) {
|
||||||
fVolumes.RemoveItem(volume);
|
fVolumes.RemoveItem(volume, false);
|
||||||
|
if (fListener)
|
||||||
|
fListener->VolumeUnmounted(volume);
|
||||||
|
delete volume;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,15 @@
|
|||||||
#ifndef VOLUME_LIST_H
|
#ifndef VOLUME_LIST_H
|
||||||
#define VOLUME_LIST_H
|
#define VOLUME_LIST_H
|
||||||
|
|
||||||
#include <Handler.h>
|
#include <Messenger.h>
|
||||||
#include <Node.h>
|
#include <Node.h>
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <VolumeRoster.h>
|
#include <VolumeRoster.h>
|
||||||
|
|
||||||
|
#include "MessageHandler.h"
|
||||||
|
|
||||||
|
class BLocker;
|
||||||
|
|
||||||
// RVolume
|
// RVolume
|
||||||
class RVolume {
|
class RVolume {
|
||||||
public:
|
public:
|
||||||
@@ -32,14 +36,23 @@ private:
|
|||||||
char fDevicePath[B_FILE_NAME_LENGTH];
|
char fDevicePath[B_FILE_NAME_LENGTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
// RVolumeList
|
// RVolumeListListener
|
||||||
class RVolumeList : public BHandler {
|
class RVolumeListListener {
|
||||||
public:
|
public:
|
||||||
RVolumeList();
|
RVolumeListListener();
|
||||||
|
virtual ~RVolumeListListener();
|
||||||
|
|
||||||
|
virtual void VolumeMounted(const RVolume *volume);
|
||||||
|
virtual void VolumeUnmounted(const RVolume *volume);
|
||||||
|
};
|
||||||
|
|
||||||
|
// RVolumeList
|
||||||
|
class RVolumeList : public MessageHandler {
|
||||||
|
public:
|
||||||
|
RVolumeList(BMessenger target, BLocker &lock);
|
||||||
virtual ~RVolumeList();
|
virtual ~RVolumeList();
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage *message);
|
virtual void HandleMessage(BMessage *message);
|
||||||
virtual void SetNextHandler(BHandler *handler);
|
|
||||||
|
|
||||||
status_t Rescan();
|
status_t Rescan();
|
||||||
|
|
||||||
@@ -48,16 +61,21 @@ public:
|
|||||||
bool Lock();
|
bool Lock();
|
||||||
void Unlock();
|
void Unlock();
|
||||||
|
|
||||||
|
void SetListener(RVolumeListListener *listener);
|
||||||
|
|
||||||
void Dump() const;
|
void Dump() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _AddVolume(dev_t id);
|
RVolume *_AddVolume(dev_t id);
|
||||||
void _DeviceMounted(BMessage *message);
|
void _DeviceMounted(BMessage *message);
|
||||||
void _DeviceUnmounted(BMessage *message);
|
void _DeviceUnmounted(BMessage *message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
mutable BLocker &fLock;
|
||||||
|
BMessenger fTarget;
|
||||||
BObjectList<RVolume> fVolumes;
|
BObjectList<RVolume> fVolumes;
|
||||||
BVolumeRoster fRoster;
|
BVolumeRoster fRoster;
|
||||||
|
RVolumeListListener *fListener;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VOLUME_LIST_H
|
#endif // VOLUME_LIST_H
|
||||||
|
|||||||
Reference in New Issue
Block a user