Exemplo n.º 1
0
	/**
	 * pops the next item from the top of the queue.  this may cause the calling
	 * thread to sleep until an item is available, and will only return when an
	 * item has been successfully retrieved or when the thread is stopping
	 *
	 * @param t assigned to the item at the top of the queue
	 * @param thread_info ConsumerThread object used to manage the thread
	 *
	 * @return true if an item was retrieved, false if the queue is empty
	 */
	bool pop(T& t, ConsumerThread& thread_info) {
		boost::uint32_t last_known_version;
		while (thread_info.isRunning()) {
			// try to get the next value
			if ( dequeue(t, last_known_version) )
				return true;	// got an item

			// queue is empty
			boost::mutex::scoped_lock tail_lock(m_tail_mutex);
			if (m_tail_ptr->version == last_known_version) {
				// still empty after acquiring lock
				thread_info.m_next_ptr = m_idle_ptr;
				m_idle_ptr = & thread_info;
				// get wakeup time (if any)
				if (thread_info.hasWakeupTimer()) {
					// wait for an item to become available
					const boost::posix_time::ptime wakeup_time(boost::get_system_time() + thread_info.getWakeupTimer());
					if (!thread_info.m_wakeup_event.timed_wait(tail_lock, wakeup_time))
						return false;	// timer expired if timed_wait() returns false
				} else {
					// wait for an item to become available
					thread_info.m_wakeup_event.wait(tail_lock);
				}
			}
		}
		return false;
	}
Exemplo n.º 2
0
	/**
	 * pushes a new item into the back of the queue
	 *
	 * @param t the item to add to the back of the queue
	 */
	void push(const T& t) {
		// sleep while MaxSize is exceeded
		if (MaxSize > 0) {
			boost::system_time wakeup_time;
			while (size() >= MaxSize) {
				wakeup_time = boost::get_system_time()
					+ boost::posix_time::millisec(SleepMilliSec);
				boost::thread::sleep(wakeup_time);
			}
		}

		// create a new list node for the queue item
		QueueNode *node_ptr = createNode();
		node_ptr->data = t;
		node_ptr->next = NULL;
		node_ptr->version = 0;

		// append node to the end of the list
		boost::mutex::scoped_lock tail_lock(m_tail_mutex);
		node_ptr->version = (m_next_version += 2);
		m_tail_ptr->next = node_ptr;

		// update the tail pointer for the new node
		m_tail_ptr = node_ptr;

		// increment size
		++m_size;

		// wake up an idle thread (if any)
		if (m_idle_ptr) {
			ConsumerThread *idle_ptr = m_idle_ptr;
			m_idle_ptr = m_idle_ptr->m_next_ptr;
			idle_ptr->m_wakeup_event.notify_one();
		}
	}
 void push(T new_value) {
     std::shared_ptr<T> new_data(
       std::make_shared<T>(std::move(new_value)));
     std::unique_ptr<node> p(new node());
     const node* new_tail = p.get();
     std::lock_guard<std::mutex> tail_lock(_tail_mutex);
     _tail->data = new_data;
     _tail->next = std::move(p);
     _tail = new_tail;
 }
Exemplo n.º 4
0
	/// clears the list by removing all remaining items
	void clear(void) {
		boost::mutex::scoped_lock tail_lock(m_tail_mutex);
		boost::mutex::scoped_lock head_lock(m_head_mutex);
		// also delete dummy node and reinitialize it to clear old value
		while (m_head_ptr) {
			m_tail_ptr = m_head_ptr;
			m_head_ptr = m_head_ptr->next;
			destroyNode(m_tail_ptr);
			if (m_head_ptr)
				--m_size;
		}
		initialize();
	}
Exemplo n.º 5
0
 void push(T new_value)
 {
     std::shared_ptr<T> new_data(
         std::make_shared<T>(std::move(new_value)));
     std::unique_ptr<node> p(new node);
     {
         std::lock_guard<std::mutex> tail_lock(tail_mutex);
         tail->data = new_data;
         node *const new_tail = p.get();
         tail->next = std::move(p);
         tail = new_tail;
     }
     data_cond.notify_one();
 }
 node* get_tail() {
     std::lock_guard<std::mutex> tail_lock(_tail_mutex);
     return _tail;
 }