[Interest] QFileSystemWatcher malfunctioning

790 views
Skip to first unread message

Sujan Dasmahapatra

unread,
Jan 12, 2012, 2:01:17 AM1/12/12
to inte...@qt-project.org

Dear Friends

I am using QFileSystemWatcher for knowing when the file is modified from outside my application. I am seeing even if the file is modified from the application this is giving message that the file is modified. Can anyone tell whats going wrong in this..see the snippet below

 

[code]

QFile file(“/home/sdh/projects/opt.cfg”);

watcher = new QFileSystemWatcher(this);

connect(watcher,SIGNAL(fileChanged(const QString &)),this, SLOT(cfgFileModified(const QString &)));

watcher->addPath(file.fileName());

[\code]

 

Please tell me whats going wrong. I am modifying the file from my application then also its giving message. Thanks for any help. Thanks Sujan

 

Kind regards,

 

 

Sujan Dasmahapatra
Project Leader, Aero Group
CE - Aero Group

Tel    +91 80 66470248
Mob 

s...@lmwindpower.com

 

LM Wind Power Blades

lmwindpower.com

 

Together we capture the wind to power a cleaner world


 

This e-mail and any attachments are confidential. If you are not the named or intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Any unauthorized disclosure, use or storage is prohibited and might be unlawful.

 

Andreas Pakulat

unread,
Jan 12, 2012, 2:35:39 AM1/12/12
to inte...@qt-project.org
On 12.01.12 08:01:17, Sujan Dasmahapatra wrote:
> Dear Friends
>
> I am using QFileSystemWatcher for knowing when the file is modified from
> outside my application. I am seeing even if the file is modified from
> the application this is giving message that the file is modified. Can
> anyone tell whats going wrong in this..see the snippet below

There is nothing going wrong here, thats how QFileSystemWatcher is
intended to work. If you don't want to be notified for changes you're
doing yourself you need to add code for that in your application.

Andreas

_______________________________________________
Interest mailing list
Inte...@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Bo Thorsen

unread,
Jan 12, 2012, 3:14:33 AM1/12/12
to inte...@qt-project.org
Den 12-01-2012 08:35, Andreas Pakulat skrev:
> On 12.01.12 08:01:17, Sujan Dasmahapatra wrote:
>> Dear Friends
>>
>> I am using QFileSystemWatcher for knowing when the file is modified from
>> outside my application. I am seeing even if the file is modified from
>> the application this is giving message that the file is modified. Can
>> anyone tell whats going wrong in this..see the snippet below
>
> There is nothing going wrong here, thats how QFileSystemWatcher is
> intended to work. If you don't want to be notified for changes you're
> doing yourself you need to add code for that in your application.

And this is of course the task for a SignalBlocker. I've done exactly
this (block QFileSystemWatcher) for a customer a couple of months ago,
and it really is the only solution.

I just put my SignalBlocker implementation on my blog:

http://www.fioniasoftware.dk/blog/?p=158

(Sorry for the plug but it was a bit long for a mail, and there might be
other interested in it.)

With this class you just do this:

{
SignalBlocker blocker(watcher);
modifyTheFile();
}

I hope this helps.

Bo Thorsen,
Fionia Software.

--

Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk

André Somers

unread,
Jan 12, 2012, 3:27:05 AM1/12/12
to inte...@qt-project.org
Op 12-1-2012 9:14, Bo Thorsen schreef:

> I just put my SignalBlocker implementation on my blog:
>
> http://www.fioniasoftware.dk/blog/?p=158
>
> (Sorry for the plug but it was a bit long for a mail, and there might be
> other interested in it.)
>
> With this class you just do this:
>
> {
> SignalBlocker blocker(watcher);
> modifyTheFile();
> }
>
> I hope this helps.
>
Funny, I wrote exactly the same class (ok, named slightly differently)
at work just a month ago or so :-)

André

Andreas Pakulat

unread,
Jan 12, 2012, 5:08:33 AM1/12/12
to inte...@qt-project.org
On 12.01.12 09:14:33, Bo Thorsen wrote:
> Den 12-01-2012 08:35, Andreas Pakulat skrev:
> > On 12.01.12 08:01:17, Sujan Dasmahapatra wrote:
> >> Dear Friends
> >>
> >> I am using QFileSystemWatcher for knowing when the file is modified from
> >> outside my application. I am seeing even if the file is modified from
> >> the application this is giving message that the file is modified. Can
> >> anyone tell whats going wrong in this..see the snippet below
> >
> > There is nothing going wrong here, thats how QFileSystemWatcher is
> > intended to work. If you don't want to be notified for changes you're
> > doing yourself you need to add code for that in your application.
>
> And this is of course the task for a SignalBlocker. I've done exactly
> this (block QFileSystemWatcher) for a customer a couple of months ago,
> and it really is the only solution.

