Added implementation of the node monitoring functions.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3065 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2003-04-13 15:02:24 +00:00
parent 2cb55578bd
commit 150bfa3714
2 changed files with 218 additions and 0 deletions

View File

@ -0,0 +1,217 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <AppMisc.h>
#include <Looper.h>
#include <Messenger.h>
#include <NodeMonitor.h>
// TODO: Tests!
// private libroot.so functions
/*! \brief Subscribes a target to node and/or mount watching.
Depending on \a flags, different actions are performed. If flags is \c 0,
mount watching is requested. \a device and \a node must be \c -1 in this
case. Otherwise node watching is requested. \a device and \a node must
refer to a valid node, and \a flags must note contain the flag
\c B_WATCH_MOUNT, but at least one of the other valid flags.
\param device The device the node resides on (node_ref::device). \c -1, if
only mount watching is requested.
\param node The node ID of the node (node_ref::device). \c -1, if
only mount watching is requested.
\param flags A bit mask composed of the values specified in
<NodeMonitor.h>.
\param port The port of the target (a looper port).
\param handlerToken The token of the target handler. \c -2, if the
preferred handler of the looper is the target.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
extern "C" status_t _kstart_watching_vnode_(dev_t device, ino_t node,
uint32 flags, port_id port,
int32 handlerToken);
/*! \brief Unsubscribes a target from watching a node.
\param device The device the node resides on (node_ref::device).
\param node The node ID of the node (node_ref::device).
\param port The port of the target (a looper port).
\param handlerToken The token of the target handler. \c -2, if the
preferred handler of the looper is the target.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
extern "C" status_t _kstop_watching_vnode_(dev_t device, ino_t node,
port_id port, int32 handlerToken);
/*! \brief Unsubscribes a target from node and mount monitoring.
\param port The port of the target (a looper port).
\param handlerToken The token of the target handler. \c -2, if the
preferred handler of the looper is the target.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
extern "C" status_t _kstop_notifying_(port_id port, int32 handlerToken);
// actual implementation
// watch_node
/*! \brief Subscribes a target to node and/or mount watching, or unsubscribes
it from node watching.
Depending of \a flags the action performed by this function varies:
- \a flags is \c 0: The target is unsubscribed from watching the node.
\a node must not be \c NULL in this case.
- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
watching.
- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
\c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
watching the specified aspects of the node. \a node must not be \c NULL
in this case.
Note, that the latter two cases are not mutual exlusive, i.e. mount and
node watching can be requested with a single call.
\param node node_ref referring to the node to be watched. May be \c NULL,
if only mount watching is requested.
\param flags Flags indicating the actions to be performed.
\param target Messenger referring to the target. Must be valid.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
watch_node(const node_ref *node, uint32 flags, BMessenger target)
{
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
BLooper *looper = NULL;
BHandler *handler = target.Target(&looper);
error = watch_node(node, flags, handler, looper);
}
return error;
}
// watch_node
/*! \brief Subscribes a target to node and/or mount watching, or unsubscribes
it from node watching.
Depending of \a flags the action performed by this function varies:
- \a flags is \c 0: The target is unsubscribed from watching the node.
\a node must not be \c NULL in this case.
- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
watching.
- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
\c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
watching the specified aspects of the node. \a node must not be \c NULL
in this case.
Note, that the latter two cases are not mutual exlusive, i.e. mount and
node watching can be requested with a single call.
\param node node_ref referring to the node to be watched. May be \c NULL,
if only mount watching is requested.
\param flags Flags indicating the actions to be performed.
\param handler The target handler. May be \c NULL, if \a looper is not
\c NULL. Then the preferred handler of the looper is targeted.
\param looper The target looper. May be \c NULL, if \a handler is not
\c NULL. Then the handler's looper is the target looper.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
const BLooper *looper)
{
status_t error = B_OK;
// check looper and handler and get the handler token
int32 handlerToken = -2;
if (handler) {
handlerToken = _get_object_token_(handler);
if (looper) {
if (looper != handler->Looper())
error = B_BAD_VALUE;
} else {
looper = handler->Looper();
if (!looper)
error = B_BAD_VALUE;
}
} else if (!looper)
error = B_BAD_VALUE;
if (error == B_OK) {
port_id port = _get_looper_port_(looper);
if (flags == B_STOP_WATCHING) {
// unsubscribe from node node watching
if (node) {
error = _kstop_watching_vnode_(node->device, node->node, port,
handlerToken);
} else
error = B_BAD_VALUE;
} else {
// subscribe to...
// mount watching
if (flags & B_WATCH_MOUNT) {
error = _kstart_watching_vnode_(-1, -1, 0, port, handlerToken);
flags &= ~B_WATCH_MOUNT;
}
// node watching
if (error == B_OK && flags) {
error = _kstart_watching_vnode_(node->device, node->node,
flags, port, handlerToken);
}
}
}
return error;
}
// stop_watching
/*! \brief Unsubscribes a target from node and mount monitoring.
\param target Messenger referring to the target. Must be valid.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
stop_watching(BMessenger target)
{
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
BLooper *looper = NULL;
BHandler *handler = target.Target(&looper);
error = stop_watching(handler, looper);
}
return error;
}
// stop_watching
/*! \brief Unsubscribes a target from node and mount monitoring.
\param handler The target handler. May be \c NULL, if \a looper is not
\c NULL. Then the preferred handler of the looper is targeted.
\param looper The target looper. May be \c NULL, if \a handler is not
\c NULL. Then the handler's looper is the target looper.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
stop_watching(const BHandler *handler, const BLooper *looper)
{
status_t error = B_OK;
// check looper and handler and get the handler token
int32 handlerToken = -2;
if (handler) {
handlerToken = _get_object_token_(handler);
if (looper) {
if (looper != handler->Looper())
error = B_BAD_VALUE;
} else {
looper = handler->Looper();
if (!looper)
error = B_BAD_VALUE;
}
} else if (!looper)
error = B_BAD_VALUE;
// unsubscribe
if (error == B_OK) {
port_id port = _get_looper_port_(looper);
error = _kstop_notifying_(port, handlerToken);
}
return error;
}

View File

@ -11,6 +11,7 @@ STORAGE_KIT_SOURCE =
MimeType.cpp
Node.cpp
NodeInfo.cpp
NodeMonitor.cpp
OffsetFile.cpp
Path.cpp
Query.cpp