func newRWFolder(m *Model, shortID protocol.ShortID, cfg config.FolderConfiguration) *rwFolder { p := &rwFolder{ stateTracker: stateTracker{ folder: cfg.ID, mut: sync.NewMutex(), }, model: m, progressEmitter: m.progressEmitter, virtualMtimeRepo: db.NewVirtualMtimeRepo(m.db, cfg.ID), folder: cfg.ID, dir: cfg.Path(), scanIntv: time.Duration(cfg.RescanIntervalS) * time.Second, ignorePerms: cfg.IgnorePerms, copiers: cfg.Copiers, pullers: cfg.Pullers, shortID: shortID, order: cfg.Order, maxConflicts: cfg.MaxConflicts, allowSparse: !cfg.DisableSparseFiles, checkFreeSpace: cfg.MinDiskFreePct != 0, stop: make(chan struct{}), queue: newJobQueue(), pullTimer: time.NewTimer(time.Second), scanTimer: time.NewTimer(time.Millisecond), // The first scan should be done immediately. delayScan: make(chan time.Duration), scanNow: make(chan rescanRequest), remoteIndex: make(chan struct{}, 1), // This needs to be 1-buffered so that we queue a notification if we're busy doing a pull when it comes. errorsMut: sync.NewMutex(), } if p.copiers == 0 { p.copiers = defaultCopiers } if p.pullers == 0 { p.pullers = defaultPullers } if cfg.PullerPauseS == 0 { p.pause = defaultPullerPause } else { p.pause = time.Duration(cfg.PullerPauseS) * time.Second } if cfg.PullerSleepS == 0 { p.sleep = defaultPullerSleep } else { p.sleep = time.Duration(cfg.PullerSleepS) * time.Second } return p }