That only works as long as the detection of changes happens immediately,
that might not be the case all the time since it depends on which
backend QFSWatcher uses (there's a polling one). Usually I add a
modification-timestamp check to the system, i.e. store the
modification-time right after modifying the file and then compare when
the QFSWatcher triggers. This is of course not a 100% safe solution
(hashing the file would be even better) but in my experience good
enough.

Andreas

Sujan Dasmahapatra

unread,
Jan 12, 2012, 7:26:07 AM1/12/12
to inte...@qt-project.org
QFileSystemWatcher intends to give signal if the file is modified outside of the application right ??? Let me know if I am wrong. But I am modified the file from within the application then why it should emit the signal. ????

Kind regards,


Sujan Dasmahapatra
Project Leader, Aero Group
CE - Aero Group


LM Wind Power Blades
lmwindpower.com

Together we capture the wind to power a cleaner world

This e-mail and any attachments are confidential. If you are not the named or intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Any unauthorized disclosure, use or storage is prohibited and might be unlawful.

André Somers

unread,
Jan 12, 2012, 7:39:19 AM1/12/12
to inte...@qt-project.org
Op 12-1-2012 13:26, Sujan Dasmahapatra schreef:

> QFileSystemWatcher intends to give signal if the file is modified outside of the application right ???
Wrong. It will notify you if a file is modified, period. It doesn't care
about who did the modification.

> Let me know if I am wrong. But I am modified the file from within the application then why it should emit the signal. ????
>
Because you misunderstood what QFileSystemWatcher is doing. Where does
it say in the documentation that it _only_ reports modifations triggered
from outside the current application?

André

Robin Burchell

unread,
Jan 12, 2012, 7:45:45 AM1/12/12
to Sujan Dasmahapatra, inte...@qt-project.org
On Thu, Jan 12, 2012 at 2:26 PM, Sujan Dasmahapatra <s...@lmwindpower.com> wrote:
> QFileSystemWatcher intends to give signal if the file is modified outside of the application right ??? Let me know if I am wrong. But I am modified the file from within the application then why it should emit the signal. ????

That's not a correct assumption. QFileSystemWatcher's job is to report
modifications. It doesn't care what made them. Filtering the changes
your application makes is your application's responsibility.

Atlant Schmidt

unread,
Jan 12, 2012, 8:56:26 AM1/12/12
to André Somers, inte...@qt-project.org
All:

> With this class you just do this:
>
> {
> SignalBlocker blocker(watcher);
> modifyTheFile();
> }

It seems to me that there's a race condition here.
Unless you're taking steps to deliberately lock-out
other processes from modifying the file, then they
could slip in immediately before or after you modify
the file and you would never know they'd been there
because you have the signal blocked.

A later reply talks about hashing the file; if you
really want precision notification of modifications,
then that's the sort of thing you have to do *EVERY
TIME* the file watcher tells you a modification has
been made, even if you suspect that the modification
was your own. Either that, or lock-out other changers
while you make your change.

Atlant

-----Original Message-----
From: interest-bounces+aschmidt=dekarese...@qt-project.org [mailto:interest-bounces+aschmidt=dekarese...@qt-project.org] On Behalf Of André Somers
Sent: Thursday, January 12, 2012 03:27
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning

André


Click https://www.mailcontrol.com/sr/!2Y+ytpCNNXTndxI!oX7UsdpzMR7Bo2KuJJ25aNl2Ia2ErDASQGKpjk4Jw0OJtPBO9sXebjFfhJ6aunJTqVygQ== to report this email as spam.

This e-mail and the information, including any attachments, it contains are intended to be a confidential communication only to the person or entity to whom it is addressed and may contain information that is privileged. If the reader of this message is not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender and destroy the original message.

Thank you.

Please consider the environment before printing this email.

Jason H

unread,
Jan 12, 2012, 9:14:25 AM1/12/12
to Sujan Dasmahapatra, inte...@qt-project.org
No. It is just an abstraction of your operating system's file system notification code. AFAIK, none of these native APIs support "do not notify for process X".



From: Sujan Dasmahapatra <s...@lmwindpower.com>
To: inte...@qt-project.org
Sent: Thursday, January 12, 2012 7:26 AM

Bo Thorsen

unread,
Jan 12, 2012, 4:13:48 PM1/12/12
to inte...@qt-project.org
Den 12-01-2012 14:56, Atlant Schmidt skrev:
> All:
>
>> With this class you just do this:
>>
>> {
>> SignalBlocker blocker(watcher);
>> modifyTheFile();
>> }
>
> It seems to me that there's a race condition here.
> Unless you're taking steps to deliberately lock-out
> other processes from modifying the file, then they
> could slip in immediately before or after you modify
> the file and you would never know they'd been there
> because you have the signal blocked.

True. But if you modify the file, you have a race condition anyway,
since you don't know if that was done before or after you do this. You
might not get the modified signal before you change the file contents.

If you're after a fool proof system, don't block the filewatcher and
read it after your own changes, and check that the contents hadn't been
changed before you do it. Or use a database.

Bo Thorsen,
Fionia Software.

--

Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk

Jason H

unread,
Jan 12, 2012, 4:20:52 PM1/12/12
to Bo Thorsen, inte...@qt-project.org
MD5 summing & comparing would be the only way, and even then another program would be indistinguishable if it made the same changes. However that corner case should be a moot point.


From: Bo Thorsen <b...@fioniasoftware.dk>
To: inte...@qt-project.org
Sent: Thursday, January 12, 2012 4:13 PM

Subject: Re: [Interest] QFileSystemWatcher malfunctioning

Sujan Dasmahapatra

unread,
Feb 2, 2012, 8:19:25 AM2/2/12
to inte...@qt-project.org

Dear Thorsen

I need your help. I have implemented the SignalBlocker class in a new header file;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef SIGNALBLOCKER_H

#define SIGNALBLOCKER_H

/**

 * Small helper class that blocks all signals from an object for the lifetime of this object.

 * it is safe against deletion of the object before deletion of this.

 *

 * This class was written by Bo Thorsen of Fionia Software <b...@fioniasoftware.dk>.

 * The code is in the public domain.

 */

class SignalBlocker {

public:

    explicit SignalBlocker(QObject* object) : mObject(object) {

        mWasBlocked = object->signalsBlocked();

        object->blockSignals(true);

    }

    ~SignalBlocker() {

        if (mObject && !mWasBlocked)

            mObject->blockSignals(false);

    }

private:

    // Disabled

    SignalBlocker(const SignalBlocker&);

    SignalBlocker& operator=(const SignalBlocker&);

    QPointer<QObject> mObject;

    bool mWasBlocked;

};


#endif // SIGNALBLOCKER_H

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

Now I have 2 .cpp files. One is plotgraphs.cpp and other is mainwindow.cpp

So I want to block the signal at some function in mainwindow.cpp

And my QFileSystemWatcher object is initialized and connected  in plotgraphs.cpp file. Like below.

//plotgraphs.cpp

QFileSystemWatcher *watcher;

/////////////////////////////////////

PlotGraphsDlg::PlotGraphsDlg(MainWindow *parent)

{

    watcher = new QFileSystemWatcher(this);

    connect(watcher,SIGNAL(fileChanged(const QString &)),this, SLOT(cfgFileModified(const QString &)));

}

/////////////////////////////////////

And in mainwindow at some function I am modifying the file. So in that function in the beginning I am writing this

/////////////////////////////////////////

void MainWindow::saveCFG()

{

    if(!plotgraphsdlg)

    return;

    SignalBlocker blocker(plotgraphsdlg->watcher); //blocking the signal

    QString update;

    QFile file(filename);

    if(!file.exists())

    return;

    if(!file.open(QIODevice::WriteOnly))

    qWarning("Cannot Open file % s", filename);

    QTextStream out(&file);

   out << update;  //This is updating the file.....

}

/////////////////////////////////////////

But after updating I am still getting the message that the file is updated. The signal is not blocked. Please tell me whats going wrong in this. Thanks in advance for your help.

Kind regards,


Sujan Dasmahapatra

Project Leader, Aero Group

CE - Aero Group

Tel  +91 80 66470248

Mob 

s...@lmwindpower.com


LM Wind Power Blades

lmwindpower.com

Together we capture the wind to power a cleaner world


This e-mail and any attachments are confidential. If you are not the named or intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Any unauthorized disclosure, use or storage is prohibited and might be unlawful.

-----Original Message-----
From: interest-bounces+sdh=lmwindp...@qt-project.org [mailto:interest-bounces+sdh=lmwindp...@qt-project.org] On Behalf Of Bo Thorsen
Sent: Thursday, January 12, 2012 1:45 PM
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning

Andreas Pakulat

unread,
Feb 2, 2012, 8:29:51 AM2/2/12
to inte...@qt-project.org
On 02.02.12 14:19:25, Sujan Dasmahapatra wrote:
> But after updating I am still getting the message that the file is
> updated. The signal is not blocked. Please tell me whats going wrong in
> this. Thanks in advance for your help.

Most probably the watcher notices the change asynchronously, i.e. after
your function has ended and the signal blocker has been deleted. You
should be able to verify that either using a debugger or by printing
some timestamps to see when the function is exited and when the slot
connected to the signal is received

Andreas

Bo Thorsen

unread,
Feb 2, 2012, 8:36:35 AM2/2/12
to inte...@qt-project.org
Den 02-02-2012 14:29, Andreas Pakulat skrev:
> On 02.02.12 14:19:25, Sujan Dasmahapatra wrote:
>> But after updating I am still getting the message that the file is
>> updated. The signal is not blocked. Please tell me whats going wrong in
>> this. Thanks in advance for your help.
>
> Most probably the watcher notices the change asynchronously, i.e. after
> your function has ended and the signal blocker has been deleted. You
> should be able to verify that either using a debugger or by printing
> some timestamps to see when the function is exited and when the slot
> connected to the signal is received

That is a bit surprising to me, since I actually used it exactly for
blocking a file watcher, and that worked fine. Perhaps a flush is
necessary on the stream.

Bo Thorsen,
Fionia Software.

--

Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk

Andreas Pakulat

unread,
Feb 2, 2012, 9:35:46 AM2/2/12
to inte...@qt-project.org
On 02.02.12 14:36:35, Bo Thorsen wrote:
> Den 02-02-2012 14:29, Andreas Pakulat skrev:
> > On 02.02.12 14:19:25, Sujan Dasmahapatra wrote:
> >> But after updating I am still getting the message that the file is
> >> updated. The signal is not blocked. Please tell me whats going wrong in
> >> this. Thanks in advance for your help.
> >
> > Most probably the watcher notices the change asynchronously, i.e. after
> > your function has ended and the signal blocker has been deleted. You
> > should be able to verify that either using a debugger or by printing
> > some timestamps to see when the function is exited and when the slot
> > connected to the signal is received
>
> That is a bit surprising to me, since I actually used it exactly for
> blocking a file watcher, and that worked fine. Perhaps a flush is
> necessary on the stream.

Well, it depends on how the Filewatcher does the watching, which depends
on what the OS provides for watching files and wether its
enabled/disabled. QFSWatcher uses a Polling-Backend in case it cannot
use some native notification system and that one surely is asynchronous.

Andreas

Sujan Dasmahapatra

unread,
Feb 2, 2012, 9:49:05 AM2/2/12
to inte...@qt-project.org
May Thorson you're right, I'll do a flush on the stream and see. Also I'll follow Andreas suggestion check it by debugging. It should work. Thanks for your valuable suggestions. Thanks Sujan
--
Thanks & Regards
Sujan Dasmahapatra
B.E. (Aeronautics)
Bangalore, India
Ph:91-9900839788
mail id : sujan.das...@gmail.com
yahoo msn : dasmahapatra...@yahoo.co.in
icq # 556023244
skype:sujan.das...@skyepe.com
msn: sujan.das...@hotmail.com

Till Oliver Knoll

unread,
Feb 2, 2012, 6:19:57 PM2/2/12
to inte...@qt-project.org

Am 02.02.2012 um 15:49 schrieb Sujan Dasmahapatra <sujan.das...@gmail.com>:

> May Thorson you're right, I'll do a flush on the stream and see. Also I'll follow Andreas suggestion check it by debugging. It should work. Thanks for your valuable suggestions.

No. That cannot possibly work. Even if the file is being polled (that is handled *synchronously* by the Qt event queue) imagine if the poll interval was one minute! Your method would have long returned before (and hence the signal blocker destroyed) before the Qt event queue would be informed either via a QTimer based polling (synchronous) or (asynchronously) via some OS event.

In any case the Qt event queue can only handle such an event *after* your method has returned (and have the QFileWatcher emit its signal): no Qt event interrupts your method execution, so the QFileWatcher would not emit any signals while your method is being executed anyway!

So I cannot imagine how that could have worked with Bo's solution in the first place - unless off course we are talking about multiple threads, but even then chances are that your method (where you try to block the signal from QFileWatcher) would finish *before* the OS gets a chance to notify the application and you would *still* get the signal (at some random time in the future) later on.

So unless you write some application-specific values (an encrypted signature for example which only your process can create, in the extreme case) into the file I don't see how you could detect whether it was your or some other process that modified the file last!

Cheers, Oliver

Scott Aron Bloom

unread,
Feb 2, 2012, 6:23:53 PM2/2/12
to Till Oliver Knoll, inte...@qt-project.org
QFileSystemWatcher DOES operate in a separate thread 100% certainly for
windows, 99% for linux..

Its been a while since I looked at the insides on linux.

Scott

-----Original Message-----
From: interest-bounces+scott.bloom=onshor...@qt-project.org
[mailto:interest-bounces+scott.bloom=onshor...@qt-project.org] On
Behalf Of Till Oliver Knoll
Sent: Thursday, February 02, 2012 3:20 PM
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning

Andreas Pakulat

unread,
Feb 2, 2012, 6:53:37 PM2/2/12
to inte...@qt-project.org
On 02.02.12 15:23:53, Scott Aron Bloom wrote:
> QFileSystemWatcher DOES operate in a separate thread 100% certainly for
> windows, 99% for linux..
>
> Its been a while since I looked at the insides on linux.

All engines run in a separate thread and some of the engines have
multiple threads themselves again (win32 and dnotify) as far as I can
see from a quick grep.

However these threads could be delivering their signals directly
instead of delivering them through the event-queue, so there is actually
a way that the blocker really blocks signals.

But if the used backend is actually not triggered by the OS directly
when a filesystem change happens, i.e. if it takes a few ms for the OS
to notify the watcher (and thats definetly the case for the polling
backend) then signal blocking will not work.

Andreas

Scott Aron Bloom

unread,
Feb 2, 2012, 7:04:13 PM2/2/12
to Andreas Pakulat, inte...@qt-project.org
I have found with windows at least, its instantaneous. Essentially it
sets up a blocking win32 call, that gets release and emits the signal...

But it does take the event loop of the connected slots thread to be
running...

Scott

-----Original Message-----
From: interest-bounces+scott.bloom=onshor...@qt-project.org
[mailto:interest-bounces+scott.bloom=onshor...@qt-project.org] On
Behalf Of Andreas Pakulat
Sent: Thursday, February 02, 2012 3:54 PM
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning

Sujan Dasmahapatra

unread,
Feb 3, 2012, 1:10:10 AM2/3/12
to inte...@qt-project.org
 SignalBlocker blocker(plotgraphsdlg->watcher); //blocking the signal 

 Is the above code is sufficient to block the signal ????

Scott Aron Bloom

unread,
Feb 3, 2012, 11:51:18 AM2/3/12
to inte...@qt-project.org

Yes, no, maybe.  I didn’t write SignalBlocker…

 

As has been stated, keep a MD5 of the file after you write it, and ignore the file change notification if it hasn’t changed..

Till Oliver Knoll

unread,
Feb 4, 2012, 10:40:00 AM2/4/12
to inte...@qt-project.org

Am 03.02.2012 um 01:04 schrieb "Scott Aron Bloom" <Scott...@onshorecs.com>:

> I have found with windows at least, its instantaneous. Essentially it
> sets up a blocking win32 call, that gets release and emits the signal...
>
> But it does take the event loop of the connected slots thread to be
> running...

... and the later is exactly my point: the underlying implementation can be threaded ("asynchronous") or polling - but in the end it goes through the Qt event queue, and if *your* code is not multi-threaded then there is no point in blocking the signals of QFileWatcher, since the signal would get delivered only *after* your method returns to the Qt event queue anyway (and at that point the mentioned instance of the "signal blocker" would have gone, not blocking anything anymore).

But even if the application code itself was multi-threaded there is no *guarantee* when the OS would actually inform your application. "Instantaneously" might not be fast enough: depending on how fast your method is terminating you might indeed successfully block the signal in 99.9% of all cases - making you wonder why in the other 0.1% your code still seems to think that another process had modified the file, when in fact it was *your* process.

And that off course still does not take into account that on some other platforms the underlying implementation might be polling, and that the polling intervall X might just be slightly larger than the time Y it takes your method to execute (and hence the signal blocker would "live"). And again that would leave you wondering "But my code works on Windows (by chance), but not on Foo OS!"


So if your requirement would be: "For the lifetime of that *method* I don't want to get informed when *I* change that file" then the signal blocker approach would work (taking any possible race conditions out of the equation for now).

For all other scenarios one has to apply application-specific measures, such as some MD5 checksum which has been mentioned several times by now (possibly together with some "file-locking mechanisms" which make the story even more interesting when we talk about files located on network-mapped drives - did I hear "cloud services" just now? ;))

Cheers, Oliver

Reply all
Reply to author
Forward
0 new messages