Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef INCLUDED_RTL_INSTANCE_HXX
30 : : #define INCLUDED_RTL_INSTANCE_HXX
31 : :
32 : : #include "osl/doublecheckedlocking.h"
33 : : #include "osl/getglobalmutex.hxx"
34 : :
35 : : namespace {
36 : :
37 : : /** A non-broken version of the double-checked locking pattern.
38 : :
39 : : See
40 : : <http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html>
41 : : for a description of double-checked locking, why it is broken, and how it
42 : : can be fixed. Always use this template instead of spelling out the
43 : : double-checked locking pattern explicitly, and only in those rare cases
44 : : where that is not possible and you have to spell it out explicitly, at
45 : : least call OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER() at the right
46 : : places. That way, all platform-dependent code to make double-checked
47 : : locking work can be kept in one place.
48 : :
49 : : Usage scenarios:
50 : :
51 : : 1 Static instance (most common case)
52 : :
53 : : Pattern:
54 : :
55 : : T * getInstance()
56 : : {
57 : : static T * pInstance = 0;
58 : : if (!pInstance)
59 : : {
60 : : ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
61 : : if (!pInstance)
62 : : {
63 : : static T aInstance;
64 : : pInstance = &aInstance;
65 : : }
66 : : }
67 : : return pInstance;
68 : : }
69 : :
70 : : Code:
71 : :
72 : : #include "rtl/instance.hxx"
73 : : #include "osl/getglobalmutex.hxx"
74 : :
75 : : namespace {
76 : : struct Init
77 : : {
78 : : T * operator()()
79 : : {
80 : : static T aInstance;
81 : : return &aInstance;
82 : : }
83 : : };
84 : : }
85 : :
86 : : T * getInstance()
87 : : {
88 : : return rtl_Instance< T, Init, ::osl::MutexGuard,
89 : : ::osl::GetGlobalMutex >::create(
90 : : Init(), ::osl::GetGlobalMutex());
91 : : }
92 : :
93 : : 2 Dynamic instance
94 : :
95 : : Pattern:
96 : :
97 : : T * getInstance()
98 : : {
99 : : static T * pInstance = 0;
100 : : if (!pInstance)
101 : : {
102 : : ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
103 : : if (!pInstance)
104 : : pInstance = new T;
105 : : }
106 : : return pInstance;
107 : : }
108 : :
109 : : Code:
110 : :
111 : : #include "rtl/instance.hxx"
112 : : #include "osl/getglobalmutex.hxx"
113 : :
114 : : namespace {
115 : : struct Init
116 : : {
117 : : T * operator()()
118 : : {
119 : : return new T;
120 : : }
121 : : };
122 : : }
123 : :
124 : : T * getInstance()
125 : : {
126 : : return rtl_Instance< T, Init, ::osl::MutexGuard,
127 : : ::osl::GetGlobalMutex >::create(
128 : : Init(), ::osl::GetGlobalMutex());
129 : : }
130 : :
131 : : 3 Other guard/mutex
132 : :
133 : : Pattern:
134 : :
135 : : T * getInstance()
136 : : {
137 : : static T * pInstance = 0;
138 : : if (!pInstance)
139 : : {
140 : : SomeGuard aGuard(pSomeMutex);
141 : : if (!pInstance)
142 : : {
143 : : static T aInstance;
144 : : pInstance = &aInstance;
145 : : }
146 : : }
147 : : return pInstance;
148 : : }
149 : :
150 : : Code:
151 : :
152 : : #include "rtl/instance.hxx"
153 : :
154 : : namespace {
155 : : struct InitInstance
156 : : {
157 : : T * operator()()
158 : : {
159 : : static T aInstance;
160 : : return &aInstance;
161 : : }
162 : : };
163 : :
164 : : struct InitGuard
165 : : {
166 : : SomeMutex * operator()()
167 : : {
168 : : return pSomeMutex;
169 : : }
170 : : };
171 : : }
172 : :
173 : : T * getInstance()
174 : : {
175 : : return rtl_Instance< T, InitInstance,
176 : : SomeGuard, InitGuard >::create(
177 : : InitInstance(), InitMutex());
178 : : }
179 : :
180 : : 4 Calculate extra data
181 : :
182 : : Pattern:
183 : :
184 : : T * getInstance()
185 : : {
186 : : static T * pInstance = 0;
187 : : if (!pInstance)
188 : : {
189 : : Data aData(...);
190 : : ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
191 : : if (!pInstance)
192 : : {
193 : : static T aInstance(aData);
194 : : pInstance = &aInstance;
195 : : }
196 : : }
197 : : return pInstance;
198 : : }
199 : :
200 : : Code:
201 : :
202 : : #include "rtl/instance.hxx"
203 : : #include "osl/getglobalmutex.hxx"
204 : :
205 : : namespace {
206 : : struct InitInstance
207 : : {
208 : : T * operator()()
209 : : {
210 : : static T aInstance;
211 : : return &aInstance;
212 : : }
213 : : }
214 : :
215 : : struct InitData
216 : : {
217 : : Data const & operator()()
218 : : {
219 : : return ...;
220 : : }
221 : : }
222 : : }
223 : :
224 : : T * getInstance()
225 : : {
226 : : return rtl_Instance< T, InitInstance,
227 : : ::osl::Mutex, ::osl::GetGlobalMutex,
228 : : Data, InitData >::create(
229 : : InitInstance(), ::osl::GetGlobalMutex(), InitData());
230 : : }
231 : :
232 : : Some comments:
233 : :
234 : : For any instantiation of rtl_Instance, at most one call to a create method
235 : : may occur in the program code: Each occurrence of a create method within
236 : : the program code is supposed to return a fresh object instance on the
237 : : first call, and that same object instance on subsequent calls; but
238 : : independent occurrences of create methods are supposed to return
239 : : independent object instances. Since there is a one-to-one correspondence
240 : : between object instances and instantiations of rtl_Instance, the
241 : : requirement should be clear. One measure to enforce the requirement is
242 : : that rtl_Instance lives in an unnamed namespace, so that instantiations of
243 : : rtl_Instance in different translation units will definitely be different
244 : : instantiations. A drawback of that measure is that the name of the class
245 : : needs a funny "hand coded" prefix "rtl_" instead of a proper namespace
246 : : prefix like "::rtl::".
247 : :
248 : : A known problem with this template is when two occurrences of calls to
249 : : create methods with identical template arguments appear in one translation
250 : : unit. Those two places will share a single object instance. This can be
251 : : avoided by using different Init structs (see the above code samples) in
252 : : the two places.
253 : :
254 : : There is no need to make m_pInstance volatile, in order to avoid usage of
255 : : stale copies of m_pInstance: At the first check, a thread will see that
256 : : m_pInstance contains either 0 or a valid pointer. If it contains a valid
257 : : pointer, it cannot be stale, and that pointer is used. If it contains 0,
258 : : acquiring the mutex will ensure that the second check sees a non-stale
259 : : value in all cases.
260 : :
261 : : On some compilers, the create methods would not be inlined if they
262 : : contained any static variables, so m_pInstance is made a class member
263 : : instead (and the create methods are inlined). But on MSC, the definition
264 : : of the class member m_pInstance would cause compilation to fail with an
265 : : internal compiler error. Since MSC is able to inline methods containing
266 : : static variables, m_pInstance is moved into the methods there. Note that
267 : : this only works well because for any instantiation of rtl_Instance at most
268 : : one call to a create method should be present, anyway.
269 : : */
270 : : template< typename Inst, typename InstCtor,
271 : : typename Guard, typename GuardCtor,
272 : : typename Data = int, typename DataCtor = int >
273 : : class rtl_Instance
274 : : {
275 : : public:
276 : 438165 : static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor)
277 : : {
278 : : #if defined _MSC_VER
279 : : static Inst * m_pInstance = 0;
280 : : #endif // _MSC_VER
281 : 438165 : Inst * p = m_pInstance;
282 [ + + ]: 438165 : if (!p)
283 : : {
284 [ + - ][ + - ]: 882 : Guard aGuard(aGuardCtor());
285 : 882 : p = m_pInstance;
286 [ + - ]: 882 : if (!p)
287 : : {
288 [ + - ]: 882 : p = aInstCtor();
289 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
290 [ + - ]: 882 : m_pInstance = p;
291 : : }
292 : : }
293 : : else
294 : : {
295 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
296 : : }
297 : 438165 : return p;
298 : : }
299 : :
300 : 6 : static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
301 : : DataCtor aDataCtor)
302 : : {
303 : : #if defined _MSC_VER
304 : : static Inst * m_pInstance = 0;
305 : : #endif // _MSC_VER
306 : 6 : Inst * p = m_pInstance;
307 [ + - ]: 6 : if (!p)
308 : : {
309 [ + - ]: 6 : Data aData(aDataCtor());
310 [ + - ][ + - ]: 6 : Guard aGuard(aGuardCtor());
311 : 6 : p = m_pInstance;
312 [ + - ]: 6 : if (!p)
313 : : {
314 : 6 : p = aInstCtor(aData);
315 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
316 [ + - ]: 6 : m_pInstance = p;
317 : : }
318 : : }
319 : : else
320 : : {
321 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
322 : : }
323 : 6 : return p;
324 : : }
325 : :
326 : : static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
327 : : const Data &rData)
328 : : {
329 : : #if defined _MSC_VER
330 : : static Inst * m_pInstance = 0;
331 : : #endif // _MSC_VER
332 : : Inst * p = m_pInstance;
333 : : if (!p)
334 : : {
335 : : Guard aGuard(aGuardCtor());
336 : : p = m_pInstance;
337 : : if (!p)
338 : : {
339 : : p = aInstCtor(rData);
340 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
341 : : m_pInstance = p;
342 : : }
343 : : }
344 : : else
345 : : {
346 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
347 : : }
348 : : return p;
349 : : }
350 : :
351 : : private:
352 : : #if !defined _MSC_VER
353 : : static Inst * m_pInstance;
354 : : #endif // _MSC_VER
355 : : };
356 : :
357 : : #if !defined _MSC_VER
358 : : template< typename Inst, typename InstCtor,
359 : : typename Guard, typename GuardCtor,
360 : : typename Data, typename DataCtor >
361 : : Inst *
362 : : rtl_Instance< Inst, InstCtor, Guard, GuardCtor, Data, DataCtor >::m_pInstance
363 : : = 0;
364 : : #endif // _MSC_VER
365 : :
366 : : }
367 : :
368 : : namespace rtl {
369 : :
370 : : /** Helper base class for a late-initialized (default-constructed)
371 : : static variable, implementing the double-checked locking pattern correctly.
372 : :
373 : : @derive
374 : : Derive from this class (common practice), e.g.
375 : : <pre>
376 : : struct MyStatic : public rtl::Static<MyType, MyStatic> {};
377 : : ...
378 : : MyType & rStatic = MyStatic::get();
379 : : ...
380 : : </pre>
381 : :
382 : : @tparam T
383 : : variable's type
384 : : @tparam Unique
385 : : Implementation trick to make the inner static holder unique,
386 : : using the outer class
387 : : (the one that derives from this base class)
388 : : */
389 : : #if defined HAVE_THREADSAFE_STATICS
390 : : template<typename T, typename Unique>
391 : : class Static {
392 : : public:
393 : : /** Gets the static. Mutual exclusion is implied by a functional
394 : : -fthreadsafe-statics
395 : :
396 : : @return
397 : : static variable
398 : : */
399 : 47760669 : static T & get() {
400 [ + + ][ + - ]: 47760669 : static T instance;
[ + + - ][ #
# # # #
# ][ # # ]
[ # # ]
[ # # # # ]
[ + + # # ]
[ + - ][ + - ]
[ + + + +
# # ]
[ + - + - ]
[ + + - +
- ][ # # #
# # # ]
[ + + # # ]
[ + - ]
[ + - # # ]
[ + + # #
# # ][ + - ]
[ + - # # ]
[ # # # # ]
[ + + ]
[ + - # # ]
[ + - # # ]
[ + + # # ]
[ + - ][ + - ]
[ # # ][ + + ]
[ + - ][ + - ]
[ # # ][ + + ]
[ + - ][ + - ]
[ # # # # ]
[ # # ][ # # ]
[ + + # # ]
[ + - ]
[ + - # # ]
[ # # # # ]
[ # # ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
401 : 47760624 : return instance;
402 : : }
403 : : };
404 : : #else
405 : : template<typename T, typename Unique>
406 : : class Static {
407 : : public:
408 : : /** Gets the static. Mutual exclusion is performed using the
409 : : osl global mutex.
410 : :
411 : : @return
412 : : static variable
413 : : */
414 : : static T & get() {
415 : : return *rtl_Instance<
416 : : T, StaticInstance,
417 : : ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
418 : : StaticInstance(), ::osl::GetGlobalMutex() );
419 : : }
420 : : private:
421 : : struct StaticInstance {
422 : : T * operator () () {
423 : : static T instance;
424 : : return &instance;
425 : : }
426 : : };
427 : : };
428 : : #endif
429 : :
430 : : /** Helper base class for a late-initialized (default-constructed)
431 : : static variable, implementing the double-checked locking pattern correctly.
432 : :
433 : : @derive
434 : : Derive from this class (common practice), e.g.
435 : : <pre>
436 : : struct MyStatic : public rtl::Static<MyType, MyStatic> {};
437 : : ...
438 : : MyType & rStatic = MyStatic::get();
439 : : ...
440 : : </pre>
441 : :
442 : : @tparam T
443 : : variable's type
444 : : @tparam Unique
445 : : Implementation trick to make the inner static holder unique,
446 : : using the outer class
447 : : (the one that derives from this base class)
448 : : */
449 : : #if defined HAVE_THREADSAFE_STATICS
450 : : template<typename T, typename Data, typename Unique>
451 : : class StaticWithArg {
452 : : public:
453 : : /** Gets the static. Mutual exclusion is implied by a functional
454 : : -fthreadsafe-statics
455 : :
456 : : @return
457 : : static variable
458 : : */
459 : 134655 : static T & get(const Data& rData) {
460 [ + + ][ + - ]: 134655 : static T instance(rData);
[ + - ][ # # ]
461 : 134655 : return instance;
462 : : }
463 : :
464 : : /** Gets the static. Mutual exclusion is implied by a functional
465 : : -fthreadsafe-statics
466 : :
467 : : @return
468 : : static variable
469 : : */
470 : 12794 : static T & get(Data& rData) {
471 [ + + ][ + - ]: 12794 : static T instance(rData);
[ + - ][ # # ]
472 : 12794 : return instance;
473 : : }
474 : : };
475 : : #else
476 : : template<typename T, typename Data, typename Unique>
477 : : class StaticWithArg {
478 : : public:
479 : : /** Gets the static. Mutual exclusion is performed using the
480 : : osl global mutex.
481 : :
482 : : @return
483 : : static variable
484 : : */
485 : : static T & get(const Data& rData) {
486 : : return *rtl_Instance<
487 : : T, StaticInstanceWithArg,
488 : : ::osl::MutexGuard, ::osl::GetGlobalMutex,
489 : : Data >::create( StaticInstanceWithArg(),
490 : : ::osl::GetGlobalMutex(),
491 : : rData );
492 : : }
493 : :
494 : : /** Gets the static. Mutual exclusion is performed using the
495 : : osl global mutex.
496 : :
497 : : @return
498 : : static variable
499 : : */
500 : : static T & get(Data& rData) {
501 : : return *rtl_Instance<
502 : : T, StaticInstanceWithArg,
503 : : ::osl::MutexGuard, ::osl::GetGlobalMutex,
504 : : Data >::create( StaticInstanceWithArg(),
505 : : ::osl::GetGlobalMutex(),
506 : : rData );
507 : : }
508 : : private:
509 : : struct StaticInstanceWithArg {
510 : : T * operator () (const Data& rData) {
511 : : static T instance(rData);
512 : : return &instance;
513 : : }
514 : :
515 : : T * operator () (Data& rData) {
516 : : static T instance(rData);
517 : : return &instance;
518 : : }
519 : : };
520 : : };
521 : : #endif
522 : :
523 : : /** Helper class for a late-initialized static aggregate, e.g. an array,
524 : : implementing the double-checked locking pattern correctly.
525 : :
526 : : @tparam T
527 : : aggregate's element type
528 : : @tparam InitAggregate
529 : : initializer functor class
530 : : */
531 : : #if defined HAVE_THREADSAFE_STATICS
532 : : template<typename T, typename InitAggregate>
533 : : class StaticAggregate {
534 : : public:
535 : : /** Gets the static aggregate, late-initializing.
536 : : Mutual exclusion is implied by a functional
537 : : -fthreadsafe-statics
538 : :
539 : : @return
540 : : aggregate
541 : : */
542 : 19070872 : static T * get() {
543 [ + + ][ + - ]: 19070872 : static T *instance = InitAggregate()();
[ + - ]
[ + + # # ]
[ + - ][ + - ]
[ + + # # ]
[ + - ]
[ + + + - ]
[ + - + +
# # ]
[ + - + - ]
[ + + # # ]
[ + - + + ]
[ + - + - ]
[ + + # # ]
[ + - + + ]
[ + + + -
+ - ]
[ + - # # ]
[ + - + + ]
[ + + # #
+ - ][ + - ]
[ + - + + ]
[ # # + - ]
[ + + ][ + - ]
[ # # + + ]
[ # # + - ]
[ # # ]
[ # # + + ]
[ + - ][ + + ]
[ + - ][ + + ]
[ + - ][ + + ]
[ + - ]
544 : 19070872 : return instance;
545 : : }
546 : : };
547 : : #else
548 : : template<typename T, typename InitAggregate>
549 : : class StaticAggregate {
550 : : public:
551 : : /** Gets the static aggregate, late-initializing.
552 : : Mutual exclusion is performed using the osl global mutex.
553 : :
554 : : @return
555 : : aggregate
556 : : */
557 : : static T * get() {
558 : : return rtl_Instance<
559 : : T, InitAggregate,
560 : : ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
561 : : InitAggregate(), ::osl::GetGlobalMutex() );
562 : : }
563 : : };
564 : : #endif
565 : : /** Helper base class for a late-initialized static variable,
566 : : implementing the double-checked locking pattern correctly.
567 : :
568 : : @derive
569 : : Derive from this class (common practice),
570 : : providing an initializer functor class, e.g.
571 : : <pre>
572 : : struct MyStatic : public rtl::StaticWithInit<MyType, MyStatic> {
573 : : MyType operator () () {
574 : : ...
575 : : return MyType( ... );
576 : : }
577 : : };
578 : : ...
579 : : MyType & rStatic = MyStatic::get();
580 : : ...
581 : : </pre>
582 : :
583 : : @tparam T
584 : : variable's type
585 : : @tparam InitData
586 : : initializer functor class
587 : : @tparam Unique
588 : : Implementation trick to make the inner static holder unique,
589 : : using the outer class
590 : : (the one that derives from this base class).
591 : : Default is InitData (common practice).
592 : : @tparam Data
593 : : Initializer functor's return type.
594 : : Default is T (common practice).
595 : : */
596 : : #if defined HAVE_THREADSAFE_STATICS
597 : : template<typename T, typename InitData,
598 : : typename Unique = InitData, typename Data = T>
599 : : class StaticWithInit {
600 : : public:
601 : : /** Gets the static. Mutual exclusion is implied by a functional
602 : : -fthreadsafe-statics
603 : :
604 : : @return
605 : : static variable
606 : : */
607 : 43949130 : static T & get() {
608 [ + + ][ + - ]: 43949130 : static T instance = InitData()();
[ + - ]
[ # # # ]
[ + + + ]
[ + + - ]
[ + + - ]
[ # # # # ]
[ + + + + ]
[ + - + - ]
[ + - + - ]
[ # # # #
# ]
[ + + + - ]
[ + + + - ]
[ + + + - ]
[ # # # # ]
[ + + + + ]
[ + + + - ]
[ + + + - ]
[ # # # # ]
[ + + + + ]
[ + - + - ]
[ + - + - ]
[ # # # # ]
[ + + + + ]
[ + - + - ]
[ + - + - ]
[ # # # # ]
[ + + + - ]
[ + + + - ]
[ + + + - ]
[ # # # # ]
[ + + + # ]
[ + + - # ]
[ + + - # ]
[ # # # # ]
[ + + - # ]
[ + + - # ]
[ + + - # ]
[ # # # # ]
[ + + # # ]
[ + - # # ]
[ + - # # ]
[ # # # # ]
[ + + # # ]
[ + - # # ]
[ + - # # ]
[ # # # # ]
[ + + + - ]
[ + - + - ]
[ + - + - ]
[ # # # # ]
[ + + # # ]
[ + - # # ]
[ + - # # ]
[ # # # # ]
[ + + + + ]
[ + - + - ]
[ + - + - ]
[ # # # # ]
[ + + # # ]
[ + - # # ]
[ + - # # ]
[ # # # # ]
[ + + # # ]
[ + - # # ]
[ + - # # ]
[ # # # # ]
[ + + # # ]
[ + - # # ]
[ + - # # ]
[ # # # # ]
[ + + + + ]
[ + - + - ]
[ + - + - ]
[ # # # # ]
[ + + + + ]
[ + - + - ]
[ + - + - ]
[ # # # # ]
[ + + # # ]
[ + - # # ]
[ + - # # ]
[ # # # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + - ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + - ][ + - ]
[ + - ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + - ][ + - ]
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ][ + - ]
[ + - ][ # # ]
[ + - ][ + - ]
[ + - ][ # # ]
[ + - ][ + - ]
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
609 : 43949130 : return instance;
610 : : }
611 : : };
612 : : #else
613 : : template<typename T, typename InitData,
614 : : typename Unique = InitData, typename Data = T>
615 : : class StaticWithInit {
616 : : public:
617 : : /** Gets the static. Mutual exclusion is performed using the
618 : : osl global mutex.
619 : :
620 : : @return
621 : : static variable
622 : : */
623 : : static T & get() {
624 : : return *rtl_Instance<
625 : : T, StaticInstanceWithInit,
626 : : ::osl::MutexGuard, ::osl::GetGlobalMutex,
627 : : Data, InitData >::create( StaticInstanceWithInit(),
628 : : ::osl::GetGlobalMutex(),
629 : : InitData() );
630 : : }
631 : : private:
632 : : struct StaticInstanceWithInit {
633 : : T * operator () ( Data d ) {
634 : : static T instance(d);
635 : : return &instance;
636 : : }
637 : : };
638 : : };
639 : : #endif
640 : : } // namespace rtl
641 : :
642 : : #endif // INCLUDED_RTL_INSTANCE_HXX
643 : :
644 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|