You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							158 lines
						
					
					
						
							5.4 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							158 lines
						
					
					
						
							5.4 KiB
						
					
					
				
								// -*- C++ -*-
							 | 
						|
								//  Copyright (C) 2009-2010, Vaclav Haisman. All rights reserved.
							 | 
						|
								//  
							 | 
						|
								//  Redistribution and use in source and binary forms, with or without modifica-
							 | 
						|
								//  tion, are permitted provided that the following conditions are met:
							 | 
						|
								//  
							 | 
						|
								//  1. Redistributions of  source code must  retain the above copyright  notice,
							 | 
						|
								//     this list of conditions and the following disclaimer.
							 | 
						|
								//  
							 | 
						|
								//  2. Redistributions in binary form must reproduce the above copyright notice,
							 | 
						|
								//     this list of conditions and the following disclaimer in the documentation
							 | 
						|
								//     and/or other materials provided with the distribution.
							 | 
						|
								//  
							 | 
						|
								//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
							 | 
						|
								//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
							 | 
						|
								//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
							 | 
						|
								//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
							 | 
						|
								//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
							 | 
						|
								//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
							 | 
						|
								//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
							 | 
						|
								//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
							 | 
						|
								//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
							 | 
						|
								//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
							 | 
						|
								
							 | 
						|
								#ifndef LOG4CPLUS_HELPERS_QUEUE_H
							 | 
						|
								#define LOG4CPLUS_HELPERS_QUEUE_H
							 | 
						|
								
							 | 
						|
								#include <log4cplus/config.hxx>
							 | 
						|
								
							 | 
						|
								#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
							 | 
						|
								#pragma once
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#if ! defined (LOG4CPLUS_SINGLE_THREADED)
							 | 
						|
								
							 | 
						|
								#include <deque>
							 | 
						|
								#include <log4cplus/spi/loggingevent.h>
							 | 
						|
								#include <log4cplus/thread/threads.h>
							 | 
						|
								#include <log4cplus/thread/syncprims.h>
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								namespace log4cplus { namespace thread {
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								//! Single consumer, multiple producers queue.
							 | 
						|
								class LOG4CPLUS_EXPORT Queue
							 | 
						|
								    : public virtual helpers::SharedObject
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    //! Type of the state flags field.
							 | 
						|
								    typedef unsigned flags_type;
							 | 
						|
								
							 | 
						|
								    //! Queue storage type.
							 | 
						|
								    typedef std::deque<spi::InternalLoggingEvent> queue_storage_type;
							 | 
						|
								
							 | 
						|
								    Queue (unsigned len = 100);
							 | 
						|
								    virtual ~Queue ();
							 | 
						|
								
							 | 
						|
								    // Producers' methods.
							 | 
						|
								
							 | 
						|
								    //! Puts event <code>ev</code> into queue, sets QUEUE flag and
							 | 
						|
								    //! sets internal event object into signaled state. If the EXIT
							 | 
						|
								    //! flags is already set upon entering the function, nothing is
							 | 
						|
								    //! inserted into the queue. The function can block on internal
							 | 
						|
								    //! semaphore if the queue has reached maximal allowed
							 | 
						|
								    //! length. Calling thread is unblocked either by consumer thread
							 | 
						|
								    //! removing item from queue or by any other thread calling
							 | 
						|
								    //! signal_exit().
							 | 
						|
								    //!
							 | 
						|
								    //! \param ev spi::InternalLoggingEvent to be put into the queue.
							 | 
						|
								    //! \return Flags.
							 | 
						|
								    flags_type put_event (spi::InternalLoggingEvent const & ev);
							 | 
						|
								
							 | 
						|
								    //! Sets EXIT flag and DRAIN flag and sets internal event object
							 | 
						|
								    //! into signaled state.
							 | 
						|
								    //! \param drain If true, DRAIN flag will be set, otherwise unset.
							 | 
						|
								    //! \return Flags, ERROR_BIT can be set upon error.
							 | 
						|
								    flags_type signal_exit (bool drain = true);
							 | 
						|
								
							 | 
						|
								    // Consumer's methods.
							 | 
						|
								
							 | 
						|
								    //! The get_events() function is used by queue's consumer. It
							 | 
						|
								    //! fills <code>buf</code> argument and sets EVENT flag in return
							 | 
						|
								    //! value. If EXIT flag is already set in flags member upon
							 | 
						|
								    //! entering the function then depending on DRAIN flag it either
							 | 
						|
								    //! fills <code>buf</code> argument or does not fill the argument,
							 | 
						|
								    //! if the queue is non-empty. The function blocks by waiting for
							 | 
						|
								    //! internal event object to be signaled if the queue is empty,
							 | 
						|
								    //! unless EXIT flag is set. The calling thread is unblocked when
							 | 
						|
								    //! items are added into the queue or when exit is signaled using
							 | 
						|
								    //! the signal_exit() function.
							 | 
						|
								    //!
							 | 
						|
								    //!
							 | 
						|
								    //! Upon error, return value has one of the error flags set.
							 | 
						|
								    //!
							 | 
						|
								    //! \param buf Pointer to storage of spi::InternalLoggingEvent
							 | 
						|
								    //! instances to be filled from queue.
							 | 
						|
								    //! \return Flags.
							 | 
						|
								    flags_type get_events (queue_storage_type * buf);
							 | 
						|
								
							 | 
						|
								    //! Possible state flags.
							 | 
						|
								    enum Flags
							 | 
						|
								    {
							 | 
						|
								        //! EVENT flag is set in return value of get_event() call if
							 | 
						|
								        //! the <code>ev</code> argument is filled with event from the queue.
							 | 
						|
								        EVENT       = 0x0001,
							 | 
						|
								
							 | 
						|
								        //! QUEUE flag is set by producers when they put item into the
							 | 
						|
								        //! queue.
							 | 
						|
								        QUEUE       = 0x0002,
							 | 
						|
								
							 | 
						|
								        //! EXIT flag is set by signal_exit() call, signaling that the
							 | 
						|
								        //! queue worker thread should end itself.
							 | 
						|
								        EXIT        = 0x0004,
							 | 
						|
								
							 | 
						|
								        //! When DRAIN flag is set together with EXIT flag, the queue
							 | 
						|
								        //! worker thread will first drain the queue before exiting.
							 | 
						|
								        DRAIN       = 0x0008,
							 | 
						|
								
							 | 
						|
								        //! ERROR_BIT signals error.
							 | 
						|
								        ERROR_BIT   = 0x0010,
							 | 
						|
								
							 | 
						|
								        //! ERROR_AFTER signals error that has occured after queue has
							 | 
						|
								        //! already been touched.
							 | 
						|
								        ERROR_AFTER = 0x0020
							 | 
						|
								    };
							 | 
						|
								
							 | 
						|
								protected:
							 | 
						|
								    //! Queue storage.
							 | 
						|
								    queue_storage_type queue;
							 | 
						|
								
							 | 
						|
								    //! Mutex protecting queue and flags.
							 | 
						|
								    Mutex mutex;
							 | 
						|
								
							 | 
						|
								    //! Event on which consumer can wait if it finds queue empty.
							 | 
						|
								    ManualResetEvent ev_consumer;
							 | 
						|
								
							 | 
						|
								    //! Semaphore that limits the queue length.
							 | 
						|
								    Semaphore sem;
							 | 
						|
								
							 | 
						|
								    //! State flags.
							 | 
						|
								    flags_type flags;
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    Queue (Queue const &);
							 | 
						|
								    Queue & operator = (Queue const &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef helpers::SharedObjectPtr<Queue> QueuePtr;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								} } // namespace log4cplus { namespace thread {
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#endif // LOG4CPLUS_SINGLE_THREADED
							 | 
						|
								
							 | 
						|
								#endif // LOG4CPLUS_HELPERS_QUEUE_H
							 |