Fix some races found by -race.

This commit is contained in:
Josh Rickmar 2013-11-21 13:45:14 -05:00
parent 6558986cc5
commit 828544cb2f
2 changed files with 44 additions and 39 deletions

View file

@ -84,7 +84,10 @@ func (w *Account) writeDirtyToDisk() error {
// with block N-1. // with block N-1.
// UTXOs // UTXOs
if w.UtxoStore.dirty { w.UtxoStore.RLock()
dirty := w.TxStore.dirty
w.UtxoStore.RUnlock()
if dirty {
w.UtxoStore.Lock() w.UtxoStore.Lock()
defer w.UtxoStore.Unlock() defer w.UtxoStore.Unlock()
tmpfilepath := utxofilepath + "-" + timeStr tmpfilepath := utxofilepath + "-" + timeStr
@ -107,7 +110,10 @@ func (w *Account) writeDirtyToDisk() error {
} }
// Transactions // Transactions
if w.TxStore.dirty { w.TxStore.RLock()
dirty = w.TxStore.dirty
w.TxStore.RUnlock()
if dirty {
w.TxStore.Lock() w.TxStore.Lock()
defer w.TxStore.Unlock() defer w.TxStore.Unlock()
tmpfilepath := txfilepath + "-" + timeStr tmpfilepath := txfilepath + "-" + timeStr
@ -130,7 +136,10 @@ func (w *Account) writeDirtyToDisk() error {
} }
// Wallet // Wallet
if w.dirty { w.mtx.RLock()
dirty = w.dirty
w.mtx.RUnlock()
if dirty {
w.mtx.Lock() w.mtx.Lock()
defer w.mtx.Unlock() defer w.mtx.Unlock()
tmpfilepath := wfilepath + "-" + timeStr tmpfilepath := wfilepath + "-" + timeStr

View file

@ -272,25 +272,20 @@ func frontendSendRecv(ws *websocket.Conn) {
// BtcdHandler listens for replies and notifications from btcd over a // BtcdHandler listens for replies and notifications from btcd over a
// websocket and sends messages that btcwallet does not understand to // websocket and sends messages that btcwallet does not understand to
// btcd. Unlike FrontendHandler, exactly one BtcdHandler goroutine runs. // btcd. Unlike FrontendHandler, exactly one BtcdHandler goroutine runs.
func BtcdHandler(ws *websocket.Conn) { func BtcdHandler(ws *websocket.Conn, done chan struct{}) {
// Notification channel to return from listener goroutine when
// btcd disconnects.
disconnected := make(chan int)
defer func() {
close(disconnected)
}()
// Listen for replies/notifications from btcd, and decide how to handle them. // Listen for replies/notifications from btcd, and decide how to handle them.
replies := make(chan []byte) replies := make(chan []byte)
go func() { go func() {
defer close(replies) defer close(replies)
for { for {
select { select {
case <-disconnected: case <-done:
return return
default: default:
var m []byte var m []byte
if err := websocket.Message.Receive(ws, &m); err != nil { if err := websocket.Message.Receive(ws, &m); err != nil {
close(done)
return return
} }
replies <- m replies <- m
@ -298,23 +293,31 @@ func BtcdHandler(ws *websocket.Conn) {
} }
}() }()
for { go func() {
select { for {
case rply, ok := <-replies: select {
if !ok { case <-done:
// btcd disconnected
return
}
// Handle message here.
go ProcessBtcdNotificationReply(rply)
case r := <-btcdMsgs:
if err := websocket.Message.Send(ws, r); err != nil {
// btcd disconnected.
log.Errorf("Unable to send message to btcd: %v", err)
return return
case rply, ok := <-replies:
if !ok {
// btcd disconnected
close(done)
return
}
// Handle message here.
go ProcessBtcdNotificationReply(rply)
case r := <-btcdMsgs:
if err := websocket.Message.Send(ws, r); err != nil {
// btcd disconnected.
log.Errorf("Unable to send message to btcd: %v", err)
close(done)
return
}
} }
} }
} }()
} }
type notificationHandler func(btcws.Notification) type notificationHandler func(btcws.Notification)
@ -462,11 +465,6 @@ func NtfnBlockConnected(n btcws.Notification) {
// TODO(jrick): send frontend tx notifications once that's // TODO(jrick): send frontend tx notifications once that's
// implemented. // implemented.
for _, a := range accounts.m { for _, a := range accounts.m {
// Mark wallet as being synced with the new blockstamp.
a.mtx.Lock()
a.Wallet.SetSyncedWith(bs)
a.mtx.Unlock()
// The UTXO store will be dirty if it was modified // The UTXO store will be dirty if it was modified
// from a tx notification. // from a tx notification.
if a.UtxoStore.dirty { if a.UtxoStore.dirty {
@ -490,7 +488,10 @@ func NtfnBlockConnected(n btcws.Notification) {
// //
// Instead, the wallet is queued to be written to disk at the // Instead, the wallet is queued to be written to disk at the
// next scheduled disk sync. // next scheduled disk sync.
a.mtx.Lock()
a.Wallet.SetSyncedWith(bs)
a.dirty = true a.dirty = true
a.mtx.Unlock()
dirtyAccounts.Lock() dirtyAccounts.Lock()
dirtyAccounts.m[a] = true dirtyAccounts.m[a] = true
dirtyAccounts.Unlock() dirtyAccounts.Unlock()
@ -636,15 +637,10 @@ func BtcdConnect(certificates []byte, reply chan error) {
} }
replyHandlers.Unlock() replyHandlers.Unlock()
handlerClosed := make(chan int) done := make(chan struct{})
go func() { BtcdHandler(btcdws, done)
BtcdHandler(btcdws)
close(handlerClosed)
}()
BtcdHandshake(btcdws) BtcdHandshake(btcdws)
<-done
<-handlerClosed
reply <- ErrConnLost reply <- ErrConnLost
} }