33Copyright © 2019 Jean-Christophe Bos & HC² (www.hc2.fr)
44"""
55
6+ import sys
7+ _IS_MICROPYTHON = sys .implementation .name == 'micropython'
68
79from _thread import allocate_lock , start_new_thread
810from time import sleep
9- from select import select
11+ if _IS_MICROPYTHON :
12+ from select import poll
13+ import select
14+ import struct
15+ else :
16+ from select import select
1017import socket
1118import ssl
1219
@@ -30,6 +37,7 @@ def __init__(self) :
3037 self ._processing = False
3138 self ._threadsCount = 0
3239 self ._opLock = allocate_lock ()
40+ if _IS_MICROPYTHON : self ._poll = poll ()
3341 self ._asyncSockets = { }
3442 self ._readList = [ ]
3543 self ._writeList = [ ]
@@ -107,29 +115,56 @@ def _processWaitEvents(self) :
107115 self ._incThreadsCount ()
108116 timeSec = perf_counter ()
109117 while self ._processing :
118+ if _IS_MICROPYTHON :
119+ for socket in self ._readList :
120+ self ._poll .register (socket , select .POLLIN )
121+ for socket in self ._writeList :
122+ self ._poll .register (socket , select .POLLOUT )
110123 try :
111124 try :
112- rd , wr , ex = select ( self ._readList ,
113- self ._writeList ,
114- self ._readList ,
115- self ._CHECK_SEC_INTERVAL )
125+ if _IS_MICROPYTHON :
126+ ready = self ._poll .poll (int (self ._CHECK_SEC_INTERVAL * 1000 ))
127+ else :
128+ rd , wr , ex = select ( self ._readList ,
129+ self ._writeList ,
130+ self ._readList ,
131+ self ._CHECK_SEC_INTERVAL )
116132 except KeyboardInterrupt as ex :
117133 raise ex
118- except :
134+ except Exception as ex :
119135 continue
120136 if not self ._processing :
121137 break
122- for socketsList in ex , wr , rd :
123- for socket in socketsList :
138+ if _IS_MICROPYTHON :
139+ for socket , mask in ready :
140+ if (0x20 ) & mask :
141+ self ._poll .unregister (socket )
142+ continue
124143 asyncSocket = self ._asyncSockets .get (id (socket ), None )
125144 if asyncSocket and self ._socketListAdd (socket , self ._handlingList ) :
126- if socketsList is ex :
127- asyncSocket .OnExceptionalCondition ()
128- elif socketsList is wr :
129- asyncSocket .OnReadyForWriting ()
130- else :
145+ # POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI
146+ if ((select .POLLIN | 0x40 | 0x80 | 0x2 ) & mask ):
131147 asyncSocket .OnReadyForReading ()
148+ # POLLOUT | POLLWRNORM | POLLWRBAND
149+ elif ((select .POLLOUT | 0x100 | 0x200 ) & mask ):
150+ asyncSocket .OnReadyForWriting ()
151+ # POLLNVAL
152+ else :
153+ asyncSocket .OnExceptionalCondition ()
132154 self ._socketListRemove (socket , self ._handlingList )
155+ self ._poll .unregister (socket )
156+ else :
157+ for socketsList in ex , wr , rd :
158+ for socket in socketsList :
159+ asyncSocket = self ._asyncSockets .get (id (socket ), None )
160+ if asyncSocket and self ._socketListAdd (socket , self ._handlingList ) :
161+ if socketsList is ex :
162+ asyncSocket .OnExceptionalCondition ()
163+ elif socketsList is wr :
164+ asyncSocket .OnReadyForWriting ()
165+ else :
166+ asyncSocket .OnReadyForReading ()
167+ self ._socketListRemove (socket , self ._handlingList )
133168 sec = perf_counter ()
134169 if sec > timeSec + self ._CHECK_SEC_INTERVAL :
135170 timeSec = sec
@@ -372,7 +407,10 @@ def Create(asyncSocketsPool, srvAddr, srvBacklog=256, bufSlots=None) :
372407 raise XAsyncTCPServerException ('Create : Cannot open socket (no enought memory).' )
373408 try :
374409 srvSocket .setsockopt (socket .SOL_SOCKET , socket .SO_REUSEADDR , 1 )
375- srvSocket .bind (srvAddr )
410+ if _IS_MICROPYTHON :
411+ srvSocket .bind (socket .getaddrinfo (srvAddr [0 ], srvAddr [1 ])[0 ][- 1 ])
412+ else :
413+ srvSocket .bind (srvAddr )
376414 srvSocket .listen (srvBacklog )
377415 except :
378416 raise XAsyncTCPServerException ('Create : Error to binding the TCP server on this address.' )
@@ -401,6 +439,12 @@ def __init__(self, asyncSocketsPool, srvSocket, srvAddr, bufSlots) :
401439 def OnReadyForReading (self ) :
402440 try :
403441 cliSocket , cliAddr = self ._socket .accept ()
442+ if _IS_MICROPYTHON :
443+ # b'\x02\x00\x89L\x7f\x00\x00\x01'
444+ address = "." .join ([str (byte [0 ])
445+ for byte in struct .unpack ('ssss' , cliAddr [4 :8 ])])
446+ port = struct .unpack ('H' , cliAddr [2 :4 ])[0 ]
447+ cliAddr = (address , port )
404448 except :
405449 return
406450 recvBufSlot = self ._bufSlots .GetAvailableSlot ()
0 commit comments