fix data races in controller

In #309, we ended up with using ``sync.Cond``, which introduced the data race again.

In this PR, I use channel instead of ``sync.Cond`` similar to the first commit in #309. The difference is that instead of using close() to broadcast, I used the send operation on the channel.