PageRenderTime 45ms CodeModel.GetById 23ms app.highlight 6ms RepoModel.GetById 14ms app.codeStats 0ms

/sparrowhawk/foundation/ESFSharedEmbeddedQueue.cpp

http://github.com/jtblatt/duderino
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