File: [Development] / fam / fam / ClientInterest.c++ (download)
Revision 1.1.1.1 (vendor branch), Thu Apr 24 19:08:26 2003 UTC (14 years, 6 months ago) by trev
Branch: sgi-fam, MAIN
CVS Tags: fam-2-6-10, HEAD Changes since 1.1: +0 -0
lines
Initial FAM CVS repository build..
-- Trev
|
// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of version 2 of the GNU General Public License as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it would be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
// license provided herein, whether implied or otherwise, is limited to
// this program in accordance with the express provisions of the GNU
// General Public License. Patent licenses, if any, provided herein do not
// apply to combinations of this program with other product or programs, or
// any other product whatsoever. This program is distributed without any
// warranty that the program is delivered free of the rightful claim of any
// third person by way of infringement or the like. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write the Free Software Foundation, Inc., 59
// Temple Place - Suite 330, Boston MA 02111-1307, USA.
#include "ClientInterest.h"
#include <assert.h>
#include <errno.h>
#include "Client.h"
#include "Event.h"
#include "FileSystem.h"
#include "FileSystemTable.h"
ClientInterest::ClientInterest(const char *name,
Client *c, Request r, const Cred& cr, Type type)
: Interest(name, myfilesystem = FileSystemTable::find(name, cr),
c->host(), VERIFY_EXPORTED),
myclient(c), request(r), mycred(cr), fs_request(0)
{
ci_bits() = ACTIVE_STATE;
if (exported_to_host())
{
// This is so horribly lame. If this interest doesn't exist,
// and someone somewhere set errno to EACCES, let's assume the
// interest exists but this client doesn't have permission to
// monitor it. (The actual imon_express and lstat are done in
// in the Interest constructor.) This use of errno probably
// makes it easy to become confused and suggest_insecure_compat
// even when we shouldn't.
if ((!exists()) && (errno == EACCES) && (c != NULL))
{
c->suggest_insecure_compat(name);
}
post_event(exists() ? Event::Exists : Event::Deleted);
fs_request = myfilesystem->monitor(this, type);
}
else
{
post_event(Event::Deleted);
}
}
ClientInterest::~ClientInterest()
{
myfilesystem->cancel(this, fs_request);
}
void
ClientInterest::filesystem(FileSystem *fs)
{
myfilesystem->cancel(this, fs_request);
myfilesystem = fs;
verify_exported_to_host();
if (exported_to_host())
{
fs_request = fs->monitor(this, type());
scan();
}
else if (fs_request != 0)
{
// This Interest used to be on a filesystem which was mounted by
// the client, but now is not? Send a Deleted event.
post_event(Event::Deleted);
fs_request = 0;
}
}
void
ClientInterest::findfilesystem()
{
FileSystem *new_fs = FileSystemTable::find(name(), mycred);
if (new_fs != myfilesystem)
{
filesystem(new_fs);
}
}
//////////////////////////////////////////////////////////////////////////////
// Suspend/resume.
bool
ClientInterest::active() const
{
return ci_bits() & ACTIVE_STATE;
}
void
ClientInterest::suspend()
{
if (active())
{ ci_bits() &= ~ACTIVE_STATE;
myfilesystem->hl_suspend(fs_request);
}
}
void
ClientInterest::resume()
{
bool was_active = active();
ci_bits() |= ACTIVE_STATE; // Set state before generating events.
do_scan();
if (!was_active)
myfilesystem->hl_resume(fs_request);
}
void
ClientInterest::post_event(const Event& event, const char *eventpath)
{
assert(active());
if (!eventpath)
eventpath = name();
myclient->post_event(event, request, eventpath);
}
Interest *
ClientInterest::find_name(const char *)
{
// Ignore name.
return this;
}
bool
ClientInterest::scan(Interest *ip)
{
bool changed = false;
if (!ip)
ip = this;
ip->mark_for_scan();
if (myclient->ready_for_events())
changed = ip->do_scan();
else
myclient->enqueue_for_scan(ip);
return changed;
}
void
ClientInterest::unscan(Interest *ip)
{
if (!ip)
ip = this;
if (ip->needs_scan())
myclient->dequeue_from_scan(ip);
}
bool
ClientInterest::do_scan()
{
bool changed = false;
if (needs_scan() && active()) {
become_user();
changed = Interest::do_scan();
}
return changed;
}
void
ClientInterest::notify_created(Interest *ip)
{
if (!ip)
ip = this;
myfilesystem->ll_notify_created(ip);
}
void
ClientInterest::notify_deleted(Interest *ip)
{
if (!ip)
ip = this;
myfilesystem->ll_notify_deleted(ip);
}
void
ClientInterest::cancel()
{
ci_bits() |= ACTIVE_STATE;
post_event(Event::Acknowledge);
unscan();
}