xref: /haiku/src/servers/launch/VolumeWatcher.cpp (revision 0f3fcbe43710609a57479d1fbfde349542953ac8)
1*0f3fcbe4SAxel Dörfler /*
2*0f3fcbe4SAxel Dörfler  * Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
3*0f3fcbe4SAxel Dörfler  * Distributed under the terms of the MIT License.
4*0f3fcbe4SAxel Dörfler  */
5*0f3fcbe4SAxel Dörfler 
6*0f3fcbe4SAxel Dörfler 
7*0f3fcbe4SAxel Dörfler //!	The backbone of the VolumeMountedEvent.
8*0f3fcbe4SAxel Dörfler 
9*0f3fcbe4SAxel Dörfler 
10*0f3fcbe4SAxel Dörfler #include "VolumeWatcher.h"
11*0f3fcbe4SAxel Dörfler 
12*0f3fcbe4SAxel Dörfler #include <Application.h>
13*0f3fcbe4SAxel Dörfler #include <Autolock.h>
14*0f3fcbe4SAxel Dörfler #include <NodeMonitor.h>
15*0f3fcbe4SAxel Dörfler 
16*0f3fcbe4SAxel Dörfler 
17*0f3fcbe4SAxel Dörfler static BLocker sLocker("volume watcher");
18*0f3fcbe4SAxel Dörfler static VolumeWatcher* sWatcher;
19*0f3fcbe4SAxel Dörfler 
20*0f3fcbe4SAxel Dörfler 
~VolumeListener()21*0f3fcbe4SAxel Dörfler VolumeListener::~VolumeListener()
22*0f3fcbe4SAxel Dörfler {
23*0f3fcbe4SAxel Dörfler }
24*0f3fcbe4SAxel Dörfler 
25*0f3fcbe4SAxel Dörfler 
26*0f3fcbe4SAxel Dörfler // #pragma mark -
27*0f3fcbe4SAxel Dörfler 
28*0f3fcbe4SAxel Dörfler 
VolumeWatcher()29*0f3fcbe4SAxel Dörfler VolumeWatcher::VolumeWatcher()
30*0f3fcbe4SAxel Dörfler 	:
31*0f3fcbe4SAxel Dörfler 	BHandler("volume watcher")
32*0f3fcbe4SAxel Dörfler {
33*0f3fcbe4SAxel Dörfler 	if (be_app->Lock()) {
34*0f3fcbe4SAxel Dörfler 		be_app->AddHandler(this);
35*0f3fcbe4SAxel Dörfler 
36*0f3fcbe4SAxel Dörfler 		watch_node(NULL, B_WATCH_MOUNT, this);
37*0f3fcbe4SAxel Dörfler 		be_app->Unlock();
38*0f3fcbe4SAxel Dörfler 	}
39*0f3fcbe4SAxel Dörfler }
40*0f3fcbe4SAxel Dörfler 
41*0f3fcbe4SAxel Dörfler 
~VolumeWatcher()42*0f3fcbe4SAxel Dörfler VolumeWatcher::~VolumeWatcher()
43*0f3fcbe4SAxel Dörfler {
44*0f3fcbe4SAxel Dörfler 	if (be_app->Lock()) {
45*0f3fcbe4SAxel Dörfler 		stop_watching(this);
46*0f3fcbe4SAxel Dörfler 
47*0f3fcbe4SAxel Dörfler 		be_app->RemoveHandler(this);
48*0f3fcbe4SAxel Dörfler 		be_app->Unlock();
49*0f3fcbe4SAxel Dörfler 	}
50*0f3fcbe4SAxel Dörfler }
51*0f3fcbe4SAxel Dörfler 
52*0f3fcbe4SAxel Dörfler 
53*0f3fcbe4SAxel Dörfler void
AddListener(VolumeListener * listener)54*0f3fcbe4SAxel Dörfler VolumeWatcher::AddListener(VolumeListener* listener)
55*0f3fcbe4SAxel Dörfler {
56*0f3fcbe4SAxel Dörfler 	BAutolock lock(sLocker);
57*0f3fcbe4SAxel Dörfler 	fListeners.AddItem(listener);
58*0f3fcbe4SAxel Dörfler }
59*0f3fcbe4SAxel Dörfler 
60*0f3fcbe4SAxel Dörfler 
61*0f3fcbe4SAxel Dörfler void
RemoveListener(VolumeListener * listener)62*0f3fcbe4SAxel Dörfler VolumeWatcher::RemoveListener(VolumeListener* listener)
63*0f3fcbe4SAxel Dörfler {
64*0f3fcbe4SAxel Dörfler 	BAutolock lock(sLocker);
65*0f3fcbe4SAxel Dörfler 	fListeners.RemoveItem(listener);
66*0f3fcbe4SAxel Dörfler }
67*0f3fcbe4SAxel Dörfler 
68*0f3fcbe4SAxel Dörfler 
69*0f3fcbe4SAxel Dörfler int32
CountListeners() const70*0f3fcbe4SAxel Dörfler VolumeWatcher::CountListeners() const
71*0f3fcbe4SAxel Dörfler {
72*0f3fcbe4SAxel Dörfler 	BAutolock lock(sLocker);
73*0f3fcbe4SAxel Dörfler 	return fListeners.CountItems();
74*0f3fcbe4SAxel Dörfler }
75*0f3fcbe4SAxel Dörfler 
76*0f3fcbe4SAxel Dörfler 
77*0f3fcbe4SAxel Dörfler void
MessageReceived(BMessage * message)78*0f3fcbe4SAxel Dörfler VolumeWatcher::MessageReceived(BMessage* message)
79*0f3fcbe4SAxel Dörfler {
80*0f3fcbe4SAxel Dörfler 	switch (message->what) {
81*0f3fcbe4SAxel Dörfler 		case B_NODE_MONITOR:
82*0f3fcbe4SAxel Dörfler 		{
83*0f3fcbe4SAxel Dörfler 			int32 opcode = message->GetInt32("opcode", -1);
84*0f3fcbe4SAxel Dörfler 			if (opcode == B_DEVICE_MOUNTED) {
85*0f3fcbe4SAxel Dörfler 				dev_t device;
86*0f3fcbe4SAxel Dörfler 				if (message->FindInt32("new device", &device) == B_OK) {
87*0f3fcbe4SAxel Dörfler 					BAutolock lock(sLocker);
88*0f3fcbe4SAxel Dörfler 					for (int32 i = 0; i < fListeners.CountItems(); i++) {
89*0f3fcbe4SAxel Dörfler 						fListeners.ItemAt(i)->VolumeMounted(device);
90*0f3fcbe4SAxel Dörfler 					}
91*0f3fcbe4SAxel Dörfler 				}
92*0f3fcbe4SAxel Dörfler 			} else if (opcode == B_DEVICE_UNMOUNTED) {
93*0f3fcbe4SAxel Dörfler 				dev_t device;
94*0f3fcbe4SAxel Dörfler 				if (message->FindInt32("device", &device) == B_OK) {
95*0f3fcbe4SAxel Dörfler 					BAutolock lock(sLocker);
96*0f3fcbe4SAxel Dörfler 					for (int32 i = 0; i < fListeners.CountItems(); i++) {
97*0f3fcbe4SAxel Dörfler 						fListeners.ItemAt(i)->VolumeUnmounted(device);
98*0f3fcbe4SAxel Dörfler 					}
99*0f3fcbe4SAxel Dörfler 				}
100*0f3fcbe4SAxel Dörfler 			}
101*0f3fcbe4SAxel Dörfler 			break;
102*0f3fcbe4SAxel Dörfler 		}
103*0f3fcbe4SAxel Dörfler 	}
104*0f3fcbe4SAxel Dörfler }
105*0f3fcbe4SAxel Dörfler 
106*0f3fcbe4SAxel Dörfler 
107*0f3fcbe4SAxel Dörfler /*static*/ void
Register(VolumeListener * listener)108*0f3fcbe4SAxel Dörfler VolumeWatcher::Register(VolumeListener* listener)
109*0f3fcbe4SAxel Dörfler {
110*0f3fcbe4SAxel Dörfler 	BAutolock lock(sLocker);
111*0f3fcbe4SAxel Dörfler 	if (sWatcher == NULL)
112*0f3fcbe4SAxel Dörfler 		sWatcher = new VolumeWatcher();
113*0f3fcbe4SAxel Dörfler 
114*0f3fcbe4SAxel Dörfler 	sWatcher->AddListener(listener);
115*0f3fcbe4SAxel Dörfler }
116*0f3fcbe4SAxel Dörfler 
117*0f3fcbe4SAxel Dörfler 
118*0f3fcbe4SAxel Dörfler /*static*/ void
Unregister(VolumeListener * listener)119*0f3fcbe4SAxel Dörfler VolumeWatcher::Unregister(VolumeListener* listener)
120*0f3fcbe4SAxel Dörfler {
121*0f3fcbe4SAxel Dörfler 	BAutolock lock(sLocker);
122*0f3fcbe4SAxel Dörfler 	sWatcher->RemoveListener(listener);
123*0f3fcbe4SAxel Dörfler 
124*0f3fcbe4SAxel Dörfler 	if (sWatcher->CountListeners() == 0)
125*0f3fcbe4SAxel Dörfler 		delete sWatcher;
126*0f3fcbe4SAxel Dörfler }
127