Skip to content

Commit 4acd5be

Browse files
author
Norman Young
committed
Adapt to MicroPython ports/unix using select.poll() in libs/XAsyncSockets.py
1 parent 1a44e07 commit 4acd5be

File tree

1 file changed

+58
-14
lines changed

1 file changed

+58
-14
lines changed

MicroWebSrv2/libs/XAsyncSockets.py

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@
33
Copyright © 2019 Jean-Christophe Bos & HC² (www.hc2.fr)
44
"""
55

6+
import sys
7+
_IS_MICROPYTHON = sys.implementation.name == 'micropython'
68

79
from _thread import allocate_lock, start_new_thread
810
from 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
1017
import socket
1118
import 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

Comments
 (0)