summaryrefslogtreecommitdiffhomepage
path: root/server/fsm.go
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-01-18 23:16:40 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-01-18 23:16:40 +0900
commit97c124246d0b2e714d57eca814f95c0a82d97113 (patch)
tree3f877e9b9093df59c7a2e2eb6a2e8f04e115f976 /server/fsm.go
parentec278710f10c2cae7d6b3e393aa957edfd536181 (diff)
server: fix 'deleted config' race
When a config is deleted, goroutine for FSMHandler.h.Dying becomes active. sendMessageloop must send notifcation before dying. So it should not check Dying(). After sending notificaiton, it closes the conneciton and return. It makes sure that rx goroutine will die too. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server/fsm.go')
-rw-r--r--server/fsm.go7
1 files changed, 4 insertions, 3 deletions
diff --git a/server/fsm.go b/server/fsm.go
index 5c93fce6..b70f0860 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -388,9 +388,10 @@ func (h *FSMHandler) sendMessageloop() error {
conn := h.conn
fsm := h.fsm
for {
+ // this function doesn't check Dying() because we
+ // can't die before sending notificaiton. After
+ // sending notification, we'll die.
select {
- case <-h.t.Dying():
- return nil
case m := <-h.outgoing:
b, _ := m.Serialize()
_, err := conn.Write(b)
@@ -407,6 +408,7 @@ func (h *FSMHandler) sendMessageloop() error {
if m.Header.Type == bgp.BGP_MSG_NOTIFICATION {
h.errorCh <- true
+ conn.Close()
return nil
}
case <-fsm.keepaliveTicker.C:
@@ -445,7 +447,6 @@ func (h *FSMHandler) established() bgp.FSMState {
h.t.Kill(nil)
return bgp.BGP_FSM_IDLE
case <-h.t.Dying():
- h.conn.Close()
return 0
}
}