Skip to content

Race condition with SQLite3Store.startCleanup #228

@earthboundkid

Description

@earthboundkid

My tests hit a race. IIUC, the cause of the race is that there is a bug in SQLite3Store.

func NewWithCleanupInterval(db *sql.DB, cleanupInterval time.Duration) *SQLite3Store {
	p := &SQLite3Store{db: db}
	if cleanupInterval > 0 {
		go p.startCleanup(cleanupInterval)
	}
	return p
}

Notice p.startCleanup(cleanupInterval) is called with go.

func (p *SQLite3Store) startCleanup(interval time.Duration) {
	p.stopCleanup = make(chan bool)
	...

Observe that p.stopCleanup is written to inside that goroutine, without any lock on p.

Finally

func (p *SQLite3Store) StopCleanup() {
	if p.stopCleanup != nil {
		p.stopCleanup <- true
	}
}

The line p.stopCleanup <- true is good and race free, but p.stopCleanup != nil is a race because it is reading stopCleanup, which was written to in the startCleanup routine.

I think the solution is to change NewWithCleanupInterval to

func NewWithCleanupInterval(db *sql.DB, cleanupInterval time.Duration) *SQLite3Store {
	p := &SQLite3Store{db: db}
	if cleanupInterval > 0 {
		p.stopCleanup = make(chan bool) // NEW!
		go p.startCleanup(cleanupInterval)
	}
	return p
}

And remove p.stopCleanup = make(chan bool) from startCleanup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions