예제 #1
0
    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)
예제 #2
0
 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)
예제 #3
0
    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()