Index: twisted/internet/interfaces.py =================================================================== --- twisted/internet/interfaces.py (revision 29075) +++ twisted/internet/interfaces.py (working copy) @@ -408,6 +408,37 @@ """ + +class IReactorWin32Events(Interface): + """ + Win32 Event API methods + """ + + def addEvent(event, fd, action): + """ + Add a new win32 event to the event loop. + + @param event: a Win32 event object created using win32event.CreateEvent() + + @param fd: an instance of L{twisted.internet.abstract.FileDescriptor} + + @param action: a string that is a method name of the fd instance. + This method is called in response to the event. + + @return: None + """ + + def removeEvent(event): + """ + Remove an event. + + @param event: a Win32 event object added using L{IReactorWin32Events.addEvent} + + @return: None + """ + + + class IReactorUDP(Interface): """ UDP socket methods. Index: twisted/internet/win32eventreactor.py =================================================================== --- twisted/internet/win32eventreactor.py (revision 29075) +++ twisted/internet/win32eventreactor.py (working copy) @@ -1,12 +1,18 @@ -# Copyright (c) 2001-2007 Twisted Matrix Laboratories. +# Copyright (c) 2001-2010 Twisted Matrix Laboratories. # See LICENSE for details. """ A win32event based implementation of the Twisted main loop. -This requires win32all or ActivePython to be installed. +This requires pywin32 (formerly win32all) or ActivePython to be installed. +To install the event loop (and you should do this before any connections, +listeners or connectors are added):: + + from twisted.internet import win32eventreactor + win32eventreactor.install() + Maintainer: Itamar Shtull-Trauring @@ -58,6 +64,7 @@ from twisted.internet import posixbase from twisted.python import log, threadable, failure from twisted.internet.interfaces import IReactorFDSet, IReactorProcess +from twisted.internet.interfaces import IReactorWin32Events from twisted.internet._dumbwin32proc import Process @@ -76,7 +83,7 @@ @ivar _events: A dictionary mapping win32 event object to tuples of L{FileDescriptor} instances and event masks. """ - implements(IReactorFDSet, IReactorProcess) + implements(IReactorFDSet, IReactorProcess, IReactorWin32Events) dummyEvent = CreateEvent(None, 0, 0, None) Index: twisted/internet/test/test_win32eventreactor.py =================================================================== --- twisted/internet/test/test_win32eventreactor.py (revision 0) +++ twisted/internet/test/test_win32eventreactor.py (revision 0) @@ -0,0 +1,23 @@ +# Copyright (c) 2010 Twisted Matrix Laboratories. +# See LICENSE for details. + +""" +Tests for L{twisted.internet.win32eventreactor} and supporting code. +""" + +from twisted.trial import unittest +from twisted.internet import reactor +from twisted.internet.interfaces import IReactorWin32Events + +from zope.interface.verify import verifyObject + +class win32eventreactorTestCase(unittest.TestCase): + """IReactorWin32Events""" + + def test_provides_interface(self): + verifyObject(IReactorWin32Events, reactor) + + + +if reactor.__class__.__name__ != 'Win32Reactor': + win32eventreactorTestCase.skip = 'This test only applies to win32eventreactor' Index: twisted/internet/_win32serialport.py =================================================================== --- twisted/internet/_win32serialport.py (revision 29075) +++ twisted/internet/_win32serialport.py (working copy) @@ -21,6 +21,7 @@ from twisted.protocols import basic from twisted.internet import abstract from twisted.python import log +from twisted.internet.interfaces import IReactorWin32Events # sibling imports from serialport import BaseSerialPort @@ -34,6 +35,12 @@ def __init__(self, protocol, deviceNameOrPortNumber, reactor, baudrate = 9600, bytesize = EIGHTBITS, parity = PARITY_NONE, stopbits = STOPBITS_ONE, xonxoff = 0, rtscts = 0): + + if not IReactorWin32Events.providedBy(reactor): + raise ValueError( + "SerialPort on Windows requires a reactor that " + "implements IReactorWin32Events, e.g. win32eventreactor.") + self._serial = serial.Serial(deviceNameOrPortNumber, baudrate=baudrate, bytesize=bytesize, parity=parity, stopbits=stopbits, timeout=None, @@ -52,7 +59,7 @@ self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None) self._overlappedWrite = win32file.OVERLAPPED() self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None) - + self.reactor.addEvent(self._overlappedRead.hEvent, self, 'serialReadEvent') self.reactor.addEvent(self._overlappedWrite.hEvent, self, 'serialWriteEvent') Index: twisted/internet/serialport.py =================================================================== --- twisted/internet/serialport.py (revision 29075) +++ twisted/internet/serialport.py (working copy) @@ -4,6 +4,15 @@ """ Serial Port Protocol + +pySerial is required for all platforms: http://pyserial.sourceforge.net/ + +Windows requires the use of a reactor that supports +L{twisted.internet.interfaces.IReactorWin32Events} +e.g. L{twisted.internet.win32eventreactor} + +pywin32 (previously win32all) is also required for Windows: +http://sourceforge.net/projects/pywin32/ """ # http://twistedmatrix.com/trac/ticket/3725#comment:24