Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 49 additions & 10 deletions boost_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <boost/thread/thread_time.hpp>
#include <boost/foreach.hpp>

/* get_many considarations:
/* get_many considerations:
* Avoid using get_many() on the consumer side and using put() on the producer.
* The get_many() thread is notified on every single put(), however immediatly
* goes to sleep again because the Queue is not big enough. Hence a lot of
Expand Down Expand Up @@ -128,7 +128,7 @@ Queue_dealloc(Queue *self)
Queue_clear(self);
delete self->bridge;
}
self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
}


Expand Down Expand Up @@ -667,8 +667,7 @@ static PyGetSetDef Queue_getsets[] = {
};

static PyTypeObject QueueType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
PyVarObject_HEAD_INIT(NULL, 0)
"boost_queue.Queue", /*tp_name*/
sizeof(Queue), /*tp_basicsize*/
0, /*tp_itemsize*/
Expand Down Expand Up @@ -708,24 +707,49 @@ static PyTypeObject QueueType = {
Queue_new, /* tp_new */
};

PyMODINIT_FUNC
initboost_queue(void){
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"boost_queue", /* m_name */
"Python wrapper for C++ Queue template using boost locking", /* m_doc */
-1, /* m_size */
NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
#endif

static PyObject *
moduleinit(void)
{
PyObject* module;
PyObject* std_lib_queue;
PyObject* std_empty;
PyObject* std_full;

if (PyType_Ready(&QueueType) < 0) {
return;
return NULL;
}

#if PY_MAJOR_VERSION >= 3
module = PyModule_Create(&moduledef);
#else
module = Py_InitModule("boost_queue", NULL);
#endif
if (module == NULL) {
return;
return NULL;
}

if((std_lib_queue = PyImport_ImportModule("Queue")) == NULL) {
return;
#if PY_MAJOR_VERSION >= 3
std_lib_queue = PyImport_ImportModule("queue");
#else
std_lib_queue = PyImport_ImportModule("Queue");
#endif

if(std_lib_queue == NULL) {
return NULL;
}

if((std_empty = PyObject_GetAttrString(std_lib_queue, "Empty")) == NULL) {
Expand Down Expand Up @@ -757,4 +781,19 @@ initboost_queue(void){

Py_INCREF((PyObject*) &QueueType);
PyModule_AddObject(module, "Queue", (PyObject*)&QueueType);

return module;
}

PyMODINIT_FUNC
#if PY_MAJOR_VERSION >= 3
PyInit_boost_queue(void)
{
return moduleinit();
}
#else
initboost_queue(void)
{
moduleinit();
}
#endif
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
mod = Extension(
'boost_queue',
sources=['boost_queue.cpp'],
libraries=['boost_thread', 'boost_date_time'],
libraries=['boost_thread', 'boost_date_time', 'boost_system'],
extra_compile_args=["-O2"],
)

Expand Down
6 changes: 3 additions & 3 deletions tests/perf_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, q):
threading.Thread.__init__(self)

def run(self):
for _ in xrange(10**6):
for _ in range(10**6):
self.q.get()

class Prod(threading.Thread):
Expand All @@ -34,7 +34,7 @@ def __init__(self, q):
threading.Thread.__init__(self)

def run(self):
for _ in xrange(10**6):
for _ in range(10**6):
self.q.put(BigFatObject())

if __name__ == '__main__':
Expand All @@ -46,4 +46,4 @@ def run(self):
start = time.time()
[x.start() for x in cons + prods]
[x.join() for x in prods + cons]
print time.time() - start
print(time.time() - start)
14 changes: 9 additions & 5 deletions tests/test_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
from boost_queue import Full
from boost_queue import Empty

import Queue as std_queue
import sys
if sys.version_info[0] >= 3:
import queue as std_queue
else:
import Queue as std_queue


class TestQueue(TestCase):
Expand Down Expand Up @@ -59,7 +63,7 @@ def consumer(test, q):

def test_get_put_with_thread_and_late_put(self):
def consumer(test, q):
to_consume = range(40)
to_consume = list(range(40))
for x in range(40):
to_consume.remove(q.get(True, 4))
self.assertEqual(to_consume, [])
Expand Down Expand Up @@ -129,8 +133,8 @@ def test_except_with_std_queue_empty(self):
def test_put_many_too_many_items(self):
q = Queue(1)
msg = "items of size 3 is bigger then maxsize: 1"
with self.assertRaisesRegexp(ValueError, msg):
q.put_many((1, 2, 3))
with self.assertRaises(ValueError, msg=msg):
q.put_many((1, 2, 3))

q.put(None)
with self.assertRaises(Full):
Expand All @@ -157,7 +161,7 @@ def test_get_many_enough_space(self):
def test_get_many_not_enough_space(self):
q = Queue(10)
msg = "you want to get 12 but maxsize is 10"
with self.assertRaisesRegexp(ValueError, msg):
with self.assertRaises(ValueError, msg=msg):
q.get_many(12)

with self.assertRaises(Empty):
Expand Down
10 changes: 5 additions & 5 deletions tests/test_std_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def setUp(self):

def simple_queue_test(self, q):
if not q.empty():
raise RuntimeError, "Call this function with an empty queue"
raise RuntimeError("Call this function with an empty queue")
# I guess we better check things actually queue correctly a little :)
q.put(111)
q.put(333)
Expand Down Expand Up @@ -155,7 +155,7 @@ def queue_join_test(self, q):
t.start()
threads.append(t)

for i in xrange(100):
for i in range(100):
q.put(i)
q.join()
self.assertEqual(self.cum, sum(range(100)),
Expand Down Expand Up @@ -208,20 +208,20 @@ def __init__(self, *args):
def _put(self, item):
if self.fail_next_put:
self.fail_next_put = False
raise FailingQueueException, "You Lose"
raise FailingQueueException("You Lose")
return Queue.Queue._put(self, item)
def _get(self):
if self.fail_next_get:
self.fail_next_get = False
raise FailingQueueException, "You Lose"
raise FailingQueueException("You Lose")
return Queue.Queue._get(self)

#class FailingQueueTest(unittest.TestCase, BlockingTestMixin):
def doit():

def failing_queue_test(self, q):
if not q.empty():
raise RuntimeError, "Call this function with an empty queue"
raise RuntimeError("Call this function with an empty queue")
for i in range(QUEUE_SIZE-1):
q.put(i)
# Test a failing non-blocking put.
Expand Down