From 8be437d44e59c043d79f072c04a06b295c913b3b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 7 Jun 2021 14:32:25 +0200 Subject: PySide6: Add QSharedMemory Return a buffer from data()/constData(), from which a memoryview can be constructed. [ChangeLog][PySide6] QSharedMemory was added. Fixes: PYSIDE-1370 Task-number: PYSIDE-1482 Change-Id: I089801c55ed696d3dd59ef64da0e52e538e9b54d Reviewed-by: Christian Tismer (cherry picked from commit 4ee3c492e3fd19d7f863f0e2853901e0cb8f2c9e) Reviewed-by: Qt Cherry-pick Bot --- sources/pyside6/PySide6/QtCore/CMakeLists.txt | 1 + .../PySide6/QtCore/typesystem_core_common.xml | 16 +++- sources/pyside6/PySide6/glue/qtcore.cpp | 10 +++ .../pyside6/tests/QtCore/qsharedmemory_client.py | 61 ++++++++++++++ sources/pyside6/tests/QtCore/qsharedmemory_test.py | 98 ++++++++++++++++++++++ 5 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 sources/pyside6/tests/QtCore/qsharedmemory_client.py create mode 100644 sources/pyside6/tests/QtCore/qsharedmemory_test.py diff --git a/sources/pyside6/PySide6/QtCore/CMakeLists.txt b/sources/pyside6/PySide6/QtCore/CMakeLists.txt index a6d523e89..66b15b060 100644 --- a/sources/pyside6/PySide6/QtCore/CMakeLists.txt +++ b/sources/pyside6/PySide6/QtCore/CMakeLists.txt @@ -128,6 +128,7 @@ ${QtCore_GEN_DIR}/qsemaphore_wrapper.cpp ${QtCore_GEN_DIR}/qsemaphorereleaser_wrapper.cpp ${QtCore_GEN_DIR}/qsequentialanimationgroup_wrapper.cpp ${QtCore_GEN_DIR}/qsettings_wrapper.cpp +${QtCore_GEN_DIR}/qsharedmemory_wrapper.cpp ${QtCore_GEN_DIR}/qsignalblocker_wrapper.cpp ${QtCore_GEN_DIR}/qsignalmapper_wrapper.cpp ${QtCore_GEN_DIR}/qsize_wrapper.cpp diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml index bec575e54..16d739056 100644 --- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml +++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml @@ -513,7 +513,7 @@ - + @@ -3020,6 +3020,20 @@ + + + + + + + + + + + + diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp index a30c6635b..bbc18c59e 100644 --- a/sources/pyside6/PySide6/glue/qtcore.cpp +++ b/sources/pyside6/PySide6/glue/qtcore.cpp @@ -1913,3 +1913,13 @@ Py_DECREF(oldResult); Py_DECREF(suffix); #endif // @snippet qlibraryinfo_build + +// @snippet qsharedmemory_data_readonly +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size()); +// @snippet qsharedmemory_data_readonly + +// @snippet qsharedmemory_data_readwrite +// FIXME: There is no way to tell whether QSharedMemory was attached read/write +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size(), + Shiboken::Buffer::ReadWrite); +// @snippet qsharedmemory_data_readwrite diff --git a/sources/pyside6/tests/QtCore/qsharedmemory_client.py b/sources/pyside6/tests/QtCore/qsharedmemory_client.py new file mode 100644 index 000000000..fd994b0cb --- /dev/null +++ b/sources/pyside6/tests/QtCore/qsharedmemory_client.py @@ -0,0 +1,61 @@ +############################################################################# +## +## Copyright (C) 2021 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Client for the unit test of QSharedMemory''' + +import sys + +from PySide6.QtCore import QSharedMemory + + +def read_string(shared_memory): + """Read out a null-terminated string from the QSharedMemory""" + mv = memoryview(shared_memory.constData()) + result = '' + for i in range(shared_memory.size()): + char = mv[i] + if not char: + break + result += chr(char) + return result + + +if __name__ == '__main__': + if len(sys.argv) != 2: + print('Pass segment name', file=sys.stderr) + sys.exit(-1) + shared_memory = QSharedMemory(sys.argv[1]) + if not shared_memory.attach(QSharedMemory.ReadOnly): + raise SystemError(f'attach to "{name}" failed') + if not shared_memory.lock(): + raise SystemError(f'lock of "{name}" failed') + data = read_string(shared_memory) + shared_memory.unlock() + shared_memory.detach() + sys.stdout.write(data) + sys.exit(0) diff --git a/sources/pyside6/tests/QtCore/qsharedmemory_test.py b/sources/pyside6/tests/QtCore/qsharedmemory_test.py new file mode 100644 index 000000000..ee2e6c40a --- /dev/null +++ b/sources/pyside6/tests/QtCore/qsharedmemory_test.py @@ -0,0 +1,98 @@ +############################################################################# +## +## Copyright (C) 2021 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Unit tests for QSharedMemory''' + +import ctypes +import os +import subprocess +import sys +import unittest + +from pathlib import Path +FILE = Path(__file__).resolve() +sys.path.append(os.fspath(FILE.parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QSharedMemory, QRandomGenerator, qVersion +from qsharedmemory_client import read_string + + +TEST_STRING = 'ABCD' + + +def run(cmd): + # FIXME Python 3.7: Use subprocess.run() + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False, + universal_newlines=True) + output, error = proc.communicate() + proc.wait() + return_code = proc.returncode + return (return_code, output, error) + + +class QSharedMemoryTest(unittest.TestCase): + + def setUp(self): + r = QRandomGenerator.global_().bounded(1000) + v = qVersion() + self._name = f"pyside{v}_test_{r}" + print(self._name) + self._shared_memory = QSharedMemory(self._name) + + def tearDown(self): + if self._shared_memory.isAttached(): + self._shared_memory.detach() + + def test(self): + # Create and write + self.assertTrue(self._shared_memory.create(1024, QSharedMemory.ReadWrite)) + self.assertTrue(self._shared_memory.lock()) + mv = memoryview(self._shared_memory.data()) + for idx, c in enumerate(TEST_STRING + chr(0)): + mv[idx] = ord(c) + mv = None + self.assertTrue(self._shared_memory.unlock()) + + # Read + self.assertTrue(self._shared_memory.lock()) + self.assertEqual(read_string(self._shared_memory), TEST_STRING) + self.assertTrue(self._shared_memory.unlock()) + + # Run a subprocess and let it read + client = FILE.parent / 'qsharedmemory_client.py' + returncode, output, error = run([sys.executable, client, self._name]) + if error: + print(error, file=sys.stderr) + self.assertEqual(returncode, 0) + self.assertEqual(output, TEST_STRING) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.3