xref: /haiku/src/kits/storage/NodeMonitor.cpp (revision 0e50eab75e25d0d82090e22dbff766dfaa6f5e86)
1 /*
2  * Copyright 2001-2005, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ingo Weinhold, bonefish@@users.sf.net
7  *		Axel Dörfler, axeld@pinc-software.de
8  */
9 
10 
11 #include <Messenger.h>
12 #include <NodeMonitor.h>
13 
14 #include <MessengerPrivate.h>
15 
16 #include <syscalls.h>
17 
18 // TODO: Tests!
19 
20 
21 // watch_node
22 /*!	\brief Subscribes a target to node and/or mount watching, or unsubscribes
23 		   it from node watching.
24 
25 	Depending of \a flags the action performed by this function varies:
26 	- \a flags is \c 0: The target is unsubscribed from watching the node.
27 	  \a node must not be \c NULL in this case.
28 	- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
29 	  watching.
30 	- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
31 	  \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
32 	  watching the specified aspects of the node. \a node must not be \c NULL
33 	  in this case.
34 
35 	Note, that the latter two cases are not mutual exlusive, i.e. mount and
36 	node watching can be requested with a single call.
37 
38 	\param node node_ref referring to the node to be watched. May be \c NULL,
39 		   if only mount watching is requested.
40 	\param flags Flags indicating the actions to be performed.
41 	\param target Messenger referring to the target. Must be valid.
42 	\return \c B_OK, if everything went fine, another error code otherwise.
43 */
44 status_t
45 watch_node(const node_ref *node, uint32 flags, BMessenger target)
46 {
47 	if (!target.IsValid())
48 		return B_BAD_VALUE;
49 
50 	BMessenger::Private messengerPrivate(target);
51 	port_id port = messengerPrivate.Port();
52 	int32 token = messengerPrivate.Token();
53 
54 	if (flags == B_STOP_WATCHING) {
55 		// unsubscribe from node node watching
56 		if (node == NULL)
57 			return B_BAD_VALUE;
58 
59 		return _kern_stop_watching(node->device, node->node, flags, port, token);
60 	}
61 
62 	// subscribe to...
63 	// mount watching
64 	if (flags & B_WATCH_MOUNT) {
65 		status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1,
66 			B_WATCH_MOUNT, port, token);
67 		if (status < B_OK)
68 			return status;
69 
70 		flags &= ~B_WATCH_MOUNT;
71 	}
72 
73 	// node watching
74 	if (flags != 0) {
75 		if (node == NULL)
76 			return B_BAD_VALUE;
77 
78 		return _kern_start_watching(node->device, node->node, flags, port,
79 			token);
80 	}
81 
82 	return B_OK;
83 }
84 
85 // watch_node
86 /*!	\brief Subscribes a target to node and/or mount watching, or unsubscribes
87 		   it from node watching.
88 
89 	Depending of \a flags the action performed by this function varies:
90 	- \a flags is \c 0: The target is unsubscribed from watching the node.
91 	  \a node must not be \c NULL in this case.
92 	- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
93 	  watching.
94 	- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
95 	  \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
96 	  watching the specified aspects of the node. \a node must not be \c NULL
97 	  in this case.
98 
99 	Note, that the latter two cases are not mutual exlusive, i.e. mount and
100 	node watching can be requested with a single call.
101 
102 	\param node node_ref referring to the node to be watched. May be \c NULL,
103 		   if only mount watching is requested.
104 	\param flags Flags indicating the actions to be performed.
105 	\param handler The target handler. May be \c NULL, if \a looper is not
106 		   \c NULL. Then the preferred handler of the looper is targeted.
107 	\param looper The target looper. May be \c NULL, if \a handler is not
108 		   \c NULL. Then the handler's looper is the target looper.
109 	\return \c B_OK, if everything went fine, another error code otherwise.
110 */
111 status_t
112 watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
113 	const BLooper *looper)
114 {
115 	return watch_node(node, flags, BMessenger(handler, looper));
116 }
117 
118 
119 /*!	\brief Unsubscribes a target from node and mount monitoring.
120 	\param target Messenger referring to the target. Must be valid.
121 	\return \c B_OK, if everything went fine, another error code otherwise.
122 */
123 status_t
124 stop_watching(BMessenger target)
125 {
126 	if (!target.IsValid())
127 		return B_BAD_VALUE;
128 
129 	BMessenger::Private messengerPrivate(target);
130 	port_id port = messengerPrivate.Port();
131 	int32 token = messengerPrivate.Token();
132 
133 	return _kern_stop_notifying(port, token);
134 }
135 
136 
137 /*!	\brief Unsubscribes a target from node and mount monitoring.
138 	\param handler The target handler. May be \c NULL, if \a looper is not
139 		   \c NULL. Then the preferred handler of the looper is targeted.
140 	\param looper The target looper. May be \c NULL, if \a handler is not
141 		   \c NULL. Then the handler's looper is the target looper.
142 	\return \c B_OK, if everything went fine, another error code otherwise.
143 */
144 status_t
145 stop_watching(const BHandler *handler, const BLooper *looper)
146 {
147 	return stop_watching(BMessenger(handler, looper));
148 }
149 
150