<commit_before>var log = require('./log')
  , fs = require('fs')

module.exports = function(cb) {
  var watchers = {}
    , polling = process.platform == 'win32'
    , called = false

  function close() {
    for (var file in watchers) watchers[file].close()
    watchers = {}
  }

  function changed(file) {
    if (!called) {
      called = true
      cb.call({ close: close }, file)
    }
  }

  return function watch(file) {

    if (file in watchers || !fs.existsSync(file)) return

    var mtime = fs.statSync(file).mtime

    function check() {
      fs.stat(file, function(err, stat) {
        if (err || stat.mtime > mtime) changed(null, file)
      })
    }

    if (polling) {
      fs.watchFile(file, { interval: 1000 }, check)
      watchers[file] = { close: function() { fs.unwatchFile(file) }}
      return
    }

    try {
      watchers[file] = fs.watch(file, check)
    }
    catch (err) {
      if (err.code == 'EMFILE') {
        polling = true
        var watched = Object.keys(watchers)
        close()
        log.warn('node-dev ran out of file handles after watching ' + watched.length +  ' files.')
        log.warn('Falling back to polling which uses more CPU.')
        log.info('Run ulimit -n 10000 to increase the limit of open file descriptors.')
        watched.forEach(watch)
      }
      else log.warn(err)
    }
  }<commit_msg>call back only if file is still watched<commit_after>var log = require('./log')
  , fs = require('fs')

module.exports = function(cb) {
  var watchers = {}
    , polling = process.platform == 'win32'

  function close() {
    for (var file in watchers) watchers[file].close()
    watchers = {}
  }

  function changed(file) {
    if (file in watchers) cb.call({ close: close }, file)
  }

  return function watch(file) {

    if (file in watchers || !fs.existsSync(file)) return

    var mtime = fs.statSync(file).mtime

    function check() {
      fs.stat(file, function(err, stat) {
        if (err || stat.mtime > mtime) changed(file)
      })
    }

    if (polling) {
      fs.watchFile(file, { interval: 1000 }, check)
      watchers[file] = { close: function() { fs.unwatchFile(file) }}
      return
    }

    try {
      watchers[file] = fs.watch(file, check)
    }
    catch (err) {
      if (err.code == 'EMFILE') {
        polling = true
        var watched = Object.keys(watchers)
        close()
        log.warn('node-dev ran out of file handles after watching ' + watched.length +  ' files.')
        log.warn('Falling back to polling which uses more CPU.')
        log.info('Run ulimit -n 10000 to increase the limit of open file descriptors.')
        watched.forEach(watch)
      }
      else log.warn(err)
    }
  }
{'fraction_non_alphanumeric': 0.13676797627872497, 'fraction_numerical': 0.00815418828762046, 'mean_word_length': 2.332098765432099, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7410864', 'n_tokens_mistral': 894, 'n_tokens_neox': 852, 'n_words': 234}