GitLab is used only for code review, issue tracking and project management. Canonical locations for source code are still and

Commit 6baa3c4d authored by Cecylia Bocovich's avatar Cecylia Bocovich

Add synchronization to prevent post-melt collects

This fixes a race condition in which snowflakes.End() is called while
snowflakes.Collect() is in progress resulting in a write to a closed
channel. We now wait for all in-progress collections to finish and add
an extra check before proceeding with a collection.
parent d7aa9b83
Pipeline #1463 canceled with stage
......@@ -5,6 +5,7 @@ import (
// Container which keeps track of multiple WebRTC remote peers.
......@@ -25,7 +26,10 @@ type Peers struct {
snowflakeChan chan *WebRTCPeer
activePeers *list.List
melt chan struct{}
melt chan struct{}
melted bool
collection sync.WaitGroup
// Construct a fresh container of remote peers.
......@@ -45,6 +49,11 @@ func NewPeers(tongue Tongue) (*Peers, error) {
// As part of |SnowflakeCollector| interface.
func (p *Peers) Collect() (*WebRTCPeer, error) {
// Engage the Snowflake Catching interface, which must be available.
defer p.collection.Done()
if p.melted {
return nil, fmt.Errorf("Snowflakes have melted")
if nil == p.Tongue {
return nil, errors.New("missing Tongue to catch Snowflakes with")
......@@ -110,8 +119,10 @@ func (p *Peers) purgeClosedPeers() {
// Close all Peers contained here.
func (p *Peers) End() {
p.melted = true
cnt := p.Count()
for e := p.activePeers.Front(); e != nil; {
next := e.Next()
......@@ -181,7 +181,6 @@ func Handler(socks net.Conn, tongue Tongue) error {
// transfer to the Tor SOCKS handler when needed.
func connectLoop(snowflakes SnowflakeCollector) {
for {
// Check if ending is necessary.
_, err := snowflakes.Collect()
if err != nil {
log.Printf("WebRTC: %v Retrying in %v...",
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment