1// NodeMonitor.cpp 2 3#include <new> 4 5#include <Message.h> 6#include <Node.h> 7#include <NodeMonitor.h> 8 9#include "AutoLocker.h" 10#include "Debug.h" 11#include "NodeMonitor.h" 12#include "NodeMonitoringEvent.h" 13 14// node monitor constants 15static const int32 kDefaultNodeMonitorLimit = 4096; 16static const int32 kNodeMonitorLimitIncrement = 512; 17 18// private BeOS syscall to set the node monitor slot limit 19extern "C" int _kset_mon_limit_(int num); 20 21// constructor 22NodeMonitor::NodeMonitor(NodeMonitorListener* listener) 23 : BLooper("node monitor", B_DISPLAY_PRIORITY, 1000), 24 fListener(listener), 25 fCurrentNodeMonitorLimit(kDefaultNodeMonitorLimit) 26{ 27 // set the initial limit -- just to be sure 28 _kset_mon_limit_(fCurrentNodeMonitorLimit); 29 30 // start volume watching 31 watch_node(NULL, B_WATCH_MOUNT, this); 32} 33 34// destructor 35NodeMonitor::~NodeMonitor() 36{ 37 // stop volume watching 38 stop_watching(this); 39} 40 41// MessageReceived 42void 43NodeMonitor::MessageReceived(BMessage* message) 44{ 45 switch (message->what) { 46 case B_NODE_MONITOR: 47 { 48 NodeMonitoringEvent* event = NULL; 49 int32 opcode; 50 if (message->FindInt32("opcode", &opcode) == B_OK) { 51 switch (opcode) { 52 case B_ENTRY_CREATED: 53 event = new(nothrow) EntryCreatedEvent; 54 break; 55 case B_ENTRY_REMOVED: 56 event = new(nothrow) EntryRemovedEvent; 57 break; 58 case B_ENTRY_MOVED: 59 event = new(nothrow) EntryMovedEvent; 60 break; 61 case B_STAT_CHANGED: 62 event = new(nothrow) StatChangedEvent; 63 break; 64 case B_ATTR_CHANGED: 65 event = new(nothrow) AttributeChangedEvent; 66 break; 67 case B_DEVICE_MOUNTED: 68 event = new(nothrow) VolumeMountedEvent; 69 break; 70 case B_DEVICE_UNMOUNTED: 71 event = new(nothrow) VolumeUnmountedEvent; 72 break; 73 } 74 } 75 if (event) { 76 if (event->Init(message) == B_OK) 77 fListener->ProcessNodeMonitoringEvent(event); 78 else 79 delete event; 80 } 81 break; 82 } 83 default: 84 BLooper::MessageReceived(message); 85 } 86} 87 88// StartWatching 89status_t 90NodeMonitor::StartWatching(const node_ref& ref) 91{ 92 uint32 flags = B_WATCH_ALL; 93 status_t error = watch_node(&ref, flags, this); 94 // If starting to watch the node fail, we allocate more node 95 // monitoring slots and try again. 96 if (error != B_OK) { 97 error = _IncreaseLimit(); 98 if (error == B_OK) 99 error = watch_node(&ref, flags, this); 100 } 101if (error == B_OK) { 102PRINT(("NodeMonitor: started watching node: (%ld, %lld)\n", ref.device, 103ref.node)); 104} 105 return error; 106} 107 108// StopWatching 109status_t 110NodeMonitor::StopWatching(const node_ref& ref) 111{ 112PRINT(("NodeMonitor: stopped watching node: (%ld, %lld)\n", ref.device, 113ref.node)); 114 return watch_node(&ref, B_STOP_WATCHING, this); 115} 116 117// _IncreaseLimit 118status_t 119NodeMonitor::_IncreaseLimit() 120{ 121 AutoLocker<BLooper> _(this); 122 123 int32 newLimit = fCurrentNodeMonitorLimit + kNodeMonitorLimitIncrement; 124 status_t error = _kset_mon_limit_(newLimit); 125 if (error == B_OK) 126 fCurrentNodeMonitorLimit = newLimit; 127 return error; 128} 129 130 131// #pragma mark - 132 133// constructor 134NodeMonitorListener::NodeMonitorListener() 135{ 136} 137 138// destructor 139NodeMonitorListener::~NodeMonitorListener() 140{ 141} 142