Skip to content

Commit

Permalink
Use netMutex to protect dhcpLeases, pingResponse, and outSockets.
Browse files Browse the repository at this point in the history
  • Loading branch information
cyoung committed Mar 3, 2017
1 parent 7631543 commit 0360e50
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
2 changes: 2 additions & 0 deletions main/managementinterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,9 @@ func doRestartApp() {
func handleClientsGetRequest(w http.ResponseWriter, r *http.Request) {
setNoCache(w)
setJSONHeaders(w)
netMutex.Lock()
clientsJSON, _ := json.Marshal(&outSockets)
netMutex.Unlock()
fmt.Fprintf(w, "%s\n", clientsJSON)
}

Expand Down
28 changes: 23 additions & 5 deletions main/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,14 @@ type serialConnection struct {
}

var messageQueue chan networkMessage

var outSockets map[string]networkConnection
var dhcpLeases map[string]string
var netMutex *sync.Mutex
var pingResponse map[string]time.Time // Last time an IP responded to an "echo" response.
var netMutex *sync.Mutex // netMutex needs to be locked before accessing dhcpLeases, pingResponse, and outSockets and calling isSleeping() and isThrottled().

var totalNetworkMessagesSent uint32

var pingResponse map[string]time.Time // Last time an IP responded to an "echo" response.

const (
NETWORK_GDL90_STANDARD = 1
Expand Down Expand Up @@ -145,6 +146,11 @@ func getDHCPLeases() (map[string]string, error) {
return ret, nil
}

/*
isSleeping().
Check if a client identifier 'ip:port' is in either a sleep or active state.
***WARNING***: netMutex must be locked before calling this function.
*/
func isSleeping(k string) bool {
ipAndPort := strings.Split(k, ":")
// No ping response. Assume disconnected/sleeping device.
Expand All @@ -157,8 +163,13 @@ func isSleeping(k string) bool {
return false
}

// Throttle mode for testing port open and giving some start-up time to the app.
// Throttling is 0.1% data rate for first 15 seconds.
/*
isThrottled().
Checks if a client identifier 'ip:port' is throttled.
Throttle mode is for testing port open and giving some start-up time to the app.
Throttling is 0.1% data rate for first 15 seconds.
***WARNING***: netMutex must be locked before calling this function.
*/
func isThrottled(k string) bool {
return (rand.Int()%1000 != 0) && stratuxClock.Since(outSockets[k].LastUnreachable) < (15*time.Second)
}
Expand Down Expand Up @@ -286,6 +297,9 @@ func serialOutWatcher() {
// Returns the number of DHCP leases and prints queue lengths.
func getNetworkStats() {

netMutex.Lock()
defer netMutex.Unlock()

var numNonSleepingClients uint

for k, netconn := range outSockets {
Expand Down Expand Up @@ -357,7 +371,7 @@ func refreshConnectedClients() {
}

func messageQueueSender() {
secondTimer := time.NewTicker(15 * time.Second)
secondTimer := time.NewTicker(15 * time.Second) // getNetworkStats().
queueTimer := time.NewTicker(100 * time.Millisecond)

var lastQueueTimeChange time.Time // Reevaluate send frequency every 5 seconds.
Expand Down Expand Up @@ -467,6 +481,7 @@ func icmpEchoSender(c *icmp.PacketConn) {
timer := time.NewTicker(5 * time.Second)
for {
<-timer.C
netMutex.Lock()
// Collect IPs.
ips := make(map[string]bool)
for k, _ := range outSockets {
Expand All @@ -493,6 +508,7 @@ func icmpEchoSender(c *icmp.PacketConn) {
}
totalNetworkMessagesSent++
}
netMutex.Unlock()
}
}

Expand Down Expand Up @@ -521,7 +537,9 @@ func sleepMonitor() {

// Look for echo replies, mark it as received.
if msg.Type == ipv4.ICMPTypeEchoReply {
netMutex.Lock()
pingResponse[ip] = stratuxClock.Time
netMutex.Unlock()
continue // No further processing needed.
}

Expand Down

3 comments on commit 0360e50

@TravGoneFlying
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a GO programmer but don't you need unlocks at the continues in icmpEchoSender()? Although, I don't see what you are protecting in the second for loop. Could you move the unlock up in between the two for loops?

@cyoung
Copy link
Owner Author

@cyoung cyoung commented on 0360e50 Mar 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two "continue"s on line 503 and 507 are for the nested "for", and the lock/unlock are outside of that loop:

for ip, _ := range ips {

@TravGoneFlying
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course. I had some lines collapsed and missed that. Thanks for commenting.

Please sign in to comment.