Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hang queue on open due to panic on atomic op #31

Merged
merged 4 commits into from
Jan 21, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Removed

### Fixed
- Panic on atomic operation (arm, x86-32) and File lock not released when panic occurs. PR #31

## [0.0.4]

Expand Down
18 changes: 15 additions & 3 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ import (
// pages of type PageSize. Pages within the file are only accessible by page IDs
// from within active transactions.
type File struct {
// Atomic fields.
// Do not move: Must be 64bit-word aligned on some architectures.
txids uint64

observer Observer

path string
Expand All @@ -59,8 +63,6 @@ type File struct {
metaActive int

stats FileStats

txids uint64
}

// internal contants
Expand Down Expand Up @@ -336,15 +338,25 @@ func (f *File) beginTx(settings TxOptions) (*Tx, reason) {
}

tracef("request new transaction (readonly: %v)\n", settings.Readonly)

// Acquire transaction log.
// Unlock on panic, so applications will not be blocked in case they try to
// defer some close operations on the file.
ok := false
lock := f.locks.TxLock(settings.Readonly)
lock.Lock()
tracef("init new transaction (readonly: %v)\n", settings.Readonly)
defer cleanup.IfNot(&ok, lock.Unlock)

txid := atomic.AddUint64(&f.txids, 1)

tracef("init new transaction (readonly: %v)\n", settings.Readonly)

tx := newTx(f, txid, lock, settings)
tracef("begin transaction: %p (readonly: %v)\n", tx, settings.Readonly)

tx.onBegin()

ok = true
return tx, nil
}

Expand Down