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