tag:blogger.com,1999:blog-3528393554015655906.post4556948387434147373..comments2022-12-05T06:29:08.808-08:00Comments on The programmable programmer: Go Language is lovelyMichael Speerhttp://www.blogger.com/profile/05288923100813819592noreply@blogger.comBlogger1125tag:blogger.com,1999:blog-3528393554015655906.post-89991268744098965812010-03-09T02:56:37.634-08:002010-03-09T02:56:37.634-08:00a few comments on your code, which is generally fi...a few comments on your code, which is generally fine AFAICS.<br /><br />> type Manager interface {<br />> Go(func())<br />> Wait()<br />> }<br />why bother defining the Manager interface?<br />just return the Manager struct.<br /><br />> go func(){<br />> for ; i > 0 ; i-- {<br />> oc <- true<br />> }<br />> }()<br />this doesn't need to be run in its own goroutine,<br />as it's already in a different goroutine from the waiters,<br />and we know they're all currently waiting.<br /><br />> if wait {<br />> <- m.wakeup<br />> }<br />> }<br />you need to store m.wakeup in a temporary<br />variable inside the lock, otherwise there's a race<br />condition here.<br /><br />here's another version of your code:<br />i also changed it so that no initialisation is necessary, so the New function becomes redundant.<br />you'll need to run it through gofmt to de-blogger-fy it...<br /><br />package dispatch<br /><br />import "sync"<br /><br />type Manager struct {<br /> lock sync.Mutex<br /> running uint<br /> waiting uint<br /> wakeup chan bool<br />}<br /><br />func (m *Manager) Go(fn func()) {<br /> m.lock.Lock()<br /> m.running++<br /> m.lock.Unlock()<br /> go func() {<br /> fn()<br /> m.lock.Lock()<br /> m.running--<br /> if m.running == 0 && m.waiting > 0 {<br /> for ; m.waiting > 0; m.waiting-- {<br /> m.wakeup <- true<br /> }<br /> m.wakeup = make(chan bool)<br /> }<br /> m.lock.Unlock()<br /> }()<br />}<br /><br />func (m *Manager) Wait() {<br /> wait := false<br /> m.lock.Lock()<br /> if m.wakeup == nil {<br /> m.wakeup = make(chan bool)<br /> }<br /> c := m.wakeup<br /> if m.running > 0 {<br /> m.waiting++<br /> wait = true<br /> }<br /> m.lock.Unlock()<br /> if wait {<br /> <-c<br /> }<br />}rog peppehttps://www.blogger.com/profile/00839344798030831980noreply@blogger.com