finish closes the control buffer, cleaning up any streams that have queued header frames. Once this method returns, no more frames can be added to the control buffer, and attempts to do so will return ErrConnClosing.
()
| 452 | // header frames. Once this method returns, no more frames can be added to the |
| 453 | // control buffer, and attempts to do so will return ErrConnClosing. |
| 454 | func (c *controlBuffer) finish() { |
| 455 | c.mu.Lock() |
| 456 | defer c.mu.Unlock() |
| 457 | |
| 458 | if c.closed { |
| 459 | return |
| 460 | } |
| 461 | c.closed = true |
| 462 | // There may be headers for streams in the control buffer. |
| 463 | // These streams need to be cleaned out since the transport |
| 464 | // is still not aware of these yet. |
| 465 | for head := c.list.dequeueAll(); head != nil; head = head.next { |
| 466 | switch v := head.it.(type) { |
| 467 | case *headerFrame: |
| 468 | if v.onOrphaned != nil { // It will be nil on the server-side. |
| 469 | v.onOrphaned(ErrConnClosing) |
| 470 | } |
| 471 | case *dataFrame: |
| 472 | if !v.processing { |
| 473 | v.data.Free() |
| 474 | } |
| 475 | } |
| 476 | } |
| 477 | |
| 478 | // In case throttle() is currently in flight, it needs to be unblocked. |
| 479 | // Otherwise, the transport may not close, since the transport is closed by |
| 480 | // the reader encountering the connection error. |
| 481 | ch := c.trfChan.Swap(nil) |
| 482 | if ch != nil { |
| 483 | close(*ch) |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | type side int |
| 488 |