Salome HOME
sources v1.2
[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 using namespace std;
30 #include "SALOME_Component_i.hxx"
31 #include "RegistryConnexion.hxx"
32 #include "OpUtil.hxx"
33 #include <stdio.h>
34 #include <dlfcn.h>
35 #include "utilities.h"
36
37 extern bool _Sleeping ;
38
39 Engines_Component_i::Engines_Component_i()
40 {
41 //  MESSAGE("Component constructor");
42 }
43
44 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
45                                          PortableServer::POA_ptr poa, 
46                                          PortableServer::ObjectId * contId, 
47                                          const char *instanceName,
48                                          const char *interfaceName,
49                                          bool notif) :
50   _instanceName(instanceName), _interfaceName(interfaceName),
51   _myConnexionToRegistry(0), _ThreadId(0) , _graphName("") , _nodeName("") {
52   MESSAGE("Component constructor with instanceName "<< _instanceName);
53   _orb = CORBA::ORB::_duplicate(orb);
54   _poa = PortableServer::POA::_duplicate(poa);
55   _contId = contId ;
56   CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior...
57   const CORBA::String_var ior = _orb->object_to_string(o);
58   _myConnexionToRegistry = new RegistryConnexion(0, 0, ior, "theSession", _instanceName.c_str());
59
60   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
61 }
62
63 // Constructeur pour composant parallele: ne pas faire appel au registry!!
64 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
65                                          PortableServer::POA_ptr poa, 
66                                          PortableServer::ObjectId * contId, 
67                                          const char *instanceName,
68                                          const char *interfaceName,
69                                          int flag,
70                                          bool notif )
71   : _instanceName(instanceName),
72     _interfaceName(interfaceName),
73     _myConnexionToRegistry(0),
74     _ThreadId(0)
75 {
76 //  MESSAGE("Component constructor with instanceName "<< _instanceName);
77   _orb = CORBA::ORB::_duplicate(orb);
78   _poa = PortableServer::POA::_duplicate(poa);
79   _contId = contId ;
80   //  CORBA::Object_var myself = this->_this(); //appel a _this = increment reference
81
82   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
83 }
84
85 Engines_Component_i::~Engines_Component_i()
86 {
87   MESSAGE("Component destructor");
88 //   delete _myConnexionToRegistry;
89 //   _myConnexionToRegistry = 0 ;
90 }
91
92 char* Engines_Component_i::instanceName() {
93    return CORBA::string_dup(_instanceName.c_str()) ;
94 }
95
96 char* Engines_Component_i::interfaceName() {
97    return CORBA::string_dup(_interfaceName.c_str()) ;
98 }
99
100 void Engines_Component_i::ping()
101 {
102   MESSAGE("Engines_Component_i::ping() pid "<< getpid() << " threadid "
103           << pthread_self());
104 }
105
106 void Engines_Component_i::destroy()
107 {
108   MESSAGE("Engines_Component_i::destroy()");
109
110   delete _notifSupplier;
111   _notifSupplier = 0;
112
113   delete _myConnexionToRegistry;
114   _myConnexionToRegistry = 0 ;
115   _poa->deactivate_object(*_id) ;
116   CORBA::release(_poa) ;
117   delete(_id) ;
118   _thisObj->_remove_ref();
119   MESSAGE("Engines_Component_i::destroyed") ;
120 }
121
122 Engines::Container_ptr Engines_Component_i::GetContainerRef()
123 {
124   MESSAGE("Engines_Component_i::GetContainerRef");
125   CORBA::Object_ptr o = _poa->id_to_reference(*_contId) ;
126   return Engines::Container::_narrow(o);
127 }
128
129 PortableServer::ObjectId * Engines_Component_i::getId()
130 {
131 //  MESSAGE("PortableServer::ObjectId * Engines_Component_i::getId()");
132   return _id ;
133 }
134
135 void Engines_Component_i::beginService(const char *serviceName)
136 {
137   MESSAGE("Send BeginService notification for " << serviceName << endl
138           << "Component instance : " << _instanceName << endl << endl);
139   _ThreadId = pthread_self() ;
140   _StartUsed = 0 ;
141   _StartUsed = CpuUsed_impl() ;
142   _serviceName = serviceName ;
143   if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) ) {
144     perror("pthread_setcanceltype ") ;
145     exit(0) ;
146   }
147   if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) ) {
148     perror("pthread_setcancelstate ") ;
149     exit(0) ;
150   }
151   MESSAGE("Return from BeginService for " << serviceName
152           << " ThreadId " << _ThreadId
153           << " _graphName " << _graphName << " _nodeName " << _nodeName );
154 }
155
156 void Engines_Component_i::endService(const char *serviceName)
157 {
158   MESSAGE("Send EndService notification for " << serviceName << endl
159           << "Component instance : " << _instanceName << endl << endl);
160   _ThreadId = 0 ;
161 }
162
163 void Engines_Component_i::Names( const char * graphName ,
164                                  const char * nodeName ) {
165   _graphName = graphName ;
166   _nodeName = nodeName ;
167 //  MESSAGE("Engines_Component_i::Names( '" << _graphName << "' , '"
168 //          << _nodeName << "' )");
169 }
170
171 char* Engines_Component_i::graphName() {
172   return CORBA::string_dup( _graphName.c_str() ) ;
173 }
174
175 char* Engines_Component_i::nodeName() {
176   return CORBA::string_dup( _nodeName.c_str() ) ;
177 }
178
179 bool Killer( int ThreadId , int signum ) {
180   if ( ThreadId ) {
181     if ( signum == 0 ) {
182       if ( pthread_cancel( ThreadId ) ) {
183         perror("Killer pthread_cancel error") ;
184         return false ;
185       }
186       else {
187         MESSAGE("Killer : ThreadId " << ThreadId << " pthread_canceled") ;
188       }
189     }
190     else {
191       if ( pthread_kill( ThreadId , signum ) == -1 ) {
192         perror("Killer pthread_kill error") ;
193         return false ;
194       }
195       else {
196         MESSAGE("Killer : ThreadId " << ThreadId << " pthread_killed("
197                 << signum << ")") ;
198       }
199     }
200   }
201   return true ;
202 }
203
204 bool Engines_Component_i::Kill_impl() {
205   MESSAGE("Engines_Component_i::Kill_i() pthread_t "<< pthread_self()
206           << " pid " << getpid() << " instanceName "
207           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
208           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
209           << dec << " _ThreadId " << _ThreadId << " this " << hex << this
210           << dec ) ;
211   bool RetVal = false ;
212   if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
213     RetVal = Killer( _ThreadId , 0 ) ;
214     _ThreadId = (pthread_t ) -1 ;
215   }
216   return RetVal ;
217 }
218
219 bool Engines_Component_i::Stop_impl() {
220   MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self()
221           << " pid " << getpid() << " instanceName "
222           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
223           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
224           << dec << " _ThreadId " << _ThreadId );
225   bool RetVal = false ;
226   if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
227     RetVal = Killer( _ThreadId , 0 ) ;
228     _ThreadId = (pthread_t ) -1 ;
229   }
230   return RetVal ;
231 }
232
233 bool Engines_Component_i::Suspend_impl() {
234   MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self()
235           << " pid " << getpid() << " instanceName "
236           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
237           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
238           << dec << " _ThreadId " << _ThreadId );
239   bool RetVal = false ;
240   if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
241     if ( _Sleeping ) {
242       return false ;
243     }
244     else {
245       RetVal = Killer( _ThreadId ,SIGINT ) ;
246     }
247   }
248   return RetVal ;
249 }
250
251 bool Engines_Component_i::Resume_impl() {
252   MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self()
253           << " pid " << getpid() << " instanceName "
254           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
255           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
256           << dec << " _ThreadId " << _ThreadId );
257   bool RetVal = false ;
258   if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
259     if ( _Sleeping ) {
260       _Sleeping = false ;
261       RetVal = true ;
262     }
263     else {
264       RetVal = false ;
265     }
266   }
267   return RetVal ;
268
269 }
270
271 #include <sys/time.h>
272 #include <sys/resource.h>
273 #include <unistd.h>
274
275 long Engines_Component_i::CpuUsed_impl() {
276   struct rusage usage ;
277   long cpu ;
278   if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
279     perror("GraphBase::CpuUsed") ;
280     return 0 ;
281   }
282 //  return usage.ru_utime.__time_t tv_sec ;
283   cout << "CpuUsed " << usage.ru_utime.tv_sec << " " << usage.ru_utime.tv_usec << " "
284        << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec << endl ;
285   cpu = usage.ru_utime.tv_sec - _StartUsed ;
286   return cpu ;
287 }
288
289 // Send message to event channel
290
291 void Engines_Component_i::sendMessage(const char *event_type, const char *message) {
292     _notifSupplier->Send(graphName(), nodeName(), event_type, message);
293 }