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
