emcrisostomo / fswatch

A cross-platform file change monitor with multiple backends: Apple OS X File System Events, *BSD kqueue, Solaris/Illumos File Events Notification, Linux inotify, Microsoft Windows and a stat()-based backend.
https://emcrisostomo.github.io/fswatch/
GNU General Public License v3.0
5.02k stars 327 forks source link

100% CPU usage while using libfswatch #67

Closed vnd closed 9 years ago

vnd commented 9 years ago

Here's a simple program that uses up 100% of CPU on my machine:

#include <stdio.h>
#include "libfswatch.h"

static void fsw_callback(fsw_cevent const * const events, const unsigned int event_num)
{
     printf("%s\n", __func__);
}

int main(void)
{
    FSW_HANDLE handle;

    fsw_init_library();

    handle = fsw_init_session();
    if (handle == FSW_INVALID_HANDLE)
        return -1;

    if (fsw_add_path(handle, "/tmp") != FSW_OK)
        return -1;

    if (fsw_set_callback(handle, fsw_callback) != FSW_OK)
        return -1;

    if (fsw_set_recursive(handle, true) != FSW_OK)
        return -1;

    if (fsw_start_monitor(handle) != FSW_OK)
        return -1;
}

I compiled latest fswatch and took libfswatch.so, libfswatch.h and dependent header file (cevent.h cfilter.h cmonitor.h error.h libfswatch_log.h) from there in order to compile the program above.

Some notes: 1) Callback is called infrequently (2-3 times per second), as supposed to be. 2) If a call to fsw_set_callback is removed CPU usage becomes neglibible.

Thanks for any help.

vnd commented 9 years ago

Also, here's a top of perf output:

18.54%    a.out  [kernel.kallsyms]    [k] memset                                                                                                                             
11.49%    a.out  [kernel.kallsyms]    [k] do_select                                                                                                                          
 9.12%    a.out  [kernel.kallsyms]    [k] copy_user_enhanced_fast_string                                                                                                     
 7.96%    a.out  [kernel.kallsyms]    [k] core_sys_select                                                                                                                    
 6.64%    a.out  libfswatch.so        [.] std::_Hashtable<std::string, std::pair<std::string const, int>, std::allocator<std::pair<std::string const, int> >, std::__detail::
 5.33%    a.out  libfswatch.so        [.] fsw::inotify_monitor::is_watched(std::string const&)                                                                               
 5.27%    a.out  libfswatch.so        [.] fsw::inotify_monitor::run()                                                                                                        
emcrisostomo commented 9 years ago

Hi @vnd,

It appears there's a bug in the inotify monitor that keeps it spinning. I'll have a look at it ASAP.

emcrisostomo commented 9 years ago

I found a bug which explains what happens in your case and fixed it in fswatch 1.4.5.3. Please, download the source distribution, build it and compile against it.

I'm closing this issue. If you still experience any issues, please reopen it.

vnd commented 9 years ago

Issue does not reproduce, thank you.

emcrisostomo commented 9 years ago

You're welcome, thanks for reporting it.

vnd commented 9 years ago

Sorry for false positive: it turns out that my application didn't show up in top not b/c previous commit fixed the issue but b/c it simply crashed. Please take a look at the pull request instead.

emcrisostomo commented 9 years ago

Thanks.

Yes, you're right: that field is not correctly initialised in all code paths.

I won't merge the pull request, though, because you reverted the previous change which was necessary: it simply affects the C++ binding, and affects the C binding too because the latter is just a wrapper around the former.

I will reapply that change in develop.

Thanks!