PDA

View Full Version : Overriding QReadWriteLock's lockForRead and lockForWrite



mentalmushroom
19th July 2011, 11:06
I am interested if there is any way to change the functionality of QReadWriteLock's lockForRead and lockForWrite methods while retaining the ability of using them along with QReadLocker and QWriteLocker classes. I noticed lockForRead and lockForWrite methods of QReadWriteLock are not virtual, so when passing derived class to QReadLocker it calls old method. More specifically, I'd like to make lockForRead/lockForWrite methods to be const, because they don't change any data and I think it should be possible to call them on const data. Also I want to add some reporting, so it would be easier to know if some object is locked.

mcosta
19th July 2011, 11:12
I'd like to make lockForRead/lockForWrite methods to be const, because they don't change any data

Are you sure of that??

Probably they change the status of internal data!!

What do you need? Probably there is an other way to obtain that

mentalmushroom
19th July 2011, 12:06
Perhaps, they change something in QReadWriteLock, but I use multiple inheritance when I want to protect some list for example. See example:


class FileList: public QList<MyFile>, public QReadWriteLock
{
//... overriding lockForRead and lockForWrite methods
}

class MyClass
{
public:
const FileList & getFiles() const;
void modifyFiles();
protected:
FileList fileList;
}


So I'd like to be able to read const FileList & (returned by getFiles) protecting it with lockForRead.

mcosta
19th July 2011, 13:38
Write as



class FileList: public QList<MyFile>
{
void readLock () const {m_lock.readForRead();}
void writeLock () const {m_lock.readForWrite();}

private:
mutable QReadWriteLock m_lock;
}

class MyClass
{
public:
const FileList & getFiles() const;
void modifyFiles();
protected:
FileList fileList;
}


However IMO isn't correct to make the lock functions const. They modify the internal state of the object

mentalmushroom
19th July 2011, 13:49
Write as...
yes, but then I am unable to use it along with QReadLocker.


However IMO isn't correct to make the lock functions const. They modify the internal state of the object
then how should i check my file list in another thread?


bool findFile()
{
const FileList &fileList = myclass->getFiles();

// need to protect fileList here
fileList.lockForRead();

// i don't modify file list here, but i need it to be protected from modification with something else
foreach (const MyFile &file, fileList)
{
//...
}

fileList.unlock();
}

mcosta
19th July 2011, 14:21
In a previous post I wrote



What do you need? Probably there is an other way to obtain that


If you need to protect the access to a collection, you should write wrapper functions that completely hide the internal data structure.
Instead of using inheritance, you should think to use composition and implement the interface to manipulate internal data.

if you leave to the client code the responsibility to call *Lock functions, you have to call them explicitly each time you need.

mentalmushroom
19th July 2011, 14:47
What do you need? Probably there is an other way to obtain that
If there is, I don't know about that way.


If you need to protect the access to a collection, you should write wrapper functions that completely hide the internal data structure.
not really possible, fileList is used many times in different functions that require some things that have no relation to MyClass object where as far as i understood i should add a wrapper function.


Instead of using inheritance, you should think to use composition and implement the interface to manipulate internal data.
Multiple inheritance is more convenient and i can use it along with QReadLocker for example. I rather keep it like i have now doing this way: const_cast<FileList&>.lockForRead().


if you leave to the client code the responsibility to call *Lock functions, you have to call them explicitly each time you need.
Well, i call it explicitly in findFile function (that is a client function). Or did you mean something else?