mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-18 01:57:02 +00:00
Add mutex to protect directory operations
This commit is contained in:
@@ -19,11 +19,14 @@ import (
|
|||||||
const indexFileName = "index.gob"
|
const indexFileName = "index.gob"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// indexLock is locked while reading/writing an index file
|
// indexMx is locked while reading/writing an index file
|
||||||
//
|
//
|
||||||
// NOTE: This is a bottleneck because it's a single lock even if we have a
|
// NOTE: This is a bottleneck because it's a single lock even if we have a
|
||||||
// million index files
|
// million index files
|
||||||
indexLock = new(sync.RWMutex)
|
indexMx = new(sync.RWMutex)
|
||||||
|
|
||||||
|
// dirMx is locked while creating/removing directories
|
||||||
|
dirMx = new(sync.Mutex)
|
||||||
|
|
||||||
// countChannel is filled with a sequential numbers (0000..9999), which are
|
// countChannel is filled with a sequential numbers (0000..9999), which are
|
||||||
// used by generateID() to generate unique message IDs. It's global
|
// used by generateID() to generate unique message IDs. It's global
|
||||||
@@ -198,8 +201,8 @@ func (mb *FileMailbox) readIndex() error {
|
|||||||
// Clear message slice, open index
|
// Clear message slice, open index
|
||||||
mb.messages = mb.messages[:0]
|
mb.messages = mb.messages[:0]
|
||||||
// Lock for reading
|
// Lock for reading
|
||||||
indexLock.RLock()
|
indexMx.RLock()
|
||||||
defer indexLock.RUnlock()
|
defer indexMx.RUnlock()
|
||||||
// Check if index exists
|
// Check if index exists
|
||||||
if _, err := os.Stat(mb.indexPath); err != nil {
|
if _, err := os.Stat(mb.indexPath); err != nil {
|
||||||
// Does not exist, but that's not an error in our world
|
// Does not exist, but that's not an error in our world
|
||||||
@@ -238,6 +241,8 @@ func (mb *FileMailbox) readIndex() error {
|
|||||||
|
|
||||||
// createDir checks for the presence of the path for this mailbox, creates it if needed
|
// createDir checks for the presence of the path for this mailbox, creates it if needed
|
||||||
func (mb *FileMailbox) createDir() error {
|
func (mb *FileMailbox) createDir() error {
|
||||||
|
dirMx.Lock()
|
||||||
|
defer dirMx.Unlock()
|
||||||
if _, err := os.Stat(mb.path); err != nil {
|
if _, err := os.Stat(mb.path); err != nil {
|
||||||
if err := os.MkdirAll(mb.path, 0770); err != nil {
|
if err := os.MkdirAll(mb.path, 0770); err != nil {
|
||||||
log.Errorf("Failed to create directory %v, %v", mb.path, err)
|
log.Errorf("Failed to create directory %v, %v", mb.path, err)
|
||||||
@@ -250,8 +255,8 @@ func (mb *FileMailbox) createDir() error {
|
|||||||
// writeIndex overwrites the index on disk with the current mailbox data
|
// writeIndex overwrites the index on disk with the current mailbox data
|
||||||
func (mb *FileMailbox) writeIndex() error {
|
func (mb *FileMailbox) writeIndex() error {
|
||||||
// Lock for writing
|
// Lock for writing
|
||||||
indexLock.Lock()
|
indexMx.Lock()
|
||||||
defer indexLock.Unlock()
|
defer indexMx.Unlock()
|
||||||
if len(mb.messages) > 0 {
|
if len(mb.messages) > 0 {
|
||||||
// Ensure mailbox directory exists
|
// Ensure mailbox directory exists
|
||||||
if err := mb.createDir(); err != nil {
|
if err := mb.createDir(); err != nil {
|
||||||
@@ -283,6 +288,9 @@ func (mb *FileMailbox) writeIndex() error {
|
|||||||
} else {
|
} else {
|
||||||
// No messages, delete index+maildir
|
// No messages, delete index+maildir
|
||||||
log.Tracef("Removing mailbox %v", mb.path)
|
log.Tracef("Removing mailbox %v", mb.path)
|
||||||
|
// deletes are dangerous, requires write lock
|
||||||
|
dirMx.Lock()
|
||||||
|
defer dirMx.Unlock()
|
||||||
return os.RemoveAll(mb.path)
|
return os.RemoveAll(mb.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user