Ejemplo n.º 1
0
func (w *Watcher) watchPath(path string, options *Options) error {
	path, _ = filepath.Abs(path)

	w.wmut.Lock()
	_, found := w.watches[path]
	w.wmut.Unlock()

	if !found {
		cPaths := C.ArrayCreateMutable(C.int(1))
		defer C.CFRelease(C.CFTypeRef(cPaths))

		cpath := C.CString(path)
		defer C.free(unsafe.Pointer(cpath))

		str := C.CFStringCreateWithCString(nil, cpath, C.kCFStringEncodingUTF8)
		C.CFArrayAppendValue(cPaths, unsafe.Pointer(str))

		context := C.FSEventStreamContext{info: unsafe.Pointer(&w.internalEvent)}
		latency := C.CFTimeInterval(0)
		if options != nil && options.Throttle {
			latency = C.CFTimeInterval(options.ThrottleDuration / time.Second)
		}
		stream := C.EventStreamCreate(&context, cPaths, C.kFSEventStreamEventIdSinceNow+(1<<64), latency)
		w.wmut.Lock()
		w.watches[path] = stream
		w.wmut.Unlock()
		C.FSEventStreamScheduleWithRunLoop(stream, w.rlref, C.kCFRunLoopDefaultMode)
		C.FSEventStreamStart(stream)
	}

	return nil
}
Ejemplo n.º 2
0
func startScanner(dir string) {
	lock.Lock()
	chans[dir] = make(chan string)
	lock.Unlock()

	cpaths := C.fswatch_make_mutable_array()
	defer C.free(unsafe.Pointer(cpaths))

	path := C.CString(dir)
	str := C.CFStringCreateWithCString(nil, path, C.kCFStringEncodingUTF8)
	defer C.free(unsafe.Pointer(path))
	defer C.free(unsafe.Pointer(str))

	C.CFArrayAppendValue(cpaths, unsafe.Pointer(str))

	ctx := C.FSEventStreamContext{info: unsafe.Pointer(C.CString(dir))}

	stream := C.fswatch_create(&ctx, cpaths, now, C.CFTimeInterval(interval/time.Second), cflags)

	go func() {
		C.FSEventStreamScheduleWithRunLoop(stream, C.CFRunLoopGetCurrent(), C.kCFRunLoopCommonModes)
		C.FSEventStreamStart(stream)
		C.CFRunLoopRun()
	}()
}
Ejemplo n.º 3
0
func New(dev Device, since EventID, interval time.Duration, flags CreateFlags,
	paths ...string) *Stream {

	cpaths := C.fswatch_make_mutable_array()
	defer C.free(unsafe.Pointer(cpaths))
	for _, dir := range paths {
		path := C.CString(dir)
		defer C.free(unsafe.Pointer(path))
		str := C.CFStringCreateWithCString(nil, path, C.kCFStringEncodingUTF8)
		defer C.free(unsafe.Pointer(str))
		C.CFArrayAppendValue(cpaths, unsafe.Pointer(str))
	}

	csince := C.FSEventStreamEventId(since)
	cinterval := C.CFTimeInterval(interval / time.Second)
	cflags := C.FSEventStreamCreateFlags(flags &^ CF_USECFTYPES)

	s := new(Stream)
	s.Chan = make(chan []Event)

	ctx := C.FSEventStreamContext{info: unsafe.Pointer(&s.Chan)}

	var cstream C.FSEventStreamRef
	if dev == 0 {
		cstream = C.fswatch_create(&ctx, cpaths, csince, cinterval, cflags)
	} else {
		cdev := C.dev_t(dev)
		cstream = C.fswatch_create_relative_to_device(
			cdev, &ctx, cpaths, csince, cinterval, cflags)
	}
	s.cstream = cstream

	return s
}
Ejemplo n.º 4
0
// Start listening to an event stream.
func (es *EventStream) Start() {
	cPaths := C.ArrayCreateMutable(C.int(len(es.Paths)))
	defer C.CFRelease(C.CFTypeRef(cPaths))

	for _, p := range es.Paths {
		p, _ = filepath.Abs(p)
		cpath := C.CString(p)
		defer C.free(unsafe.Pointer(cpath))

		str := C.CFStringCreateWithCString(nil, cpath, C.kCFStringEncodingUTF8)
		C.CFArrayAppendValue(cPaths, unsafe.Pointer(str))
	}

	since := C.FSEventStreamEventId(EventIDSinceNow)
	if es.Resume {
		since = C.FSEventStreamEventId(es.EventID)
	}

	if es.Events == nil {
		es.Events = make(chan []Event)
	}

	es.registryID = registry.Add(es)
	context := C.FSEventStreamContext{}
	info := C.uintptr_t(es.registryID)
	latency := C.CFTimeInterval(float64(es.Latency) / float64(time.Second))
	if es.Device != 0 {
		es.stream = C.EventStreamCreateRelativeToDevice(&context, info, C.dev_t(es.Device), cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags))
	} else {
		es.stream = C.EventStreamCreate(&context, info, cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags))
	}

	started := make(chan struct{})

	go func() {
		runtime.LockOSThread()
		es.rlref = C.CFRunLoopGetCurrent()
		C.FSEventStreamScheduleWithRunLoop(es.stream, es.rlref, C.kCFRunLoopDefaultMode)
		C.FSEventStreamStart(es.stream)
		close(started)
		C.CFRunLoopRun()
	}()

	if !es.hasFinalizer {
		runtime.SetFinalizer(es, finalizer)
		es.hasFinalizer = true
	}

	<-started
}