Use chan struct{} for semaphores

With semaphores we don't actually care about the value passed in. It
makes sense to use a 0 bytes type in these cases.
There is also the added benefit of compiler optimisations for this
specific use case as described here:
https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub
This commit is contained in:
Tomás Senart 2014-07-02 17:31:10 +02:00 committed by Dave Collins
parent cc2c486791
commit f439dece37
8 changed files with 47 additions and 47 deletions

View file

@ -338,7 +338,7 @@ type AddrManager struct {
started int32
shutdown int32
wg sync.WaitGroup
quit chan bool
quit chan struct{}
nTried int
nNew int
lamtx sync.Mutex
@ -759,7 +759,7 @@ func (a *AddrManager) reset() {
func NewAddrManager() *AddrManager {
am := AddrManager{
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
quit: make(chan bool),
quit: make(chan struct{}),
localAddresses: make(map[string]*localAddress),
}
am.reset()

View file

@ -174,7 +174,7 @@ type blockManager struct {
msgChan chan interface{}
chainState chainState
wg sync.WaitGroup
quit chan bool
quit chan struct{}
// The following fields are used for headers-first mode.
headersFirstMode bool
@ -1309,7 +1309,7 @@ func newBlockManager(s *server) (*blockManager, error) {
lastBlockLogTime: time.Now(),
msgChan: make(chan interface{}, cfg.MaxPeers*3),
headerList: list.New(),
quit: make(chan bool),
quit: make(chan struct{}),
}
bm.blockChain = btcchain.New(s.db, s.netParams, bm.handleNotifyMsg)
bm.blockChain.DisableCheckpoints(cfg.DisableCheckpoints)

View file

@ -18,7 +18,7 @@ import (
var (
cfg *config
shutdownChannel = make(chan bool)
shutdownChannel = make(chan struct{})
)
// winServiceMain is only invoked on Windows. It detects when btcd is running
@ -114,7 +114,7 @@ func btcdMain(serverChan chan<- *server) error {
go func() {
server.WaitForShutdown()
srvrLog.Infof("Server shutdown complete")
shutdownChannel <- true
shutdownChannel <- struct{}{}
}()
// Wait for shutdown signal from either a graceful server stop or from

12
peer.go
View file

@ -160,12 +160,12 @@ type peer struct {
continueHash *btcwire.ShaHash
outputQueue chan outMsg
sendQueue chan outMsg
sendDoneQueue chan bool
sendDoneQueue chan struct{}
queueWg sync.WaitGroup // TODO(oga) wg -> single use channel?
outputInvChan chan *btcwire.InvVect
txProcessed chan bool
blockProcessed chan bool
quit chan bool
quit chan struct{}
StatsMtx sync.Mutex // protects all statistics below here.
versionKnown bool
protocolVersion uint32
@ -1478,7 +1478,7 @@ out:
msg.doneChan <- true
}
peerLog.Tracef("%s: acking queuehandler", p)
p.sendDoneQueue <- true
p.sendDoneQueue <- struct{}{}
peerLog.Tracef("%s: acked queuehandler", p)
case <-p.quit:
@ -1622,12 +1622,12 @@ func newPeerBase(s *server, inbound bool) *peer {
requestedBlocks: make(map[btcwire.ShaHash]struct{}),
requestQueue: list.New(),
outputQueue: make(chan outMsg, outputBufferSize),
sendQueue: make(chan outMsg, 1), // nonblocking sync
sendDoneQueue: make(chan bool, 1), // nonblocking sync
sendQueue: make(chan outMsg, 1), // nonblocking sync
sendDoneQueue: make(chan struct{}, 1), // nonblocking sync
outputInvChan: make(chan *btcwire.InvVect, outputBufferSize),
txProcessed: make(chan bool, 1),
blockProcessed: make(chan bool, 1),
quit: make(chan bool),
quit: make(chan struct{}),
}
return &p
}

View file

@ -259,7 +259,7 @@ type notificationUnregisterAddr struct {
// handler and processes one at a time.
func (m *wsNotificationManager) notificationHandler() {
// clients is a map of all currently connected websocket clients.
clients := make(map[chan bool]*wsClient)
clients := make(map[chan struct{}]*wsClient)
// Maps used to hold lists of websocket clients to be notified on
// certain events. Each websocket client also keeps maps for the events
@ -268,10 +268,10 @@ func (m *wsNotificationManager) notificationHandler() {
//
// Where possible, the quit channel is used as the unique id for a client
// since it is quite a bit more efficient than using the entire struct.
blockNotifications := make(map[chan bool]*wsClient)
txNotifications := make(map[chan bool]*wsClient)
watchedOutPoints := make(map[btcwire.OutPoint]map[chan bool]*wsClient)
watchedAddrs := make(map[string]map[chan bool]*wsClient)
blockNotifications := make(map[chan struct{}]*wsClient)
txNotifications := make(map[chan struct{}]*wsClient)
watchedOutPoints := make(map[btcwire.OutPoint]map[chan struct{}]*wsClient)
watchedAddrs := make(map[string]map[chan struct{}]*wsClient)
out:
for {
@ -398,7 +398,7 @@ func (m *wsNotificationManager) UnregisterBlockUpdates(wsc *wsClient) {
// notifyBlockConnected notifies websocket clients that have registered for
// block updates when a block is connected to the main chain.
func (*wsNotificationManager) notifyBlockConnected(clients map[chan bool]*wsClient,
func (*wsNotificationManager) notifyBlockConnected(clients map[chan struct{}]*wsClient,
block *btcutil.Block) {
hash, err := block.Sha()
@ -423,7 +423,7 @@ func (*wsNotificationManager) notifyBlockConnected(clients map[chan bool]*wsClie
// notifyBlockDisconnected notifies websocket clients that have registered for
// block updates when a block is disconnected from the main chain (due to a
// reorganize).
func (*wsNotificationManager) notifyBlockDisconnected(clients map[chan bool]*wsClient, block *btcutil.Block) {
func (*wsNotificationManager) notifyBlockDisconnected(clients map[chan struct{}]*wsClient, block *btcutil.Block) {
// Skip notification creation if no clients have requested block
// connected/disconnected notifications.
if len(clients) == 0 {
@ -465,7 +465,7 @@ func (m *wsNotificationManager) UnregisterNewMempoolTxsUpdates(wsc *wsClient) {
// notifyForNewTx notifies websocket clients that have registerd for updates
// when a new transaction is added to the memory pool.
func (m *wsNotificationManager) notifyForNewTx(clients map[chan bool]*wsClient, tx *btcutil.Tx) {
func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClient, tx *btcutil.Tx) {
txShaStr := tx.Sha().String()
mtx := tx.MsgTx()
@ -521,7 +521,7 @@ func (m *wsNotificationManager) RegisterSpentRequest(wsc *wsClient, op *btcwire.
// addSpentRequest modifies a map of watched outpoints to sets of websocket
// clients to add a new request watch the outpoint op and create and send
// a notification when spent to the websocket client wsc.
func (*wsNotificationManager) addSpentRequest(ops map[btcwire.OutPoint]map[chan bool]*wsClient,
func (*wsNotificationManager) addSpentRequest(ops map[btcwire.OutPoint]map[chan struct{}]*wsClient,
wsc *wsClient, op *btcwire.OutPoint) {
// Track the request in the client as well so it can be quickly be
@ -532,7 +532,7 @@ func (*wsNotificationManager) addSpentRequest(ops map[btcwire.OutPoint]map[chan
// Create the list as needed.
cmap, ok := ops[*op]
if !ok {
cmap = make(map[chan bool]*wsClient)
cmap = make(map[chan struct{}]*wsClient)
ops[*op] = cmap
}
cmap[wsc.quit] = wsc
@ -552,7 +552,7 @@ func (m *wsNotificationManager) UnregisterSpentRequest(wsc *wsClient, op *btcwir
// websocket client wsc from the set of clients to be notified when a
// watched outpoint is spent. If wsc is the last client, the outpoint
// key is removed from the map.
func (*wsNotificationManager) removeSpentRequest(ops map[btcwire.OutPoint]map[chan bool]*wsClient,
func (*wsNotificationManager) removeSpentRequest(ops map[btcwire.OutPoint]map[chan struct{}]*wsClient,
wsc *wsClient, op *btcwire.OutPoint) {
// Remove the request tracking from the client.
@ -609,8 +609,8 @@ func newRedeemingTxNotification(txHex string, index int, block *btcutil.Block) (
// websocket clients of the transaction if an output spends to a watched
// address. A spent notification request is automatically registered for
// the client for each matching output.
func (m *wsNotificationManager) notifyForTxOuts(ops map[btcwire.OutPoint]map[chan bool]*wsClient,
addrs map[string]map[chan bool]*wsClient, tx *btcutil.Tx, block *btcutil.Block) {
func (m *wsNotificationManager) notifyForTxOuts(ops map[btcwire.OutPoint]map[chan struct{}]*wsClient,
addrs map[string]map[chan struct{}]*wsClient, tx *btcutil.Tx, block *btcutil.Block) {
// Nothing to do if nobody is listening for address notifications.
if len(addrs) == 0 {
@ -618,7 +618,7 @@ func (m *wsNotificationManager) notifyForTxOuts(ops map[btcwire.OutPoint]map[cha
}
txHex := ""
wscNotified := make(map[chan bool]struct{})
wscNotified := make(map[chan struct{}]struct{})
for i, txOut := range tx.MsgTx().TxOut {
_, txAddrs, _, err := btcscript.ExtractPkScriptAddrs(
txOut.PkScript, m.server.server.netParams)
@ -659,8 +659,8 @@ func (m *wsNotificationManager) notifyForTxOuts(ops map[btcwire.OutPoint]map[cha
// notifyForTx examines the inputs and outputs of the passed transaction,
// notifying websocket clients of outputs spending to a watched address
// and inputs spending a watched outpoint.
func (m *wsNotificationManager) notifyForTx(ops map[btcwire.OutPoint]map[chan bool]*wsClient,
addrs map[string]map[chan bool]*wsClient, tx *btcutil.Tx, block *btcutil.Block) {
func (m *wsNotificationManager) notifyForTx(ops map[btcwire.OutPoint]map[chan struct{}]*wsClient,
addrs map[string]map[chan struct{}]*wsClient, tx *btcutil.Tx, block *btcutil.Block) {
if len(ops) != 0 {
m.notifyForTxIns(ops, tx, block)
@ -674,7 +674,7 @@ func (m *wsNotificationManager) notifyForTx(ops map[btcwire.OutPoint]map[chan bo
// interested websocket clients a redeemingtx notification if any inputs
// spend a watched output. If block is non-nil, any matching spent
// requests are removed.
func (m *wsNotificationManager) notifyForTxIns(ops map[btcwire.OutPoint]map[chan bool]*wsClient,
func (m *wsNotificationManager) notifyForTxIns(ops map[btcwire.OutPoint]map[chan struct{}]*wsClient,
tx *btcutil.Tx, block *btcutil.Block) {
// Nothing to do if nobody is watching outpoints.
@ -683,7 +683,7 @@ func (m *wsNotificationManager) notifyForTxIns(ops map[btcwire.OutPoint]map[chan
}
txHex := ""
wscNotified := make(map[chan bool]struct{})
wscNotified := make(map[chan struct{}]struct{})
for _, txIn := range tx.MsgTx().TxIn {
prevOut := &txIn.PreviousOutpoint
if cmap, ok := ops[*prevOut]; ok {
@ -721,7 +721,7 @@ func (m *wsNotificationManager) RegisterTxOutAddressRequest(wsc *wsClient, addr
// addAddrRequest adds the websocket client wsc to the address to client set
// addrs so wsc will be notified for any mempool or block transaction outputs
// spending to addr.
func (*wsNotificationManager) addAddrRequest(addrs map[string]map[chan bool]*wsClient,
func (*wsNotificationManager) addAddrRequest(addrs map[string]map[chan struct{}]*wsClient,
wsc *wsClient, addr string) {
// Track the request in the client as well so it can be quickly be
@ -732,7 +732,7 @@ func (*wsNotificationManager) addAddrRequest(addrs map[string]map[chan bool]*wsC
// seen. Create map as needed.
cmap, ok := addrs[addr]
if !ok {
cmap = make(map[chan bool]*wsClient)
cmap = make(map[chan struct{}]*wsClient)
addrs[addr] = cmap
}
cmap[wsc.quit] = wsc
@ -750,7 +750,7 @@ func (m *wsNotificationManager) UnregisterTxOutAddressRequest(wsc *wsClient, add
// removeAddrRequest removes the websocket client wsc from the address to
// client set addrs so it will no longer receive notification updates for
// any transaction outputs send to addr.
func (*wsNotificationManager) removeAddrRequest(addrs map[string]map[chan bool]*wsClient,
func (*wsNotificationManager) removeAddrRequest(addrs map[string]map[chan struct{}]*wsClient,
wsc *wsClient, addr string) {
// Remove the request tracking from the client.
@ -909,7 +909,7 @@ type wsClient struct {
asyncChan chan btcjson.Cmd
ntfnChan chan []byte
sendChan chan wsResponse
quit chan bool
quit chan struct{}
wg sync.WaitGroup
}
@ -1193,7 +1193,7 @@ cleanup:
// serialized. It must be run as a goroutine. Also, this goroutine is not
// started until/if the first long-running request is made.
func (c *wsClient) asyncHandler() {
asyncHandlerDoneChan := make(chan bool, 1) // nonblocking sync
asyncHandlerDoneChan := make(chan struct{}, 1) // nonblocking sync
pendingCmds := list.New()
waiting := false
@ -1226,7 +1226,7 @@ out:
c.wg.Add(1)
go func(cmd btcjson.Cmd) {
runHandler(cmd)
asyncHandlerDoneChan <- true
asyncHandlerDoneChan <- struct{}{}
c.wg.Done()
}(cmd)
} else {
@ -1249,7 +1249,7 @@ out:
c.wg.Add(1)
go func(cmd btcjson.Cmd) {
runHandler(cmd)
asyncHandlerDoneChan <- true
asyncHandlerDoneChan <- struct{}{}
c.wg.Done()
}(element.(btcjson.Cmd))
@ -1375,7 +1375,7 @@ func newWebsocketClient(server *rpcServer, conn *websocket.Conn,
ntfnChan: make(chan []byte, 1), // nonblocking sync
asyncChan: make(chan btcjson.Cmd, 1), // nonblocking sync
sendChan: make(chan wsResponse, websocketSendBufferSize),
quit: make(chan bool),
quit: make(chan struct{}),
}
}

View file

@ -80,12 +80,12 @@ type server struct {
newPeers chan *peer
donePeers chan *peer
banPeers chan *peer
wakeup chan bool
wakeup chan struct{}
query chan interface{}
relayInv chan *btcwire.InvVect
broadcast chan broadcastMsg
wg sync.WaitGroup
quit chan bool
quit chan struct{}
nat NAT
db btcdb.Db
}
@ -541,7 +541,7 @@ func (s *server) peerHandler() {
}
// if nothing else happens, wake us up soon.
time.AfterFunc(10*time.Second, func() { s.wakeup <- true })
time.AfterFunc(10*time.Second, func() { s.wakeup <- struct{}{} })
out:
for {
@ -658,7 +658,7 @@ out:
// We we need more peers, wake up in ten seconds and try again.
if state.NeedMoreOutbound() {
time.AfterFunc(10*time.Second, func() {
s.wakeup <- true
s.wakeup <- struct{}{}
})
}
}
@ -1172,11 +1172,11 @@ func newServer(listenAddrs []string, db btcdb.Db, netParams *btcnet.Params) (*se
newPeers: make(chan *peer, cfg.MaxPeers),
donePeers: make(chan *peer, cfg.MaxPeers),
banPeers: make(chan *peer, cfg.MaxPeers),
wakeup: make(chan bool),
wakeup: make(chan struct{}),
query: make(chan interface{}),
relayInv: make(chan *btcwire.InvVect, cfg.MaxPeers),
broadcast: make(chan broadcastMsg, cfg.MaxPeers),
quit: make(chan bool),
quit: make(chan struct{}),
modifyRebroadcastInv: make(chan interface{}),
nat: nat,
db: db,

View file

@ -36,7 +36,7 @@ func mainInterruptHandler() {
}
// Signal the main goroutine to shutdown.
shutdownChannel <- true
shutdownChannel <- struct{}{}
case handler := <-addHandlerChannel:
interruptCallbacks = append(interruptCallbacks, handler)

View file

@ -36,7 +36,7 @@ type blockImporter struct {
processQueue chan []byte
doneChan chan bool
errChan chan error
quit chan bool
quit chan struct{}
wg sync.WaitGroup
blocksProcessed int64
blocksImported int64
@ -293,7 +293,7 @@ func newBlockImporter(db btcdb.Db, r io.ReadSeeker) *blockImporter {
processQueue: make(chan []byte, 2),
doneChan: make(chan bool),
errChan: make(chan error),
quit: make(chan bool),
quit: make(chan struct{}),
chain: btcchain.New(db, activeNetwork, nil),
lastLogTime: time.Now(),
}