summaryrefslogtreecommitdiff
path: root/subvertpy/_ra_iter_log.c
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2010-07-25 16:06:49 +0200
committerJelmer Vernooij <jelmer@samba.org>2010-07-25 16:06:49 +0200
commit487ba5e6ece501cf721ce23b7ff34e7fd94393bc (patch)
treef388f35f798d669c4fda46a2cd5534901c2ae0ff /subvertpy/_ra_iter_log.c
parenta1eb50308c222172d1eea116ba86d6b3357be4de (diff)
Fix arbitrary iteration over None.
Diffstat (limited to 'subvertpy/_ra_iter_log.c')
-rw-r--r--subvertpy/_ra_iter_log.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/subvertpy/_ra_iter_log.c b/subvertpy/_ra_iter_log.c
index f013487b..5e5ecb65 100644
--- a/subvertpy/_ra_iter_log.c
+++ b/subvertpy/_ra_iter_log.c
@@ -37,6 +37,8 @@ typedef struct {
svn_boolean_t done;
PyObject *exception;
PyThread_type_lock lock;
+ PyThread_type_lock suspend_thread;
+ int queue_size;
struct log_entry *head;
struct log_entry *tail;
} LogIteratorObject;
@@ -50,32 +52,40 @@ static void log_iter_dealloc(PyObject *self)
static PyObject *log_iter_next(LogIteratorObject *iter)
{
+ struct log_entry *first;
+ PyObject *ret;
+ Py_BEGIN_ALLOW_THREADS
PyThread_acquire_lock(iter->lock, WAIT_LOCK);
- if (iter->head == NULL) {
+ Py_END_ALLOW_THREADS
+
+ while (iter->head == NULL) {
/* Done, raise stopexception */
- if (iter->done) {
+ if (iter->done) {
if (iter->exception) {
PyThread_release_lock(iter->lock);
PyErr_SetNone(iter->exception);
- return NULL;
} else {
PyThread_release_lock(iter->lock);
PyErr_SetNone(PyExc_StopIteration);
- return NULL;
}
+ return NULL;
} else {
- /* FIXME: Wait for next item to come in */
PyThread_release_lock(iter->lock);
- Py_RETURN_NONE;
+ Py_BEGIN_ALLOW_THREADS
+ /* FIXME: Don't waste cycles */
+ PyThread_acquire_lock(iter->lock, WAIT_LOCK);
+ Py_END_ALLOW_THREADS
}
- } else {
- struct log_entry *first = iter->head;
- PyObject *ret = iter->head->tuple;
- iter->head = first->next;
- free(first);
- PyThread_release_lock(iter->lock);
- return ret;
}
+ first = iter->head;
+ ret = iter->head->tuple;
+ iter->head = first->next;
+ if (first == iter->tail)
+ iter->tail = NULL;
+ free(first);
+ iter->queue_size--;
+ PyThread_release_lock(iter->lock);
+ return ret;
}
PyTypeObject LogIterator_Type = {
@@ -157,6 +167,8 @@ static PyObject *py_iter_append(LogIteratorObject *iter, PyObject *tuple)
if (iter->head == NULL)
iter->head = entry;
+ iter->queue_size++;
+
PyThread_release_lock(iter->lock);
Py_RETURN_NONE;
@@ -355,6 +367,7 @@ PyObject *ra_iter_log(PyObject *self, PyObject *args, PyObject *kwargs)
ret->apr_revprops = apr_revprops;
ret->done = FALSE;
ret->lock = PyThread_allocate_lock();
+ ret->queue_size = 0;
ret->head = NULL;
ret->tail = NULL;