* watch_node() now returns B_BAD_VALUE if it's used with a NULL node and

flags unequal B_WATCH_MOUNT/B_STOP_WATCHING set.
* Changed watch_node() and stop_watching() to be messenger based instead
  of handler/looper - that greatly simplifies the code.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15828 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-01-03 18:02:56 +00:00
parent d9a5e6050f
commit 4eeeeea969
+58 -78
View File
@@ -1,13 +1,18 @@
//---------------------------------------------------------------------- /*
// This software is part of the OpenBeOS distribution and is covered * Copyright 2001-2005, Haiku.
// by the OpenBeOS license. * Distributed under the terms of the MIT License.
//--------------------------------------------------------------------- *
* Authors:
* Ingo Weinhold, bonefish@@users.sf.net
* Axel Dörfler, [email protected]
*/
#include <AppMisc.h>
#include <Looper.h>
#include <Messenger.h> #include <Messenger.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
#include <MessengerPrivate.h>
#include <syscalls.h> #include <syscalls.h>
// TODO: Tests! // TODO: Tests!
@@ -39,13 +44,42 @@
status_t status_t
watch_node(const node_ref *node, uint32 flags, BMessenger target) watch_node(const node_ref *node, uint32 flags, BMessenger target)
{ {
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE); if (!target.IsValid())
if (error == B_OK) { return B_BAD_VALUE;
BLooper *looper = NULL;
BHandler *handler = target.Target(&looper); BMessenger::Private messengerPrivate(target);
error = watch_node(node, flags, handler, looper); port_id port = messengerPrivate.Port();
int32 token = messengerPrivate.Token();
if (flags == B_STOP_WATCHING) {
// unsubscribe from node node watching
if (node == NULL)
return B_BAD_VALUE;
return _kern_stop_watching(node->device, node->node, flags, port, token);
} }
return error;
// subscribe to...
// mount watching
if (flags & B_WATCH_MOUNT) {
status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1, 0, port,
token);
if (status < B_OK)
return status;
flags &= ~B_WATCH_MOUNT;
}
// node watching
if (flags != 0) {
if (node == NULL)
return B_BAD_VALUE;
return _kern_start_watching(node->device, node->node, flags, port,
token);
}
return B_OK;
} }
// watch_node // watch_node
@@ -78,45 +112,10 @@ status_t
watch_node(const node_ref *node, uint32 flags, const BHandler *handler, watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
const BLooper *looper) const BLooper *looper)
{ {
status_t error = B_OK; return watch_node(node, flags, BMessenger(handler, looper));
// 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 = _kern_stop_watching(node->device, node->node, flags, port, handlerToken);
else
error = B_BAD_VALUE;
} else {
// subscribe to...
// mount watching
if (flags & B_WATCH_MOUNT) {
error = _kern_start_watching((dev_t)-1, (ino_t)-1, 0, port, handlerToken);
flags &= ~B_WATCH_MOUNT;
}
// node watching
if (error == B_OK && flags)
error = _kern_start_watching(node->device, node->node, flags, port, handlerToken);
}
}
return error;
} }
// stop_watching
/*! \brief Unsubscribes a target from node and mount monitoring. /*! \brief Unsubscribes a target from node and mount monitoring.
\param target Messenger referring to the target. Must be valid. \param target Messenger referring to the target. Must be valid.
\return \c B_OK, if everything went fine, another error code otherwise. \return \c B_OK, if everything went fine, another error code otherwise.
@@ -124,16 +123,17 @@ watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
status_t status_t
stop_watching(BMessenger target) stop_watching(BMessenger target)
{ {
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE); if (!target.IsValid())
if (error == B_OK) { return B_BAD_VALUE;
BLooper *looper = NULL;
BHandler *handler = target.Target(&looper); BMessenger::Private messengerPrivate(target);
error = stop_watching(handler, looper); port_id port = messengerPrivate.Port();
} int32 token = messengerPrivate.Token();
return error;
return _kern_stop_notifying(port, token);
} }
// stop_watching
/*! \brief Unsubscribes a target from node and mount monitoring. /*! \brief Unsubscribes a target from node and mount monitoring.
\param handler The target handler. May be \c NULL, if \a looper is not \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. \c NULL. Then the preferred handler of the looper is targeted.
@@ -144,26 +144,6 @@ stop_watching(BMessenger target)
status_t status_t
stop_watching(const BHandler *handler, const BLooper *looper) stop_watching(const BHandler *handler, const BLooper *looper)
{ {
status_t error = B_OK; return stop_watching(BMessenger(handler, looper));
// 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 = _kern_stop_notifying(port, handlerToken);
}
return error;
} }