~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/internet/win32.py

  • Committer: Bazaar Package Importer
  • Author(s): Moshe Zadka
  • Date: 2002-03-08 07:14:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020308071416-oxvuw76tpcpi5v1q
Tags: upstream-0.15.5
ImportĀ upstreamĀ versionĀ 0.15.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
# This library is free software; you can redistribute it and/or
 
3
# modify it under the terms of version 2.1 of the GNU Lesser General Public
 
4
# License as published by the Free Software Foundation.
 
5
 
6
# This library is distributed in the hope that it will be useful,
 
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
9
# Lesser General Public License for more details.
 
10
 
11
# You should have received a copy of the GNU Lesser General Public
 
12
# License along with this library; if not, write to the Free Software
 
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
14
 
 
15
"""A win32event based implementation of the twisted main loop.
 
16
 
 
17
To install the event loop (and you should do this before any connections,
 
18
listeners or connectors are added):
 
19
 
 
20
    from twisted.internet import win32
 
21
    win32.install()
 
22
 
 
23
"""
 
24
 
 
25
# Win32 imports
 
26
from win32file import WSAEventSelect, FD_READ, FD_WRITE, FD_CLOSE, \
 
27
                      FD_ACCEPT, FD_CONNECT
 
28
from win32event import CreateEvent, WaitForMultipleObjects, \
 
29
                       WAIT_OBJECT_0, WAIT_TIMEOUT, INFINITE
 
30
 
 
31
# System imports
 
32
import time
 
33
 
 
34
# Twisted imports
 
35
from twisted.python import log, threadable
 
36
 
 
37
 
 
38
# globals
 
39
reads = {}
 
40
writes = {}
 
41
events = {}
 
42
 
 
43
def _makeSocketEvent(fd, action, why, events=events):
 
44
    """Make a win32 event object for a socket."""
 
45
    event = CreateEvent(None, 0, 0, None)
 
46
    WSAEventSelect(fd, event, why)
 
47
    events[event] = (fd, action)
 
48
    return event
 
49
 
 
50
def addEvent(event, fd, action, events=events):
 
51
    """Add a new win32 event to the event loop."""
 
52
    events[event] = (fd, action)
 
53
 
 
54
def removeEvent(event):
 
55
    """Remove an event."""
 
56
    del events[event]
 
57
 
 
58
def addReader(reader, reads=reads):
 
59
    """Add a socket FileDescriptor for notification of data available to read.
 
60
    """
 
61
    if not reads.has_key(reader):
 
62
        reads[reader] = _makeSocketEvent(reader, reader.doRead, FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE)
 
63
        
 
64
def addWriter(writer, writes=writes):
 
65
    """Add a socket FileDescriptor for notification of data available to write.
 
66
    """
 
67
    if not writes.has_key(writer):
 
68
        writes[writer] =_makeSocketEvent(writer, writer.doWrite, FD_WRITE|FD_CLOSE)
 
69
 
 
70
def removeReader(reader):
 
71
    """Remove a Selectable for notification of data available to read.
 
72
    """
 
73
    if reads.has_key(reader):
 
74
        del events[reads[reader]]
 
75
        del reads[reader]
 
76
 
 
77
def removeWriter(writer, writes=writes):
 
78
    """Remove a Selectable for notification of data available to write.
 
79
    """
 
80
    if writes.has_key(writer):
 
81
        del events[writes[writer]]
 
82
        del writes[writer]
 
83
 
 
84
def removeAll():
 
85
    """Remove all selectables, and return a list of them."""
 
86
    result = reads.keys() + writes.keys()
 
87
    reads.clear()
 
88
    writes.clear()
 
89
    events.clear()
 
90
    return result
 
91
 
 
92
def doWaitForMultipleEvents(timeout,
 
93
                            reads=reads,
 
94
                            writes=writes):
 
95
    if timeout is None:
 
96
        #timeout = INFINITE
 
97
        timeout = 5000
 
98
    else:
 
99
        timeout = timeout * 1000
 
100
    
 
101
    handles = events.keys()
 
102
    if not handles:
 
103
        # sleep so we don't suck up CPU time
 
104
        time.sleep(timeout / 1000.0)
 
105
        return
 
106
    val = WaitForMultipleObjects(handles, 0, timeout)
 
107
    if val == WAIT_TIMEOUT:
 
108
        return
 
109
    elif val >= WAIT_OBJECT_0 and val < WAIT_OBJECT_0 + len(handles):
 
110
        fd, action = events[handles[val - WAIT_OBJECT_0]]
 
111
        closed = 0
 
112
        log.logOwner.own(fd)
 
113
        try:
 
114
            closed = action()
 
115
        except:
 
116
            log.deferr()
 
117
            closed = 1
 
118
 
 
119
        if closed:
 
120
            removeReader(fd)
 
121
            removeWriter(fd)
 
122
            try:
 
123
                fd.connectionLost()
 
124
            except:
 
125
                log.deferr()
 
126
 
 
127
        log.logOwner.disown(fd)
 
128
 
 
129
 
 
130
def install():
 
131
    """Install the win32 event loop."""
 
132
    import main
 
133
    main.addReader = addReader
 
134
    main.addWriter = addWriter
 
135
    main.removeReader = removeReader
 
136
    main.removeWriter = removeWriter
 
137
    main.doSelect = doWaitForMultipleEvents
 
138
    main.removeAll = removeAll
 
139
 
 
140
 
 
141
def initThreads():
 
142
    """Do initialization for threads."""
 
143
    import main
 
144
    if main.wakerInstalled:
 
145
        # make sure waker is registered with us
 
146
        removeReader(main.waker)
 
147
        addReader(main.waker)
 
148
 
 
149
threadable.whenThreaded(initThreads)
 
150
 
 
151
 
 
152
__all__ = ["install"]
 
153