Saggi Mizrahi has uploaded a new change for review.

Change subject: infra: Introduce EventFD support
......................................................................

infra: Introduce EventFD support

This patch adds a wrapper for the eventfd(2) functionality.

For more information check the inline documentation.

Change-Id: I6035d4a8dc13ce11cf0425e4945bbf0c19bd92a7
Signed-off-by: Saggi Mizrahi <[email protected]>
---
M configure.ac
M doc/infra/index.rst
M lib/vdsm/infra/Makefile.am
M lib/vdsm/infra/__init__.py
A lib/vdsm/infra/eventfd/Makefile.am
A lib/vdsm/infra/eventfd/__init__.py
A lib/vdsm/infra/eventfd/tests.py
7 files changed, 206 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/51/37051/1

diff --git a/configure.ac b/configure.ac
index c3dfea4..35aa919 100644
--- a/configure.ac
+++ b/configure.ac
@@ -355,6 +355,7 @@
        lib/vdsm/tool/configurators/Makefile
        lib/yajsonrpc/Makefile
        lib/vdsm/infra/Makefile
+       lib/vdsm/infra/eventfd/Makefile
        lib/vdsm/infra/filecontrol/Makefile
        lib/vdsm/infra/zombiereaper/Makefile
        tests/Makefile
diff --git a/doc/infra/index.rst b/doc/infra/index.rst
index bb825f8..71f5bcc 100644
--- a/doc/infra/index.rst
+++ b/doc/infra/index.rst
@@ -4,5 +4,6 @@
 Contents:
 
 .. toctree::
+    eventfd
     filecontrol
     zombiereaper
diff --git a/lib/vdsm/infra/Makefile.am b/lib/vdsm/infra/Makefile.am
index b1c28be..55d4315 100644
--- a/lib/vdsm/infra/Makefile.am
+++ b/lib/vdsm/infra/Makefile.am
@@ -20,6 +20,7 @@
 include $(top_srcdir)/build-aux/Makefile.subs
 
 SUBDIRS = \
+       eventfd \
        filecontrol  \
        zombiereaper \
        $(NULL)
diff --git a/lib/vdsm/infra/__init__.py b/lib/vdsm/infra/__init__.py
index 6d5ba95..5eb0b07 100644
--- a/lib/vdsm/infra/__init__.py
+++ b/lib/vdsm/infra/__init__.py
@@ -18,6 +18,7 @@
 # Refer to the README and COPYING files for full details of the license
 #
 __all__ = [
+    "eventfd",
     "filecontrol",
     "zombiereaper",
 ]
