Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : //------------------------------------------------------------------------
21 : // include files
22 : //------------------------------------------------------------------------
23 : #include <sal/types.h>
24 :
25 : #include <osl/thread.hxx>
26 : #include <osl/time.h>
27 :
28 : #include <rtl/instance.hxx>
29 : #include <rtl/ustring.hxx>
30 :
31 : #include <cppunit/TestFixture.h>
32 : #include <cppunit/extensions/HelperMacros.h>
33 : #include <cppunit/plugin/TestPlugIn.h>
34 :
35 : #ifdef WNT
36 : #include <windows.h>
37 : #else
38 : #include <unistd.h>
39 : #include <time.h>
40 : #endif
41 :
42 : // -----------------------------------------------------------------------------
43 : #define CONST_TEST_STRING "gregorian"
44 :
45 : namespace {
46 : struct Gregorian : public rtl::StaticWithInit<rtl::OUString, Gregorian> {
47 1 : const rtl::OUString operator () () {
48 1 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
49 : }
50 : };
51 : }
52 :
53 : // -----------------------------------------------------------------------------
54 : namespace ThreadHelper
55 : {
56 : // typedef enum {
57 : // QUIET=1,
58 : // VERBOSE
59 : // } eSleepVerboseMode;
60 :
61 11 : void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/)
62 : {
63 : // if (nVerbose == VERBOSE)
64 : // {
65 : // printf("wait %d tenth seconds. ", _nTenthSec );
66 : // fflush(stdout);
67 : // }
68 : #ifdef WNT //Windows
69 : Sleep(_nTenthSec * 100 );
70 : #endif
71 : #if ( defined UNX )
72 : TimeValue nTV;
73 11 : nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 );
74 11 : nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
75 11 : osl_waitThread(&nTV);
76 : #endif
77 : // if (nVerbose == VERBOSE)
78 : // {
79 : // printf("done\n");
80 : // }
81 11 : }
82 : }
83 :
84 : // -----------------------------------------------------------------------------
85 :
86 : /** Simple thread for testing Thread-create.
87 : * Just add 1 of value 0, and after running, result is 1.
88 : */
89 : class OGetThread : public osl::Thread
90 : {
91 : sal_Int32 m_nOK;
92 : sal_Int32 m_nFails;
93 :
94 : rtl::OUString m_sConstStr;
95 : public:
96 2 : OGetThread()
97 : :m_nOK(0),
98 2 : m_nFails(0)
99 : {
100 2 : m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
101 2 : }
102 :
103 2 : sal_Int32 getOK() { return m_nOK; }
104 2 : sal_Int32 getFails() {return m_nFails;}
105 :
106 : protected:
107 :
108 : /** guarded value which initialized 0
109 :
110 : @see ThreadSafeValue
111 : */
112 2 : void SAL_CALL run()
113 : {
114 14 : while(schedule())
115 : {
116 10 : rtl::OUString aStr = Gregorian::get();
117 10 : if (aStr.equals(m_sConstStr))
118 : {
119 10 : m_nOK++;
120 : }
121 : else
122 : {
123 0 : m_nFails++;
124 : }
125 10 : ThreadHelper::thread_sleep_tenth_sec(1);
126 10 : }
127 2 : }
128 :
129 : public:
130 :
131 0 : virtual void SAL_CALL suspend()
132 : {
133 0 : ::osl::Thread::suspend();
134 0 : }
135 :
136 4 : ~OGetThread()
137 4 : {
138 2 : if (isRunning())
139 : {
140 0 : printf("error: not terminated.\n");
141 : }
142 4 : }
143 : };
144 :
145 : // -----------------------------------------------------------------------------
146 : namespace rtl_DoubleLocking
147 : {
148 :
149 : /** Test of the osl::Thread::create method
150 : */
151 :
152 6 : class getValue : public CppUnit::TestFixture
153 : {
154 : public:
155 :
156 : // initialise your test code values here.
157 2 : void setUp()
158 : {
159 2 : }
160 :
161 2 : void tearDown()
162 : {
163 2 : }
164 :
165 :
166 1 : void getValue_001()
167 : {
168 1 : rtl::OUString aStr = Gregorian::get();
169 :
170 2 : CPPUNIT_ASSERT_MESSAGE(
171 : "Gregorian::get() failed, wrong value expected.",
172 : !aStr.isEmpty()
173 2 : );
174 1 : }
175 :
176 : /** check 2 threads.
177 :
178 : ALGORITHM:
179 : Here the function should show, that 2 different threads,
180 : which only increase a value, should run at the same time with same prio.
181 : The test fails, if the difference between the two values is more than 5%
182 : but IMHO this isn't a failure, it's only a feature of the OS.
183 : */
184 :
185 1 : void getValue_002()
186 : {
187 : // initial 5 threads with different priorities
188 1 : OGetThread* pThread = new OGetThread();
189 1 : OGetThread* p2Thread = new OGetThread();
190 :
191 : //Create them and start running at the same time
192 1 : pThread->create();
193 1 : p2Thread->create();
194 :
195 1 : ThreadHelper::thread_sleep_tenth_sec(5);
196 :
197 1 : pThread->terminate();
198 1 : p2Thread->terminate();
199 :
200 1 : pThread->join();
201 1 : p2Thread->join();
202 :
203 1 : sal_Int32 nValueOK = 0;
204 1 : nValueOK = pThread->getOK();
205 :
206 1 : sal_Int32 nValueOK2 = 0;
207 1 : nValueOK2 = p2Thread->getOK();
208 :
209 : #if OSL_DEBUG_LEVEL > 2
210 : printf("Value in Thread #1 is %d\n", nValueOK);
211 : printf("Value in Thread #2 is %d\n", nValueOK2);
212 : #else
213 : (void)nValueOK2;
214 : #endif
215 :
216 1 : sal_Int32 nValueFails = 0;
217 1 : nValueFails = pThread->getFails();
218 :
219 1 : sal_Int32 nValueFails2 = 0;
220 1 : nValueFails2 = p2Thread->getFails();
221 :
222 : #if OSL_DEBUG_LEVEL > 2
223 : printf("Fails in Thread #1 is %d\n", nValueFails);
224 : printf("Fails in Thread #2 is %d\n", nValueFails2);
225 : #endif
226 :
227 1 : delete pThread;
228 1 : delete p2Thread;
229 :
230 2 : CPPUNIT_ASSERT_MESSAGE(
231 : "getValue() failed, wrong value expected.",
232 : nValueOK != 0 && nValueFails == 0 && nValueFails2 == 0
233 1 : );
234 1 : }
235 :
236 2 : CPPUNIT_TEST_SUITE(getValue);
237 1 : CPPUNIT_TEST(getValue_001);
238 1 : CPPUNIT_TEST(getValue_002);
239 2 : CPPUNIT_TEST_SUITE_END();
240 : }; // class create
241 : // -----------------------------------------------------------------------------
242 1 : CPPUNIT_TEST_SUITE_REGISTRATION(rtl_DoubleLocking::getValue);
243 : } // namespace rtl_DoubleLocking
244 :
245 : // this macro creates an empty function, which will called by the RegisterAllFunctions()
246 : // to let the user the possibility to also register some functions by hand.
247 4 : CPPUNIT_PLUGIN_IMPLEMENT();
248 :
249 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|