def __process_queues(self, timer, context): # Die when asked to. self.lock.acquire() if self.die: CFRunLoopStop(CFRunLoopGetCurrent()) self.lock.release() # Process add queue. self.lock.acquire() if not self.add_queue.empty(): (path, event_mask) = self.add_queue.get() self.lock.release() self.__add_dir(path, event_mask) else: self.lock.release() # Process remove queue. self.lock.acquire() if not self.remove_queue.empty(): path = self.add_queue.get() self.lock.release() self.__remove_dir(path) else: self.lock.release() # Ensure all monitored paths are actually being monitored. If they're # not yet being monitored, start doing so. for path in self.monitored_paths.keys(): if self.monitored_paths[path].monitoring: continue streamRef = self.monitored_paths[path].fsmonitor_ref # Schedule stream on a loop. FSEventStreamScheduleWithRunLoop(streamRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode) # Register with the FS Events service to receive events. started = FSEventStreamStart(streamRef) if not started: raise CouldNotStartError else: self.monitored_paths[path].monitoring = True # Generate the missed events. # TODO: use FSEvents' sinceWhen parameter instead of the current # inefficient scanning method. if self.persistent: FSMonitor.generate_missed_events(self, path)
def run(self): pool = AppKit.NSAutoreleasePool.alloc().init() self._run_loop = CFRunLoopGetCurrent() FSEventStreamScheduleWithRunLoop(self._stream_ref, self._run_loop, kCFRunLoopDefaultMode) if not FSEventStreamStart(self._stream_ref): FSEventStreamInvalidate(self._stream_ref) FSEventStreamRelease(self._stream_ref) raise IOError('FSEvents. Could not start stream.') CFRunLoopRun() FSEventStreamStop(self._stream_ref) FSEventStreamInvalidate(self._stream_ref) FSEventStreamRelease(self._stream_ref) del pool self._queue.put(None)
def run(self): # Necessary because we're using PyObjC in a thread other than the main # thread. self.auto_release_pool = NSAutoreleasePool.alloc().init() # Setup. Ensure that this isn't interleaved with any other thread, so # that the DB setup continues as expected. self.lock.acquire() FSMonitor.setup(self) self.lock.release() # Set up a callback to a function that process the queues frequently. CFRunLoopAddTimer( CFRunLoopGetCurrent(), CFRunLoopTimerCreate(None, CFAbsoluteTimeGetCurrent(), 0.5, 0, 0, self.__process_queues, None), kCFRunLoopDefaultMode) # Start the run loop. CFRunLoopRun()