blob: 373fa20c933399cfd4a43a2493734c93323146a2 [file] [log] [blame]
Holger Hans Peter Freytherb7749a72018-02-25 21:08:01 +00001# osmo_ms_driver: Event loop because asyncio is not up to the job
2#
3# Copyright (C) 2018 by Holger Hans Peter Freyther
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as
7# published by the Free Software Foundation, either version 3 of the
8# License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
Pau Espin Pedrole8bbcbf2020-04-10 19:51:31 +020018from osmo_gsm_tester.core import log
Holger Hans Peter Freytherb7749a72018-02-25 21:08:01 +000019
20import os
21import selectors
22import socket
23
24
25class SimpleLoop(log.Origin):
26 def __init__(self):
27 super().__init__(log.C_RUN, "SimpleLoop")
28 self._loop = selectors.DefaultSelector()
29 self._timeout = None
30
31 def register_fd(self, fd, event, callback):
32 self._loop.register(fd, event, callback)
33
34 def schedule_timeout(self, timeout):
35 assert self._timeout == None
36 self._timeout = timeout
37
38 def create_unix_server(self, cb, path):
39 sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
40
41 if len(path.encode()) > 107:
42 raise log.Error('Path for unix socket is longer than max allowed len for unix socket path (107):', path)
43
44 # If not a special Linux namespace...
45 if path[0] != '\0':
46 try:
47 os.unlink(path)
48 except FileNotFoundError:
49 pass
50
51 # Now bind+listen+NONBLOCK
52 sock.bind(path)
53 sock.setblocking(False)
54
55 self.register_fd(sock.fileno(), selectors.EVENT_READ, cb)
56 return sock
57
58 def select(self):
59 events = self._loop.select(timeout=self._timeout)
60 self._timeout = None
61 for key, mask in events:
62 key.data(key.fileobj, mask)