From 00f6ba7a85829ec94f91f63dd9fd00a08d74e3d5 Mon Sep 17 00:00:00 2001 From: Ivan Kh Date: Wed, 28 Jun 2017 16:27:59 +0700 Subject: [PATCH] safe access to shared collections --- server/src/main/main.go | 74 ++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/server/src/main/main.go b/server/src/main/main.go index 1382e71..aee3c32 100755 --- a/server/src/main/main.go +++ b/server/src/main/main.go @@ -39,11 +39,9 @@ func (cr *ChatRoom) Init(db *bolt.DB) { return } - chat.clientsMtx.Lock() - client, ok := cr.namedClients[to] - chat.clientsMtx.Unlock() + client := getNamedClient(to) - if ok == false { + if client == nil { fmt.Println("Can't find " + to) } else { which := message.Which @@ -63,6 +61,45 @@ func (cr *ChatRoom) Init(db *bolt.DB) { }() } +func getClient(sessionId string) (*Client) { + var result *Client + + //fmt.Println("getClient will lock") + chat.clientsMtx.Lock() + result = chat.clients[sessionId] + chat.clientsMtx.Unlock() + //fmt.Println("getClient did lock") + + return result +} + +func setClient(sessionId string, client *Client) { + //fmt.Println("setClient lock") + chat.clientsMtx.Lock() + chat.clients[sessionId] = client + chat.clientsMtx.Unlock() + //fmt.Println("setClient unlock") +} + +func getNamedClient(name string) (*Client) { + var result *Client + + //fmt.Println("getNamedClient lock") + chat.clientsMtx.Lock() + result = chat.namedClients[name] + chat.clientsMtx.Unlock() + //fmt.Println("getNamedClient unlock") + + return result +} + +func setNamedClient(name string, client *Client) { + //fmt.Println("setNamedClient lock") + chat.clientsMtx.Lock() + chat.namedClients[name] = client + chat.clientsMtx.Unlock() + //fmt.Println("setNamedClient unlock") +} // Client type Client struct { @@ -156,6 +193,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { for { _, data, err := conn.ReadMessage() if err != nil { + fmt.Println("Error ", err) fmt.Println("\nConnection closed for session " + sessionId) updatePresence(sessionId, false) return @@ -202,7 +240,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { case Haber_CALL_STOP: fallthrough case Haber_FILE: - if _,ok := chat.clients[sessionId]; ok { + if getClient(sessionId) != nil { forward(sessionId, haber) } } @@ -211,14 +249,16 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { } func updatePresence(sessionId string, online bool) { - if client, ok := chat.clients[sessionId]; ok { + client := getClient(sessionId) + + if client != nil { if online == client.online { fmt.Printf("updatePresence: %s is already %t\n", client.name, client.online) return } fmt.Println("updatePresence sessionId=" + sessionId) client.online = online - chat.clients[sessionId] = client + setClient(sessionId, client) // inform subscribers from := client.name fmt.Println("\t from=" + from) @@ -274,26 +314,23 @@ func remove(s []string, r string) []string { func receivedUsername(conn *websocket.Conn, username string) string { fmt.Println("\nreceivedUsername: " + username) - defer chat.clientsMtx.Unlock() - chat.clientsMtx.Lock() sessionId := createSessionId() - var client *Client - if c, ok := chat.namedClients[username]; ok { - client = c - } else { + client := getNamedClient(username) + if client == nil { client = &Client{ name: username, sessions: make(map[string]*websocket.Conn), online: false, } + setNamedClient(username, client) + fmt.Println("new client for ", username) } client.sessions[sessionId] = conn - chat.namedClients[username] = client fmt.Println("new client name=" + client.name + " session=" + sessionId) client.Load(chat.db) - chat.clients[sessionId] = client + setClient(sessionId, client) sendContacts(client, sessionId) updatePresence(sessionId, true) @@ -302,8 +339,7 @@ func receivedUsername(conn *websocket.Conn, username string) string { func sendContacts(client *Client, sessionId string) { for _,contact := range client.contacts { - _,ok := chat.namedClients[contact.Name] - contact.Online = ok + contact.Online = getNamedClient(contact.Name) != nil } buds := &Haber { @@ -316,14 +352,14 @@ func sendContacts(client *Client, sessionId string) { } func forward(sessionId string, haber *Haber) { - sourceClient := chat.clients[sessionId] + sourceClient := getClient(sessionId) haber.From = sourceClient.name chat.queue <- *haber // forward to all devices with source's and destination's names } func receivedContacts(sessionId string, haber *Haber) { fmt.Println("receivedContacts for session " + sessionId) - client := chat.clients[sessionId] + client := getClient(sessionId) client.contacts = haber.GetContacts() client.subscribeToContacts() client.Save(chat.db, haber)