Branch: Tag:

2016-02-15

2016-02-15 14:08:22 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Filesystem.Monitor: Improved thread safety.

ADT.Heap is NOT thread-safe (especially not pop()), so use
a Thread.Mutex to control access to the monitor_queue.

Potential fix for [bug 7644 (#7644)] (where the top element becomes zero
instead of an ADT.Heap()->Element).

203:    if (initial) {    // We need to be polled...    MON_WERR("Registering %O for polling.\n", path); +  mixed key = monitor_mutex->lock();    monitor_queue->push(this);    }    }
217:    // We are going away permanently, so remove ourselves from    // from the monitor_queue.    MON_WERR("Unregistering %O from polling.\n", path); +  mixed key = monitor_mutex->lock();    monitor_queue->remove(this);    }    }
1079:    if (!dying && !(flags & MF_AUTO)) {    // We now need to be polled...    MON_WERR("Registering for polling.\n"); +  mixed key = monitor_mutex->lock();    monitor_queue->push(this); -  +  key = UNDEFINED;    }    }    ::unregister_path(dying);
1129:   //! The heap is sorted on @[Monitor()->next_poll].   protected ADT.Heap monitor_queue = ADT.Heap();    + //! Mutex controlling access to @[monitor_queue]. + protected Thread.Mutex monitor_mutex = Thread.Mutex(); +    //! Create a new monitor.   //!   //! @param max_dir_check_interval
1170:   //! to call this function prior to discarding the object.   void clear()   { +  mixed key = monitor_mutex->lock();    monitors = ([]);    monitor_queue = ADT.Heap();   #if HAVE_EVENTSTREAM
1201:   protected void release_monitor(Monitor m)   {    if (m->accellerated) return; +  mixed key = monitor_mutex->lock();    monitor_queue->remove(m);   }   
1209:   protected void adjust_monitor(Monitor m)   {    if (m->accellerated) return; +  mixed key = monitor_mutex->lock();    monitor_queue->adjust(m);   }   
1563: Inside #if HAVE_EVENTSTREAM and #if 0 /* FIXME: The following does NOT work properly. */
  #if HAVE_EVENTSTREAM   #if 0 /* FIXME: The following does NOT work properly. */    if (eventstream && backend) { +  mixed key = monitor_mutex->lock();    foreach(monitors; string path; Monitor m) {    if (m->accellerated) {    m->accellerated = 0;    monitor_queue->push(m);    }    } -  +  key = UNDEFINED;    }   #endif   #elif HAVE_INOTIFY