Fix race when opening DB for first time (#1691)

This commit is contained in:
Dominic Wong 2020-06-08 16:19:22 +01:00 committed by GitHub
parent 47bdd5c993
commit a346064eaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -105,7 +105,6 @@ func (f *fileStore) getDB(database, table string) (*fileHandle, error) {
} }
k := key(database, table) k := key(database, table)
f.RLock() f.RLock()
fd, ok := f.handles[k] fd, ok := f.handles[k]
f.RUnlock() f.RUnlock()
@ -115,6 +114,13 @@ func (f *fileStore) getDB(database, table string) (*fileHandle, error) {
return fd, nil return fd, nil
} }
// double check locking
f.Lock()
defer f.Unlock()
if fd, ok := f.handles[k]; ok {
return fd, nil
}
// create a directory /tmp/micro // create a directory /tmp/micro
dir := filepath.Join(DefaultDir, database) dir := filepath.Join(DefaultDir, database)
// create the database handle // create the database handle
@ -125,18 +131,16 @@ func (f *fileStore) getDB(database, table string) (*fileHandle, error) {
dbPath := filepath.Join(dir, fname) dbPath := filepath.Join(dir, fname)
// create new db handle // create new db handle
// Bolt DB only allows one process to open the file R/W so make sure we're doing this under a lock
db, err := bolt.Open(dbPath, 0700, &bolt.Options{Timeout: 5 * time.Second}) db, err := bolt.Open(dbPath, 0700, &bolt.Options{Timeout: 5 * time.Second})
if err != nil { if err != nil {
return nil, err return nil, err
} }
f.Lock()
fd = &fileHandle{ fd = &fileHandle{
key: k, key: k,
db: db, db: db,
} }
f.handles[k] = fd f.handles[k] = fd
f.Unlock()
return fd, nil return fd, nil
} }