~ubuntu-branches/ubuntu/trusty/log4shib/trusty

« back to all changes in this revision

Viewing changes to include/log4shib/threading/OmniThreads.hh

  • Committer: Package Import Robot
  • Author(s): Russ Allbery
  • Date: 2012-06-05 21:20:25 UTC
  • Revision ID: package-import@ubuntu.com-20120605212025-uyigtav7dqwvnf41
Tags: upstream-1.0.4
ImportĀ upstreamĀ versionĀ 1.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * OmniThreads.hh
 
3
 *
 
4
 * Copyright 2002, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 
5
 * Copyright 2002, Bastiaan Bakker. All rights reserved.
 
6
 *
 
7
 * See the COPYING file for the terms of usage and distribution.
 
8
 */
 
9
 
 
10
#ifndef _LOG4SHIB_THREADING_OMNITHREADS_HH
 
11
#define _LOG4SHIB_THREADING_OMNITHREADS_HH
 
12
 
 
13
#include <log4shib/Portability.hh>
 
14
#include <omnithread.h>
 
15
#include <stdio.h>
 
16
#include <string>
 
17
 
 
18
namespace log4shib {
 
19
    namespace threading {
 
20
        /**
 
21
         * Return an identifier for the current thread. What these 
 
22
         * identifiers look like is completely up to the underlying 
 
23
         * thread library. OmniThreads returns the POSIX thread Id.
 
24
         **/
 
25
        std::string getThreadId();
 
26
        
 
27
        /**
 
28
         * A simple, non recursive Mutex.
 
29
         * Equivalent to Boost.Threads boost::mutex
 
30
         **/
 
31
        typedef omni_mutex Mutex;
 
32
 
 
33
        /**
 
34
         * A simple "resource acquisition is initialization" idiom type lock
 
35
         * for Mutex. 
 
36
         * Equivalent to Boost.Threads boost::scoped_lock.
 
37
         **/
 
38
        typedef omni_mutex_lock ScopedLock;
 
39
 
 
40
        /** 
 
41
         * This class holds Thread local data of type T, i.e. for each
 
42
         * thread a ThreadLocalDataHolder holds 0 or 1 instance of T. 
 
43
         * The held object must be heap allocated and will be deleted 
 
44
         * upon termination of the thread to wich it belongs.
 
45
         * This is an omni_threads based equivalent of Boost.Threads 
 
46
         * thread_specific_ptr<T> class.
 
47
         **/
 
48
        template<typename T> class ThreadLocalDataHolder {
 
49
            public:
 
50
            typedef T data_type;
 
51
 
 
52
            inline ThreadLocalDataHolder() :
 
53
                _key(omni_thread::allocate_key()) {};
 
54
 
 
55
            inline ~ThreadLocalDataHolder() {};
 
56
            
 
57
            /**
 
58
             * Obtains the Object held for the current thread.
 
59
             * @return a pointer to the held Object or NULL if no
 
60
             * Object has been set for the current thread.
 
61
             **/
 
62
            inline T* get() const {
 
63
                Holder* holder = dynamic_cast<Holder*>(
 
64
                    ::omni_thread::self()->get_value(_key));
 
65
                return (holder) ? holder->data : NULL;
 
66
            };
 
67
 
 
68
            /**
 
69
             * Obtains the Object held for the current thread. 
 
70
             * Initially each thread holds NULL.
 
71
             * @return a pointer to the held Object or NULL if no
 
72
             * Object has been set for the current thread.
 
73
             **/
 
74
            inline T* operator->() const { return get(); };
 
75
 
 
76
            /**
 
77
             * Obtains the Object held for the current thread.
 
78
             * @pre get() != NULL
 
79
             * @return a reference to the held Object.
 
80
             **/
 
81
            inline T& operator*() const { return *get(); };
 
82
 
 
83
            /**
 
84
             * Releases the Object held for the current thread.
 
85
             * @post get() == NULL
 
86
             * @return a pointer to the Object thas was held for 
 
87
             * the current thread or NULL if no Object was held.
 
88
             **/
 
89
            inline T* release() {
 
90
                T* result = NULL;
 
91
                Holder* holder = dynamic_cast<Holder*>(
 
92
                    ::omni_thread::self()->get_value(_key));
 
93
              
 
94
                if (holder) {
 
95
                    result = holder->data;
 
96
                    holder->data = NULL;
 
97
                }
 
98
 
 
99
                return result;
 
100
            };
 
101
 
 
102
            /**
 
103
             * Sets a new Object to be held for the current thread. A 
 
104
             * previously set Object will be deleted.
 
105
             * @param p the new object to hold.
 
106
             * @post get() == p
 
107
             **/
 
108
            inline void reset(T* p = NULL) {
 
109
                Holder* holder = dynamic_cast<Holder*>(
 
110
                    ::omni_thread::self()->get_value(_key));
 
111
                if (holder) {
 
112
                    if (holder->data)
 
113
                        delete holder->data;
 
114
 
 
115
                    holder->data = p;
 
116
                } else {
 
117
                    holder = new Holder(p);
 
118
                    ::omni_thread::self()->set_value(_key, holder);
 
119
                }
 
120
            };
 
121
 
 
122
            private:            
 
123
            class Holder : public omni_thread::value_t {
 
124
                public:
 
125
                Holder(data_type* data) : data(data) {};
 
126
                virtual ~Holder() { if (data) delete (data); };
 
127
                data_type* data;
 
128
                private:
 
129
                Holder(const Holder& other);
 
130
                Holder& operator=(const Holder& other);
 
131
            };
 
132
 
 
133
            omni_thread::key_t _key;            
 
134
        };
 
135
    }
 
136
}
 
137
#endif