summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2009-07-20 18:04:19 +0200
committerJulian Andres Klode <jak@debian.org>2009-07-20 18:04:19 +0200
commit652a7312b21aa7121c0075c3c970d5f68fcdf648 (patch)
tree019f7b8df3a4011c5121d9530f6ed576f63a9f09
parentc35f51be417e029a9ca4a571c3fcd7309634b21b (diff)
downloadpython-apt-652a7312b21aa7121c0075c3c970d5f68fcdf648.tar.gz
python/lock.cc: Introduce apt_pkg.SystemLock context manager.
This is the new alternative to pkgsystem_lock() and pkgsystem_unlock(), and is the recommended one.
-rw-r--r--python/apt_pkgmodule.cc1
-rw-r--r--python/apt_pkgmodule.h1
-rw-r--r--python/lock.cc123
-rw-r--r--setup.py2
4 files changed, 126 insertions, 1 deletions
diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc
index cbf88294..d4c23d2f 100644
--- a/python/apt_pkgmodule.cc
+++ b/python/apt_pkgmodule.cc
@@ -651,6 +651,7 @@ extern "C" void initapt_pkg()
ADDTYPE(Module,"AcquireProgress",&PyAcquireProgress_Type);
ADDTYPE(Module,"AcquireItemDesc",&PyAcquireItemDesc_Type);
ADDTYPE(Module,"CdromProgress",&PyCdromProgress_Type);
+ ADDTYPE(Module,"SystemLock",&PySystemLock_Type);
// Tag file constants
PyModule_AddObject(Module,"REWRITE_PACKAGE_ORDER",
CharCharToList(TFRewritePackageOrder));
diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h
index 1277ab60..de70c056 100644
--- a/python/apt_pkgmodule.h
+++ b/python/apt_pkgmodule.h
@@ -117,6 +117,7 @@ extern PyTypeObject PyAcquireProgress_Type;
extern PyTypeObject PyCdromProgress_Type;
extern PyTypeObject PyAcquireItemDesc_Type;
extern PyTypeObject PyAcquireWorker_Type;
+extern PyTypeObject PySystemLock_Type;
#include "python-apt.h"
#endif
diff --git a/python/lock.cc b/python/lock.cc
new file mode 100644
index 00000000..aac2d25a
--- /dev/null
+++ b/python/lock.cc
@@ -0,0 +1,123 @@
+/*
+ * lock.cc - Context managers for implementing locking.
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * 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.
+ */
+#include <apt-pkg/init.h>
+#include <apt-pkg/error.h>
+#include <Python.h>
+#include "generic.h"
+
+static PyObject *systemlock_exit(PyObject *self, PyObject *args)
+{
+
+ PyObject *exc_type = 0;
+ PyObject *exc_value = 0;
+ PyObject *traceback = 0;
+ if (!PyArg_UnpackTuple(args, "__exit__", 3, 3, &exc_type, &exc_value,
+ &traceback)) {
+ return 0;
+ }
+ if ((! exc_type || exc_type == Py_None) && _system->UnLock() == 0) {
+ return HandleErrors();
+ }
+ Py_RETURN_FALSE;
+}
+
+static PyObject *systemlock_enter(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ if (!_system->Lock())
+ return HandleErrors();
+ return self;
+}
+
+static PyObject *systemlock_new(PyTypeObject *type, PyObject *args,
+ PyObject *kwds)
+{
+ if (_system == 0) {
+ PyErr_SetString(PyExc_ValueError,"_system not initialized");
+ return 0;
+ }
+ return PyType_GenericNew(type,args,kwds);
+}
+
+static PyMethodDef systemlock_methods[] = {
+ {"__enter__",systemlock_enter,METH_VARARGS,"Lock the system."},
+ {"__exit__",systemlock_exit,METH_VARARGS,"Unlock the system."},
+ {NULL}
+};
+
+static char *systemlock_doc = "SystemLock()\n\n"
+ "Context manager for locking the package system. The lock is established\n"
+ "as soon as the method __enter__() is called. It is released when\n"
+ "__exit__() is called.\n\n"
+ "This should be used via the 'with' statement, e.g.::\n\n"
+ " with apt_pkg.SystemLock():\n"
+ " ...\n\n"
+ "Once the block is left, the lock is released automatically. The object\n"
+ "can be used multiple times::\n\n"
+ " lock = apt_pkg.SystemLock()\n"
+ " with lock:\n"
+ " ...\n"
+ " with lock:\n"
+ " ...\n\n";
+
+PyTypeObject PySystemLock_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.SystemLock", // tp_name
+ 0, // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ 0, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ systemlock_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ systemlock_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ systemlock_new, // tp_new
+};
diff --git a/setup.py b/setup.py
index 5cfe3bdc..e07bd83b 100644
--- a/setup.py
+++ b/setup.py
@@ -35,7 +35,7 @@ files = ['apt_pkgmodule.cc', 'acquire.cc', 'cache.cc', 'cdrom.cc',
'hashstring.cc', 'indexfile.cc', 'indexrecords.cc', 'metaindex.cc',
'pkgmanager.cc', 'pkgrecords.cc', 'pkgsrcrecords.cc', 'policy.cc',
'progress.cc', 'sourcelist.cc', 'string.cc', 'tag.cc',
- 'opprogress.cc', 'acquireprogress.cc', 'cdromprogress.cc']
+ 'opprogress.cc', 'acquireprogress.cc', 'cdromprogress.cc', 'lock.cc']
files = sorted(['python/' + fname for fname in files])
apt_pkg = Extension("apt_pkg", files, libraries=["apt-pkg"])