~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/xpinstall/wizard/libxpnet/GUSI/include/GUSISpecific.h

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
 
2
// % Project    :       GUSI                            -       Grand Unified Socket Interface                    
 
3
// % File               :       GUSISpecific.nw         -       Thread specific variables                  
 
4
// % Author     :       Matthias Neeracher                                           
 
5
// % Language   :       C++                                                        
 
6
// %                                                                       
 
7
// % $Log: GUSISpecific.h,v $
 
8
// % Revision 1.1  2001/03/11 22:38:39  sgehani%netscape.com
 
9
// % First Checked In.
 
10
// %                                             
 
11
// % Revision 1.9  2000/10/16 04:11:21  neeri                              
 
12
// % Plug memory leak                                                      
 
13
// %                                                                       
 
14
// % Revision 1.8  2000/03/15 07:22:07  neeri                              
 
15
// % Enforce alignment choices                                             
 
16
// %                                                                       
 
17
// % Revision 1.7  1999/08/26 05:45:10  neeri                              
 
18
// % Fixes for literate edition of source code                             
 
19
// %                                                                       
 
20
// % Revision 1.6  1999/05/30 03:09:31  neeri                              
 
21
// % Added support for MPW compilers                                       
 
22
// %                                                                       
 
23
// % Revision 1.5  1999/04/29 04:58:20  neeri                              
 
24
// % Fix key destruction bug                                               
 
25
// %                                                                       
 
26
// % Revision 1.4  1999/03/17 09:05:13  neeri                              
 
27
// % Added GUSITimer, expanded docs                                        
 
28
// %                                                                       
 
29
// % Revision 1.3  1998/10/11 16:45:25  neeri                              
 
30
// % Ready to release 2.0a2                                                
 
31
// %                                                                       
 
32
// % Revision 1.2  1998/08/01 21:32:11  neeri                              
 
33
// % About ready for 2.0a1                                                 
 
34
// %                                                                       
 
35
// % Revision 1.1  1998/01/25 21:02:52  neeri                              
 
36
// % Engine implemented, except for signals & scheduling                   
 
37
// %                                                                       
 
38
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
 
39
//                                                                         
 
40
// \chapter{Thread Specific Variables}                                     
 
41
//                                                                         
 
42
// It is often useful to have variables which maintain a different value   
 
43
// for each process. The [[GUSISpecific]] class implements such a mechanism
 
44
// in a way that is easily mappable to pthreads.                           
 
45
//                                                                         
 
46
//                                                                         
 
47
// <GUSISpecific.h>=                                                       
 
48
#ifndef _GUSISpecific_
 
49
#define _GUSISpecific_
 
50
 
 
51
#ifndef GUSI_SOURCE
 
52
 
 
53
typedef struct GUSISpecific     GUSISpecific;
 
54
 
 
55
#else
 
56
 
 
57
#include <Types.h>
 
58
#include <ConditionalMacros.h>
 
59
 
 
60
#if PRAGMA_STRUCT_ALIGN
 
61
#pragma options align=native
 
62
#endif
 
63
 
 
64
// \section{Definition of Thread Specific Variables}                       
 
65
//                                                                         
 
66
// A [[GUSISpecific]] instance contains a variable ID and a per-process    
 
67
// destructor.                                                             
 
68
//                                                                         
 
69
// <Definition of class [[GUSISpecific]]>=                                 
 
70
extern "C"  {
 
71
        typedef void (*GUSISpecificDestructor)(void *);
 
72
}
 
73
 
 
74
class GUSISpecific {
 
75
        friend class GUSISpecificTable;
 
76
public:
 
77
        GUSISpecific(GUSISpecificDestructor destructor = nil);
 
78
        ~GUSISpecific();
 
79
        
 
80
        void                                    Destruct(void * data);
 
81
private:
 
82
        GUSISpecificDestructor  fDestructor;
 
83
        unsigned                                fID;
 
84
        static unsigned                 sNextID;
 
85
};
 
86
// A [[GUSIContext]] contains a [[GUSISpecificTable]] storing the values of all
 
87
// thread specific variables defined for this thread.                      
 
88
//                                                                         
 
89
// <Definition of class [[GUSISpecificTable]]>=                            
 
