1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <sal/types.h>
23 #include <cppunit/TestAssert.h>
24 #include <cppunit/TestFixture.h>
25 #include <cppunit/extensions/HelperMacros.h>
26 #include <cppunit/plugin/TestPlugIn.h>
27 #include "osl_Mutex_Const.h"
31 /** pause nSec seconds helper function.
33 namespace ThreadHelper
35 static void thread_sleep_tenth_sec(sal_uInt32 _nTenthSec
)
37 osl::Thread::wait(std::chrono::milliseconds(_nTenthSec
* 100));
39 static void thread_sleep( sal_uInt32 _nSec
)
41 /// print statement in thread process must use fflush() to force display.
42 // t_print("# wait %d seconds. ", _nSec );
45 thread_sleep_tenth_sec( _nSec
* 10 );
46 // printf("# done\n" );
50 // Beginning of the test cases for osl_Mutex class
54 /** mutually exclusive data
62 /** IncreaseThread provide data.
64 class IncreaseThread
: public Thread
67 explicit IncreaseThread( struct resource
*pData
): pResource( pData
) { }
69 virtual ~IncreaseThread( ) override
71 CPPUNIT_ASSERT_MESSAGE( "#IncreaseThread does not shutdown properly.\n", !isRunning( ) );
74 struct resource
*pResource
;
76 void SAL_CALL
run( ) override
78 pResource
->lock
.acquire( );
79 for( sal_Int8 i
= 0; i
< 3; i
++ )
82 yield( ); //yield() give CPU time to other thread, other thread if not block, they will change the data;
84 if ( pResource
->data2
== 0 )
85 pResource
->data2
= ( pResource
->data1
> 0 ? pResource
->data1
: 0 - pResource
->data1
);
86 pResource
->lock
.release();
90 /** DecreaseThread consume data.
92 class DecreaseThread
: public Thread
95 explicit DecreaseThread( struct resource
*pData
): pResource( pData
) { }
97 virtual ~DecreaseThread( ) override
99 CPPUNIT_ASSERT_MESSAGE( "#DecreaseThread does not shutdown properly.\n", !isRunning( ) );
102 struct resource
*pResource
;
104 void SAL_CALL
run( ) override
106 pResource
->lock
.acquire( );
107 for( sal_Int8 i
= 0; i
< 3; i
++ )
110 yield( ); //yield() give CPU time to other thread, other thread if not block, they will change the data;
112 if ( pResource
->data2
== 0 )
113 pResource
->data2
= ( pResource
->data1
> 0 ? pResource
->data1
: 0 - pResource
->data1
);
114 pResource
->lock
.release();
118 /** chain structure used in Threads as critical resource
121 sal_Int32 buffer
[ BUFFER_SIZE
];
126 /** PutThread write to the chain structure in a mutex manner.
128 class PutThread
: public Thread
131 //get the struct pointer to write data to buffer
132 explicit PutThread( struct chain
* pData
): pChain( pData
) { }
134 virtual ~PutThread( ) override
136 CPPUNIT_ASSERT_MESSAGE( "#PutThread does not shutdown properly.\n", !isRunning( ) );
139 struct chain
* pChain
;
141 void SAL_CALL
run( ) override
143 //block here if the mutex has been acquired
144 pChain
->lock
.acquire( );
146 //current position in buffer to write
147 sal_Int8 nPos
= pChain
->pos
;
148 oslThreadIdentifier oId
= getIdentifier( );
151 for ( i
= 0; i
< 5; i
++ )
153 pChain
->buffer
[ nPos
+ i
] = oId
;
156 //revise the position
157 pChain
->pos
= nPos
+ i
;
159 //finish writing, release the mutex
160 pChain
->lock
.release();
164 /** thread for testing Mutex acquire.
166 class HoldThread
: public Thread
169 //get the Mutex pointer to operate
170 explicit HoldThread( Mutex
* pMutex
): pMyMutex( pMutex
) { }
172 virtual ~HoldThread( ) override
174 CPPUNIT_ASSERT_MESSAGE( "#HoldThread does not shutdown properly.\n", !isRunning( ) );
179 void SAL_CALL
run() override
181 // block here if the mutex has been acquired
182 pMyMutex
->acquire( );
183 printf("# Mutex acquired. \n" );
184 pMyMutex
->release( );
188 class WaitThread
: public Thread
191 //get the Mutex pointer to operate
192 explicit WaitThread( Mutex
* pMutex
): pMyMutex( pMutex
) { }
194 virtual ~WaitThread( ) override
196 CPPUNIT_ASSERT_MESSAGE( "#WaitThread does not shutdown properly.\n", !isRunning( ) );
201 void SAL_CALL
run( ) override
203 // block here if the mutex has been acquired
204 pMyMutex
->acquire( );
205 ThreadHelper::thread_sleep_tenth_sec( 2 );
206 pMyMutex
->release( );
210 /** thread for testing getGlobalMutex.
212 class GlobalMutexThread
: public Thread
215 //get the Mutex pointer to operate
216 GlobalMutexThread( ){ }
218 virtual ~GlobalMutexThread( ) override
220 CPPUNIT_ASSERT_MESSAGE( "#GlobalMutexThread does not shutdown properly.\n", !isRunning( ) );
223 void SAL_CALL
run( ) override
225 // block here if the mutex has been acquired
227 pGlobalMutex
= Mutex::getGlobalMutex( );
228 pGlobalMutex
->acquire( );
229 printf("# Global Mutex acquired. \n" );
230 pGlobalMutex
->release( );
239 /** Test of the osl::Mutex::constructor
241 class ctor
: public CppUnit::TestFixture
244 // initialise your test code values here.
246 struct resource m_Res
;
248 void setUp( ) override
250 for ( sal_Int8 i
=0; i
< BUFFER_SIZE
; i
++ )
251 m_Data
.buffer
[i
] = 0;
258 /** Create two threads to write data to the same buffer, use Mutex to assure
259 during one thread write data five times, the other thread should not begin writing.
260 the two threads wrote two different data: their thread ID, so we can check the data
261 in buffer to know the order of the two threads writing
265 PutThread
myThread1( &m_Data
);
266 PutThread
myThread2( &m_Data
);
271 //wait until the two threads terminate
277 // every 5 data should the same
278 // LLA: this is not a good check, it's too fix
279 if (m_Data
.buffer
[0] == m_Data
.buffer
[1] &&
280 m_Data
.buffer
[1] == m_Data
.buffer
[2] &&
281 m_Data
.buffer
[2] == m_Data
.buffer
[3] &&
282 m_Data
.buffer
[3] == m_Data
.buffer
[4] &&
283 m_Data
.buffer
[5] == m_Data
.buffer
[6] &&
284 m_Data
.buffer
[6] == m_Data
.buffer
[7] &&
285 m_Data
.buffer
[7] == m_Data
.buffer
[8] &&
286 m_Data
.buffer
[8] == m_Data
.buffer
[9])
289 /*for (sal_Int8 i=0; i<BUFFER_SIZE; i++)
290 printf("#data in buffer is %d\n", m_Data.buffer[i]);
293 CPPUNIT_ASSERT_MESSAGE("Mutex ctor", bRes
);
297 /** Create two threads to write data to operate on the same number , use Mutex to assure,
298 one thread increase data 3 times, the other thread decrease 3 times, store the operate
299 result when the first thread complete, if it is interrupt by the other thread, the stored
300 number will not be 3.
304 IncreaseThread
myThread1( &m_Res
);
305 DecreaseThread
myThread2( &m_Res
);
310 //wait until the two threads terminate
316 // every 5 data should the same
317 if ( ( m_Res
.data1
== 0 ) && ( m_Res
.data2
== 3 ) )
320 CPPUNIT_ASSERT_MESSAGE( "test Mutex ctor function: increase and decrease a number 3 times without interrupt.", bRes
);
323 CPPUNIT_TEST_SUITE( ctor
);
324 CPPUNIT_TEST( ctor_001
);
325 CPPUNIT_TEST( ctor_002
);
326 CPPUNIT_TEST_SUITE_END( );
329 /** Test of the osl::Mutex::acquire method
331 class acquire
: public CppUnit::TestFixture
334 // acquire mutex in main thread, and then call acquire again in myThread,
335 // the child thread should block, wait 2 secs, it still block.
336 // Then release mutex in main thread, the child thread could return from acquire,
337 // and go to exec next statement, so could terminate quickly.
342 bool bRes
= aMutex
.acquire( );
343 // pass the pointer of mutex to child thread
344 HoldThread
myThread( &aMutex
);
347 ThreadHelper::thread_sleep_tenth_sec( 2 );
348 // if acquire in myThread does not work, 2 secs is long enough,
349 // myThread should terminate now, and bRes1 should be sal_False
350 bool bRes1
= myThread
.isRunning( );
353 ThreadHelper::thread_sleep_tenth_sec( 1 );
354 // after release mutex, myThread stops blocking and will terminate immediately
355 bool bRes2
= myThread
.isRunning( );
358 CPPUNIT_ASSERT_MESSAGE( "Mutex acquire", bRes
);
359 CPPUNIT_ASSERT_MESSAGE( "Mutex acquire", bRes1
);
360 CPPUNIT_ASSERT_MESSAGE( "Mutex acquire", !bRes2
);
363 //in the same thread, acquire twice should success
368 bool bRes
= aMutex
.acquire();
369 bool bRes1
= aMutex
.acquire();
371 bool bRes2
= aMutex
.tryToAcquire();
375 CPPUNIT_ASSERT_MESSAGE("Mutex acquire", bRes
);
376 CPPUNIT_ASSERT_MESSAGE("Mutex acquire", bRes1
);
377 CPPUNIT_ASSERT_MESSAGE("Mutex acquire", bRes2
);
381 CPPUNIT_TEST_SUITE( acquire
);
382 CPPUNIT_TEST( acquire_001
);
383 CPPUNIT_TEST( acquire_002
);
384 CPPUNIT_TEST_SUITE_END( );
387 /** Test of the osl::Mutex::tryToAcquire method
389 class tryToAcquire
: public CppUnit::TestFixture
392 // First let child thread acquire the mutex, and wait 2 secs, during the 2 secs,
393 // in main thread, tryToAcquire mutex should return False
394 // then after the child thread terminated, tryToAcquire should return True
395 void tryToAcquire_001()
398 WaitThread
myThread(&aMutex
);
401 // ensure the child thread acquire the mutex
402 ThreadHelper::thread_sleep_tenth_sec(1);
404 bool bRes1
= aMutex
.tryToAcquire();
408 // wait the child thread terminate
411 bool bRes2
= aMutex
.tryToAcquire();
416 CPPUNIT_ASSERT_MESSAGE("Try to acquire Mutex", !bRes1
);
417 CPPUNIT_ASSERT_MESSAGE("Try to acquire Mutex", bRes2
);
420 CPPUNIT_TEST_SUITE(tryToAcquire
);
421 CPPUNIT_TEST(tryToAcquire_001
);
422 CPPUNIT_TEST_SUITE_END();
423 }; // class tryToAcquire
425 /** Test of the osl::Mutex::release method
427 class release
: public CppUnit::TestFixture
430 /** acquire/release are not used in pairs: after child thread acquired mutex,
431 the main thread release it, then any thread could acquire it.
436 WaitThread
myThread( &aMutex
);
439 // ensure the child thread acquire the mutex
440 ThreadHelper::thread_sleep_tenth_sec( 1 );
442 bool bRunning
= myThread
.isRunning( );
443 bool bRes1
= aMutex
.tryToAcquire( );
444 // wait the child thread terminate
447 bool bRes2
= aMutex
.tryToAcquire( );
452 CPPUNIT_ASSERT_MESSAGE( "release Mutex: try to acquire before and after the mutex has been released",
454 CPPUNIT_ASSERT_MESSAGE( "release Mutex: try to acquire before and after the mutex has been released",
456 CPPUNIT_ASSERT_MESSAGE( "release Mutex: try to acquire before and after the mutex has been released",
461 // how about release twice?
466 CPPUNIT_TEST_SUITE( release
);
467 CPPUNIT_TEST( release_001
);
468 CPPUNIT_TEST( release_002
);
469 CPPUNIT_TEST_SUITE_END( );
472 /** Test of the osl::Mutex::getGlobalMutex method
474 class getGlobalMutex
: public CppUnit::TestFixture
477 // initialise your test code values here.
478 void getGlobalMutex_001()
481 pGlobalMutex
= Mutex::getGlobalMutex();
482 pGlobalMutex
->acquire();
484 GlobalMutexThread myThread
;
487 ThreadHelper::thread_sleep_tenth_sec(1);
488 bool bRes1
= myThread
.isRunning();
490 pGlobalMutex
->release();
491 ThreadHelper::thread_sleep_tenth_sec(1);
492 // after release mutex, myThread stops blocking and will terminate immediately
493 bool bRes2
= myThread
.isRunning();
495 CPPUNIT_ASSERT_MESSAGE("Global Mutex works", bRes1
);
496 CPPUNIT_ASSERT_MESSAGE("Global Mutex works", !bRes2
);
499 void getGlobalMutex_002( )
504 pGlobalMutex
= Mutex::getGlobalMutex( );
505 pGlobalMutex
->acquire( );
507 Mutex
*pGlobalMutex1
;
508 pGlobalMutex1
= Mutex::getGlobalMutex( );
509 bRes
= pGlobalMutex1
->release( );
512 CPPUNIT_ASSERT_MESSAGE( "Global Mutex works: if the code between {} get the different mutex as the former one, it will return false when release.",
516 CPPUNIT_TEST_SUITE(getGlobalMutex
);
517 CPPUNIT_TEST(getGlobalMutex_001
);
518 CPPUNIT_TEST(getGlobalMutex_002
);
519 CPPUNIT_TEST_SUITE_END();
520 }; // class getGlobalMutex
522 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::ctor
, "osl_Mutex");
523 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::acquire
, "osl_Mutex");
524 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::tryToAcquire
, "osl_Mutex");
525 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::release
, "osl_Mutex");
526 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::getGlobalMutex
, "osl_Mutex");
527 } // namespace osl_Mutex
529 // Beginning of the test cases for osl_Guard class
533 class GuardThread
: public Thread
536 //get the Mutex pointer to operate
537 explicit GuardThread( Mutex
* pMutex
): pMyMutex( pMutex
) { }
539 virtual ~GuardThread( ) override
541 CPPUNIT_ASSERT_MESSAGE( "#GuardThread does not shutdown properly.\n", !isRunning( ) );
546 void SAL_CALL
run( ) override
548 // block here if the mutex has been acquired
549 MutexGuard
aGuard( pMyMutex
);
550 ThreadHelper::thread_sleep_tenth_sec( 2 );
558 class ctor
: public CppUnit::TestFixture
561 // insert your test code here.
565 GuardThread
myThread(&aMutex
);
568 ThreadHelper::thread_sleep_tenth_sec(1);
569 bool bRes
= aMutex
.tryToAcquire();
570 // after 1 second, the mutex has been guarded, and the child thread should be running
571 bool bRes1
= myThread
.isRunning();
574 bool bRes2
= aMutex
.tryToAcquire();
576 CPPUNIT_ASSERT_MESSAGE("GuardThread constructor",
578 CPPUNIT_ASSERT_MESSAGE("GuardThread constructor",
580 CPPUNIT_ASSERT_MESSAGE("GuardThread constructor",
588 /// use reference constructor here
589 MutexGuard
myGuard( aMutex
);
591 /// the GuardThread will block here when it is initialised.
592 GuardThread
myThread( &aMutex
);
595 /// is it still blocking?
596 ThreadHelper::thread_sleep_tenth_sec( 2 );
597 bool bRes
= myThread
.isRunning( );
603 CPPUNIT_ASSERT_MESSAGE("GuardThread constructor: reference initialization, acquire the mutex before running the thread, then check if it is blocking.",
607 CPPUNIT_TEST_SUITE(ctor
);
608 CPPUNIT_TEST(ctor_001
);
609 CPPUNIT_TEST(ctor_002
);
610 CPPUNIT_TEST_SUITE_END();
613 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Guard::ctor
, "osl_Guard");
614 } // namespace osl_Guard
616 // Beginning of the test cases for osl_ClearableGuard class
620 /** Thread for test ClearableGuard
622 class ClearGuardThread
: public Thread
625 //get the Mutex pointer to operate
626 explicit ClearGuardThread( Mutex
* pMutex
): pMyMutex( pMutex
) {}
628 virtual ~ClearGuardThread( ) override
630 CPPUNIT_ASSERT_MESSAGE( "#ClearGuardThread does not shutdown properly.\n", !isRunning( ) );
635 void SAL_CALL
run( ) override
638 // printf("# ClearGuardThread" );
639 ClearableMutexGuard
aGuard( pMyMutex
);
640 ThreadHelper::thread_sleep( 5 );
644 ThreadHelper::thread_sleep( 2 );
650 namespace osl_ClearableGuard
653 class ctor
: public CppUnit::TestFixture
660 /// now, the aMutex has been guarded.
661 ClearableMutexGuard
myMutexGuard( &aMutex
);
663 /// it will return sal_False if the aMutex has not been Guarded.
664 bool bRes
= aMutex
.release( );
666 CPPUNIT_ASSERT_MESSAGE("ClearableMutexGuard constructor, test the acquire operation when initialized.",
674 /// now, the aMutex has been guarded, this time, we use reference constructor.
675 ClearableMutexGuard
myMutexGuard( aMutex
);
677 /// it will return sal_False if the aMutex has not been Guarded.
678 bool bRes
= aMutex
.release( );
680 CPPUNIT_ASSERT_MESSAGE("ClearableMutexGuard constructor, test the acquire operation when initialized, we use reference constructor this time.",
684 CPPUNIT_TEST_SUITE(ctor
);
685 CPPUNIT_TEST(ctor_001
);
686 CPPUNIT_TEST(ctor_002
);
687 CPPUNIT_TEST_SUITE_END();
690 class clear
: public CppUnit::TestFixture
696 ClearGuardThread
myThread(&aMutex
);
699 TimeValue aTimeVal_befor
;
700 osl_getSystemTime( &aTimeVal_befor
);
701 // wait 1 second to assure the child thread has begun
702 ThreadHelper::thread_sleep(1);
706 if (aMutex
.tryToAcquire())
710 ThreadHelper::thread_sleep(1);
712 TimeValue aTimeVal_after
;
713 osl_getSystemTime( &aTimeVal_after
);
714 sal_Int32 nSec
= aTimeVal_after
.Seconds
- aTimeVal_befor
.Seconds
;
715 printf("nSec is %" SAL_PRIdINT32
"\n", nSec
);
719 CPPUNIT_ASSERT_MESSAGE("ClearableGuard method: clear",
721 CPPUNIT_ASSERT_MESSAGE("ClearableGuard method: clear",
729 /// now, the aMutex has been guarded.
730 ClearableMutexGuard
myMutexGuard( &aMutex
);
732 /// launch the HoldThread, it will be blocked here.
733 HoldThread
myThread( &aMutex
);
737 ThreadHelper::thread_sleep_tenth_sec( 4 );
738 bool bRes
= myThread
.isRunning( );
740 /// use clear to release.
741 myMutexGuard
.clear( );
743 bool bRes1
= myThread
.isRunning( );
745 CPPUNIT_ASSERT_MESSAGE( "ClearableGuard method: clear, control the HoldThread's running status!",
747 CPPUNIT_ASSERT_MESSAGE( "ClearableGuard method: clear, control the HoldThread's running status!",
751 CPPUNIT_TEST_SUITE( clear
);
752 CPPUNIT_TEST( clear_001
);
753 CPPUNIT_TEST( clear_002
);
754 CPPUNIT_TEST_SUITE_END( );
757 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( osl_ClearableGuard::ctor
, "osl_ClearableGuard" );
758 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( osl_ClearableGuard::clear
, "osl_ClearableGuard" );
759 } // namespace osl_ClearableGuard
761 // Beginning of the test cases for osl_ResettableGuard class
765 /** Thread for test ResettableGuard
767 class ResetGuardThread
: public Thread
770 //get the Mutex pointer to operate
771 explicit ResetGuardThread( Mutex
* pMutex
): pMyMutex( pMutex
) {}
773 virtual ~ResetGuardThread( ) override
775 CPPUNIT_ASSERT_MESSAGE( "#ResetGuardThread does not shutdown properly.\n", !isRunning( ) );
780 void SAL_CALL
run( ) override
783 printf("# ResettableGuard\n" );
784 ResettableMutexGuard
aGuard( pMyMutex
);
787 ThreadHelper::thread_sleep_tenth_sec( 2 );
793 namespace osl_ResettableGuard
795 class ctor
: public CppUnit::TestFixture
802 /// now, the aMutex has been guarded.
803 ResettableMutexGuard
myMutexGuard( &aMutex
);
805 /// it will return sal_False if the aMutex has not been Guarded.
806 bool bRes
= aMutex
.release( );
808 CPPUNIT_ASSERT_MESSAGE("ResettableMutexGuard constructor, test the acquire operation when initialized.",
818 /// now, the aMutex has been guarded, this time, we use reference constructor.
819 ResettableMutexGuard
myMutexGuard( aMutex
);
821 /// it will return sal_False if the aMutex has not been Guarded.
822 bool bRes
= aMutex
.release( );
824 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard constructor, test the acquire operation when initialized, we use reference constructor this time.",
830 CPPUNIT_TEST_SUITE(ctor
);
831 CPPUNIT_TEST(ctor_001
);
832 CPPUNIT_TEST(ctor_002
);
833 CPPUNIT_TEST_SUITE_END();
836 class reset
: public CppUnit::TestFixture
842 ResetGuardThread
myThread( &aMutex
);
843 ResettableMutexGuard
myMutexGuard( aMutex
);
846 /// is it running? and clear done?
847 bool bRes
= myThread
.isRunning( );
848 myMutexGuard
.clear( );
849 ThreadHelper::thread_sleep_tenth_sec( 1 );
851 /// if reset is not success, the release will return sal_False
852 myMutexGuard
.reset( );
853 bool bRes1
= aMutex
.release( );
856 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard method: reset",
858 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard method: reset",
868 ResettableMutexGuard
myMutexGuard( &aMutex
);
870 /// shouldn't release after clear;
871 myMutexGuard
.clear( );
873 bool bRes
= aMutex
.release( );
875 /// can release after reset.
876 myMutexGuard
.reset( );
877 bool bRes1
= aMutex
.release( );
879 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard method: reset, release after clear and reset, on Solaris, the mutex can be release without acquire, so it can not passed on (SOLARIS), but not the reason for reset_002",
881 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard method: reset, release after clear and reset, on Solaris, the mutex can be release without acquire, so it can not passed on (SOLARIS), but not the reason for reset_002",
888 CPPUNIT_TEST_SUITE(reset
);
889 CPPUNIT_TEST(reset_001
);
891 CPPUNIT_TEST(reset_002
);
893 CPPUNIT_TEST_SUITE_END();
896 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ResettableGuard::ctor
);
897 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ResettableGuard::reset
);
898 } // namespace osl_ResettableGuard
900 // The following sets variables for GNU EMACS
905 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */