| 460 | |
| 461 | |
| 462 | class MuxWrapper(SockWrapper): |
| 463 | def __init__(self, mux, channel): |
| 464 | SockWrapper.__init__(self, mux.rsock, mux.wsock) |
| 465 | self.mux = mux |
| 466 | self.channel = channel |
| 467 | self.mux.channels[channel] = self.got_packet |
| 468 | self.socks = [] |
| 469 | debug2('new channel: %d\n' % channel) |
| 470 | |
| 471 | def __del__(self): |
| 472 | self.nowrite() |
| 473 | SockWrapper.__del__(self) |
| 474 | |
| 475 | def __repr__(self): |
| 476 | return 'SW%r:Mux#%d' % (self.peername,self.channel) |
| 477 | |
| 478 | def noread(self): |
| 479 | if not self.shut_read: |
| 480 | self.shut_read = True |
| 481 | self.mux.send(self.channel, CMD_STOP_SENDING, '') |
| 482 | self.maybe_close() |
| 483 | |
| 484 | def nowrite(self): |
| 485 | if not self.shut_write: |
| 486 | self.shut_write = True |
| 487 | self.mux.send(self.channel, CMD_EOF, '') |
| 488 | self.maybe_close() |
| 489 | |
| 490 | def maybe_close(self): |
| 491 | if self.shut_read and self.shut_write: |
| 492 | # remove the mux's reference to us. The python garbage collector |
| 493 | # will then be able to reap our object. |
| 494 | self.mux.channels[self.channel] = None |
| 495 | |
| 496 | def too_full(self): |
| 497 | return self.mux.too_full |
| 498 | |
| 499 | def uwrite(self, buf): |
| 500 | if self.mux.too_full: |
| 501 | return 0 # too much already enqueued |
| 502 | if len(buf) > 2048: |
| 503 | buf = buf[:2048] |
| 504 | self.mux.send(self.channel, CMD_DATA, buf) |
| 505 | return len(buf) |
| 506 | |
| 507 | def uread(self): |
| 508 | if self.shut_read: |
| 509 | return '' # EOF |
| 510 | else: |
| 511 | return None # no data available right now |
| 512 | |
| 513 | def got_packet(self, cmd, data): |
| 514 | if cmd == CMD_EOF: |
| 515 | self.noread() |
| 516 | elif cmd == CMD_STOP_SENDING: |
| 517 | self.nowrite() |
| 518 | elif cmd == CMD_DATA: |
| 519 | self.buf.append(data) |
no outgoing calls
no test coverage detected