diff options
| author | Stephan Peijnik <debian@sp.or.at> | 2009-07-02 12:41:04 +0200 |
|---|---|---|
| committer | Stephan Peijnik <debian@sp.or.at> | 2009-07-02 12:41:04 +0200 |
| commit | d8c5f345039c9577d7326670afeeb7666c8d9c7c (patch) | |
| tree | fbe9d21eb71ad55bbf0c5c88feb2d6c9f0d19ef5 /python | |
| parent | 8e1755030e5c00bcb183213ada7084fb0f5f6be9 (diff) | |
| download | python-apt-d8c5f345039c9577d7326670afeeb7666c8d9c7c.tar.gz | |
C code must allow other python threads to work every now and then in progress.cc (take one).
Diffstat (limited to 'python')
| -rw-r--r-- | python/progress.cc | 20 | ||||
| -rw-r--r-- | python/progress.h | 17 |
2 files changed, 37 insertions, 0 deletions
diff --git a/python/progress.cc b/python/progress.cc index 95cece3b..ab0deaef 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -94,6 +94,7 @@ void PyOpProgress::Done() bool PyFetchProgress::MediaChange(string Media, string Drive) { + PyCbObj_END_ALLOW_THREADS //std::cout << "MediaChange" << std::endl; PyObject *arglist = Py_BuildValue("(ss)", Media.c_str(), Drive.c_str()); PyObject *result; @@ -106,6 +107,7 @@ bool PyFetchProgress::MediaChange(string Media, string Drive) // FIXME: find out what it should return usually //std::cerr << "res is: " << res << std::endl; + PyCbObj_BEGIN_ALLOW_THREADS return res; } @@ -116,6 +118,7 @@ void PyFetchProgress::UpdateStatus(pkgAcquire::ItemDesc &Itm, int status) // Added object file size and object partial size to // parameters that are passed to updateStatus. // -- Stephan + PyCbObj_END_ALLOW_THREADS PyObject *arglist = Py_BuildValue("(sssikk)", Itm.URI.c_str(), Itm.Description.c_str(), Itm.ShortDesc.c_str(), @@ -131,6 +134,7 @@ void PyFetchProgress::UpdateStatus(pkgAcquire::ItemDesc &Itm, int status) Itm.ShortDesc.c_str(), status); RunSimpleCallback("updateStatus", arglist); + PyCbObj_BEGIN_ALLOW_THREADS } @@ -190,11 +194,22 @@ void PyFetchProgress::Start() Py_XDECREF(o); RunSimpleCallback("start"); + /* After calling the start method we can safely allow + * other Python threads to do their work for now. + */ + PyCbObj_BEGIN_ALLOW_THREADS } void PyFetchProgress::Stop() { + /* After the stop operation occured no other threads + * are allowed. This is done so we have a matching + * PyCbObj_END_ALLOW_THREADS to our previous + * PyCbObj_BEGIN_ALLOW_THREADS (Python requires this!). + */ + std::cout << "PyFetchProgress::STOP" << std::endl; + PyCbObj_END_ALLOW_THREADS //std::cout << "Stop" << std::endl; pkgAcquireStatus::Stop(); RunSimpleCallback("stop"); @@ -202,6 +217,7 @@ void PyFetchProgress::Stop() bool PyFetchProgress::Pulse(pkgAcquire * Owner) { + PyCbObj_END_ALLOW_THREADS pkgAcquireStatus::Pulse(Owner); //std::cout << "Pulse" << std::endl; @@ -290,11 +306,13 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) RunSimpleCallback("pulse_items", arglist, &result); if (result != NULL && PyArg_Parse(result, "b", &res) && res == false) { // the user returned a explicit false here, stop + PyCbObj_BEGIN_ALLOW_THREADS return false; } arglist = Py_BuildValue("()"); if (!RunSimpleCallback("pulse", arglist, &result)) { + PyCbObj_BEGIN_ALLOW_THREADS return true; } @@ -303,9 +321,11 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) // most of the time the user who subclasses the pulse() // method forgot to add a return {True,False} so we just // assume he wants a True + PyCbObj_BEGIN_ALLOW_THREADS return true; } + PyCbObj_BEGIN_ALLOW_THREADS // fetching can be canceld by returning false return res; } diff --git a/python/progress.h b/python/progress.h index 5ac67b1c..29243bfc 100644 --- a/python/progress.h +++ b/python/progress.h @@ -15,10 +15,27 @@ #include <apt-pkg/cdrom.h> #include <Python.h> +/* PyCbObj_BEGIN_ALLOW_THREADS and PyCbObj_END_ALLOW_THREADS are sligthly + * modified versions of Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. + * Instead of storing the thread state in a function-local variable these + * use a class attribute (with the same) name, allowing blocking and + * unblocking from different class methods. + * Py_BLOCK_THREADS and Py_UNBLOCK_THREADS do not define their own + * local variable but use the one provided by PyCbObj_BEGIN_ALLOW_THREADS + * and thus are the same as Py_BLOCK_THREADS and Py_UNBLOCK_THREADS. + */ +#define PyCbObj_BEGIN_ALLOW_THREADS \ + _save = PyEval_SaveThread(); +#define PyCbObj_END_ALLOW_THREADS \ + PyEval_RestoreThread(_save); \ + _save = NULL; +#define PyCbObj_BLOCK_THREADS Py_BLOCK_THREADS +#define PyCbObj_UNBLOCK_THREADS Py_UNBLOCK_THREADS class PyCallbackObj { protected: PyObject *callbackInst; + PyThreadState *_save; public: void setCallbackInst(PyObject *o) { |
