* Now uses BPathMonitor instead of the node monitor; this fixes several issues with

changes to settings files that were ignored (for example, watching "services" did
  only work if "interfaces" existed).
* On services update, Services::_Update() accidently compared the pointers of the
  service objects, instead of the objects themselves.
* Implemented comparison of address changes in service objects; IOW when you change
  the addresses a service should bind itself to, but leave the rest of the service
  unchanged, this will now be detected as well.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21555 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-07-04 18:53:51 +00:00
parent 2702a877ac
commit 43d946d6d6
4 changed files with 69 additions and 32 deletions

View File

@ -1,6 +1,6 @@
SubDir HAIKU_TOP src servers net ; SubDir HAIKU_TOP src servers net ;
UsePrivateHeaders app net ; UsePrivateHeaders app net storage ;
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp headers ] ; #UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp headers ] ;
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; #UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;

View File

@ -16,8 +16,8 @@
#include <Deskbar.h> #include <Deskbar.h>
#include <Directory.h> #include <Directory.h>
#include <Entry.h> #include <Entry.h>
#include <NodeMonitor.h>
#include <Path.h> #include <Path.h>
#include <PathMonitor.h>
#include <Roster.h> #include <Roster.h>
#include <Server.h> #include <Server.h>
#include <TextView.h> #include <TextView.h>
@ -278,7 +278,7 @@ void
NetServer::MessageReceived(BMessage* message) NetServer::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case B_NODE_MONITOR: case B_PATH_MONITOR:
fSettings.Update(message); fSettings.Update(message);
break; break;

View File

@ -30,6 +30,8 @@ struct service_address {
int type; int type;
int protocol; int protocol;
sockaddr address; sockaddr address;
bool operator==(const struct service_address& other) const;
}; };
typedef vector<service_address> AddressList; typedef vector<service_address> AddressList;
@ -42,8 +44,8 @@ struct service {
AddressList addresses; AddressList addresses;
~service(); ~service();
bool operator!=(const struct service& other); bool operator!=(const struct service& other) const;
bool operator==(const struct service& other); bool operator==(const struct service& other) const;
}; };
@ -86,6 +88,20 @@ type_for_protocol(int protocol)
// #pragma mark - // #pragma mark -
bool
service_address::operator==(const struct service_address& other) const
{
return family == other.family
&& type == other.type
&& protocol == other.protocol
&& address.sa_len == other.address.sa_len
&& !memcmp(&address, &other.address, address.sa_len);
}
// #pragma mark -
service::~service() service::~service()
{ {
// close all open sockets // close all open sockets
@ -99,20 +115,38 @@ service::~service()
bool bool
service::operator!=(const struct service& other) service::operator!=(const struct service& other) const
{ {
return !(*this == other); return !(*this == other);
} }
bool bool
service::operator==(const struct service& other) service::operator==(const struct service& other) const
{ {
if (name != other.name if (name != other.name
|| launch != other.launch) || launch != other.launch
|| addresses.size() != other.addresses.size())
return false; return false;
// TODO: compare addresses! // compare addresses
AddressList::const_iterator iterator = addresses.begin();
for (; iterator != addresses.end(); iterator++) {
const service_address& address = *iterator;
// find address in other addresses
AddressList::const_iterator otherIterator = other.addresses.begin();
for (; otherIterator != other.addresses.end(); otherIterator++) {
if (address == *otherIterator)
break;
}
if (otherIterator == other.addresses.end())
return false;
}
return true; return true;
} }
@ -419,7 +453,7 @@ Services::_Update(const BMessage& services)
} else { } else {
// this service does already exist - check for any changes // this service does already exist - check for any changes
if (service != iterator->second) { if (*service != *iterator->second) {
_StopService(*iterator->second); _StopService(*iterator->second);
_StartService(*service); _StartService(*service);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All Rights Reserved. * Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@ -11,8 +11,9 @@
#include <Directory.h> #include <Directory.h>
#include <FindDirectory.h> #include <FindDirectory.h>
#include <NodeMonitor.h> #include <fs_interface.h>
#include <Path.h> #include <Path.h>
#include <PathMonitor.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -158,7 +159,8 @@ Settings::_ConvertFromDriverParameter(const driver_parameter& parameter,
} }
} }
if (settingsTemplate->type == B_MESSAGE_TYPE && parameter.parameter_count > 0) { if (settingsTemplate->type == B_MESSAGE_TYPE
&& parameter.parameter_count > 0) {
status_t status = B_OK; status_t status = B_OK;
BMessage subMessage; BMessage subMessage;
for (int32 j = 0; j < parameter.parameter_count; j++) { for (int32 j = 0; j < parameter.parameter_count; j++) {
@ -248,17 +250,7 @@ Settings::_StartWatching(const char* name, const BMessenger& target)
if (status < B_OK) if (status < B_OK)
return status; return status;
BNode node; return BPrivate::BPathMonitor::StartWatching(path.Path(), B_WATCH_STAT,
status = node.SetTo(path.Path());
if (status < B_OK)
return status;
node_ref ref;
status = node.GetNodeRef(&ref);
if (status < B_OK)
return status;
return watch_node(&ref, name != NULL ? B_WATCH_STAT : B_WATCH_DIRECTORY,
target); target);
} }
@ -273,9 +265,7 @@ Settings::StartMonitoring(const BMessenger& target)
fListener = target; fListener = target;
status_t status = _StartWatching(NULL, target); status_t status = _StartWatching("interfaces", target);
if (status == B_OK)
status = _StartWatching("interfaces", target);
if (status == B_OK) if (status == B_OK)
status = _StartWatching("services", target); status = _StartWatching("services", target);
@ -288,24 +278,37 @@ Settings::StopMonitoring(const BMessenger& target)
{ {
// TODO: this needs to be changed in case the server will watch // TODO: this needs to be changed in case the server will watch
// anything else but settings // anything else but settings
return stop_watching(target); return BPrivate::BPathMonitor::StopWatching(target);
} }
status_t status_t
Settings::Update(BMessage* message) Settings::Update(BMessage* message)
{ {
const char* name; message->PrintToStream();
const char* pathName;
int32 opcode; int32 opcode;
if (message->FindInt32("opcode", &opcode) < B_OK if (message->FindInt32("opcode", &opcode) < B_OK
|| message->FindString("name", &name) < B_OK) || message->FindString("path", &pathName) < B_OK)
return B_BAD_VALUE; return B_BAD_VALUE;
if (opcode == B_ENTRY_REMOVED) if (message->FindBool("removed")) {
// for now, we only consider existing settings files
// (ie. deleting "services" won't stop any)
return B_OK; return B_OK;
}
int32 fields;
if (opcode == B_STAT_CHANGED
&& message->FindInt32("fields", &fields) == B_OK
&& (fields & FS_WRITE_STAT_MTIME) == 0) {
// only update when the modified time has changed
return B_OK;
}
BPath path(pathName);
uint32 type; uint32 type;
if (_Load(name, &type) == B_OK) { if (_Load(path.Leaf(), &type) == B_OK) {
BMessage update(type); BMessage update(type);
fListener.SendMessage(&update); fListener.SendMessage(&update);
} }