mirror of
https://github.com/jech/galene.git
synced 2024-11-26 02:25:58 +01:00
Use an unbounded buffer for client actions.
We no longer risk deadlocking when sending actions, which in turn enables pushing connections synchronously.
This commit is contained in:
parent
3b505a89fe
commit
183ab4fed7
1 changed files with 36 additions and 32 deletions
|
@ -67,6 +67,7 @@ type webClient struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
down map[string]*rtpDownConnection
|
down map[string]*rtpDownConnection
|
||||||
up map[string]*rtpUpConnection
|
up map[string]*rtpUpConnection
|
||||||
|
actions []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *webClient) Group() *group.Group {
|
func (c *webClient) Group() *group.Group {
|
||||||
|
@ -276,14 +277,12 @@ func delUpConn(c *webClient, id string, userId string, push bool) error {
|
||||||
conn.pc.Close()
|
conn.pc.Close()
|
||||||
|
|
||||||
if push && g != nil {
|
if push && g != nil {
|
||||||
go func(clients []group.Client) {
|
for _, c := range g.GetClients(c) {
|
||||||
for _, c := range clients {
|
|
||||||
err := c.PushConn(g, id, nil, nil, replace)
|
err := c.PushConn(g, id, nil, nil, replace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("PushConn: %v", err)
|
log.Printf("PushConn: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(g.GetClients(c))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -681,7 +680,7 @@ func gotICE(c *webClient, candidate *webrtc.ICECandidateInit, id string) error {
|
||||||
func (c *webClient) setRequested(requested map[string]uint32) error {
|
func (c *webClient) setRequested(requested map[string]uint32) error {
|
||||||
c.requested = requested
|
c.requested = requested
|
||||||
|
|
||||||
go pushConns(c, c.group)
|
pushConns(c, c.group)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,6 +810,13 @@ func clientLoop(c *webClient, ws *websocket.Conn) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
c.mu.Lock()
|
||||||
|
actions := c.actions
|
||||||
|
c.actions = nil
|
||||||
|
c.mu.Unlock()
|
||||||
|
for _, a := range actions {
|
||||||
|
handleAction(c, a)
|
||||||
|
}
|
||||||
select {
|
select {
|
||||||
case m, ok := <-read:
|
case m, ok := <-read:
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -921,19 +927,10 @@ func handleAction(c *webClient, a interface{}) error {
|
||||||
for i, t := range tracks {
|
for i, t := range tracks {
|
||||||
ts[i] = t
|
ts[i] = t
|
||||||
}
|
}
|
||||||
go func(u *rtpUpConnection,
|
err := a.client.PushConn(g, u.id, u, ts, replace)
|
||||||
ts []conn.UpTrack,
|
|
||||||
replace string) {
|
|
||||||
err := a.client.PushConn(
|
|
||||||
g, u.id, u, ts, replace,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf(
|
log.Printf("PushConn: %v", err)
|
||||||
"PushConn: %v",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}(u, ts, replace)
|
|
||||||
}
|
}
|
||||||
case connectionFailedAction:
|
case connectionFailedAction:
|
||||||
if down := getDownConn(c, a.id); down != nil {
|
if down := getDownConn(c, a.id); down != nil {
|
||||||
|
@ -947,7 +944,7 @@ func handleAction(c *webClient, a interface{}) error {
|
||||||
for i, t := range down.tracks {
|
for i, t := range down.tracks {
|
||||||
tracks[i] = t.remote
|
tracks[i] = t.remote
|
||||||
}
|
}
|
||||||
go c.PushConn(
|
c.PushConn(
|
||||||
c.group,
|
c.group,
|
||||||
down.remote.Id(), down.remote,
|
down.remote.Id(), down.remote,
|
||||||
tracks, "",
|
tracks, "",
|
||||||
|
@ -1393,7 +1390,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
disk.Close()
|
disk.Close()
|
||||||
return c.error(err)
|
return c.error(err)
|
||||||
}
|
}
|
||||||
go pushConns(disk, c.group)
|
pushConns(disk, c.group)
|
||||||
case "unrecord":
|
case "unrecord":
|
||||||
if !c.permissions.Record {
|
if !c.permissions.Record {
|
||||||
return c.error(group.UserError("not authorised"))
|
return c.error(group.UserError("not authorised"))
|
||||||
|
@ -1551,14 +1548,21 @@ func (c *webClient) Warn(oponly bool, message string) error {
|
||||||
|
|
||||||
var ErrClientDead = errors.New("client is dead")
|
var ErrClientDead = errors.New("client is dead")
|
||||||
|
|
||||||
func (c *webClient) action(m interface{}) error {
|
func (c *webClient) action(a interface{}) error {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
if len(c.actions) == 0 {
|
||||||
select {
|
select {
|
||||||
case c.actionCh <- m:
|
case c.actionCh <- a:
|
||||||
return nil
|
return nil
|
||||||
case <-c.done:
|
case <-c.done:
|
||||||
return ErrClientDead
|
return ErrClientDead
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c.actions = append(c.actions, a)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *webClient) write(m clientMessage) error {
|
func (c *webClient) write(m clientMessage) error {
|
||||||
select {
|
select {
|
||||||
|
|
Loading…
Reference in a new issue