]> SALOME platform Git repositories - modules/kernel.git/blob - src/Container/Component_i.cxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[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.salome-platform.org/ or email : webmaster.salome@opencascade.com
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  // for pd_refCount trace
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 #ifndef WNT
36 #include <dlfcn.h>
37 #endif
38 #include <cstdlib>
39 #include "utilities.h"
40
41 #ifndef WNT
42 #include <sys/time.h>
43 #include <sys/resource.h>
44 #include <unistd.h>
45 #else
46 #include <sys/timeb.h>
47 int SIGUSR11 = 1000;
48 #include <process.h>
49 #endif
50
51
52 using namespace std;
53
54 extern bool _Sleeping ;
55 static Engines_Component_i * theEngines_Component ;
56
57 bool Engines_Component_i::_isMultiStudy = true;
58 bool Engines_Component_i::_isMultiInstance = false;
59
60 //=============================================================================
61 /*! 
62  *  Default constructor, not for use
63  */
64 //=============================================================================
65
66 Engines_Component_i::Engines_Component_i():_myConnexionToRegistry(0), _notifSupplier(0)
67 {
68   //ASSERT(0);
69   MESSAGE("Default Constructor, not for normal use...");
70 }
71
72 //=============================================================================
73 /*! 
74  *  Standard Constructor for generic Component, used in derived class
75  *  Connection to Registry and Notification
76  *  \param orb Object Request broker given by Container
77  *  \param poa Portable Object Adapter from Container (normally root_poa)
78  *  \param contId container CORBA id inside the server
79  *  \param instanceName unique instance name for this object (see Container_i)
80  *  \param interfaceName component class name
81  *  \param notif use of notification
82  */
83 //=============================================================================
84
85 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
86                                          PortableServer::POA_ptr poa, 
87                                          PortableServer::ObjectId * contId, 
88                                          const char *instanceName,
89                                          const char *interfaceName,
90                                          bool notif) :
91   _instanceName(instanceName),
92   _interfaceName(interfaceName),
93   _myConnexionToRegistry(0),
94   _notifSupplier(0),
95   _ThreadId(0) ,
96   _ThreadCpuUsed(0) ,
97   _Executed(false) ,
98   _graphName("") ,
99   _nodeName(""),
100   _studyId(-1),
101   _CanceledThread(false)
102 {
103   MESSAGE("Component constructor with instanceName "<< _instanceName);
104   //SCRUTE(pd_refCount);
105   _orb = CORBA::ORB::_duplicate(orb);
106   _poa = PortableServer::POA::_duplicate(poa);
107   _contId = contId ;
108   CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior...
109   const CORBA::String_var ior = _orb->object_to_string(o);
110   _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession",
111                                                  _instanceName.c_str());
112
113   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
114   //SCRUTE(pd_refCount);
115 }
116
117 //=============================================================================
118 /*! 
119  * Standard constructor for parallel component
120  *  Connection Notification (no connection to Registry !)
121  *  \param orb Object Request broker given by Container
122  *  \param poa Portable Object Adapter from Container (normally root_poa)
123  *  \param contId container CORBA id inside the server
124  *  \param instanceName unique instance name for this object (see Container_i)
125  *  \param interfaceName component class name
126  *  \param flag not used...
127  *  \param notif use of notification
128  */
129 //=============================================================================
130
131 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
132                                          PortableServer::POA_ptr poa, 
133                                          PortableServer::ObjectId * contId, 
134                                          const char *instanceName,
135                                          const char *interfaceName,
136                                          int flag,
137                                          bool notif ) :
138  _instanceName(instanceName),
139  _interfaceName(interfaceName),
140  _myConnexionToRegistry(0),
141   _notifSupplier(0),
142  _ThreadId(0) ,
143  _ThreadCpuUsed(0) ,
144  _Executed(false) ,
145  _graphName("") ,
146  _nodeName(""),
147  _studyId(-1),
148  _CanceledThread(false)
149 {
150   _orb = CORBA::ORB::_duplicate(orb);
151   _poa = PortableServer::POA::_duplicate(poa);
152   _contId = contId ;
153
154   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
155 }
156
157 //=============================================================================
158 /*! 
159  *  Destructor: call Container for decrement of instances count.
160  *  When instances count falls to 0, the container tries to remove the
161  *  component library (dlclose)
162  */
163 //=============================================================================
164
165 Engines_Component_i::~Engines_Component_i()
166 {
167   MESSAGE("Component destructor");
168   Engines_Container_i::decInstanceCnt(_interfaceName);
169   if(_myConnexionToRegistry)delete _myConnexionToRegistry;
170   if(_notifSupplier)delete _notifSupplier;
171 }
172
173 //=============================================================================
174 /*! 
175  *  CORBA method: return name of the instance, unique in this Container
176  */
177 //=============================================================================
178
179 char* Engines_Component_i::instanceName()
180 {
181    return CORBA::string_dup(_instanceName.c_str()) ;
182 }
183
184 //=============================================================================
185 /*! 
186  *  CORBA method: return name of the component class
187  */
188 //=============================================================================
189
190 char* Engines_Component_i::interfaceName()
191 {
192   return CORBA::string_dup(_interfaceName.c_str()) ;
193 }
194
195 //=============================================================================
196 /*! 
197  *  CORBA method: Get study Id
198  *  \return -1: not initialised (Internal Error)
199  *           0: multistudy component instance
200  *          >0: study id associated to this instance
201  */
202 //=============================================================================
203
204 CORBA::Long Engines_Component_i::getStudyId()
205 {
206   return _studyId;
207 }
208
209 //=============================================================================
210 /*! 
211  *  CORBA method: Test if instance is alive and responds
212  */
213 //=============================================================================
214
215 void Engines_Component_i::ping()
216 {
217 #ifndef WNT
218   MESSAGE("Engines_Component_i::ping() pid "<< getpid() << " threadid "
219           << pthread_self());
220 #else
221   MESSAGE("Engines_Component_i::ping() pid "<< _getpid()<< " threadid "
222           << pthread_self().p );
223 #endif
224 }
225
226 //=============================================================================
227 /*! 
228  *  CORBA method: Deactivate this instance. CORBA object is deactivated (do not
229  *  respond any more to CORBA calls), the connection to Regsitry is removed
230  *  (Registry informed of deactivation), internal server reference counter on
231  *  the derived servant class is decremented, to allow destruction of the class
232  *  (delete) by POA, when there are no more references.
233  *  -- TO BE USED BY CONTAINER ONLY (Container housekeeping) --
234  */
235 //=============================================================================
236
237 void Engines_Component_i::destroy()
238 {
239   MESSAGE("Engines_Component_i::destroy()");
240   //SCRUTE(pd_refCount);
241
242   delete _notifSupplier;
243   _notifSupplier = 0;
244
245   delete _myConnexionToRegistry;
246   _myConnexionToRegistry = 0 ;
247   _poa->deactivate_object(*_id) ;
248   delete(_id) ;
249   //SCRUTE(pd_refCount);
250   _thisObj->_remove_ref();
251   //SCRUTE(pd_refCount);
252   MESSAGE("Engines_Component_i::destroyed") ;
253 }
254
255 //=============================================================================
256 /*! 
257  *  CORBA method: return CORBA reference of the Container
258  *
259  */
260 //=============================================================================
261
262 Engines::Container_ptr Engines_Component_i::GetContainerRef()
263 {
264   //  MESSAGE("Engines_Component_i::GetContainerRef");
265   CORBA::Object_var o = _poa->id_to_reference(*_contId) ;
266   return Engines::Container::_narrow(o);
267 }
268
269 //=============================================================================
270 /*! 
271  *  CORBA method: 
272  *  Gives a sequence of (key=string,value=any) to the component. 
273  *  Base class component stores the sequence in a map.
274  *  The map is cleared before.
275  *  This map is for use by derived classes. 
276  *  \param dico sequence of (key=string,value=any)
277  */
278 //=============================================================================
279
280 void Engines_Component_i::setProperties(const Engines::FieldsDict& dico)
281 {
282   _fieldsDict.clear();
283   for (CORBA::ULong i=0; i<dico.length(); i++)
284     {
285       std::string cle(dico[i].key);
286       _fieldsDict[cle] = dico[i].value;
287     }
288 }
289
290 //=============================================================================
291 /*! 
292  *  CORBA method: 
293  *  returns a previously stored map (key=string,value=any) as a sequence.
294  *  (see setProperties)
295  */
296 //=============================================================================
297
298 Engines::FieldsDict* Engines_Component_i::getProperties()
299 {
300   Engines::FieldsDict_var copie = new Engines::FieldsDict;
301   copie->length(_fieldsDict.size());
302   map<std::string,CORBA::Any>::iterator it;
303   CORBA::ULong i = 0;
304   for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++, i++)
305     {
306       std::string cle((*it).first);
307       copie[i].key = CORBA::string_dup(cle.c_str());
308       copie[i].value = _fieldsDict[cle];
309     }
310   return copie._retn();
311 }
312
313 //=============================================================================
314 /*! 
315  *  CORBA method: used by Supervision to give names to this instance
316  */
317 //=============================================================================
318
319 void Engines_Component_i::Names( const char * graphName ,
320                                  const char * nodeName )
321 {
322   _graphName = graphName ;
323   _nodeName = nodeName ;
324   //  MESSAGE("Engines_Component_i::Names( '" << _graphName << "' , '"
325   //          << _nodeName << "' )");
326 }
327
328 //=============================================================================
329 /*! 
330  *  CORBA method: used in Supervision
331  */
332 //=============================================================================
333
334 bool Engines_Component_i::Kill_impl() 
335 {
336 //  MESSAGE("Engines_Component_i::Kill_i() pthread_t "<< pthread_self()
337 //          << " pid " << getpid() << " instanceName "
338 //          << _instanceName.c_str() << " interface " << _interfaceName.c_str()
339 //          << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
340 //          << dec << " _ThreadId " << _ThreadId << " this " << hex << this
341 //          << dec ) ;
342
343   bool RetVal = false ;
344 #ifndef WNT
345   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
346     {
347       RetVal = Killer( _ThreadId , SIGUSR2 ) ;
348       _ThreadId = (pthread_t ) -1 ;
349     }
350
351 #else
352   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
353     {
354       RetVal = Killer( *_ThreadId , 0 ) ;
355       _ThreadId = (pthread_t* ) 0 ;
356     }
357
358 #endif
359   return RetVal ;
360 }
361
362 //=============================================================================
363 /*! 
364  *  CORBA method: used in Supervision
365  */
366 //=============================================================================
367
368 bool Engines_Component_i::Stop_impl()
369 {
370 #ifndef WNT
371   MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self()
372           << " pid " << getpid() << " instanceName "
373           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
374           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
375           << dec << " _ThreadId " << _ThreadId );
376 #else
377   MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self().p
378           << " pid " << _getpid() << " instanceName "
379           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
380           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
381           << dec << " _ThreadId " << _ThreadId );
382 #endif
383   
384
385   bool RetVal = false ;
386 #ifndef WNT
387   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
388     {
389       RetVal = Killer( _ThreadId , 0 ) ;
390       _ThreadId = (pthread_t ) -1 ;
391     }
392 #else
393   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
394     {
395       RetVal = Killer( *_ThreadId , 0 ) ;
396       _ThreadId = (pthread_t* ) 0 ;
397     }
398 #endif
399   return RetVal ;
400 }
401
402 //=============================================================================
403 /*! 
404  *  CORBA method: used in Supervision
405  */
406 //=============================================================================
407
408 bool Engines_Component_i::Suspend_impl()
409 {
410 #ifndef WNT
411   MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self()
412           << " pid " << getpid() << " instanceName "
413           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
414           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
415           << dec << " _ThreadId " << _ThreadId );
416 #else
417   MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self().p
418           << " pid " << _getpid() << " instanceName "
419           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
420           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
421           << dec << " _ThreadId " << _ThreadId );
422 #endif
423
424   bool RetVal = false ;
425 #ifndef WNT
426   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
427 #else
428   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
429 #endif
430     {
431       if ( _Sleeping )
432         {
433           return false ;
434         }
435     else 
436       {
437 #ifndef WNT
438         RetVal = Killer( _ThreadId ,SIGINT ) ;
439 #else
440         RetVal = Killer( *_ThreadId ,SIGINT ) ;
441 #endif
442         //if ( RetVal ) _Sleeping = true;
443
444       }
445     }
446   return RetVal ;
447 }
448
449 //=============================================================================
450 /*! 
451  *  CORBA method: used in Supervision
452  */
453 //=============================================================================
454
455 bool Engines_Component_i::Resume_impl()
456 {
457 #ifndef WNT
458   MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self()
459           << " pid " << getpid() << " instanceName "
460           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
461           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
462           << dec << " _ThreadId " << _ThreadId );
463 #else
464   MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self().p
465           << " pid " << _getpid() << " instanceName "
466           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
467           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
468           << dec << " _ThreadId " << _ThreadId );
469 #endif
470   bool RetVal = false ;
471 #ifndef WNT
472   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
473 #else
474   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
475 #endif
476     {
477     if ( _Sleeping ) 
478       {
479         _Sleeping = false ;
480         RetVal = true ;
481       }
482     else
483       {
484         RetVal = false ;
485       }
486     }
487   return RetVal ;
488 }
489
490 //=============================================================================
491 /*! 
492  *  CORBA method: 
493  */
494 //=============================================================================
495
496 CORBA::Long Engines_Component_i::CpuUsed_impl()
497 {
498   long cpu = 0 ;
499   if ( _ThreadId || _Executed )
500     {
501     if ( _ThreadId > 0 )
502       {
503 #ifndef WNT
504       if ( pthread_self() != _ThreadId )
505 #else
506       if ( pthread_self().p != _ThreadId->p )
507 #endif
508         {
509         if ( _Sleeping )
510           {
511           }
512         else
513           {
514             // Get Cpu in the appropriate thread with that object !...
515             theEngines_Component = this ;
516 #ifndef WNT
517             Killer( _ThreadId ,SIGUSR1 ) ;
518 #else
519             Killer( *_ThreadId ,SIGUSR11 ) ;
520 #endif
521           }
522         cpu = _ThreadCpuUsed ;
523         }
524       else
525         {
526           _ThreadCpuUsed = CpuUsed() ;
527           cpu = _ThreadCpuUsed ;
528           // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
529           //      << _serviceName << " " << cpu << endl ;
530       }
531     }
532     else 
533       {
534         cpu = _ThreadCpuUsed ;
535         // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
536         //      << _serviceName << " " << cpu<< endl ;
537       }
538     }
539   else
540     {
541       // cout<< pthread_self()<<"Engines_Component_i::CpuUsed_impl _ThreadId "
542       //     <<_ThreadId <<" "<<_serviceName<<" _StartUsed "<<_StartUsed<<endl;
543     }
544   return cpu ;
545 }
546
547
548 //=============================================================================
549 /*! 
550  *  C++ method: return Container Servant
551  */
552 //=============================================================================
553
554 Engines_Container_i *Engines_Component_i::GetContainerPtr()
555 {
556   return dynamic_cast<Engines_Container_i*>(_poa->id_to_servant(*_contId)) ;
557 }
558
559 //=============================================================================
560 /*! 
561  *  C++ method: set study Id
562  *  \param studyId         0 if instance is not associated to a study, 
563  *                         >0 otherwise (== study id)
564  *  \return true if the set of study Id is OK
565  *  must be set once by Container, at instance creation,
566  *  and cannot be changed after.
567  */
568 //=============================================================================
569
570 CORBA::Boolean Engines_Component_i::setStudyId(CORBA::Long studyId)
571 {
572   ASSERT( studyId >= 0);
573   CORBA::Boolean ret = false;
574   if (_studyId < 0) // --- not yet initialized 
575     {
576       _studyId = studyId;
577       ret = true;
578     }
579   else
580     if ( _studyId == studyId) ret = true;
581   return ret;
582 }
583
584 //=============================================================================
585 /*! 
586  *  C++ method: return CORBA instance id, the id is set in derived class
587  *  constructor, when instance is activated.
588  */
589 //=============================================================================
590
591 PortableServer::ObjectId * Engines_Component_i::getId()
592 {
593 //  MESSAGE("PortableServer::ObjectId * Engines_Component_i::getId()");
594   return _id ;
595 }
596
597 //=============================================================================
598 /*! 
599  *  C++ method: used by derived classes for supervision
600  */
601 //=============================================================================
602
603 void Engines_Component_i::beginService(const char *serviceName)
604 {
605 #ifndef WNT
606   MESSAGE(pthread_self() << "Send BeginService notification for " <<serviceName
607           << endl << "Component instance : " << _instanceName << endl << endl);
608 #else
609   MESSAGE(pthread_self().p << "Send BeginService notification for " <<serviceName
610           << endl << "Component instance : " << _instanceName << endl << endl);
611 #endif
612 #ifndef WNT
613   _ThreadId = pthread_self() ;
614 #else
615   _ThreadId = new pthread_t;
616   _ThreadId->p = pthread_self().p ;
617   _ThreadId->x = pthread_self().x ;
618 #endif
619   _StartUsed = 0 ;
620   _StartUsed = CpuUsed_impl() ;
621   _ThreadCpuUsed = 0 ;
622   _Executed = true ;
623   _serviceName = serviceName ;
624   theEngines_Component = this ;
625   if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) )
626     {
627       perror("pthread_setcanceltype ") ;
628       exit(0) ;
629     }
630   if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) )
631     {
632       perror("pthread_setcancelstate ") ;
633       exit(0) ;
634     }
635 //  MESSAGE(pthread_self() << " Return from BeginService for " << serviceName
636 //          << " ThreadId " << _ThreadId << " StartUsed " << _StartUsed
637 //          << " _graphName " << _graphName << " _nodeName " << _nodeName );
638
639   // --- for supervisor : all strings given with setProperties
640   //     are set in environment
641   bool overwrite = true;
642   map<std::string,CORBA::Any>::iterator it;
643   for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++)
644     {
645       std::string cle((*it).first);
646       if ((*it).second.type()->kind() == CORBA::tk_string)
647         {
648           const char* value;
649           (*it).second >>= value;
650           // ---todo: replace __GNUC__ test by an autoconf macro AC_CHECK_FUNC.
651 #if defined __GNUC__
652 //        int ret = setenv(cle.c_str(), value, overwrite);
653           setenv(cle.c_str(), value, overwrite);
654 #else
655           //CCRT porting : setenv not defined in stdlib.h
656           std::string s(cle);
657           s+='=';
658           s+=value;
659           // char* cast because 1st arg of linux putenv function
660           // is not a const char* !
661 //        int ret=putenv((char *)s.c_str());
662           putenv((char *)s.c_str());
663           //End of CCRT porting
664 #endif
665           MESSAGE("--- setenv: "<<cle<<" = "<< value);
666         }
667     }
668 }
669
670 //=============================================================================
671 /*! 
672  *  C++ method: used by derived classes for supervision
673  */
674 //=============================================================================
675
676 void Engines_Component_i::endService(const char *serviceName)
677 {
678   if ( !_CanceledThread )
679     _ThreadCpuUsed = CpuUsed_impl() ;
680
681 #ifndef WNT
682   MESSAGE(pthread_self() << " Send EndService notification for " << serviceName
683           << endl << " Component instance : " << _instanceName << " StartUsed "
684           << _StartUsed << " _ThreadCpuUsed "<< _ThreadCpuUsed << endl <<endl);
685 #else
686   MESSAGE(pthread_self().p << " Send EndService notification for " << serviceName
687           << endl << " Component instance : " << _instanceName << " StartUsed "
688     << _StartUsed << " _ThreadCpuUsed "<< _ThreadCpuUsed << endl <<endl);
689 #endif
690   _ThreadId = 0 ;
691 }
692
693 //=============================================================================
694 /*! 
695  *  C++ method: -- CHECK IF USED --
696  */
697 //=============================================================================
698
699 char* Engines_Component_i::graphName()
700 {
701   return CORBA::string_dup( _graphName.c_str() ) ;
702 }
703
704 //=============================================================================
705 /*! 
706  *  C++ method: -- CHECK IF USED --
707  */
708 //=============================================================================
709
710 char* Engines_Component_i::nodeName()
711 {
712   return CORBA::string_dup( _nodeName.c_str() ) ;
713 }
714
715 //=============================================================================
716 /*! 
717  *  C++ method: used in Supervision (see kill_impl)
718  */
719 //=============================================================================
720
721 bool Engines_Component_i::Killer( pthread_t ThreadId , int signum )
722 {
723 #ifndef WNT
724   if ( ThreadId )
725 #else
726   if ( ThreadId.p )
727 #endif
728     {
729       if ( signum == 0 )
730         {
731           if ( pthread_cancel( ThreadId ) )
732             {
733               perror("Killer pthread_cancel error") ;
734               return false ;
735             }
736           else
737             {
738 #ifndef WNT
739               MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
740                       << " pthread_canceled") ;
741 #else
742         MESSAGE(pthread_self().p << "Killer : ThreadId " << ThreadId.p
743                       << " pthread_canceled") ;
744 #endif
745             }
746         }
747       else
748         {
749           if ( pthread_kill( ThreadId , signum ) == -1 )
750             {
751               perror("Killer pthread_kill error") ;
752               return false ;
753             }
754           else 
755             {
756 #ifndef WNT
757         MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
758                       << " pthread_killed(" << signum << ")") ;
759 #else
760         MESSAGE(pthread_self().p << "Killer : ThreadId " << ThreadId.p
761                       << " pthread_killed(" << signum << ")") ;
762 #endif
763             }
764         }
765     }
766   return true ;
767 }
768
769 //=============================================================================
770 /*! 
771  *  C++ method:
772  */ 
773 //=============================================================================
774
775 void SetCpuUsed()
776 {
777   if ( theEngines_Component )
778     theEngines_Component->SetCurCpu() ;
779 }
780
781 //=============================================================================
782 /*! 
783  *  C++ method:
784  */
785 //=============================================================================
786
787 void Engines_Component_i::SetCurCpu()
788 {
789   _ThreadCpuUsed =  CpuUsed() ;
790   //  MESSAGE(pthread_self() << 
791   //  " Engines_Component_i::SetCurCpu() _ThreadCpuUsed " << _ThreadCpuUsed) ;
792 }
793
794 //=============================================================================
795 /*! 
796  *  C++ method:
797  */
798 //=============================================================================
799
800 long Engines_Component_i::CpuUsed()
801 {
802   long cpu = 0 ;
803 #ifndef WNT
804   struct rusage usage ;
805   if ( _ThreadId || _Executed )
806     {
807       if ( getrusage( RUSAGE_SELF , &usage ) == -1 )
808         {
809           perror("Engines_Component_i::CpuUsed") ;
810           return 0 ;
811         }
812       cpu = usage.ru_utime.tv_sec - _StartUsed ;
813       // cout << pthread_self() << " Engines_Component_i::CpuUsed " << " "
814       //      << _serviceName   << usage.ru_utime.tv_sec << " - " << _StartUsed
815       //      << " = " << cpu << endl ;
816     }
817   else
818     {
819       // cout << pthread_self() << "Engines_Component_i::CpuUsed _ThreadId "
820       //      << _ThreadId << " " << _serviceName<< " _StartUsed " 
821       //      << _StartUsed << endl ;
822     }
823 #else
824         // NOT implementet yet
825 #endif
826
827
828   return cpu ;
829 }
830
831 void CallCancelThread()
832 {
833   if ( theEngines_Component )
834     theEngines_Component->CancelThread() ;
835 }
836
837 //=============================================================================
838 /*!
839  *  C++ method:
840  */
841 //=============================================================================
842
843 void Engines_Component_i::CancelThread()
844 {
845   _CanceledThread = true;
846 }
847
848 //=============================================================================
849 /*! 
850  *  C++ method: Send message to event channel
851  */
852 //=============================================================================
853
854 void Engines_Component_i::sendMessage(const char *event_type,
855                                       const char *message)
856 {
857     _notifSupplier->Send(_graphName.c_str(), _nodeName.c_str(), event_type, message);
858 }
859
860 //=============================================================================
861 /*! 
862  *  C++ method: return standard library name built on component name
863  */
864 //=============================================================================
865
866 string Engines_Component_i::GetDynLibraryName(const char *componentName)
867 {
868   string ret="lib";
869   ret+=componentName;
870   ret+="Engine.so";
871   return ret;
872 }
873
874 //=============================================================================
875 /*! 
876  *  C++ method: DumpPython default implementation
877  */
878 //=============================================================================
879
880 Engines::TMPFile* Engines_Component_i::DumpPython(CORBA::Object_ptr theStudy, 
881                                                   CORBA::Boolean isPublished, 
882                                                   CORBA::Boolean& isValidScript)
883 {
884   const char* aScript = "def RebuildData(theStudy): pass";
885   char* aBuffer = new char[strlen(aScript)+1];
886   strcpy(aBuffer, aScript);
887   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
888   int aBufferSize = strlen(aBuffer)+1;
889   Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1); 
890   isValidScript = true;
891   return aStreamFile._retn(); 
892 }
893
894 Engines::Salome_file_ptr 
895 Engines_Component_i::getInputFileToService(const char* service_name, 
896                                            const char* Salome_file_name) 
897 {
898   // Try to find the service, if it doesn't exist, we throw an exception.
899   _Service_file_map_it = _Input_Service_file_map.find(service_name);
900   if (_Service_file_map_it ==  _Input_Service_file_map.end()) {
901     SALOME::ExceptionStruct es;
902     es.type = SALOME::INTERNAL_ERROR;
903     es.text = "service doesn't have salome files";
904     throw SALOME::SALOME_Exception(es);
905   }
906   _t_Salome_file_map * _map = _Input_Service_file_map[service_name];
907
908   // Try to find the Salome_file ...
909   _Salome_file_map_it = _map->find(Salome_file_name);
910   if (_Salome_file_map_it ==  _map->end()) {
911     SALOME::ExceptionStruct es;
912     es.type = SALOME::INTERNAL_ERROR;
913     es.text = "service doesn't have this Salome_file";
914     throw SALOME::SALOME_Exception(es);
915   }
916   Salome_file_i * Sfile = (*_map)[Salome_file_name];
917
918   return Sfile->_this();
919 }
920
921 Engines::Salome_file_ptr 
922 Engines_Component_i::setInputFileToService(const char* service_name, 
923                                            const char* Salome_file_name) 
924 {
925   // Try to find the service, if it doesn't exist, we add it.
926   _Service_file_map_it = _Input_Service_file_map.find(service_name);
927   if (_Service_file_map_it ==  _Input_Service_file_map.end()) {
928     _t_Salome_file_map * _map = new _t_Salome_file_map();
929     _Input_Service_file_map[service_name] = _map;
930   }
931   _t_Salome_file_map * _map = _Input_Service_file_map[service_name];
932   
933   // Try to find the Salome_file ...
934   _Salome_file_map_it = _map->find(Salome_file_name);
935   if (_Salome_file_map_it ==  _map->end()) {
936     Salome_file_i * Sfile = new Salome_file_i();
937     Engines::Container_ptr container = this->GetContainerRef();
938     Sfile->setContainer(Engines::Container::_duplicate(container));
939     (*_map)[Salome_file_name] = Sfile;
940   }
941
942   Salome_file_i * Sfile = (*_map)[Salome_file_name];
943   return Sfile->_this();
944 }
945
946 void 
947 Engines_Component_i::checkInputFilesToService(const char* service_name) 
948 {
949   // Try to find the service, if it doesn't exist, nothing to do.
950   _Service_file_map_it = _Input_Service_file_map.find(service_name);
951   if (_Service_file_map_it !=  _Input_Service_file_map.end()) {
952     _t_Salome_file_map * _map = _Input_Service_file_map[service_name];
953     _t_Salome_file_map::iterator begin = _map->begin();
954     _t_Salome_file_map::iterator end = _map->end();
955
956     for(;begin!=end;begin++) {
957       Salome_file_i * file = begin->second;
958       std::string file_port_name = begin->first;
959       configureSalome_file(service_name, file_port_name, file);
960       file->recvFiles();
961     }
962   }
963 }
964
965 Engines::Salome_file_ptr 
966 Engines_Component_i::getOutputFileToService(const char* service_name, 
967                                             const char* Salome_file_name) 
968 {
969   // Try to find the service, if it doesn't exist, we throw an exception.
970   _Service_file_map_it = _Output_Service_file_map.find(service_name);
971   if (_Service_file_map_it ==  _Output_Service_file_map.end()) {
972     SALOME::ExceptionStruct es;
973     es.type = SALOME::INTERNAL_ERROR;
974     es.text = "service doesn't have salome files";
975     throw SALOME::SALOME_Exception(es);
976   }
977   _t_Salome_file_map * _map = _Output_Service_file_map[service_name];
978
979   // Try to find the Salome_file ...
980   _Salome_file_map_it = _map->find(Salome_file_name);
981   if (_Salome_file_map_it ==  _map->end()) {
982     SALOME::ExceptionStruct es;
983     es.type = SALOME::INTERNAL_ERROR;
984     es.text = "service doesn't have this Salome_file";
985     throw SALOME::SALOME_Exception(es);
986   }
987   Salome_file_i * Sfile = (*_map)[Salome_file_name];
988
989   return Sfile->_this();
990 }
991
992 Engines::Salome_file_ptr 
993 Engines_Component_i::setOutputFileToService(const char* service_name, 
994                                            const char* Salome_file_name) 
995 {
996   // Try to find the service, if it doesn't exist, we add it.
997   _Service_file_map_it = _Output_Service_file_map.find(service_name);
998   if (_Service_file_map_it ==  _Output_Service_file_map.end()) {
999     _t_Salome_file_map * _map = new _t_Salome_file_map();
1000     _Output_Service_file_map[service_name] = _map;
1001   }
1002   _t_Salome_file_map * _map = _Output_Service_file_map[service_name];
1003   
1004   // Try to find the Salome_file ...
1005   _Salome_file_map_it = _map->find(Salome_file_name);
1006   if (_Salome_file_map_it ==  _map->end()) {
1007     Salome_file_i * Sfile = new Salome_file_i();
1008     Engines::Container_ptr container = this->GetContainerRef();
1009     Sfile->setContainer(Engines::Container::_duplicate(container));
1010     (*_map)[Salome_file_name] = Sfile;
1011   }
1012
1013   Salome_file_i * Sfile = (*_map)[Salome_file_name];
1014   return Sfile->_this();
1015 }
1016
1017 void 
1018 Engines_Component_i::checkOutputFilesToService(const char* service_name) 
1019 {
1020   // Try to find the service, if it doesn't exist, nothing to do.
1021   _Service_file_map_it = _Output_Service_file_map.find(service_name);
1022   if (_Service_file_map_it !=  _Output_Service_file_map.end()) {
1023     _t_Salome_file_map * _map = _Output_Service_file_map[service_name];
1024     _t_Salome_file_map::iterator begin = _map->begin();
1025     _t_Salome_file_map::iterator end = _map->end();
1026
1027     for(;begin!=end;begin++) {
1028       Salome_file_i * file = begin->second;
1029       std::string file_port_name = begin->first;
1030       configureSalome_file(service_name, file_port_name, file);
1031       file->recvFiles();
1032     }
1033   }
1034
1035 }
1036
1037 //=============================================================================
1038 /*! 
1039  *  C++ method: used to configure the Salome_file into the runtime.
1040  *  \param service_name name of the service that use this Salome_file
1041  *  \param file_port_name name of the Salome_file
1042  *  \param file Salome_file C++ object
1043  */
1044 //=============================================================================
1045 void
1046 Engines_Component_i::configureSalome_file(std::string service_name,
1047                                           std::string file_port_name,
1048                                           Salome_file_i * file) 
1049 {
1050   // By default this method does nothing
1051 }
1052