From e0d98c07e7b073b85e817a3677c6c419ebb3ee36 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 14 Oct 2020 09:31:47 +0530 Subject: [PATCH] Wrap create mutex --- src/calibre/test_build.py | 3 +++ src/calibre/utils/windows/winutil.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/calibre/test_build.py b/src/calibre/test_build.py index 9cd22ffa3b..b2a6c328e2 100644 --- a/src/calibre/test_build.py +++ b/src/calibre/test_build.py @@ -247,6 +247,9 @@ class BuildTest(unittest.TestCase): os.rmdir(dpath) del h shutil.rmtree(tdir) + m = winutil.create_mutex("test-mutex", False) + self.assertRaises(OSError, winutil.create_mutex, 'test-mutex', False) + m.close() def test_sqlite(self): import sqlite3 diff --git a/src/calibre/utils/windows/winutil.cpp b/src/calibre/utils/windows/winutil.cpp index a01997f43d..84d42aa0a1 100644 --- a/src/calibre/utils/windows/winutil.cpp +++ b/src/calibre/utils/windows/winutil.cpp @@ -786,6 +786,20 @@ load_library(PyObject *self, PyObject *args) { return (PyObject*)Handle_create(h, ModuleHandle, PyTuple_GET_ITEM(args, 0)); } +static PyObject* +create_mutex(PyObject *self, PyObject *args) { + int initial_owner = 0, allow_existing = 1; + wchar_raii name; + if (!PyArg_ParseTuple(args, "O&|pp", py_to_wchar, &name, &allow_existing, &initial_owner)) return NULL; + HANDLE h = CreateMutexW(NULL, initial_owner, name.ptr()); + if (h == NULL) return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, PyTuple_GET_ITEM(args, 0)); + if (!allow_existing && GetLastError() == ERROR_ALREADY_EXISTS) { + CloseHandle(h); + return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_FileExistsError, ERROR_ALREADY_EXISTS, PyTuple_GET_ITEM(args, 0)); + } + return (PyObject*)Handle_create(h); +} + // Icon loading {{{ #pragma pack( push ) #pragma pack( 2 ) @@ -920,6 +934,7 @@ static const char winutil_doc[] = "Defines utility methods to interface with win #define M(name, args) { #name, name, args, ""} static PyMethodDef winutil_methods[] = { M(get_dll_directory, METH_NOARGS), + M(create_mutex, METH_VARARGS), M(get_async_key_state, METH_VARARGS), M(create_named_pipe, METH_VARARGS), M(set_handle_information, METH_VARARGS),