// NodeMonitor.cpp #include #include #include #include #include #include #include #include "DebugSupport.h" #include "NodeMonitor.h" #include "NodeMonitoringEvent.h" // node monitor constants static const int32 kDefaultNodeMonitorLimit = 4096; static const int32 kNodeMonitorLimitIncrement = 512; // constructor NodeMonitor::NodeMonitor(NodeMonitorListener* listener) : BLooper("node monitor", B_DISPLAY_PRIORITY, 1000), fListener(listener), fCurrentNodeMonitorLimit(kDefaultNodeMonitorLimit) { // set the initial limit -- just to be sure struct rlimit rl; rl.rlim_cur = fCurrentNodeMonitorLimit; rl.rlim_max = RLIM_SAVED_MAX; setrlimit(RLIMIT_NOVMON, &rl); // start volume watching watch_node(NULL, B_WATCH_MOUNT, this); } // destructor NodeMonitor::~NodeMonitor() { // stop volume watching stop_watching(this); } // MessageReceived void NodeMonitor::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: { NodeMonitoringEvent* event = NULL; int32 opcode; if (message->FindInt32("opcode", &opcode) == B_OK) { switch (opcode) { case B_ENTRY_CREATED: event = new(std::nothrow) EntryCreatedEvent; break; case B_ENTRY_REMOVED: event = new(std::nothrow) EntryRemovedEvent; break; case B_ENTRY_MOVED: event = new(std::nothrow) EntryMovedEvent; break; case B_STAT_CHANGED: event = new(std::nothrow) StatChangedEvent; break; case B_ATTR_CHANGED: event = new(std::nothrow) AttributeChangedEvent; break; case B_DEVICE_MOUNTED: event = new(std::nothrow) VolumeMountedEvent; break; case B_DEVICE_UNMOUNTED: event = new(std::nothrow) VolumeUnmountedEvent; break; } } if (event) { if (event->Init(message) == B_OK) fListener->ProcessNodeMonitoringEvent(event); else delete event; } break; } default: BLooper::MessageReceived(message); } } // StartWatching status_t NodeMonitor::StartWatching(const node_ref& ref) { uint32 flags = B_WATCH_ALL; status_t error = watch_node(&ref, flags, this); // If starting to watch the node fail, we allocate more node // monitoring slots and try again. if (error != B_OK) { error = _IncreaseLimit(); if (error == B_OK) error = watch_node(&ref, flags, this); } if (error == B_OK) { PRINT("NodeMonitor: started watching node: " "(%" B_PRIdDEV ", %" B_PRIdINO ")\n", ref.device, ref.node); } return error; } // StopWatching status_t NodeMonitor::StopWatching(const node_ref& ref) { PRINT("NodeMonitor: stopped watching node: " "(%" B_PRIdDEV ", %" B_PRIdINO ")\n", ref.device, ref.node); return watch_node(&ref, B_STOP_WATCHING, this); } // _IncreaseLimit status_t NodeMonitor::_IncreaseLimit() { AutoLocker _(this); int32 newLimit = fCurrentNodeMonitorLimit + kNodeMonitorLimitIncrement; struct rlimit rl; rl.rlim_cur = newLimit; rl.rlim_max = RLIM_SAVED_MAX; if (setrlimit(RLIMIT_NOVMON, &rl) < 0) return errno; fCurrentNodeMonitorLimit = newLimit; return B_OK; } // #pragma mark - // constructor NodeMonitorListener::NodeMonitorListener() { } // destructor NodeMonitorListener::~NodeMonitorListener() { }