diff --git a/lib/vdsm/infra/eventfd/Makefile.am 
b/lib/vdsm/infra/eventfd/Makefile.am
new file mode 100644
index 0000000..e4fc0ba
--- /dev/null
+++ b/lib/vdsm/infra/eventfd/Makefile.am
@@ -0,0 +1,34 @@
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+include $(top_srcdir)/build-aux/Makefile.subs
+
+eventfddir = $(vdsminfradir)/eventfd
+
+dist_eventfd_PYTHON = \
+       __init__.py \
+       $(NULL)
+
+dist_noinst_PYTHON = \
+       tests.py \
+       $(NULL)
+
+check-local:
+       nosetests tests.py
diff --git a/lib/vdsm/infra/eventfd/__init__.py 
b/lib/vdsm/infra/eventfd/__init__.py
new file mode 100644
index 0000000..cf13107
--- /dev/null
+++ b/lib/vdsm/infra/eventfd/__init__.py
@@ -0,0 +1,123 @@
+#
+# Copyright 2015 Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+"""
+This is a module to implement a python wrapper for eventfd(2).
+
+Please check the man page for complete information on eventfd(2).
+
+Flags:
+
+- EFD_CLOEXEC: Set the close-on-exec (FD_CLOEXEC) flag on the new file
+  descriptor.
+- EFD_NONBLOCK: Set the O_NONBLOCK file status flag on the new open file
+  description.
+- EFD_SEMAPHORE: Provide semaphore-like semantics for reads from the new file
+  descriptor.
+"""
+import ctypes
+import os
+
+
+libc = ctypes.CDLL("libc.so.6", use_errno=True)
+
+EFD_SEMAPHORE = 00000001,
+EFD_CLOEXEC = 02000000,
+EFD_NONBLOCK = 00004000
+
+
+class EventFD(object):
+    """
+    Creates an "eventfd object" that can be used as an event wait/notify
+    mechanism by user-space applications, and by the kernel to notify
+    user-space applications of events.
+
+    The object contains an unsigned 64-bit integer (uint64_t) counter that is
+    maintained by the kernel.  This counter is initialized with the value
+    specified in the argument initial_value.
+    """
+    def __init__(self, initial_value=0, flags=0):
+        fd = libc.eventfd(
+            ctypes.c_uint(initial_value),
+            ctypes.c_int(flags)
+        )
+        if fd < 0:
+            err = ctypes.get_errno()
+            if err != 0:
+                msg = os.strerror(err)
+                raise OSError(err, msg)
+        self._fd = fd
+
+    def fileno(self):
+        "Return the number of the eventfd"
+        return self._fd
+
+    def read(self):
+        """
+        The semantics of read depend on whether the eventfd counter currently
+        has a nonzero value and whether the EFD_SEMAPHORE flag was specified
+        when creating the eventfd file descriptor:
+
+        - If EFD_SEMAPHORE was not specified and the eventfd counter has a
+          nonzero value, then a read() returns that value, and the counter's
+          value is reset to zero.
+        - If EFD_SEMAPHORE was specified and the eventfd counter has a nonzero
+          value, then a read() the value 1, and the counter's value is
+          decremented by 1.
+        - If the eventfd counter is zero at the time of the call to read(),
+          then the call either blocks until the counter becomes nonzero (at
+          which time, the read() proceeds as described above) or fails with
+          the error EAGAIN if the file descriptor has been made nonblocking.
+        """
+        n = ctypes.c_uint64()
+        rv = libc.read(self._fd, ctypes.pointer(n), 8)
+        if rv < 0:
+            err = ctypes.get_errno()
+            if err != 0:
+                msg = os.strerror(err)
+                raise OSError(err, msg)
+
+        return int(n.value)
+
+    def write(self, value=1):
+        """
+        A  write()  call  adds the integer value to the counter. The maximum
+        value that may be stored in the counter is the largest unsigned 64-bit
+        value minus 1 (i.e., 0xfffffffffffffffe). If the addition would cause
+        the counter's value to exceed the maximum, then the write() either
+        blocks until a read() is performed on the file descriptor, or fails
+        with the error EAGAIN if the file descriptor has been made nonblocking.
+        """
+        n = ctypes.c_uint64(value)
+        rv = libc.write(self._fd, ctypes.pointer(n), 8)
+        if rv < 0:
+            err = ctypes.get_errno()
+            if err != 0:
+                msg = os.strerror(err)
+                raise OSError(err, msg)
+
+    def close(self):
+        "Closes the fd and clears the internal counter"
+        fd = self._fd
+        if fd != -1:
+            self._fd = -1
+            os.close(fd)
+
+    def __del__(self):
+        self.close()
diff --git a/lib/vdsm/infra/eventfd/tests.py b/lib/vdsm/infra/eventfd/tests.py
new file mode 100644
index 0000000..f19c772
--- /dev/null
+++ b/lib/vdsm/infra/eventfd/tests.py
@@ -0,0 +1,45 @@
+#
+# Copyright 2015 Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+from .. import eventfd
+from nose import tools
+
+
+def test_create():
+    efd = eventfd.EventFD()
+    tools.assert_is_not_none(efd)
+
+
+def test_close():
+    efd = eventfd.EventFD()
+    efd.close()
+    tools.assert_equals(efd.fileno(), -1)
+
+
+def test_read():
+    value = 10
+    efd = eventfd.EventFD(value)
+    tools.assert_equals(efd.read(), value)
+
+
+def test_write():
+    value = 10
+    efd = eventfd.EventFD()
+    efd.write(value)
+    tools.assert_equals(efd.read(), value)


-- 
To view, visit http://gerrit.ovirt.org/37051
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6035d4a8dc13ce11cf0425e4945bbf0c19bd92a7
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to