[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-pim
Subject: [Kde-pim] KSharedFile RFC
From: Holger Freyther <freyther () gmx ! net>
Date: 2001-12-16 17:12:22
[Download RAW message or body]
Hi Cornelius, kde-pims,
Cornelius and me created KSharedFile. Cornelius I added all the stuff you
missed and I think my file is ready for committing. I would like to add it to
kio? Any comments>
KSharedFile is a class to share file access between processes. It gives api
to lock a file. Locking means no other process than the holder can write to
the file. This is done in 2 ways. First the holder needs to have a ticket and
the other is inside the class.
Actually I don't know what to say else
regards Holger
PS: Cornelius sorry it took so long. But I had to study and did some work for
kafka and kitchensync
["ksharedfile.h" (text/x-c++)]
/* This file is part of the KDE libraries
Copyright (C) 2001 Holger Freyther <freyher@kde.org>
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef ksharedfile_h
#define ksharedfile_h
#include <sys/types.h>
#include <qstring.h>
#include <qobject.h>
class QFile;
class QTimer;
/** The point of KSharedFile is to make it possible for more than one
program to work with a file. It take's care that only one program
writes to the file at a time. There's no really way of pretending a
program to write to the file.
The program creates a instance of KSharedFile and sets the FileName.
If it want's to write to the file it calls tryLockFile( ) and either get's
the lock or not.
Then there are also signal which signalize a change.
@short KSharedFile to lock a file
@author Holger Freyther <freyther@kde.org>
@version 0.5
*/
class KSharedFile : public QObject
{
Q_OBJECT;
public:
/** Instantiate the class.
@param filename The resource to be shared with others
*/
KSharedFile( const QString &filename );
/** this function is for convience
it does the same a above but takes a file as paramter
@param file The file to be shared.
*/
KSharedFile( const QFile &file );
~KSharedFile( );
class Ticket
{
friend class KSharedFile;
Ticket ( const QString &filename ) : m_fileName( filename ) {}
private:
QString m_fileName;
};
/** sets the Filename
@param filename The name of the resource to be shared
*/
void setFileName( const QString &filename );
/** This method is for convience.It sets the File
@param file The file to be shared
*/
void setFile( const QFile &file );
/** @return the fileName of the shared file
*/
QString fileName( ) const;
/** This tries to lock the file. It returns right after trying either successful or not
@return if Ticket is not equal to 0l the file was successfully locked
*/
Ticket* tryLockFile( );
/** This loads the file specified
@see setFileName(const QString & )
*/
QString load( );
/** This writes to the file if the ticket is valid
@param
*/
bool save( Ticket *ticket, const QString &string );
/** after locking this unlocks the file
*/
bool unlockFile( Ticket *ticket );
/** check whether or not the file is locked
@return the state of the lock
*/
bool isLocked( );
/**
@returns whether or not I locked the file
*/
bool didILock( );
/** In future this will tell you who to blame for the file is locked.
*/
QString whoHoldsLock( ) const;
protected:
QString m_uniqueName;
private:
QString m_fileName;
bool m_locked:1;
bool m_lockedOther:1;
QTimer *m_FileCheckTimer;
time_t m_ChangeTime;
private slots:
void checkFile( );
signals:
/**
This signal get emitted when the file get unlocked
@param filename The name of the file which gets locked
*/
void fileUnlocked( const QString &filename);
/** The file got locked
@param filename filename got locked
*/
void fileLocked( const QString &filename );
/**
The file changed during a lock and unlock session
@param filename The file with the name filenam changed
*/
void fileChanged( const QString &filename );
};
#endif
["ksharedfile.cpp" (text/x-c)]
/* This file is part of the KDE libraries
Copyright (C) 2001 Holger Freyther <freyher@kde.org>
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <sys/stat.h>
#include <unistd.h>
#include <kapplication.h>
#include <kdebug.h>
#include <qfile.h>
#include <qtimer.h>
#include <qtextstream.h>
#include "ksharedfile.h"
KSharedFile::KSharedFile( const QString &filename ) : QObject( 0, "KSharedFile" )
{
m_locked = false;
m_FileCheckTimer = new QTimer (this );
connect( m_FileCheckTimer, SIGNAL( timeout() ), SLOT( checkFile()) );
setFileName( filename);
}
KSharedFile::KSharedFile( const QFile &file ) : QObject( 0, "KSharedFile" )
{
m_locked = false;
m_FileCheckTimer = new QTimer(this );
connect( m_FileCheckTimer, SIGNAL( timeout() ), SLOT( checkFile()) );
setFile( file);
}
KSharedFile::~KSharedFile( )
{
unlockFile(new Ticket(m_fileName) );
delete m_FileCheckTimer; // qt would do this too
}
void KSharedFile::setFileName ( const QString &filename )
{
unlockFile(new Ticket(m_fileName) );
m_lockedOther = false;
m_fileName = filename;
struct stat s;
int result = stat( QFile::encodeName( m_fileName ), &s );
if ( result == 0 ) { // file exists
m_ChangeTime = s.st_ctime; // last change
m_FileCheckTimer->start( 500 );
}
}
void KSharedFile::setFile( const QFile &file )
{
setFileName( file.name() );
}
QString KSharedFile::fileName( )const
{
return m_fileName;
}
KSharedFile::Ticket *KSharedFile::tryLockFile( )
{
kdDebug(5910) << "KSharedFile::tryLockFile " << m_fileName << endl;
if(!QFile::exists( m_fileName ) ) return 0l;
if(QFile::exists( m_fileName+".lock") ) return 0l;
QString lockFile(m_fileName + ".lock" );
//create unique file
m_uniqueName = m_fileName + kapp->randomString(8) ;
QFile file( m_uniqueName);
file.open( IO_WriteOnly );
file.close( );
// Create lock file
int result = link ( QFile::encodeName( m_uniqueName ),
QFile::encodeName( m_fileName + ".lock" ));
if( result == 0 )
{
emit fileLocked(m_fileName );
m_locked = true;
return new KSharedFile::Ticket(m_fileName );
}
return 0l;
}
bool KSharedFile::unlockFile( Ticket* ticket )
{
if( m_locked && ticket->m_fileName==m_fileName){
m_locked = false;
unlink( QFile::encodeName(m_fileName+ ".lock") );
QFile::remove( m_uniqueName );
emit fileUnlocked( m_fileName );
delete ticket;
ticket=0;
return true;
}else
return false;
}
bool KSharedFile::isLocked( )
{
//return m_locked;
return QFile::exists(m_fileName + ".lock");
}
bool KSharedFile::didILock( )
{
return m_locked;
}
QString KSharedFile::whoHoldsLock( ) const
{
return QString();
}
bool KSharedFile::save( Ticket *ticket, const QString &string )
{
if ( m_locked && ticket->m_fileName == m_fileName ){
QFile file( m_fileName ); // handles unicode names inernal
file.open(IO_WriteOnly);
QTextStream stream( &file );
//file.writeBlock( string ); //doesn't work
stream << string;
file.close();
return true;
}
return false;
}
QString KSharedFile::load( )
{
QString dummy;
QFile file( m_fileName );
file.open(IO_ReadOnly);
dummy = QString(file.readAll() );
file.close();
return dummy;
}
void KSharedFile::checkFile( )
{
// ok somebody holds the lock
if( !m_lockedOther && !m_locked && QFile::exists( QFile::encodeName( m_fileName+ ".lock" ) ) ) {
emit fileLocked( m_fileName );
m_lockedOther= true; // other locked our file
return;
}
else if( m_lockedOther && !m_locked &&!QFile::exists( QFile::encodeName( m_fileName + ".lock" ) ) ) {
emit fileUnlocked( m_fileName );
m_lockedOther = false; // other
}
struct stat s;
int result = stat( QFile::encodeName( m_fileName ), &s );
if ( result == 0 && (m_ChangeTime != s.st_ctime ) ){
m_ChangeTime = s.st_ctime;
emit fileChanged( m_fileName );
}
}
#include "ksharedfile.moc"
_______________________________________________
kde-pim mailing list
kde-pim@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-pim
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic