Changeset 138


Ignore:
Timestamp:
05/13/12 21:17:45 (12 years ago)
Author:
atzm
Message:
  • change handler structure
File:
1 edited

Legend:

Unmodified
Added
Removed
  • etherws/trunk/etherws.py

    r137 r138  
    4444import sys 
    4545import base64 
    46 import select 
    4746import argparse 
    4847import threading 
     
    5655 
    5756 
    58 class TapListener(threading.Thread): 
    59     daemon = True 
    60  
     57class TapHandler(object): 
    6158    def __init__(self, dev, debug=False): 
    62         super(TapListener, self).__init__() 
    63  
    6459        self._debug = debug 
     60        self._clients = [] 
    6561        self._tap = pytun.TunTapDevice(dev, pytun.IFF_TAP | pytun.IFF_NO_PI) 
    66         self._tap_lock = threading.Lock() 
    67  
    68         self._clients = [] 
    69         self._clients_lock = threading.Lock() 
    70  
    71         try: 
    72             self._tap_lock.acquire() 
    73             self._tap.up() 
    74         finally: 
    75             self._tap_lock.release() 
     62        self._tap.up() 
     63        self._write_lock = threading.Lock() 
     64 
     65    def fileno(self): 
     66        return self._tap.fileno() 
    7667 
    7768    def register_client(self, client): 
    78         try: 
    79             self._clients_lock.acquire() 
    80             self._clients.append(client) 
    81         finally: 
    82             self._clients_lock.release() 
     69        self._clients.append(client) 
    8370 
    8471    def unregister_client(self, client): 
    85         try: 
    86             self._clients_lock.acquire() 
    87             self._clients.remove(client) 
    88         except ValueError: 
    89             pass 
    90         finally: 
    91             self._clients_lock.release() 
     72        self._clients.remove(client) 
    9273 
    9374    def write(self, caller, message): 
     
    9778 
    9879        try: 
    99             self._clients_lock.acquire() 
     80            self._write_lock.acquire() 
    10081 
    10182            clients = self._clients[:] 
     
    10384            if caller is not self: 
    10485                clients.remove(caller) 
    105                 try: 
    106                     self._tap_lock.acquire() 
    107                     self._tap.write(message) 
    108                 finally: 
    109                     self._tap_lock.release() 
     86                self._tap.write(message) 
    11087 
    11188            message = base64.b64encode(message) 
     
    11592 
    11693        finally: 
    117             self._clients_lock.release() 
    118  
    119     def run(self): 
    120         epoll = select.epoll() 
    121  
    122         try: 
    123             self._tap_lock.acquire() 
    124             epoll.register(self._tap.fileno(), select.EPOLLIN) 
    125         finally: 
    126             self._tap_lock.release() 
    127  
    128         while True: 
    129             evts = epoll.poll(1) 
    130             for fileno, evt in evts: 
    131                 try: 
    132                     self._tap_lock.acquire() 
    133                     data = self._tap.read(self._tap.mtu) 
    134                 finally: 
    135                     self._tap_lock.release() 
    136                 self.write(self, data) 
     94            self._write_lock.release() 
     95 
     96    def __call__(self, fd, events): 
     97        self.write(self, self._tap.read(self._tap.mtu)) 
    13798 
    13899 
     
    144105 
    145106    def open(self): 
    146         if self._debug: 
    147             sys.stderr.write('[%s] opened\n' % self.request.remote_ip) 
    148107        self._tap.register_client(self) 
    149108 
    150109    def on_message(self, message): 
    151         if self._debug: 
    152             sys.stderr.write('[%s] received\n' % self.request.remote_ip) 
    153110        self._tap.write(self, base64.b64decode(message)) 
    154111 
    155112    def on_close(self): 
    156         if self._debug: 
    157             sys.stderr.write('[%s] closed\n' % self.request.remote_ip) 
    158113        self._tap.unregister_client(self) 
    159114 
     
    185140 
    186141def server_main(args): 
    187     tap = TapListener(args.device, debug=args.debug) 
    188     tap.start() 
    189  
     142    tap = TapHandler(args.device, debug=args.debug) 
    190143    app = tornado.web.Application([ 
    191144        (args.path, EtherWebSocket, {'tap': tap, 'debug': args.debug}), 
     
    194147    server.listen(args.port, address=args.address) 
    195148 
    196     tornado.ioloop.IOLoop.instance().start() 
     149    ioloop = tornado.ioloop.IOLoop.instance() 
     150    ioloop.add_handler(tap.fileno(), tap, ioloop.READ) 
     151    ioloop.start() 
    197152 
    198153 
     
    201156        websocket.enableTrace(True) 
    202157 
    203     tap = TapListener(args.device, debug=args.debug) 
     158    tap = TapHandler(args.device, debug=args.debug) 
    204159    client = websocket.WebSocketApp(args.uri) 
    205160    client.write_message = client.send 
    206161    client.on_message = lambda s, m: tap.write(client, base64.b64decode(m)) 
    207  
    208     if args.debug: 
    209         client.on_error = lambda s, e: sys.stderr.write(str(e) + '\n') 
    210         client.on_close = lambda s: sys.stderr.write('closed\n') 
    211  
    212162    tap.register_client(client) 
    213     tap.start() 
    214  
    215     client.run_forever() 
     163 
     164    t = threading.Thread(target=client.run_forever) 
     165    t.setDaemon(True) 
     166    t.start() 
     167 
     168    ioloop = tornado.ioloop.IOLoop.instance() 
     169    ioloop.add_handler(tap.fileno(), tap, ioloop.READ) 
     170    ioloop.start() 
    216171 
    217172 
Note: See TracChangeset for help on using the changeset viewer.