]> SALOME platform Git repositories - modules/kernel.git/blob - src/Container/Component_i.cxx
Salome HOME
e0622fec3dc95c9b2cd18661d684209c9f0259ea
[modules/kernel.git] / src / Container / Component_i.cxx
1 //  SALOME Container : implementation of container and engine for Kernel
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : Component_i.cxx
25 //  Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA
26 //  Module : SALOME
27 //  $Header$
28
29 #define private protected
30 #include "SALOME_Component_i.hxx"
31 #include "SALOME_Container_i.hxx"
32 #include "RegistryConnexion.hxx"
33 #include "OpUtil.hxx"
34 #include <stdio.h>
35 #include <dlfcn.h>
36 #include <cstdlib>
37 #include "utilities.h"
38
39 #include <sys/time.h>
40 #include <sys/resource.h>
41 #include <unistd.h>
42
43 using namespace std;
44
45 extern bool _Sleeping ;
46 static Engines_Component_i * theEngines_Component ;
47
48 bool Engines_Component_i::_isMultiStudy = true;
49 bool Engines_Component_i::_isMultiInstance = false;
50
51 //=============================================================================
52 /*! 
53  *
54  */
55 //=============================================================================
56
57 Engines_Component_i::Engines_Component_i()
58 {
59 //  MESSAGE("Component constructor");
60 }
61
62 //=============================================================================
63 /*! 
64  *
65  */
66 //=============================================================================
67
68 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
69                                          PortableServer::POA_ptr poa, 
70                                          PortableServer::ObjectId * contId, 
71                                          const char *instanceName,
72                                          const char *interfaceName,
73                                          bool notif) :
74   _instanceName(instanceName),
75   _interfaceName(interfaceName),
76   _myConnexionToRegistry(0),
77   _ThreadId(0) ,
78   _ThreadCpuUsed(0) ,
79   _Executed(false) ,
80   _graphName("") ,
81   _nodeName(""),
82  _studyId(-1)
83 {
84   MESSAGE("Component constructor with instanceName "<< _instanceName);
85   SCRUTE(pd_refCount);
86   _orb = CORBA::ORB::_duplicate(orb);
87   _poa = PortableServer::POA::_duplicate(poa);
88   _contId = contId ;
89   CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior...
90   const CORBA::String_var ior = _orb->object_to_string(o);
91   _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession",
92                                                  _instanceName.c_str());
93
94   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
95   SCRUTE(pd_refCount);
96 }
97
98 //=============================================================================
99 /*! 
100  *
101  */
102 //=============================================================================
103
104 // Constructeur pour composant parallele: ne pas faire appel au registry!!
105 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
106                                          PortableServer::POA_ptr poa, 
107                                          PortableServer::ObjectId * contId, 
108                                          const char *instanceName,
109                                          const char *interfaceName,
110                                          int flag,
111                                          bool notif ) :
112  _instanceName(instanceName),
113  _interfaceName(interfaceName),
114  _myConnexionToRegistry(0),
115  _ThreadId(0) ,
116  _ThreadCpuUsed(0) ,
117  _Executed(false) ,
118  _graphName("") ,
119  _nodeName(""),
120  _studyId(-1)
121 {
122   //  MESSAGE("Component constructor with instanceName "<< _instanceName);
123   _orb = CORBA::ORB::_duplicate(orb);
124   _poa = PortableServer::POA::_duplicate(poa);
125   _contId = contId ;
126
127   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
128 }
129
130 //=============================================================================
131 /*! 
132  *
133  */
134 //=============================================================================
135
136 Engines_Component_i::~Engines_Component_i()
137 {
138   MESSAGE("Component destructor");
139   Engines_Container_i::decInstanceCnt(_interfaceName);
140 }
141
142 //=============================================================================
143 /*! 
144  *
145  */
146 //=============================================================================
147
148 char* Engines_Component_i::instanceName()
149 {
150    return CORBA::string_dup(_instanceName.c_str()) ;
151 }
152
153 //=============================================================================
154 /*! 
155  *
156  */
157 //=============================================================================
158
159 char* Engines_Component_i::interfaceName()
160 {
161   return CORBA::string_dup(_interfaceName.c_str()) ;
162 }
163
164 //=============================================================================
165 /*! 
166  *
167  */
168 //=============================================================================
169
170 CORBA::Boolean Engines_Component_i::setStudyId(CORBA::Long studyId)
171 {
172   ASSERT( studyId >= 0);
173   CORBA::Boolean ret = false;
174   if (_studyId < 0)
175     {
176       _studyId = studyId;
177       ret = true;
178     }
179   else
180     if ( _studyId == studyId) ret = true;
181   return ret;
182 }
183
184 //=============================================================================
185 /*! 
186  *
187  */
188 //=============================================================================
189
190 CORBA::Long Engines_Component_i::getStudyId()
191 {
192   return _studyId;
193 }
194
195 //=============================================================================
196 /*! 
197  *
198  */
199 //=============================================================================
200
201 void Engines_Component_i::ping()
202 {
203   MESSAGE("Engines_Component_i::ping() pid "<< getpid() << " threadid "
204           << pthread_self());
205 }
206
207 //=============================================================================
208 /*! 
209  *
210  */
211 //=============================================================================
212
213 void Engines_Component_i::destroy()
214 {
215   MESSAGE("Engines_Component_i::destroy()");
216   SCRUTE(pd_refCount);
217
218   delete _notifSupplier;
219   _notifSupplier = 0;
220
221   delete _myConnexionToRegistry;
222   _myConnexionToRegistry = 0 ;
223   _poa->deactivate_object(*_id) ;
224   CORBA::release(_poa) ;
225   delete(_id) ;
226   SCRUTE(pd_refCount);
227   _thisObj->_remove_ref();
228   SCRUTE(pd_refCount);
229   MESSAGE("Engines_Component_i::destroyed") ;
230 }
231
232 //=============================================================================
233 /*! 
234  *
235  */
236 //=============================================================================
237
238 Engines::Container_ptr Engines_Component_i::GetContainerRef()
239 {
240   MESSAGE("Engines_Component_i::GetContainerRef");
241   CORBA::Object_ptr o = _poa->id_to_reference(*_contId) ;
242   return Engines::Container::_narrow(o);
243 }
244
245 //=============================================================================
246 /*! 
247  *
248  */
249 //=============================================================================
250
251 PortableServer::ObjectId * Engines_Component_i::getId()
252 {
253 //  MESSAGE("PortableServer::ObjectId * Engines_Component_i::getId()");
254   return _id ;
255 }
256
257 //=============================================================================
258 /*! 
259  *
260  */
261 //=============================================================================
262
263 void Engines_Component_i::setProperties(const Engines::FieldsDict& dico)
264 {
265   _fieldsDict.clear();
266   for (CORBA::ULong i=0; i<dico.length(); i++)
267     {
268       std::string cle(dico[i].key);
269       _fieldsDict[cle] = dico[i].value;
270     }
271 }
272
273 //=============================================================================
274 /*! 
275  *
276  */
277 //=============================================================================
278
279 Engines::FieldsDict* Engines_Component_i::getProperties()
280 {
281   Engines::FieldsDict_var copie = new Engines::FieldsDict;
282   copie->length(_fieldsDict.size());
283   map<std::string,CORBA::Any>::iterator it;
284   CORBA::ULong i = 0;
285   for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++, i++)
286     {
287       std::string cle((*it).first);
288       copie[i].key = CORBA::string_dup(cle.c_str());
289       copie[i].value = _fieldsDict[cle];
290     }
291   return copie._retn();
292 }
293
294 //=============================================================================
295 /*! 
296  *
297  */
298 //=============================================================================
299
300 void Engines_Component_i::beginService(const char *serviceName)
301 {
302   MESSAGE(pthread_self() << "Send BeginService notification for " <<serviceName
303           << endl << "Component instance : " << _instanceName << endl << endl);
304   _ThreadId = pthread_self() ;
305   _StartUsed = 0 ;
306   _StartUsed = CpuUsed_impl() ;
307   _ThreadCpuUsed = 0 ;
308   _Executed = true ;
309   _serviceName = serviceName ;
310   if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) )
311     {
312       perror("pthread_setcanceltype ") ;
313       exit(0) ;
314     }
315   if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) )
316     {
317       perror("pthread_setcancelstate ") ;
318       exit(0) ;
319     }
320 //  MESSAGE(pthread_self() << " Return from BeginService for " << serviceName
321 //          << " ThreadId " << _ThreadId << " StartUsed " << _StartUsed
322 //          << " _graphName " << _graphName << " _nodeName " << _nodeName );
323
324   // --- for supervisor : all strings given with setProperties
325   //     are set in environment
326   bool overwrite = true;
327   map<std::string,CORBA::Any>::iterator it;
328   for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++)
329     {
330       std::string cle((*it).first);
331       if ((*it).second.type()->kind() == CORBA::tk_string)
332         {
333           const char* value;
334           (*it).second >>= value;
335           // --- todo: replace __GNUC__ test by an autoconf macro AC_CHECK_FUNC.
336 #if defined __GNUC__
337           int ret = setenv(cle.c_str(), value, overwrite);
338 #else
339           //CCRT porting : setenv not defined in stdlib.h
340           std::string s(cle);
341           s+='=';
342           s+=value;
343           //char* cast because 1st arg of linux putenv function is not a const char* !
344           int ret=putenv((char *)s.c_str());
345           //End of CCRT porting
346 #endif
347           MESSAGE("--- setenv: "<<cle<<" = "<< value);
348         }
349     }
350 }
351
352 //=============================================================================
353 /*! 
354  *
355  */
356 //=============================================================================
357
358 void Engines_Component_i::endService(const char *serviceName)
359 {
360   _ThreadCpuUsed = CpuUsed_impl() ;
361   MESSAGE(pthread_self() << " Send EndService notification for " << serviceName
362           << endl << " Component instance : " << _instanceName << " StartUsed "
363           << _StartUsed << " _ThreadCpuUsed "<< _ThreadCpuUsed << endl <<endl);
364   _ThreadId = 0 ;
365 }
366
367 //=============================================================================
368 /*! 
369  *
370  */
371 //=============================================================================
372
373 void Engines_Component_i::Names( const char * graphName ,
374                                  const char * nodeName )
375 {
376   _graphName = graphName ;
377   _nodeName = nodeName ;
378   //  MESSAGE("Engines_Component_i::Names( '" << _graphName << "' , '"
379   //          << _nodeName << "' )");
380 }
381
382 //=============================================================================
383 /*! 
384  *
385  */
386 //=============================================================================
387
388 char* Engines_Component_i::graphName()
389 {
390   return CORBA::string_dup( _graphName.c_str() ) ;
391 }
392
393 //=============================================================================
394 /*! 
395  *
396  */
397 //=============================================================================
398
399 char* Engines_Component_i::nodeName()
400 {
401   return CORBA::string_dup( _nodeName.c_str() ) ;
402 }
403
404 //=============================================================================
405 /*! 
406  *
407  */
408 //=============================================================================
409
410 bool Engines_Component_i::Killer( pthread_t ThreadId , int signum )
411 {
412   if ( ThreadId )
413     {
414       if ( signum == 0 )
415         {
416           if ( pthread_cancel( ThreadId ) )
417             {
418               perror("Killer pthread_cancel error") ;
419               return false ;
420             }
421           else
422             {
423               MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
424                       << " pthread_canceled") ;
425             }
426         }
427       else
428         {
429           if ( pthread_kill( ThreadId , signum ) == -1 )
430             {
431               perror("Killer pthread_kill error") ;
432               return false ;
433             }
434           else 
435             {
436               MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
437                       << " pthread_killed(" << signum << ")") ;
438             }
439         }
440     }
441   return true ;
442 }
443
444 //=============================================================================
445 /*! 
446  *
447  */
448 //=============================================================================
449
450 bool Engines_Component_i::Kill_impl() {
451 //  MESSAGE("Engines_Component_i::Kill_i() pthread_t "<< pthread_self()
452 //          << " pid " << getpid() << " instanceName "
453 //          << _instanceName.c_str() << " interface " << _interfaceName.c_str()
454 //          << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
455 //          << dec << " _ThreadId " << _ThreadId << " this " << hex << this
456 //          << dec ) ;
457   bool RetVal = false ;
458   if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
459     RetVal = Killer( _ThreadId , 0 ) ;
460     _ThreadId = (pthread_t ) -1 ;
461   }
462   return RetVal ;
463 }
464
465 //=============================================================================
466 /*! 
467  *
468  */
469 //=============================================================================
470
471 bool Engines_Component_i::Stop_impl()
472 {
473   MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self()
474           << " pid " << getpid() << " instanceName "
475           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
476           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
477           << dec << " _ThreadId " << _ThreadId );
478   
479   bool RetVal = false ;
480   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
481     {
482       RetVal = Killer( _ThreadId , 0 ) ;
483       _ThreadId = (pthread_t ) -1 ;
484     }
485   return RetVal ;
486 }
487
488 //=============================================================================
489 /*! 
490  *
491  */
492 //=============================================================================
493
494 bool Engines_Component_i::Suspend_impl()
495 {
496   MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self()
497           << " pid " << getpid() << " instanceName "
498           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
499           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
500           << dec << " _ThreadId " << _ThreadId );
501   bool RetVal = false ;
502   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
503     {
504       if ( _Sleeping )
505         {
506           return false ;
507         }
508     else 
509       {
510         RetVal = Killer( _ThreadId ,SIGINT ) ;
511       }
512     }
513   return RetVal ;
514 }
515
516 //=============================================================================
517 /*! 
518  *
519  */
520 //=============================================================================
521
522 bool Engines_Component_i::Resume_impl()
523 {
524   MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self()
525           << " pid " << getpid() << " instanceName "
526           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
527           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
528           << dec << " _ThreadId " << _ThreadId );
529   bool RetVal = false ;
530   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
531     {
532     if ( _Sleeping ) 
533       {
534         _Sleeping = false ;
535         RetVal = true ;
536       }
537     else
538       {
539         RetVal = false ;
540       }
541     }
542   return RetVal ;
543
544 }
545
546 //=============================================================================
547 /*! 
548  *
549  */
550 //=============================================================================
551
552 void SetCpuUsed()
553 {
554   theEngines_Component->SetCurCpu() ;
555 }
556
557 //=============================================================================
558 /*! 
559  *
560  */
561 //=============================================================================
562
563 void Engines_Component_i::SetCurCpu()
564 {
565   _ThreadCpuUsed =  CpuUsed() ;
566   //  MESSAGE(pthread_self() << 
567   //  " Engines_Component_i::SetCurCpu() _ThreadCpuUsed " << _ThreadCpuUsed) ;
568 }
569
570 //=============================================================================
571 /*! 
572  *
573  */
574 //=============================================================================
575
576 long Engines_Component_i::CpuUsed()
577 {
578   long cpu = 0 ;
579   struct rusage usage ;
580   if ( _ThreadId || _Executed )
581     {
582       if ( getrusage( RUSAGE_SELF , &usage ) == -1 )
583         {
584           perror("Engines_Component_i::CpuUsed") ;
585           return 0 ;
586         }
587       cpu = usage.ru_utime.tv_sec - _StartUsed ;
588       // cout << pthread_self() << " Engines_Component_i::CpuUsed " << " "
589       //      << _serviceName   << usage.ru_utime.tv_sec << " - " << _StartUsed
590       //      << " = " << cpu << endl ;
591     }
592   else
593     {
594       // cout << pthread_self() << "Engines_Component_i::CpuUsed _ThreadId "
595       //      << _ThreadId << " " << _serviceName<< " _StartUsed " 
596       //      << _StartUsed << endl ;
597     }
598   return cpu ;
599 }
600
601 //=============================================================================
602 /*! 
603  *
604  */
605 //=============================================================================
606
607 CORBA::Long Engines_Component_i::CpuUsed_impl()
608 {
609   long cpu = 0 ;
610   if ( _ThreadId || _Executed )
611     {
612     if ( _ThreadId > 0 )
613       {
614       if ( pthread_self() != _ThreadId )
615         {
616         if ( _Sleeping )
617           {
618           }
619         else
620           {
621             // Get Cpu in the appropriate thread with that object !...
622             theEngines_Component = this ;
623             Killer( _ThreadId ,SIGUSR1 ) ;
624           }
625         cpu = _ThreadCpuUsed ;
626         }
627       else
628         {
629           _ThreadCpuUsed = CpuUsed() ;
630           cpu = _ThreadCpuUsed ;
631           // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
632           //      << _serviceName << " " << cpu << endl ;
633       }
634     }
635     else 
636       {
637         cpu = _ThreadCpuUsed ;
638         // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
639         //      << _serviceName << " " << cpu<< endl ;
640       }
641     }
642   else
643     {
644       // cout << pthread_self()<<"Engines_Component_i::CpuUsed_impl _ThreadId "
645       //      <<_ThreadId <<" "<<_serviceName<<" _StartUsed "<<_StartUsed<<endl;
646     }
647   return cpu ;
648 }
649
650 //=============================================================================
651 /*! 
652  *  Send message to event channel
653  */
654 //=============================================================================
655
656 void Engines_Component_i::sendMessage(const char *event_type,
657                                       const char *message)
658 {
659     _notifSupplier->Send(graphName(), nodeName(), event_type, message);
660 }
661
662 //=============================================================================
663 /*! 
664  *
665  */
666 //=============================================================================
667
668 string Engines_Component_i::GetDynLibraryName(const char *componentName)
669 {
670   string ret="lib";
671   ret+=componentName;
672   ret+="Engine.so";
673   return ret;
674 }
675
676 //=============================================================================
677 /*! 
678  *
679  */
680 //=============================================================================
681
682 string Engines_Component_i::BuildComponentNameForNS(const char *ComponentName,
683                                                     const char *ContainerName,
684                                                     const char *hostname)
685 {
686   string ret=Engines_Container_i::BuildContainerNameForNS(ContainerName,hostname);
687   ret+="/";
688   ret+=ComponentName;
689   return ret;
690 }
691