]> xenbits.xensource.com Git - xen.git/commitdiff
xend: Implement DGRAM (connectionless) type socket listeners
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 17 Mar 2009 10:36:20 +0000 (10:36 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 17 Mar 2009 10:36:20 +0000 (10:36 +0000)
Introduce SocketDgramListener and UnixDgramListener classes.
We already have STREAM (connection) type socket listener classes in
the source tree, but we need DGRAM (connectionless) type listeners to
receive udev events.

Signed-off-by: Yosuke Iwamatsu <y-iwamatsu@ab.jp.nec.com>
tools/python/xen/web/connection.py
tools/python/xen/web/unix.py

index 7d5702fce066489dc8b62c021186aa2a81fdf114..e507323e9155ebbe4b279470d4dd72867ad1e420 100644 (file)
@@ -292,3 +292,40 @@ def hostAllowed(addrport, hosts_allowed):
                 return True
         log.warn("Rejected connection from %s (%s).", addrport[0], fqdn)
         return False
+
+
+class SocketDgramListener:
+    """A connectionless server socket, running listen in a thread.
+    """
+
+    def __init__(self, protocol_class):
+        self.protocol = protocol_class()
+        self.sock = self.createSocket()
+        threading.Thread(target=self.main).start()
+
+
+    def close(self):
+        try:
+            self.sock.close()
+        except:
+            pass
+
+
+    def createSocket(self):
+        raise NotImplementedError()
+
+
+    def main(self):
+        try:
+            while True:
+                try:
+                    data = self.sock.recv(BUFFER_SIZE)
+                    self.protocol.dataReceived(data)
+                except socket.error, ex:
+                    if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR):
+                        break
+        finally:
+            try:
+                self.close()
+            except:
+                pass
index 12b6e9694edb69401b25cf12222d392648a12526..180c0858ebd0c91c3b5957fbe411d573976f8f42 100644 (file)
@@ -27,16 +27,19 @@ from xen.util import mkdir
 import connection
 
 
-def bind(path):
-    """Create a Unix socket, and bind it to the given path.  The socket is
-created such that only the current user may access it."""
+def bind(path, type = socket.SOCK_STREAM):
+    """Create a Unix socket, and bind it to the given path.
+    The socket is created such that only the current user may access it."""
 
-    parent = os.path.dirname(path)
-    mkdir.parents(parent, stat.S_IRWXU, True)
-    if os.path.exists(path):
-        os.unlink(path)
+    if path[0] == '\0': # Abstract namespace is used for the path
+        pass
+    else:
+        parent = os.path.dirname(path)
+        mkdir.parents(parent, stat.S_IRWXU, True)
+        if os.path.exists(path):
+            os.unlink(path)
 
-    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+    sock = socket.socket(socket.AF_UNIX, type)
     sock.bind(path)
     return sock
 
@@ -48,8 +51,19 @@ class UnixListener(connection.SocketListener):
 
 
     def createSocket(self):
-        return bind(self.path)
+        return bind(self.path, socket.SOCK_STREAM)
 
 
     def acceptConnection(self, sock, _):
         connection.SocketServerConnection(sock, self.protocol_class)
+
+
+class UnixDgramListener(connection.SocketDgramListener):
+    def __init__(self, path, protocol_class):
+        self.path = path
+        connection.SocketDgramListener.__init__(self, protocol_class)
+
+
+    def createSocket(self):
+        return bind(self.path, socket.SOCK_DGRAM)
+