291 srvOut <- x |
291 srvOut <- x |
292 } |
292 } |
293 } |
293 } |
294 } |
294 } |
295 |
295 |
|
296 // Stanzas from the remote go up through a stack of filters to the |
|
297 // app. This function manages the filters. |
|
298 func filter(srvIn2 <-chan Stanza, cliOut2 chan<- Stanza, |
|
299 filterOut <-chan <-chan Stanza, filterIn chan<- <-chan Stanza) { |
|
300 defer close(cliOut2) |
|
301 var srvIn1, topFilterOut1, topFilterOut2 <-chan Stanza |
|
302 var cliOut1, botFilterIn1, botFilterIn2 chan<- Stanza |
|
303 ch := make(chan Stanza, 1) |
|
304 topFilterOut2 = ch |
|
305 botFilterIn2 = ch |
|
306 topFilterOut1 = topFilterOut2 |
|
307 srvIn1 = srvIn2 |
|
308 var botItem Stanza |
|
309 var topItem Stanza |
|
310 var ok bool |
|
311 for { |
|
312 select { |
|
313 case newFilterOut := <- filterOut: |
|
314 filterIn <- topFilterOut2 |
|
315 topFilterOut2 = newFilterOut |
|
316 if topFilterOut1 != nil { |
|
317 topFilterOut1 = topFilterOut2 |
|
318 } |
|
319 |
|
320 case topItem, ok = <-topFilterOut1: |
|
321 if !ok { |
|
322 break |
|
323 } |
|
324 topFilterOut1 = nil |
|
325 cliOut1 = cliOut2 |
|
326 case cliOut1 <- topItem: |
|
327 topFilterOut1 = topFilterOut2 |
|
328 cliOut1 = nil |
|
329 |
|
330 case botItem, ok = <-srvIn1: |
|
331 if !ok { |
|
332 close(botFilterIn2) |
|
333 srvIn1 = nil |
|
334 continue |
|
335 } |
|
336 srvIn1 = nil |
|
337 botFilterIn1 = botFilterIn2 |
|
338 case botFilterIn1 <- botItem: |
|
339 srvIn1 = srvIn2 |
|
340 botFilterIn1 = nil |
|
341 } |
|
342 } |
|
343 } |
|
344 |
296 func handleStream(ss *stream) { |
345 func handleStream(ss *stream) { |
297 } |
346 } |
298 |
347 |
299 func (cl *Client) handleStreamError(se *streamError) { |
348 func (cl *Client) handleStreamError(se *streamError) { |
300 log.Printf("Received stream error: %v", se) |
349 log.Printf("Received stream error: %v", se) |