Switch to unified view

a/src/index/rclmonrcv.cpp b/src/index/rclmonrcv.cpp
1
#include "autoconfig.h"
1
#include "autoconfig.h"
2
#ifdef RCL_MONITOR
2
#ifdef RCL_MONITOR
3
#ifndef lint
3
#ifndef lint
4
static char rcsid[] = "@(#$Id: rclmonrcv.cpp,v 1.6 2006-10-24 09:09:36 dockes Exp $ (C) 2006 J.F.Dockes";
4
static char rcsid[] = "@(#$Id: rclmonrcv.cpp,v 1.7 2006-10-25 10:52:02 dockes Exp $ (C) 2006 J.F.Dockes";
5
#endif
5
#endif
6
/*
6
/*
7
 *   This program is free software; you can redistribute it and/or modify
7
 *   This program is free software; you can redistribute it and/or modify
8
 *   it under the terms of the GNU General Public License as published by
8
 *   it under the terms of the GNU General Public License as published by
9
 *   the Free Software Foundation; either version 2 of the License, or
9
 *   the Free Software Foundation; either version 2 of the License, or
...
...
66
    virtual FsTreeWalker::Status 
66
    virtual FsTreeWalker::Status 
67
    processone(const string &fn, const struct stat *st, FsTreeWalker::CbFlag flg)
67
    processone(const string &fn, const struct stat *st, FsTreeWalker::CbFlag flg)
68
    {
68
    {
69
    LOGDEB2(("rclMonRcvRun: processone %s m_mon %p m_mon->ok %d\n", 
69
    LOGDEB2(("rclMonRcvRun: processone %s m_mon %p m_mon->ok %d\n", 
70
         fn.c_str(), m_mon, m_mon?m_mon->ok():0));
70
         fn.c_str(), m_mon, m_mon?m_mon->ok():0));
71
  // Create watch when entering directory
71
72
    if (flg == FsTreeWalker::FtwDirEnter) {
72
    if (flg == FsTreeWalker::FtwDirEnter) {
73
      // Create watch when entering directory, but first empty
73
        // Empty whatever events we may already have on queue
74
        // whatever events we may already have on queue
74
        while (m_queue->ok() && m_mon->ok()) {
75
        while (m_queue->ok() && m_mon->ok()) {
75
        RclMonEvent ev;
76
        RclMonEvent ev;
76
        if (m_mon->getEvent(ev, 0)) {
77
        if (m_mon->getEvent(ev, 0)) {
78
          if (ev.m_etyp !=  RclMonEvent::RCLEVT_NONE)
77
            m_queue->pushEvent(ev);
79
          m_queue->pushEvent(ev);
78
        } else {
80
        } else {
81
          LOGDEB(("rclMonRcvRun: no event pending\n"));
79
            break;
82
            break;
80
        }
83
        }
81
        }
84
        }
82
        if (!m_mon || !m_mon->ok() || !m_mon->addWatch(fn, true))
85
        if (!m_mon || !m_mon->ok() || !m_mon->addWatch(fn, true))
83
        return FsTreeWalker::FtwError;
86
        return FsTreeWalker::FtwError;
...
...
133
    LOGDEB(("rclMonRcvRun: walking %s\n", it->c_str()));
136
    LOGDEB(("rclMonRcvRun: walking %s\n", it->c_str()));
134
    walker.walk(*it, walkcb);
137
    walker.walk(*it, walkcb);
135
    }
138
    }
136
139
137
    // Forever wait for monitoring events and add them to queue:
140
    // Forever wait for monitoring events and add them to queue:
138
    LOGDEB2(("rclMonRcvRun: waiting for events. queue->ok() %d\n", queue->ok()));
141
    LOGDEB2(("rclMonRcvRun: waiting for events. q->ok() %d\n", queue->ok()));
139
    while (queue->ok() && mon->ok()) {
142
    while (queue->ok() && mon->ok()) {
140
    RclMonEvent ev;
143
    RclMonEvent ev;
141
    // Note: under Linux, I could find no way to get the select
144
    // Note: I could find no way to get the select
142
    // call to return when a signal is delivered to the process
145
    // call to return when a signal is delivered to the process
143
    // (it goes to the main thread, from which I tried to close or
146
    // (it goes to the main thread, from which I tried to close or
144
    // write to the select fd, with no effect. So set a 
147
    // write to the select fd, with no effect). So set a 
145
    // timeout so that an intr will be detected
148
    // timeout so that an intr will be detected
146
    if (mon->getEvent(ev, 
149
    if (mon->getEvent(ev, 2)) {
147
#ifdef linux
148
            2
149
#else
150
            -1
151
#endif
152
            )) {
153
        if (ev.m_etyp == RclMonEvent::RCLEVT_DIRCREATE) {
150
        if (ev.m_etyp == RclMonEvent::RCLEVT_DIRCREATE) {
154
        mon->addWatch(ev.m_path, true);
151
        mon->addWatch(ev.m_path, true);
155
        }
152
        }
153
      if (ev.m_etyp !=  RclMonEvent::RCLEVT_NONE)
156
        queue->pushEvent(ev);
154
      queue->pushEvent(ev);
157
    }
155
    }
158
    }
156
    }
159
157
160
    LOGDEB(("rclMonRcvRun: exiting\n"));
158
    LOGINFO(("rclMonRcvRun: exiting\n"));
161
    queue->setTerminate();
159
    queue->setTerminate();
162
    return 0;
160
    return 0;
163
}
161
}
164
162
165
#ifdef RCL_USE_FAM
163
#ifdef RCL_USE_FAM
...
...
250
    }
248
    }
251
    m_reqtopath[req.reqnum] = path;
249
    m_reqtopath[req.reqnum] = path;
252
    return true;
250
    return true;
253
}
251
}
254
252
253
// Note: return false only for queue empty or error 
254
// Return EVT_NONE for bad event to keep queue processing going
255
bool RclFAM::getEvent(RclMonEvent& ev, int secs)
255
bool RclFAM::getEvent(RclMonEvent& ev, int secs)
256
{
256
{
257
    if (!ok())
257
    if (!ok())
258
    return false;
258
    return false;
259
    LOGDEB2(("RclFAM::getEvent:\n"));
259
    LOGDEB2(("RclFAM::getEvent:\n"));
...
...
261
    fd_set readfds;
261
    fd_set readfds;
262
    int fam_fd = FAMCONNECTION_GETFD(&m_conn);
262
    int fam_fd = FAMCONNECTION_GETFD(&m_conn);
263
    FD_ZERO(&readfds);
263
    FD_ZERO(&readfds);
264
    FD_SET(fam_fd, &readfds);
264
    FD_SET(fam_fd, &readfds);
265
265
266
    LOGDEB2(("RclFAM::getEvent: select\n"));
266
    LOGDEB(("RclFAM::getEvent: select\n"));
267
    struct timeval timeout;
267
    struct timeval timeout;
268
    if (secs >= 0) {
268
    if (secs >= 0) {
269
    memset(&timeout, 0, sizeof(timeout));
269
    memset(&timeout, 0, sizeof(timeout));
270
    timeout.tv_sec = secs;
270
    timeout.tv_sec = secs;
271
    }
271
    }
272
    int ret;
272
    int ret;
273
    if ((ret=select(fam_fd + 1, &readfds, 0, 0, secs >= 0 ? &timeout : 0)) < 0) {
273
    if ((ret=select(fam_fd+1, &readfds, 0, 0, secs >= 0 ? &timeout : 0)) < 0) {
274
    LOGERR(("RclFAM::getEvent: select failed, errno %d\n", errno));
274
    LOGERR(("RclFAM::getEvent: select failed, errno %d\n", errno));
275
    close();
275
    close();
276
    return false;
276
    return false;
277
    } else if (ret == 0) {
277
    } else if (ret == 0) {
278
    // timeout
278
    // timeout
279
  LOGDEB(("RclFAM::getEvent: select timeout\n"));
279
    return false;
280
    return false;
280
    }
281
    }
282
283
    LOGDEB(("RclFAM::getEvent: select return\n"));
281
284
282
    if (!FD_ISSET(fam_fd, &readfds))
285
    if (!FD_ISSET(fam_fd, &readfds))
283
    return false;
286
    return false;
284
287
288
    LOGDEB(("RclFAM::getEvent: call FAMNextEvent\n"));
285
    FAMEvent fe;
289
    FAMEvent fe;
286
    if (FAMNextEvent(&m_conn, &fe) < 0) {
290
    if (FAMNextEvent(&m_conn, &fe) < 0) {
287
    LOGERR(("RclFAM::getEvent: FAMNextEvent failed, errno %d\n", errno));
291
    LOGERR(("RclFAM::getEvent: FAMNextEvent failed, errno %d\n", errno));
288
    close();
292
    close();
289
    return false;
293
    return false;
290
    }
294
    }
295
    LOGDEB(("RclFAM::getEvent: FAMNextEvent returned\n"));
291
    
296
    
292
    map<int,string>::const_iterator it;
297
    map<int,string>::const_iterator it;
293
    if ((fe.filename[0] != '/') && 
298
    if ((fe.filename[0] != '/') && 
294
    (it = m_reqtopath.find(fe.fr.reqnum)) != m_reqtopath.end()) {
299
    (it = m_reqtopath.find(fe.fr.reqnum)) != m_reqtopath.end()) {
295
    ev.m_path = path_cat(it->second, fe.filename);
300
    ev.m_path = path_cat(it->second, fe.filename);
...
...
324
    case FAMStartExecuting:
329
    case FAMStartExecuting:
325
    case FAMStopExecuting:
330
    case FAMStopExecuting:
326
    case FAMAcknowledge:
331
    case FAMAcknowledge:
327
    case FAMEndExist:
332
    case FAMEndExist:
328
    default:
333
    default:
329
  return false;
334
  // Have to return something, this is different from an empty queue,
335
  // esp if we are trying to empty it...
336
  LOGDEB(("RclFAM::getEvent: got move event !\n"));
337
  ev.m_etyp = RclMonEvent::RCLEVT_NONE;
338
  break;
330
    }
339
    }
331
    return true;
340
    return true;
332
}
341
}
333
#endif // RCL_USE_FAM
342
#endif // RCL_USE_FAM
334
343
...
...
430
    }
439
    }
431
    m_wdtopath[wd] = path;
440
    m_wdtopath[wd] = path;
432
    return true;
441
    return true;
433
}
442
}
434
443
444
// Note: return false only for queue empty or error 
445
// Return EVT_NONE for bad event to keep queue processing going
435
bool RclIntf::getEvent(RclMonEvent& ev, int secs)
446
bool RclIntf::getEvent(RclMonEvent& ev, int secs)
436
{
447
{
437
    if (!ok())
448
    if (!ok())
438
    return false;
449
    return false;
450
    ev.m_etyp = RclMonEvent::RCLEVT_NONE;
439
    LOGDEB2(("RclIntf::getEvent:\n"));
451
    LOGDEB2(("RclIntf::getEvent:\n"));
440
452
441
    if (m_evp == 0) {
453
    if (m_evp == 0) {
442
    fd_set readfds;
454
    fd_set readfds;
443
    FD_ZERO(&readfds);
455
    FD_ZERO(&readfds);
...
...
481
    m_evp = m_ep = 0;
493
    m_evp = m_ep = 0;
482
    
494
    
483
    map<int,string>::const_iterator it;
495
    map<int,string>::const_iterator it;
484
    if ((it = m_wdtopath.find(evp->wd)) == m_wdtopath.end()) {
496
    if ((it = m_wdtopath.find(evp->wd)) == m_wdtopath.end()) {
485
    LOGERR(("RclIntf::getEvent: unknown wd\n"));
497
    LOGERR(("RclIntf::getEvent: unknown wd\n"));
486
    return false;
498
    return true;
487
    }
499
    }
488
    ev.m_path = it->second;
500
    ev.m_path = it->second;
489
501
490
    if (evp->len > 0) {
502
    if (evp->len > 0) {
491
    ev.m_path = path_cat(ev.m_path, evp->name);
503
    ev.m_path = path_cat(ev.m_path, evp->name);
...
...
500
    ev.m_etyp = RclMonEvent::RCLEVT_DELETE;
512
    ev.m_etyp = RclMonEvent::RCLEVT_DELETE;
501
    } else if (evp->mask & (IN_CREATE)) {
513
    } else if (evp->mask & (IN_CREATE)) {
502
    if (path_isdir(ev.m_path)) {
514
    if (path_isdir(ev.m_path)) {
503
        ev.m_etyp = RclMonEvent::RCLEVT_DIRCREATE;
515
        ev.m_etyp = RclMonEvent::RCLEVT_DIRCREATE;
504
    } else {
516
    } else {
505
      // Will get modify event
517
      // Return null event. Will get modify event later
506
        return false;
518
        return true;
507
    }
519
    }
508
    } else {
520
    } else {
509
    LOGDEB(("RclIntf::getEvent: unhandled event %s 0x%x %s\n", 
521
    LOGDEB(("RclIntf::getEvent: unhandled event %s 0x%x %s\n", 
510
        event_name(evp->mask), evp->mask, ev.m_path.c_str()));
522
        event_name(evp->mask), evp->mask, ev.m_path.c_str()));
511
    return false;
523
    return true;
512
    }
524
    }
513
    return true;
525
    return true;
514
}
526
}
515
527
516
#endif // RCL_USE_INOTIFY
528
#endif // RCL_USE_INOTIFY