Ticket #2157: _pollingfile.2.patch

File _pollingfile.2.patch, 6.6 KB (added by synapsis, 8 years ago)

patch _pollingfile.py, version 2

  • _pollingfile.py

     
    33 
    44Implements a simple polling interface for file descriptors that don't work with 
    55select() - this is pretty much only useful on Windows. 
    6  
    76""" 
    87 
     8import sys 
    99from zope.interface import implements 
    1010 
    1111from twisted.internet.interfaces import IConsumer, IPushProducer 
     
    1313MIN_TIMEOUT = 0.000000001 
    1414MAX_TIMEOUT = 0.1 
    1515 
    16 class _PollableResource: 
     16 
     17class _PollableResource(object): 
    1718    active = True 
    1819 
    1920    def activate(self): 
     
    2223    def deactivate(self): 
    2324        self.active = False 
    2425 
    25 class _PollingTimer: 
     26 
     27class _PollingTimer(object): 
    2628    # Everything is private here because it is really an implementation detail. 
    2729 
    2830    def __init__(self, reactor): 
     
    9193# If we ever (let's hope not) need the above functionality on UNIX, this could 
    9294# be factored into a different module. 
    9395 
    94 import win32pipe 
    9596import win32file 
    9697import win32api 
    9798import pywintypes 
    9899 
    99 class _PollableReadPipe(_PollableResource): 
    100100 
     101class _PollableReader(_PollableResource): 
     102 
    101103    implements(IPushProducer) 
    102104 
    103     def __init__(self, pipe, receivedCallback, lostCallback): 
    104         # security attributes for pipes 
    105         self.pipe = pipe 
     105    def __init__(self, handle, receivedCallback, lostCallback): 
     106        self.handle = handle 
    106107        self.receivedCallback = receivedCallback 
    107108        self.lostCallback = lostCallback 
    108109 
    109110    def checkWork(self): 
    110         finished = 0 
    111         fullDataRead = [] 
     111        raise NotImplementedError() 
    112112 
    113         while 1: 
    114             try: 
    115                 buffer, bytesToRead, result = win32pipe.PeekNamedPipe(self.pipe, 1) 
    116                 # finished = (result == -1) 
    117                 if not bytesToRead: 
    118                     break 
    119                 hr, data = win32file.ReadFile(self.pipe, bytesToRead, None) 
    120                 fullDataRead.append(data) 
    121             except win32api.error: 
    122                 finished = 1 
    123                 break 
    124  
    125         dataBuf = ''.join(fullDataRead) 
    126         if dataBuf: 
    127             self.receivedCallback(dataBuf) 
    128         if finished: 
    129             self.cleanup() 
    130         return len(dataBuf) 
    131  
    132113    def cleanup(self): 
    133114        self.deactivate() 
    134115        self.lostCallback() 
    135116 
    136117    def close(self): 
     118        # XXX why not cleanup? 
    137119        try: 
    138             win32api.CloseHandle(self.pipe) 
     120            win32api.CloseHandle(self.handle) 
    139121        except pywintypes.error: 
    140122            # You can't close std handles...? 
    141123            pass 
     
    150132        self.activate() 
    151133 
    152134 
    153 FULL_BUFFER_SIZE = 64 * 1024 
    154135 
    155 class _PollableWritePipe(_PollableResource): 
     136class _PollableWriter(_PollableResource): 
     137    FULL_BUFFER_SIZE = 64 * 1024 
    156138 
    157139    implements(IConsumer) 
    158  
    159     def __init__(self, writePipe, lostCallback): 
     140     
     141    def __init__(self, handle, lostCallback): 
    160142        self.disconnecting = False 
    161143        self.producer = None 
    162144        self.producerPaused = 0 
    163145        self.streamingProducer = 0 
    164146        self.outQueue = [] 
    165         self.writePipe = writePipe 
     147        self.handle = handle 
    166148        self.lostCallback = lostCallback 
    167         try: 
    168             win32pipe.SetNamedPipeHandleState(writePipe, 
    169                                               win32pipe.PIPE_NOWAIT, 
    170                                               None, 
    171                                               None) 
    172         except pywintypes.error: 
    173             # Maybe it's an invalid handle.  Who knows. 
    174             pass 
    175149 
    176150    def close(self): 
    177151        self.disconnecting = True 
     
    219193    def writeConnectionLost(self): 
    220194        self.deactivate() 
    221195        try: 
    222             win32api.CloseHandle(self.writePipe) 
     196            win32api.CloseHandle(self.handle) 
    223197        except pywintypes.error: 
    224198            # OMG what 
    225199            pass 
     
    232206        if self.disconnecting: 
    233207            return 
    234208        self.outQueue.append(data) 
    235         if sum(map(len, self.outQueue)) > FULL_BUFFER_SIZE: 
     209        if sum(map(len, self.outQueue)) > self.FULL_BUFFER_SIZE: 
    236210            self.bufferFull() 
    237211 
    238212    def checkWork(self): 
     213        raise NotImplementedError() 
     214 
     215 
     216 
     217# 
     218# Pipe support 
     219#  
     220import win32pipe 
     221 
     222 
     223class _PollableReadPipe(_PollableReader): 
     224    def __init__(self, pipe, receivedCallback, lostCallback): 
     225        _PollableReader.__init__(self, pipe, receivedCallback, lostCallback) 
     226        # security attributes for pipes 
     227 
     228    def checkWork(self): 
     229        finished = 0 
     230        fullDataRead = [] 
     231 
     232        while 1: 
     233            try: 
     234                buffer, bytesToRead, result = win32pipe.PeekNamedPipe(self.handle, 1) 
     235                # finished = (result == -1) 
     236                if not bytesToRead: 
     237                    break 
     238                hr, data = win32file.ReadFile(self.handle, bytesToRead, None) 
     239                fullDataRead.append(data) 
     240            except win32api.error: 
     241                finished = 1 
     242                break 
     243 
     244        dataBuf = ''.join(fullDataRead) 
     245        if dataBuf: 
     246            self.receivedCallback(dataBuf) 
     247        if finished: 
     248            self.cleanup() 
     249        return len(dataBuf) 
     250 
     251 
     252class _PollableWritePipe(_PollableWriter): 
     253    def __init__(self, writePipe, lostCallback): 
     254        _PollableWriter.__init__(self, writePipe, lostCallback) 
     255 
     256        try: 
     257            win32pipe.SetNamedPipeHandleState(writePipe, 
     258                                              win32pipe.PIPE_NOWAIT, 
     259                                              None, 
     260                                              None) 
     261        except pywintypes.error: 
     262            # Maybe it's an invalid handle.  Who knows. 
     263            pass 
     264 
     265    def checkWork(self): 
    239266        numBytesWritten = 0 
    240267        if not self.outQueue: 
    241268            if self.disconnecting: 
    242269                self.writeConnectionLost() 
    243270                return 0 
    244271            try: 
    245                 win32file.WriteFile(self.writePipe, '', None) 
     272                win32file.WriteFile(self.handle, '', None) 
    246273            except pywintypes.error: 
    247274                self.writeConnectionLost() 
    248275                return numBytesWritten 
     
    250277            data = self.outQueue.pop(0) 
    251278            errCode = 0 
    252279            try: 
    253                 errCode, nBytesWritten = win32file.WriteFile(self.writePipe, 
     280                errCode, nBytesWritten = win32file.WriteFile(self.handle, 
    254281                                                             data, None) 
    255282            except win32api.error: 
    256283                self.writeConnectionLost() 
     
    266293            if not resumed and self.disconnecting: 
    267294                self.writeConnectionLost() 
    268295        return numBytesWritten 
    269  
    270