diff --git a/src/pkg/websocket/hixie.go b/src/pkg/websocket/hixie.go index b755a5c6a6..43de8a7800 100644 --- a/src/pkg/websocket/hixie.go +++ b/src/pkg/websocket/hixie.go @@ -235,6 +235,8 @@ func (handler *hixiFrameHandler) HandleFrame(frame frameReader) (r frameReader, } func (handler *hixiFrameHandler) WriteClose(_ int) (err os.Error) { + handler.conn.wio.Lock() + defer handler.conn.wio.Unlock() closingFrame := []byte{'\xff', '\x00'} handler.conn.buf.Write(closingFrame) return handler.conn.buf.Flush() diff --git a/src/pkg/websocket/hybi.go b/src/pkg/websocket/hybi.go index cad47182d6..c4d990d6d8 100644 --- a/src/pkg/websocket/hybi.go +++ b/src/pkg/websocket/hybi.go @@ -288,6 +288,8 @@ func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader, } func (handler *hybiFrameHandler) WriteClose(status int) (err os.Error) { + handler.conn.wio.Lock() + defer handler.conn.wio.Unlock() w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame) if err != nil { return err @@ -300,6 +302,8 @@ func (handler *hybiFrameHandler) WriteClose(status int) (err os.Error) { } func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err os.Error) { + handler.conn.wio.Lock() + defer handler.conn.wio.Unlock() w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame) if err != nil { return 0, err diff --git a/src/pkg/websocket/websocket.go b/src/pkg/websocket/websocket.go index d57d1149c8..1855705c99 100644 --- a/src/pkg/websocket/websocket.go +++ b/src/pkg/websocket/websocket.go @@ -15,6 +15,7 @@ import ( "json" "net" "os" + "sync" "url" ) @@ -147,9 +148,11 @@ type Conn struct { buf *bufio.ReadWriter rwc io.ReadWriteCloser + rio sync.Mutex frameReaderFactory frameReader + wio sync.Mutex frameWriterFactory frameHandler @@ -163,6 +166,8 @@ type Conn struct { // will read the rest of the frame data. // it reads Text frame or Binary frame. func (ws *Conn) Read(msg []byte) (n int, err os.Error) { + ws.rio.Lock() + defer ws.rio.Unlock() again: if ws.frameReader == nil { frame, err := ws.frameReaderFactory.NewFrameReader() @@ -191,6 +196,8 @@ again: // Write implements the io.Writer interface: // it writes data as a frame to the WebSocket connection. func (ws *Conn) Write(msg []byte) (n int, err os.Error) { + ws.wio.Lock() + defer ws.wio.Unlock() w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType) if err != nil { return 0, err @@ -279,6 +286,8 @@ func (cd Codec) Send(ws *Conn, v interface{}) (err os.Error) { if err != nil { return err } + ws.wio.Lock() + defer ws.wio.Unlock() w, err := ws.frameWriterFactory.NewFrameWriter(payloadType) _, err = w.Write(data) w.Close() @@ -287,6 +296,8 @@ func (cd Codec) Send(ws *Conn, v interface{}) (err os.Error) { // Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v. func (cd Codec) Receive(ws *Conn, v interface{}) (err os.Error) { + ws.rio.Lock() + defer ws.rio.Unlock() if ws.frameReader != nil { _, err = io.Copy(ioutil.Discard, ws.frameReader) if err != nil {