pike.git / lib / modules / Filesystem.pmod / Monitor.pmod / basic.pike

version» Context lines:

pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:1:   //   // Basic filesystem monitor.   // - // $Id: basic.pike,v 1.34 2010/02/01 14:36:18 grubba Exp $ + // $Id: basic.pike,v 1.35 2010/02/02 14:34:47 grubba Exp $   //   // 2009-07-09 Henrik Grubbström   //      //! Basic filesystem monitor.   //!   //! This module is intended to be used for incremental scanning of   //! a filesystem.      //! The default maximum number of seconds between checks of directories
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:150:   //! Called by @[check()] and @[check_monitor()].   //!   //! Overload this to do something useful.   void stable_data_change(string path, Stdio.Stat st);      //! Flags for @[Monitor]s.   enum MonitorFlags {    MF_RECURSE = 1,    MF_AUTO = 2,    MF_INITED = 4, +  MF_HARD = 8,   };      protected constant S_IFMT = 0x7ffff000;      //! Monitoring information for a single filesystem path.   //!   //! @seealso   //! @[monitor()]   protected class Monitor(string path,    MonitorFlags flags,
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:330:    // Time until stable.    int d = last_change + (stable_time || global::stable_time) - time(1);    d >>= 1;    if (d < 0) d = 1;    if (d < delta) delta = d;    }    next_poll = time(1) + (delta || 1);    monitor_queue->adjust(this);    }    +  //! Check if this monitor should be removed automatically. +  void check_for_release(int mask, int flags) +  { +  if ((this_program::flags & mask) == flags) { +  m_delete(monitors, path); +  release_monitor(this); +  } +  } +     //! Called when the status has changed for an existing file.    protected int(0..1) status_change(Stdio.Stat old_st, Stdio.Stat st,    int orig_flags)    {    if (st->isdir) {    array(string) files = get_dir(path) || ({});    array(string) new_files = files;    array(string) deleted_files = ({});    if (this_program::files) {    new_files -= this_program::files;
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:354:    file = canonic_path(Stdio.append_path(path, file));    Monitor m2 = monitors[file];    mixed err = catch {    if (m2) {    // We have a separate monitor on the created file.    // Let it handle the notification.    m2->check(flags);    }    };    if (this_program::flags & MF_RECURSE) { -  monitor(file, orig_flags | MF_AUTO, +  monitor(file, orig_flags | MF_AUTO | MF_HARD,    max_dir_check_interval,    file_interval_factor,    stable_time);    monitors[file]->check();    } else if (!m2) {    file_created(file, file_stat(file, 1));    }    }    foreach(deleted_files, string file) {    file = canonic_path(Stdio.append_path(path, file));
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:451:    array(string) files = get_dir(path) || ({});    this_program::files = files;    foreach(files, string file) {    file = canonic_path(Stdio.append_path(path, file));    if (monitors[file]) {    // There's already a monitor for the file.    // Assume it has already notified about existance.    continue;    }    if (this_program::flags & MF_RECURSE) { -  monitor(file, orig_flags | MF_AUTO, +  monitor(file, orig_flags | MF_AUTO | MF_HARD,    max_dir_check_interval,    file_interval_factor,    stable_time);    check_monitor(monitors[file]);    } else {    file_exists(file, file_stat(file, 1));    }    }    }    // Signal file_exists for path as an end marker.
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:497:    monitor_queue->adjust(this);    } else {    if (st) {    // Avoid race when a file has been replaced with a directory    // or vice versa or similar.    st = UNDEFINED;       // We will catch the new file at the next poll.    next_poll = time(1);    monitor_queue->adjust(this); -  } else if (this_program::flags & MF_AUTO) { -  m_delete(monitors, path); -  release_monitor(this); +  } else { +  // The monitor no longer has a link from its parent directory. +  this_program::flags &= ~MF_HARD; +  +  // Check if we should remove the monitor. +  check_for_release(MF_AUTO, MF_AUTO);    }       file_deleted(path, old_st);    return 1;    }    return 0;    }    } else if (st) {    // File created.   
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:523:    array(string) files = get_dir(path) || ({});    this_program::files = files;    foreach(files, string file) {    file = canonic_path(Stdio.append_path(path, file));    if (monitors[file]) {    // There's already a monitor for the file.    // Assume it has already notified about existance.    continue;    }    if (this_program::flags & MF_RECURSE) { -  monitor(file, orig_flags | MF_AUTO, +  monitor(file, orig_flags | MF_AUTO | MF_HARD,    max_dir_check_interval,    file_interval_factor,    stable_time);    check_monitor(monitors[file]);    } else {    file_created(file, file_stat(file, 1));    }    }    }    return 1;
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:728:    if (!(flags & MF_AUTO)) {    // The new monitor is added by hand.    // Adjust the monitor.    m->flags = flags;    m->max_dir_check_interval = max_dir_check_interval;    m->file_interval_factor = file_interval_factor;    m->stable_time = stable_time;    m->next_poll = 0;    monitor_queue->adjust(m);    } +  if (flags & MF_HARD) { +  m->flags |= MF_HARD; +  }    // For the other cases there's no need to do anything,    // since we can keep the monitor as-is.    } else {    m = monitor_factory(path, flags, max_dir_check_interval,    file_interval_factor, stable_time);    monitors[path] = m;    monitor_queue->push(m);    }   }   
pike.git/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike:768:    path = canonic_path(path);    Monitor m = m_delete(monitors, path);    if (m) {    release_monitor(m);    }    if (flags && m->st && m->st->isdir) {    if (!sizeof(path) || path[-1] != '/') {    path += "/";    }    foreach(monitors; string mpath; m) { -  if (has_prefix(mpath, path) && ((m->flags & flags) == flags)) { -  m_delete(monitors, mpath); -  release_monitor(m); +  if (has_prefix(mpath, path)) { +  m->check_for_release(flags, flags);    }    }    }   }      //! Check whether a path is monitored or not.   //!   //! @param path   //! Path to check.   //!