Inotify опроса с несколькими потоками - PullRequest
0 голосов
/ 18 октября 2019

ALL,

Было предложено открыть новую ветку с моим кодом. Я постараюсь опубликовать больше кода с некоторыми объяснениями.

В основном то, что я делаю, это:

MyObject::MyObject()
{
    m_fd = inotify_init1( IN_NONBLOCK );
    if( m_fd == -1 )
    {
        syslog( LOG_ERR, "Failed to initialize inotify" );
        m_isOK = false;
    }
}

int MyObject::ProcessFile1()
{
int result = 0;
bool fileCreated = false;
std::string error;
struct pollfd fds;
int poll_num;
nfds_t nfds;
fds.fd = m_fd;
fds.events = POLLIN;
nfds = 1;
char buf[4096] __attribute__( ( aligned( __alignof__( struct inotify_event ) ) ) );
ssize_t len;
const struct inotify_event *event;
char *ptr;
std::string logName = "/tmp/scan_results";

m_wd1 = inotify_add_watch( m_fd, "/tmp", IN_CREATE );
if( m_wd1 == -1 )
{
}
else
{
    while( true )
    {
        error = "Successfully started watching for a file creation";
        syslog( LOG_DEBUG, error.c_str() );
        poll_num = poll( &fds, nfds, -1 );
        if( poll_num == -1 )
        {
            if( errno == EINTR )
                continue;
            result = 1;
        }
        else if( poll_num > 0 && ( fds.revents & POLLIN ) )
        {
            for( ;; )
            {
                len = read( m_fd, buf, sizeof( buf ) );
                if( len == -1 && errno != EAGAIN )
                {
                    result = 1;
                    break;
                }
                for( ptr = buf; ptr < buf + len; ptr += sizeof( struct inotify_event ) + event->len )
                {
                    event = (const struct inotify_event *) ptr;
                    if( event->mask & IN_CREATE )
                    {
                        std::string name( event->name );
                        if( name == "scan_results" )
                        {
                            fileCreated = true;
                            break;
                        }
                    }
                }
                if( fileCreated || result )
                    break;
            }
        }
        if( fileCreated )
        {
            std::ifstream logfile( logName );
            if( ( logfile.rdstate() & std::ifstream::failbit ) != 0 )
            {
                result = 1;
            }
            else
            {
                // Process the file
                logfile.close();
                if( remove( logName.c_str() ) != 0 )
                {
                }
                else
                {
                }
                SendNotification();
                fileCreated = false;
            }
        }
    }
}
return result;
}

int main()
{
    MyObject obj;
    std::thread thread1( &MyObject::ProcessFile1, &obj );
    std::thread thread2( &MyObject::ProcessFile2, &obj );
}

Так что моя проблема в том, что после того, как я позвоню remove(), я неполучить уведомление о создании файла scan_results в каталоге /tmp. Поэтому цикл while успешно выполняется только один раз. Я вижу вторую итерацию сообщения журнала, но ничего после этого.

Имейте в виду, что я смотрю каталог для создания файла, а затем удаляю файл (а не каталог, за которым следят).

Функция ProcessFile2 () точно такая же, как ProcessFile1 - она ​​просто отслеживает другое имя файла внутри /tmp. Вы можете просто скопировать и вставить его.

Таким образом, код выше и проблема в том, что нет второго уведомления для создания файла scan_results в /tmp.

Я надеюсь, что этоприемлемо

...