summaryrefslogtreecommitdiff
path: root/SDL_Core/src/thirdPartyLibs/logger/log4cplus-1.1.0/include/log4cplus/helpers/queue.h
blob: 2ebd13c3e76d22f3d84655b8243063e5b921c113 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// -*- 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