Salome HOME
Fix for IPAL9408 : 3.0.0(current3106): CRASH after trying to "Close" saved document...
[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  // 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 #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()
66 {
67   //ASSERT(0);
68   INFOS("Default Constructor...");
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  *  \parap 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   _ThreadId(0) ,
94   _ThreadCpuUsed(0) ,
95   _Executed(false) ,
96   _graphName("") ,
97   _nodeName(""),
98  _studyId(-1)
99 {
100   MESSAGE("Component constructor with instanceName "<< _instanceName);
101   //SCRUTE(pd_refCount);
102   _orb = CORBA::ORB::_duplicate(orb);
103   _poa = PortableServer::POA::_duplicate(poa);
104   _contId = contId ;
105   CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior...
106   const CORBA::String_var ior = _orb->object_to_string(o);
107   _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession",
108                                                  _instanceName.c_str());
109
110   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
111   //SCRUTE(pd_refCount);
112 }
113
114 //=============================================================================
115 /*! 
116  * Standard constructor for parallel component
117  *  Connection Notification (no connection to Registry !)
118  *  \param orb Object Request broker given by Container
119  *  \parap poa Portable Object Adapter from Container (normally root_poa)
120  *  \param contId container CORBA id inside the server
121  *  \param instanceName unique instance name for this object (see Container_i)
122  *  \param interfaceName component class name
123  *  \param flag not used...
124  *  \param notif use of notification
125  */
126 //=============================================================================
127
128 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
129                                          PortableServer::POA_ptr poa, 
130                                          PortableServer::ObjectId * contId, 
131                                          const char *instanceName,
132                                          const char *interfaceName,
133                                          int flag,
134                                          bool notif ) :
135  _instanceName(instanceName),
136  _interfaceName(interfaceName),
137  _myConnexionToRegistry(0),
138  _ThreadId(0) ,
139  _ThreadCpuUsed(0) ,
140  _Executed(false) ,
141  _graphName("") ,
142  _nodeName(""),
143  _studyId(-1)
144 {
145   _orb = CORBA::ORB::_duplicate(orb);
146   _poa = PortableServer::POA::_duplicate(poa);
147   _contId = contId ;
148
149   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
150 }
151
152 //=============================================================================
153 /*! 
154  *  Destructor: call Container for decrement of instances count.
155  *  When instances count falls to 0, the container tries to remove the
156  *  component library (dlclose)
157  */
158 //=============================================================================
159
160 Engines_Component_i::~Engines_Component_i()
161 {
162   MESSAGE("Component destructor");
163   Engines_Container_i::decInstanceCnt(_interfaceName);
164 }
165
166 //=============================================================================
167 /*! 
168  *  CORBA method: return name of the instance, unique in this Container
169  */
170 //=============================================================================
171
172 char* Engines_Component_i::instanceName()
173 {
174    return CORBA::string_dup(_instanceName.c_str()) ;
175 }
176
177 //=============================================================================
178 /*! 
179  *  CORBA method: return name of the component class
180  */
181 //=============================================================================
182
183 char* Engines_Component_i::interfaceName()
184 {
185   return CORBA::string_dup(_interfaceName.c_str()) ;
186 }
187
188 //=============================================================================
189 /*! 
190  *  CORBA method: Get study Id
191  *  \return -1: not initialised (Internal Error)
192  *           0: multistudy component instance
193  *          >0: study id associated to this instance
194  */
195 //=============================================================================
196
197 CORBA::Long Engines_Component_i::getStudyId()
198 {
199   return _studyId;
200 }
201
202 //=============================================================================
203 /*! 
204  *  CORBA method: Test if instance is alive and responds
205  */
206 //=============================================================================
207
208 void Engines_Component_i::ping()
209 {
210   MESSAGE("Engines_Component_i::ping() pid "<< getpid() << " threadid "
211           << pthread_self());
212 }
213
214 //=============================================================================
215 /*! 
216  *  CORBA method: Deactivate this instance. CORBA object is deactivated (do not
217  *  respond any more to CORBA calls), the connection to Regsitry is removed
218  *  (Registry informed of deactivation), internal server reference counter on
219  *  the derived servant class is decremented, to allow destruction of the class
220  *  (delete) by POA, when there are no more references.
221  *  -- TO BE USED BY CONTAINER ONLY (Container housekeeping) --
222  */
223 //=============================================================================
224
225 void Engines_Component_i::destroy()
226 {
227   MESSAGE("Engines_Component_i::destroy()");
228   //SCRUTE(pd_refCount);
229
230   delete _notifSupplier;
231   _notifSupplier = 0;
232
233   delete _myConnexionToRegistry;
234   _myConnexionToRegistry = 0 ;
235   _poa->deactivate_object(*_id) ;
236   CORBA::release(_poa) ;
237   delete(_id) ;
238   //SCRUTE(pd_refCount);
239   _thisObj->_remove_ref();
240   //SCRUTE(pd_refCount);
241   MESSAGE("Engines_Component_i::destroyed") ;
242 }
243
244 //=============================================================================
245 /*! 
246  *  CORBA method: return CORBA reference of the Container
247  *
248  */
249 //=============================================================================
250
251 Engines::Container_ptr Engines_Component_i::GetContainerRef()
252 {
253   MESSAGE("Engines_Component_i::GetContainerRef");
254   CORBA::Object_ptr o = _poa->id_to_reference(*_contId) ;
255   return Engines::Container::_narrow(o);
256 }
257
258 //=============================================================================
259 /*! 
260  *  CORBA method: 
261  *  Gives a sequence of (key=string,value=any) to the component. 
262  *  Base class component stores the sequence in a map.
263  *  The map is cleared before.
264  *  This map is for use by derived classes. 
265  *  \param dico sequence of (key=string,value=any)
266  */
267 //=============================================================================
268
269 void Engines_Component_i::setProperties(const Engines::FieldsDict& dico)
270 {
271   _fieldsDict.clear();
272   for (CORBA::ULong i=0; i<dico.length(); i++)
273     {
274       std::string cle(dico[i].key);
275       _fieldsDict[cle] = dico[i].value;
276     }
277 }
278
279 //=============================================================================
280 /*! 
281  *  CORBA method: 
282  *  returns a previously stored map (key=string,value=any) as a sequence.
283  *  (see setProperties)
284  */
285 //=============================================================================
286
287 Engines::FieldsDict* Engines_Component_i::getProperties()
288 {
289   Engines::FieldsDict_var copie = new Engines::FieldsDict;
290   copie->length(_fieldsDict.size());
291   map<std::string,CORBA::Any>::iterator it;
292   CORBA::ULong i = 0;
293   for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++, i++)
294     {
295       std::string cle((*it).first);
296       copie[i].key = CORBA::string_dup(cle.c_str());
297       copie[i].value = _fieldsDict[cle];
298     }
299   return copie._retn();
300 }
301
302 //=============================================================================
303 /*! 
304  *  CORBA method: used by Supervision to give names to this instance
305  */
306 //=============================================================================
307
308 void Engines_Component_i::Names( const char * graphName ,
309                                  const char * nodeName )
310 {
311   _graphName = graphName ;
312   _nodeName = nodeName ;
313   //  MESSAGE("Engines_Component_i::Names( '" << _graphName << "' , '"
314   //          << _nodeName << "' )");
315 }
316
317 //=============================================================================
318 /*! 
319  *  CORBA method: used in Supervision
320  */
321 //=============================================================================
322
323 bool Engines_Component_i::Kill_impl() 
324 {
325 //  MESSAGE("Engines_Component_i::Kill_i() pthread_t "<< pthread_self()
326 //          << " pid " << getpid() << " instanceName "
327 //          << _instanceName.c_str() << " interface " << _interfaceName.c_str()
328 //          << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
329 //          << dec << " _ThreadId " << _ThreadId << " this " << hex << this
330 //          << dec ) ;
331
332   bool RetVal = false ;
333 #ifndef WNT
334   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
335     {
336       RetVal = Killer( _ThreadId , 0 ) ;
337       _ThreadId = (pthread_t ) -1 ;
338     }
339
340 #else
341   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
342     {
343       RetVal = Killer( *_ThreadId , 0 ) ;
344       _ThreadId = (pthread_t* ) 0 ;
345     }
346
347 #endif
348   return RetVal ;
349 }
350
351 //=============================================================================
352 /*! 
353  *  CORBA method: used in Supervision
354  */
355 //=============================================================================
356
357 bool Engines_Component_i::Stop_impl()
358 {
359   MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self()
360           << " pid " << getpid() << " instanceName "
361           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
362           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
363           << dec << " _ThreadId " << _ThreadId );
364   
365
366   bool RetVal = false ;
367 #ifndef WNT
368   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
369     {
370       RetVal = Killer( _ThreadId , 0 ) ;
371       _ThreadId = (pthread_t ) -1 ;
372     }
373 #else
374   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
375     {
376       RetVal = Killer( *_ThreadId , 0 ) ;
377       _ThreadId = (pthread_t* ) 0 ;
378     }
379 #endif
380   return RetVal ;
381 }
382
383 //=============================================================================
384 /*! 
385  *  CORBA method: used in Supervision
386  */
387 //=============================================================================
388
389 bool Engines_Component_i::Suspend_impl()
390 {
391   MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self()
392           << " pid " << getpid() << " instanceName "
393           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
394           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
395           << dec << " _ThreadId " << _ThreadId );
396
397   bool RetVal = false ;
398 #ifndef WNT
399   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
400 #else
401   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
402 #endif
403     {
404       if ( _Sleeping )
405         {
406           return false ;
407         }
408     else 
409       {
410 #ifndef WNT
411         RetVal = Killer( _ThreadId ,SIGINT ) ;
412 #else
413         RetVal = Killer( *_ThreadId ,SIGINT ) ;
414 #endif
415
416       }
417     }
418   return RetVal ;
419 }
420
421 //=============================================================================
422 /*! 
423  *  CORBA method: used in Supervision
424  */
425 //=============================================================================
426
427 bool Engines_Component_i::Resume_impl()
428 {
429   MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self()
430           << " pid " << getpid() << " instanceName "
431           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
432           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
433           << dec << " _ThreadId " << _ThreadId );
434   bool RetVal = false ;
435 #ifndef WNT
436   if ( _ThreadId > 0 && pthread_self() != _ThreadId )
437 #else
438   if ( _ThreadId > 0 && pthread_self().p != _ThreadId->p )
439 #endif
440     {
441     if ( _Sleeping ) 
442       {
443         _Sleeping = false ;
444         RetVal = true ;
445       }
446     else
447       {
448         RetVal = false ;
449       }
450     }
451   return RetVal ;
452 }
453
454 //=============================================================================
455 /*! 
456  *  CORBA method: 
457  */
458 //=============================================================================
459
460 CORBA::Long Engines_Component_i::CpuUsed_impl()
461 {
462   long cpu = 0 ;
463   if ( _ThreadId || _Executed )
464     {
465     if ( _ThreadId > 0 )
466       {
467 #ifndef WNT
468       if ( pthread_self() != _ThreadId )
469 #else
470       if ( pthread_self().p != _ThreadId->p )
471 #endif
472         {
473         if ( _Sleeping )
474           {
475           }
476         else
477           {
478             // Get Cpu in the appropriate thread with that object !...
479             theEngines_Component = this ;
480 #ifndef WNT
481             Killer( _ThreadId ,SIGUSR1 ) ;
482 #else
483             Killer( *_ThreadId ,SIGUSR11 ) ;
484 #endif
485           }
486         cpu = _ThreadCpuUsed ;
487         }
488       else
489         {
490           _ThreadCpuUsed = CpuUsed() ;
491           cpu = _ThreadCpuUsed ;
492           // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
493           //      << _serviceName << " " << cpu << endl ;
494       }
495     }
496     else 
497       {
498         cpu = _ThreadCpuUsed ;
499         // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
500         //      << _serviceName << " " << cpu<< endl ;
501       }
502     }
503   else
504     {
505       // cout<< pthread_self()<<"Engines_Component_i::CpuUsed_impl _ThreadId "
506       //     <<_ThreadId <<" "<<_serviceName<<" _StartUsed "<<_StartUsed<<endl;
507     }
508   return cpu ;
509 }
510
511 //=============================================================================
512 /*! 
513  *  C++ method: set study Id
514  *  \param studyId         0 if instance is not associated to a study, 
515  *                         >0 otherwise (== study id)
516  *  \return true if the set of study Id is OK
517  *  must be set once by Container, and cannot be changed after.
518  */
519 //=============================================================================
520
521 CORBA::Boolean Engines_Component_i::setStudyId(CORBA::Long studyId)
522 {
523   ASSERT( studyId >= 0);
524   CORBA::Boolean ret = false;
525   if (_studyId < 0)
526     {
527       _studyId = studyId;
528       ret = true;
529     }
530   else
531     if ( _studyId == studyId) ret = true;
532   return ret;
533 }
534
535 //=============================================================================
536 /*! 
537  *  C++ method: return CORBA instance id, the id is set in derived class
538  *  constructor, when instance is activated.
539  */
540 //=============================================================================
541
542 PortableServer::ObjectId * Engines_Component_i::getId()
543 {
544 //  MESSAGE("PortableServer::ObjectId * Engines_Component_i::getId()");
545   return _id ;
546 }
547
548 //=============================================================================
549 /*! 
550  *  C++ method: used by derived classes for supervision
551  */
552 //=============================================================================
553
554 void Engines_Component_i::beginService(const char *serviceName)
555 {
556   MESSAGE(pthread_self() << "Send BeginService notification for " <<serviceName
557           << endl << "Component instance : " << _instanceName << endl << endl);
558 #ifndef WNT
559   _ThreadId = pthread_self() ;
560 #else
561   _ThreadId = new pthread_t;
562   _ThreadId->p = pthread_self().p ;
563   _ThreadId->x = pthread_self().x ;
564 #endif
565   _StartUsed = 0 ;
566   _StartUsed = CpuUsed_impl() ;
567   _ThreadCpuUsed = 0 ;
568   _Executed = true ;
569   _serviceName = serviceName ;
570   if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) )
571     {
572       perror("pthread_setcanceltype ") ;
573       exit(0) ;
574     }
575   if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) )
576     {
577       perror("pthread_setcancelstate ") ;
578       exit(0) ;
579     }
580 //  MESSAGE(pthread_self() << " Return from BeginService for " << serviceName
581 //          << " ThreadId " << _ThreadId << " StartUsed " << _StartUsed
582 //          << " _graphName " << _graphName << " _nodeName " << _nodeName );
583
584   // --- for supervisor : all strings given with setProperties
585   //     are set in environment
586   bool overwrite = true;
587   map<std::string,CORBA::Any>::iterator it;
588   for (it = _fieldsDict.begin(); it != _fieldsDict.end(); it++)
589     {
590       std::string cle((*it).first);
591       if ((*it).second.type()->kind() == CORBA::tk_string)
592         {
593           const char* value;
594           (*it).second >>= value;
595           // ---todo: replace __GNUC__ test by an autoconf macro AC_CHECK_FUNC.
596 #if defined __GNUC__
597           int ret = setenv(cle.c_str(), value, overwrite);
598 #else
599           //CCRT porting : setenv not defined in stdlib.h
600           std::string s(cle);
601           s+='=';
602           s+=value;
603           // char* cast because 1st arg of linux putenv function
604           // is not a const char* !
605           int ret=putenv((char *)s.c_str());
606           //End of CCRT porting
607 #endif
608           MESSAGE("--- setenv: "<<cle<<" = "<< value);
609         }
610     }
611 }
612
613 //=============================================================================
614 /*! 
615  *  C++ method: used by derived classes for supervision
616  */
617 //=============================================================================
618
619 void Engines_Component_i::endService(const char *serviceName)
620 {
621   _ThreadCpuUsed = CpuUsed_impl() ;
622   MESSAGE(pthread_self() << " Send EndService notification for " << serviceName
623           << endl << " Component instance : " << _instanceName << " StartUsed "
624           << _StartUsed << " _ThreadCpuUsed "<< _ThreadCpuUsed << endl <<endl);
625   _ThreadId = 0 ;
626 }
627
628 //=============================================================================
629 /*! 
630  *  C++ method: -- CHECK IF USED --
631  */
632 //=============================================================================
633
634 char* Engines_Component_i::graphName()
635 {
636   return CORBA::string_dup( _graphName.c_str() ) ;
637 }
638
639 //=============================================================================
640 /*! 
641  *  C++ method: -- CHECK IF USED --
642  */
643 //=============================================================================
644
645 char* Engines_Component_i::nodeName()
646 {
647   return CORBA::string_dup( _nodeName.c_str() ) ;
648 }
649
650 //=============================================================================
651 /*! 
652  *  C++ method: used in Supervision (see kill_impl)
653  */
654 //=============================================================================
655
656 bool Engines_Component_i::Killer( pthread_t ThreadId , int signum )
657 {
658 #ifndef WNT
659   if ( ThreadId )
660 #else
661   if ( ThreadId.p )
662 #endif
663     {
664       if ( signum == 0 )
665         {
666           if ( pthread_cancel( ThreadId ) )
667             {
668               perror("Killer pthread_cancel error") ;
669               return false ;
670             }
671           else
672             {
673               MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
674                       << " pthread_canceled") ;
675             }
676         }
677       else
678         {
679           if ( pthread_kill( ThreadId , signum ) == -1 )
680             {
681               perror("Killer pthread_kill error") ;
682               return false ;
683             }
684           else 
685             {
686               MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
687                       << " pthread_killed(" << signum << ")") ;
688             }
689         }
690     }
691   return true ;
692 }
693
694 //=============================================================================
695 /*! 
696  *  C++ method:
697  */ 
698 //=============================================================================
699
700 void SetCpuUsed()
701 {
702   theEngines_Component->SetCurCpu() ;
703 }
704
705 //=============================================================================
706 /*! 
707  *  C++ method:
708  */
709 //=============================================================================
710
711 void Engines_Component_i::SetCurCpu()
712 {
713   _ThreadCpuUsed =  CpuUsed() ;
714   //  MESSAGE(pthread_self() << 
715   //  " Engines_Component_i::SetCurCpu() _ThreadCpuUsed " << _ThreadCpuUsed) ;
716 }
717
718 //=============================================================================
719 /*! 
720  *  C++ method:
721  */
722 //=============================================================================
723
724 long Engines_Component_i::CpuUsed()
725 {
726   long cpu = 0 ;
727 #ifndef WNT
728   struct rusage usage ;
729   if ( _ThreadId || _Executed )
730     {
731       if ( getrusage( RUSAGE_SELF , &usage ) == -1 )
732         {
733           perror("Engines_Component_i::CpuUsed") ;
734           return 0 ;
735         }
736       cpu = usage.ru_utime.tv_sec - _StartUsed ;
737       // cout << pthread_self() << " Engines_Component_i::CpuUsed " << " "
738       //      << _serviceName   << usage.ru_utime.tv_sec << " - " << _StartUsed
739       //      << " = " << cpu << endl ;
740     }
741   else
742     {
743       // cout << pthread_self() << "Engines_Component_i::CpuUsed _ThreadId "
744       //      << _ThreadId << " " << _serviceName<< " _StartUsed " 
745       //      << _StartUsed << endl ;
746     }
747 #else
748         // NOT implementet yet
749 #endif
750
751
752   return cpu ;
753 }
754
755 //=============================================================================
756 /*! 
757  *  C++ method: Send message to event channel
758  */
759 //=============================================================================
760
761 void Engines_Component_i::sendMessage(const char *event_type,
762                                       const char *message)
763 {
764     _notifSupplier->Send(graphName(), nodeName(), event_type, message);
765 }
766
767 //=============================================================================
768 /*! 
769  *  C++ method:
770  */
771 //=============================================================================
772
773 string Engines_Component_i::GetDynLibraryName(const char *componentName)
774 {
775   string ret="lib";
776   ret+=componentName;
777   ret+="Engine.so";
778   return ret;
779 }
780
781 //=============================================================================
782 /*! 
783  *  C++ method:
784  */
785 //=============================================================================
786
787 string Engines_Component_i::BuildComponentNameForNS(const char *ComponentName,
788                                                     const char *ContainerName,
789                                                     const char *hostname)
790 {
791   string ret =
792     Engines_Container_i::BuildContainerNameForNS(ContainerName,hostname);
793   ret+="/";
794   ret+=ComponentName;
795   return ret;
796 }
797 //=============================================================================
798 /*! 
799  *  C++ method: DumpPython default implementation
800  */
801 //=============================================================================
802
803 Engines::TMPFile* Engines_Component_i::DumpPython(CORBA::Object_ptr theStudy, 
804                                                   CORBA::Boolean isPublished, 
805                                                   CORBA::Boolean& isValidScript)
806 {
807   char* aScript = "def RebuildData(theStudy): pass";
808   char* aBuffer = new char[strlen(aScript)+1];
809   strcpy(aBuffer, aScript);
810   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
811   int aBufferSize = strlen(aBuffer)+1;
812   Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1); 
813   isValidScript = true;
814   return aStreamFile._retn(); 
815 }