Cluster *arvados.Cluster
setupOnce sync.Once
- lockMtx sync.Mutex
- lock map[string]*sync.RWMutex
+ lockMtx sync.Mutex
+ lock map[string]*sync.RWMutex
+ lockTidied time.Time
}
var urlPDHDecoder = strings.NewReplacer(" ", "+", "-", "+")
// collection id is outside scope of supplied
// token
tokenScopeProblem = true
+ sess.Release()
continue
} else if os.IsNotExist(err) {
// collection does not exist or is not
// readable using this token
+ sess.Release()
continue
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
+ sess.Release()
return
}
defer f.Close()
+ defer sess.Release()
collectionDir, sessionFS, session, tokenUser = f, fs, sess, user
break
func (h *handler) collectionLock(collectionID string, writing bool) sync.Locker {
h.lockMtx.Lock()
defer h.lockMtx.Unlock()
+ if time.Since(h.lockTidied) > lockTidyInterval {
+ // Periodically delete all locks that aren't in use.
+ h.lockTidied = time.Now()
+ for id, locker := range h.lock {
+ if locker.TryLock() {
+ locker.Unlock()
+ delete(h.lock, id)
+ }
+ }
+ }
locker := h.lock[collectionID]
if locker == nil {
locker = new(sync.RWMutex)