1 martin 1.24 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.25 //
|
3 martin 1.24 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.25 //
|
10 martin 1.24 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.25 //
|
17 martin 1.24 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.25 //
|
20 martin 1.24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.25 //
|
28 martin 1.24 //////////////////////////////////////////////////////////////////////////
|
29 schuur 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include "CMPI_Version.h"
33
|
34 konrad.r 1.13 #include <Pegasus/ProviderManager2/CMPI/CMPIProvider.h>
|
35 schuur 1.1 #include "CMPI_Object.h"
36 #include "CMPI_Broker.h"
37 #include "CMPI_Ftabs.h"
38 #include "CMPI_String.h"
39 #include "CMPI_SelectExp.h"
40
41 #include <Pegasus/Common/CIMName.h>
|
42 mike 1.15 #include <Pegasus/Common/Time.h>
|
43 schuur 1.1 #include <Pegasus/Common/CIMPropertyList.h>
44 #include <Pegasus/ProviderManager2/ProviderManager.h>
45 #include <Pegasus/Common/Thread.h>
|
46 konrad.r 1.12 #include <Pegasus/Common/Tracer.h>
|
47 a.arora 1.9 #include <Pegasus/Common/AutoPtr.h>
|
48 mike 1.15 #include <Pegasus/Common/Condition.h>
|
49 schuur 1.1
50 #if defined (CMPI_VER_85)
|
51 kumpf 1.20 # include <Pegasus/Common/MessageLoader.h>
|
52 schuur 1.1 #endif
53
54 #include <stdarg.h>
55 #include <string.h>
56
|
57 schuur 1.4 #if defined(CMPI_PLATFORM_WIN32_IX86_MSVC)
|
58 kumpf 1.20 # include <sys/timeb.h>
|
59 schuur 1.4 #endif
60
|
61 schuur 1.1 PEGASUS_NAMESPACE_BEGIN
62
|
63 mike 1.15 class ConditionWithMutex
64 {
65 public:
|
66 venkat.puvvada 1.19 ConditionWithMutex() : _mutex(Mutex::NON_RECURSIVE)
67 {
68 }
69 ~ConditionWithMutex()
70 {
71 }
72 void signal()
73 {
74 _cond.signal();
75 }
76 void wait()
77 {
78 _cond.wait(_mutex);
79 }
|
80 mike 1.15
81 private:
82 Mutex _mutex;
83 Condition _cond;
84 };
85
|
86 venkat.puvvada 1.19 extern "C"
87 {
88 struct thrd_data
89 {
90 CMPI_THREAD_RETURN(CMPI_THREAD_CDECL*pgm)(void*);
91 void *parm;
92 CMPIProvider *provider;
93 };
|
94 david.dillard 1.8 }
|
95 schuur 1.7
|
96 mike 1.15 static ThreadReturnType PEGASUS_THREAD_CDECL start_driver(void *parm)
|
97 schuur 1.7 {
|
98 ms.aruran 1.21 PEG_METHOD_ENTER(
99 TRC_CMPIPROVIDERINTERFACE,
100 "CMPI_BrokerExt:start_driver()");
|
101 venkat.puvvada 1.19 ThreadReturnType rc;
102 Thread* my_thread = (Thread*)parm;
103 thrd_data *pp = (thrd_data*)my_thread->get_parm();
104 thrd_data data=*pp;
105
106 delete pp;
107 rc = (ThreadReturnType)(data.pgm)(data.parm);
108
|
109 venkat.puvvada 1.26 // Remove the thread from the watch-list (and clean it up) if this (self)
110 // was created in detached mode. Don't delete the thread if this thread
111 // was not created in detached mode because it is possible that join()
112 // my be called on this thread later. This thread object is deleted when
113 // joinThread() is called later. If joinThread() is not called memory is
114 // leaked which is true as per Pthread semantics and as defined by CMPI.
115 if (!my_thread->isDetached())
116 {
117 PEG_TRACE((TRC_PROVIDERMANAGER,Tracer::LEVEL4,
118 "Thread %s is not detached, not removed from provider watch-list",
119 Threads::id().buffer));
120 }
121 else
122 {
123 data.provider->removeThreadFromWatch(my_thread);
124 PEG_TRACE((TRC_PROVIDERMANAGER,Tracer::LEVEL4,
125 "Thread %s is detached and removed from provider watch-list",
126 Threads::id().buffer));
127 }
|
128 ms.aruran 1.21 PEG_METHOD_EXIT();
|
129 venkat.puvvada 1.19 return rc;
|
130 schuur 1.7 }
131
|
132 venkat.puvvada 1.19 extern "C"
133 {
|
134 ms.aruran 1.21 static char *resolveFileName(const char *filename)
|
135 venkat.puvvada 1.19 {
136 String pn = ProviderManager::_resolvePhysicalName(filename);
137 CString n = pn.getCString();
138 return(strdup((const char*)n));
139 }
140
141 static CMPI_THREAD_TYPE newThread
142 (CMPI_THREAD_RETURN(CMPI_THREAD_CDECL *start)(void *),
143 void *parm,
144 int detached)
145 {
|
146 ms.aruran 1.21 PEG_METHOD_ENTER(
147 TRC_CMPIPROVIDERINTERFACE,
148 "CMPI_BrokerExt:newThread()");
|
149 venkat.puvvada 1.19 const CMPIBroker *brk = CM_BROKER;
150 const CMPI_Broker *broker = (CMPI_Broker*)brk;
151
152 AutoPtr<thrd_data> data(new thrd_data());
153 data->pgm = (CMPI_THREAD_RETURN (CMPI_THREAD_CDECL *)(void*))start;
154 data->parm = parm;
155 data->provider = broker->provider;
156 Thread *t = new Thread(start_driver, data.get(), detached == 1);
157
158 broker->provider->addThreadToWatch(t);
159 data.release();
160
161 ThreadStatus rtn = PEGASUS_THREAD_OK;
162 while ((rtn = t->run()) != PEGASUS_THREAD_OK)
163 {
164 if (rtn == PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
165 {
166 Threads::yield();
167 }
168 else
169 {
|
170 marek 1.23 PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL1, \
|
171 venkat.puvvada 1.19 "Could not allocate provider thread (%p) for %s provider.",
172 t, (const char *)broker->name.getCString()));
173 broker->provider->removeThreadFromWatch(t);
174 delete t;
175 t = 0;
176 break;
177 }
178 }
179 if (rtn == PEGASUS_THREAD_OK)
180 {
|
181 marek 1.23 PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL3,
|
182 venkat.puvvada 1.19 "Started provider thread (%p) for %s.",
183 t, (const char *)broker->name.getCString()));
184 }
|
185 ms.aruran 1.21 PEG_METHOD_EXIT();
|
186 venkat.puvvada 1.19 return (CMPI_THREAD_TYPE)t;
187 }
188
189 static int joinThread(
190 CMPI_THREAD_TYPE thread,
191 CMPI_THREAD_RETURN *returnCode)
192 {
|
193 venkat.puvvada 1.26 const CMPIBroker *brk = CM_BROKER;
194 const CMPI_Broker *broker = (CMPI_Broker*)brk;
|
195 venkat.puvvada 1.19 ((Thread*)thread)->join();
|
196 venkat.puvvada 1.26 if (returnCode)
197 {
198 *returnCode = (CMPI_THREAD_RETURN)((Thread*)thread)->get_exit();
199 }
200 broker->provider->removeThreadFromWatch((Thread*)thread);
|
201 venkat.puvvada 1.19 return 0;
202 }
203
204 static int exitThread(CMPI_THREAD_RETURN return_code)
205 {
206 Thread::getCurrent()->exit_self((ThreadReturnType)return_code);
207 return 0;
208 }
209
210 static int cancelThread(CMPI_THREAD_TYPE thread)
211 {
212 ((Thread*)thread)->cancel();
213 return 0;
214 }
215
216 static int threadSleep(CMPIUint32 msec)
217 {
218 Threads::sleep(msec);
219 return 0;
220 }
221
222 venkat.puvvada 1.19 static int threadOnce (int *once, void (*init)(void))
223 {
|
224 ms.aruran 1.21 PEG_METHOD_ENTER(
225 TRC_CMPIPROVIDERINTERFACE,
226 "CMPI_BrokerExt:threadOnce()");
|
227 venkat.puvvada 1.19 if (*once==0)
228 {
229 *once = 1;
230 (init)();
231 }
|
232 ms.aruran 1.21 PEG_METHOD_EXIT();
|
233 venkat.puvvada 1.19 return *once;
234 }
235
236 static int createThreadKey(
237 CMPI_THREAD_KEY_TYPE *key,
238 void (*cleanup)(void*))
239 {
240 return TSDKey::create((TSDKeyType*)key);
241 }
242
243 static int destroyThreadKey(CMPI_THREAD_KEY_TYPE key)
244 {
245 return TSDKey::destroy(key);
246 }
247
248 static void *getThreadSpecific(CMPI_THREAD_KEY_TYPE key)
249 {
250 return TSDKey::get_thread_specific(key);
251 }
252
253 static int setThreadSpecific(CMPI_THREAD_KEY_TYPE key, void *value)
254 venkat.puvvada 1.19 {
255 return TSDKey::set_thread_specific(key,value);
256 }
257
258 static CMPI_MUTEX_TYPE newMutex(int opt)
259 {
260 Mutex *m = new Mutex();
261 return m;
262 }
263
264 static void destroyMutex(CMPI_MUTEX_TYPE m)
265 {
266 delete ((Mutex*)m);
267 }
268
269 static void lockMutex(CMPI_MUTEX_TYPE m)
270 {
271 ((Mutex*)m)->lock();
272 }
273
274 static void unlockMutex(CMPI_MUTEX_TYPE m)
275 venkat.puvvada 1.19 {
276 ((Mutex*)m)->unlock();
277 }
278
279 static CMPI_COND_TYPE newCondition(int opt)
280 {
|
281 ms.aruran 1.21 PEG_METHOD_ENTER(
282 TRC_CMPIPROVIDERINTERFACE,
283 "CMPI_BrokerExt:newCondition()");
|
284 venkat.puvvada 1.19 ConditionWithMutex *c = new ConditionWithMutex();
|
285 ms.aruran 1.21 PEG_METHOD_EXIT();
|
286 venkat.puvvada 1.19 return c;
287 }
288
289 static void destroyCondition(CMPI_COND_TYPE c)
290 {
291 delete (ConditionWithMutex*)c;
292 }
293
294 static int condWait(CMPI_COND_TYPE c, CMPI_MUTEX_TYPE m)
295 {
296 // need to take care of mutex
297 ((ConditionWithMutex*)c)->wait();
298 return 0;
299 }
300
301 static int timedCondWait(
302 CMPI_COND_TYPE c,
303 CMPI_MUTEX_TYPE m,
304 struct timespec *wait)
305 {
|
306 ms.aruran 1.21 PEG_METHOD_ENTER(
307 TRC_CMPIPROVIDERINTERFACE,
308 "CMPI_BrokerExt:timedCondWait()");
|
309 venkat.puvvada 1.19 int msec;
310 struct timespec next = *wait;
311 #if defined CMPI_PLATFORM_WIN32_IX86_MSVC
312 struct timeval
313 {
314 long tv_sec;
315 long tv_usec;
316 }now;
317 struct _timeb timebuffer;
318 #endif
|
319 konrad.r 1.13
|
320 venkat.puvvada 1.19 /* this is not truely mapping to pthread_timed_wait
321 but will work for the time beeing
322 */
323 #if defined CMPI_PLATFORM_WIN32_IX86_MSVC
324 _ftime(&timebuffer);
|
325 kavita.gupta 1.22 now.tv_sec = (long)timebuffer.time;
|
326 venkat.puvvada 1.19 now.tv_usec = timebuffer.millitm*1000;
327 #else
328 struct timeval now;
329 Time::gettimeofday(&now);
330 #endif
|
331 schuur 1.6
|
332 venkat.puvvada 1.19 if (next.tv_nsec>1000000000)
333 {
334 next.tv_sec+=next.tv_nsec/1000000000;
335 next.tv_nsec=next.tv_nsec%1000000000;
336 }
337 msec = (next.tv_sec-now.tv_sec)*1000;
338 msec += (next.tv_nsec/1000000)-(now.tv_usec/1000);
339
340 Threads::sleep(msec);
|
341 ms.aruran 1.21 PEG_METHOD_EXIT();
|
342 venkat.puvvada 1.19 return 0;
343 }
344
345 static int signalCondition(CMPI_COND_TYPE cond)
346 {
347 ((ConditionWithMutex*)cond)->signal();
348 return 0;
349 }
|
350 schuur 1.1
|
351 schuur 1.2 }
352
|
353 venkat.puvvada 1.19 static CMPIBrokerExtFT brokerExt_FT =
354 {
355 CMPICurrentVersion,
356 resolveFileName,
357
358 newThread,
359 joinThread,
360 exitThread,
361 cancelThread,
362 threadSleep,
363 threadOnce,
364
365 createThreadKey,
366 destroyThreadKey,
367 getThreadSpecific,
368 setThreadSpecific,
369
370 newMutex,
371 destroyMutex,
372 lockMutex,
373 unlockMutex,
374 venkat.puvvada 1.19
375 newCondition,
376 destroyCondition,
377 condWait,
378 timedCondWait,
379 signalCondition // Signal not supported yet
|
380 schuur 1.1 };
381
|
382 venkat.puvvada 1.19 CMPIBrokerExtFT *CMPI_BrokerExt_Ftab = &brokerExt_FT;
|
383 schuur 1.1
384
385 PEGASUS_NAMESPACE_END
386
387
388
|