/sparrowhawk/foundation/ESFSharedEmbeddedQueue.cpp
C++ | 138 lines | 85 code | 37 blank | 16 comment | 28 complexity | 422918a3043a01ed74a3f18fa015d3bf MD5 | raw file
1/** @file ESFSharedEmbeddedQueue.cpp 2 * @brief A producer/consumer queue of ESFEmbeddedListElements 3 * 4 * Copyright (c) 2009 Yahoo! Inc. 5 * The copyrights embodied in the content of this file are licensed by Yahoo! Inc. 6 * under the BSD (revised) open source license. 7 * 8 * Derived from code that is Copyright (c) 2009 Joshua Blatt and offered under both 9 * BSD and Apache 2.0 licenses (http://sourceforge.net/projects/sparrowhawk/). 10 * 11 * 12 * $Author: blattj $ 13 * $Date: 2009/05/25 21:51:08 $ 14 * $Name: $ 15 * $Revision: 1.3 $ 16 */ 17 18#ifndef ESF_SHARED_EMBEDDED_QUEUE_H 19#include <ESFSharedEmbeddedQueue.h> 20#endif 21 22ESFSharedEmbeddedQueue::ESFSharedEmbeddedQueue() : 23 _isStopped(false), _list() { 24#if defined HAVE_PTHREAD_MUTEX_INIT && defined HAVE_PTHREAD_COND_INIT && \ 25 defined HAVE_PTHREAD_MUTEX_DESTROY && defined HAVE_PTHREAD_COND_DESTROY 26 27 pthread_mutex_init(&_mutex, 0); 28 pthread_cond_init(&_signal, 0); 29 30#else 31#error "Platform has no mutex or signal initializer" 32#endif 33} 34 35ESFSharedEmbeddedQueue::~ESFSharedEmbeddedQueue() { 36#if defined HAVE_PTHREAD_MUTEX_DESTROY && defined HAVE_PTHREAD_COND_DESTROY 37 38 pthread_mutex_destroy(&_mutex); 39 pthread_cond_destroy(&_signal); 40 41#else 42#error "Platform has no mutex or signal destructor" 43#endif 44} 45 46ESFError ESFSharedEmbeddedQueue::push(ESFEmbeddedListElement *element) { 47#if defined HAVE_PTHREAD_MUTEX_LOCK && defined HAVE_PTHREAD_MUTEX_UNLOCK && defined HAVE_PTHREAD_COND_SIGNAL 48 49 ESFError error = ESFConvertError(pthread_mutex_lock(&_mutex)); 50 51 if (ESF_SUCCESS != error) { 52 return error; 53 } 54 55 if (_isStopped) { 56 pthread_mutex_unlock(&_mutex); 57 58 return ESF_SHUTDOWN; 59 } 60 61 _list.addLast(element); 62 63 pthread_mutex_unlock(&_mutex); 64 pthread_cond_signal(&_signal); 65 66#else 67#error "Platform has no mutex lock, mutex unlock, or cond signal" 68#endif 69 70 return ESF_SUCCESS; 71} 72 73ESFEmbeddedListElement *ESFSharedEmbeddedQueue::pop(ESFError *result) { 74 ESFEmbeddedListElement *tmp = 0; 75 76 if (result) *result = ESF_SUCCESS; 77 78#if defined HAVE_PTHREAD_MUTEX_LOCK && defined HAVE_PTHREAD_MUTEX_UNLOCK && defined HAVE_PTHREAD_COND_WAIT 79 80 ESFError error = ESFConvertError(pthread_mutex_lock(&_mutex)); 81 82 if (ESF_SUCCESS != error) { 83 if (result) *result = error; 84 return 0; 85 } 86 87 do { 88 if (_isStopped) { 89 break; 90 } 91 92 tmp = _list.removeFirst(); 93 94 if (tmp) { 95 break; 96 } 97 98 error = ESFConvertError(pthread_cond_wait(&_signal, &_mutex)); 99 100 if (ESF_SUCCESS != error && ESF_INTR != error) { 101 if (result) *result = error; 102 return 0; 103 } 104 } while (0 == tmp); 105 106 pthread_mutex_unlock(&_mutex); 107 108#else 109#error "Platform has no mutex lock, mutex unlock, or cond wait" 110#endif 111 112 if (tmp) { 113 return tmp; 114 } 115 116 if (result) { 117 *result = ESF_SHUTDOWN; 118 } 119 120 return 0; 121} 122 123void ESFSharedEmbeddedQueue::stop() { 124#if defined HAVE_PTHREAD_MUTEX_LOCK && defined HAVE_PTHREAD_MUTEX_UNLOCK && defined HAVE_PTHREAD_COND_BROADCAST 125 126 pthread_mutex_lock(&_mutex); 127 128 _isStopped = true; 129 _list.clear(true); 130 131 pthread_mutex_unlock(&_mutex); 132 pthread_cond_broadcast(&_signal); 133 134#else 135#error "Platform has no mutex lock, mutex unlock, or cond broadcast" 136#endif 137} 138