90
class GUSISpecificTable {
 
91
        friend class GUSISpecific;
 
92
public:
 
93
        GUSISpecificTable();
 
94
        ~GUSISpecificTable();
 
95
        void *  GetSpecific(const GUSISpecific * key) const;
 
96
        void    SetSpecific(const GUSISpecific * key, void * value);
 
97
        void    DeleteSpecific(const GUSISpecific * key);
 
98
private:
 
99
        static void Register(GUSISpecific * key);
 
100
        static void Destruct(GUSISpecific * key);
 
101
        
 
102
        // We store a [[GUSISpecificTable]] as a contiguous range of IDs.          
 
103
 //                                                                         
 
104
 // <Privatissima of [[GUSISpecificTable]]>=                                
 
105
 void ***                               fValues;
 
106
 unsigned                               fAlloc;
 
107
 
 
108
 bool                                   Valid(const GUSISpecific * key) const;
 
109
 // All keys are registered in a global table.                              
 
110
 //                                                                         
 
111
 // <Privatissima of [[GUSISpecificTable]]>=                                
 
112
 static GUSISpecific ***        sKeys;
 
113
 static unsigned                        sKeyAlloc;
 
114
};
 
115
// To simplify having a particular variable assume a different instance in every
 
116
// thread, we define the [[GUSISpecificData]] template.                    
 
117
//                                                                         
 
118
// <Definition of template [[GUSISpecificData]]>=                          
 
119
template <class T, GUSISpecificDestructor D> 
 
120
class GUSISpecificData {
 
121
public:
 
122
        GUSISpecificData() : fKey(D)                    {                                                                               }
 
123
        T & operator*()                                                 { return *get();                                                }
 
124
        T * operator->()                                                { return get();                                                 }
 
125
        
 
126
        const GUSISpecific *    Key() const     { return &fKey;                                                 }
 
127
        T * get(GUSISpecificTable * table);
 
128
        T * get()                                                               { return get(GUSIContext::Current());   }
 
129
protected:
 
130
        GUSISpecific    fKey;
 
131
};
 
132
 
 
133
template <class T, GUSISpecificDestructor D> 
 
134
        T * GUSISpecificData<T,D>::get(GUSISpecificTable * table)
 
135
{
 
136
        void *                          data  = table->GetSpecific(&fKey);
 
137
        
 
138
        if (!data)
 
139
                table->SetSpecific(&fKey, data = new T);
 
140
        
 
141
        return static_cast<T *>(data);
 
142
}
 
143
 
 
144
#if PRAGMA_STRUCT_ALIGN
 
145
#pragma options align=reset
 
146
#endif
 
147
 
 
148
// <Inline member functions for class [[GUSISpecific]]>=                   
 
149
inline GUSISpecific::GUSISpecific(GUSISpecificDestructor destructor)
 
150
        : fDestructor(destructor), fID(sNextID++)
 
151
{
 
152
        GUSISpecificTable::Register(this);
 
153
}
 
154
 
 
155
inline GUSISpecific::~GUSISpecific()
 
156
{
 
157
        GUSISpecificTable::Destruct(this);
 
158
}
 
159
 
 
160
inline void GUSISpecific::Destruct(void * data)
 
161
{
 
162
        if (fDestructor)
 
163
                fDestructor(data);
 
164
}
 
165
// <Inline member functions for class [[GUSISpecificTable]]>=              
 
166
inline bool GUSISpecificTable::Valid(const GUSISpecific * key) const
 
167
{
 
168
        return key && key->fID < fAlloc;
 
169
}
 
170
// <Inline member functions for class [[GUSISpecificTable]]>=              
 
171
inline GUSISpecificTable::GUSISpecificTable()
 
172
        : fValues(nil), fAlloc(0)
 
173
{       
 
174
}
 
175
// <Inline member functions for class [[GUSISpecificTable]]>=              
 
176
inline void * GUSISpecificTable::GetSpecific(const GUSISpecific * key) const
 
177
{
 
178
        if (Valid(key))
 
179
                return fValues[0][key->fID];
 
180
        else
 
181
                return nil;
 
182
}
 
183
 
 
184
#endif /* GUSI_SOURCE */
 
185
 
 
186
#endif /* _GUSISpecific_ */