1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony GEAY (EDF R&D)
21 #include "SALOMESDS_DataServerManager.hxx"
22 #include "SALOMESDS_Exception.hxx"
24 #include "SALOME_ContainerManager.hxx"
25 #include "SALOME_NamingService.hxx"
26 #include "SALOME_Embedded_NamingService.hxx"
27 #include "KernelBasis.hxx"
32 using namespace SALOMESDS;
34 const char DataServerManager::NAME_IN_NS[]="/DataServerManager";
36 const char DataServerManager::DFT_SCOPE_NAME_IN_NS[]="Default";
38 SALOME::StringVec *RequestSwitcherDSM::listScopes()
40 return _dsm->listScopes_unsafe();
43 SALOME::DataScopeServerTransaction_ptr RequestSwitcherDSM::giveADataScopeTransactionCalled(const char *scopeName, CORBA::Boolean& isCreated)
45 return _dsm->giveADataScopeTransactionCalled_unsafe(scopeName,isCreated);
48 void RequestSwitcherDSM::holdRequests()
53 void RequestSwitcherDSM::activeRequests()
55 _dsm->activeRequests();
59 DataServerManager::DataServerManager(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, SALOME_NamingService_Abstract *ns):_orb(CORBA::ORB::_duplicate(orb))
61 _ns = ns==nullptr?new SALOME_NamingService(_orb):ns;
62 DataScopeServer *dftScope(new DataScopeServer(pyHelper,orb,SALOME::DataScopeKiller::_nil(),DFT_SCOPE_NAME_IN_NS,_ns->cloneCoVar()));//_remove_ref will be call by DataScopeServer::shutdownIfNotHostedByDSM
63 PortableServer::POAManager_var pman(poa->the_POAManager());
64 CORBA::PolicyList policies;
66 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
67 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
68 PortableServer::POA_var safePoa = poa->create_POA("SingleThPOA4SDS",pman,policies);
71 // activate this to be ready to be usable from NS.
72 PortableServer::ObjectId_var id(_poa->activate_object(this));
73 CORBA::Object_var obj(_poa->id_to_reference(id));
74 SALOME::DataServerManager_var obj2(SALOME::DataServerManager::_narrow(obj));
75 // publish Data server manager in NS
76 _ns->Register(obj2,NAME_IN_NS);
77 // the default DataScopeServer object is the only one hosted by the current process
78 dftScope->setPOA(_poa);
79 obj=dftScope->activate();
80 SALOME::DataScopeServer_var dftScopePtr(SALOME::DataScopeServer::_narrow(obj));
81 dftScope->registerInNS(dftScopePtr);// agy : Very important ! invoke this method BEFORE activation ! Because this method initializes Python !
84 DataServerManager::~DataServerManager()
86 //_ns is owned by DataServerManager
90 SALOME::StringVec * DataServerManager::listScopes_unsafe()
92 std::vector<std::string> scopes(listOfScopesCpp());
93 SALOME::StringVec *ret(new SALOME::StringVec);
94 std::size_t sz(scopes.size());
95 ret->length((CORBA::ULong)sz); //!< TODO: size_t to CORBA::ULong
96 for(std::size_t i=0;i<sz;i++)
97 (*ret)[(CORBA::ULong)i]=CORBA::string_dup(scopes[i].c_str()); //!< TODO: size_t to CORBA::ULong
101 SALOME::StringVec *DataServerManager::listScopes()
103 const std::lock_guard<std::mutex> lock(_mutex);
104 return listScopes_unsafe();
107 SALOME::StringVec *DataServerManager::listAliveAndKickingScopes()
109 const std::lock_guard<std::mutex> lock(_mutex);
110 std::vector<std::string> scopes(listOfScopesCpp());
111 std::size_t sz(scopes.size());
112 std::vector<std::string> retCpp; retCpp.reserve(sz);
113 for(std::size_t i=0;i<sz;i++)
115 if(isAliveAndKicking_unsafe(scopes[i].c_str()))
116 retCpp.push_back(scopes[i]);
119 SALOME::StringVec *ret(new SALOME::StringVec);
121 ret->length((CORBA::ULong)sz); //!< TODO: size_t to CORBA::ULong
122 for(std::size_t i=0;i<sz;i++)
123 (*ret)[(CORBA::ULong)i]=CORBA::string_dup(retCpp[i].c_str()); //!< TODO: size_t to CORBA::ULong
127 SALOME::DataScopeServer_ptr DataServerManager::getDefaultScope()
129 const std::lock_guard<std::mutex> lock(_mutex);
130 SALOME::DataScopeServerBase_var ret(retriveDataScope_unsafe(DFT_SCOPE_NAME_IN_NS));
131 if(CORBA::is_nil(ret))
132 return SALOME::DataScopeServer::_narrow(ret);
133 SALOME::DataScopeServer_ptr ret2(SALOME::DataScopeServer::_narrow(ret));
134 if(CORBA::is_nil(ret2))
135 throw Exception("DataServerManager::getDefaultScope : exists but has not expected sub type !");
139 CORBA::Boolean DataServerManager::isAliveAndKicking(const char *scopeName)
141 const std::lock_guard<std::mutex> lock(_mutex);
142 return isAliveAndKicking_unsafe(scopeName);
145 CORBA::Boolean DataServerManager::isAliveAndKicking_unsafe(const char *scopeName)
147 SALOME::DataScopeServerBase_var scopePtr(getScopePtrGivenName(scopeName));
148 return IsAliveAndKicking(scopePtr);
152 typename T::PtrType CreateDataScope(CORBA::ORB_ptr orb, const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService_Abstract& ns)
154 int isTransactionInt(T::IsTransaction);
155 if(std::find(scopes.begin(),scopes.end(),scopeName)!=scopes.end())
157 std::ostringstream oss; oss << "DataServerManager::createDataScope : scope name \"" << scopeName << "\" already exists !";
158 throw Exception(oss.str());
161 std::string fullScopeName(DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
162 std::ostringstream oss;
165 oss << "SALOME_DataScopeServer" << " " << scopeName << " " << isTransactionInt << " ";
166 SALOME_ContainerManager::AddOmninamesParams(oss,&ns);
170 oss << "SALOME_DataScopeServer_SSL" << " " << scopeName << " " << isTransactionInt << " ";
171 Engines::EmbeddedNamingService_var emb = GetEmbeddedNamingService();
172 CORBA::String_var ior = orb->object_to_string(emb);
175 std::string command(oss.str());
176 SALOME_ContainerManager::MakeTheCommandToBeLaunchedASync(command);
177 int status(SALOME_ContainerManager::SystemThreadSafe(command.c_str()));
180 std::ostringstream oss2; oss2 << "CreateDataScope : Fail to launch \"" << command << "\" ! Return code was : " << status << " !";
181 throw Exception(oss2.str());
183 int count(SALOME_ContainerManager::GetTimeOutToLoaunchServer());
184 typename T::VarType ret(T::nil());
185 while (CORBA::is_nil(ret) && count)
187 SALOME_ContainerManager::SleepInSecond(1);
189 CORBA::Object_var obj(ns.Resolve(fullScopeName.c_str()));
192 return T::duplicate(ret);
196 typename T::PtrType GiveADataScopeCalled(CORBA::ORB_ptr orb, const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService_Abstract& ns, CORBA::Boolean& isCreated)
198 if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
201 return CreateDataScope<T>(orb,scopeName,scopes,ns);
205 SALOME::DataScopeServerBase_var ret(SALOMESDS::DataServerManager::GetScopePtrGivenName(scopeName,scopes,&ns));
206 if(SALOMESDS::DataServerManager::IsAliveAndKicking(ret))
209 typename T::PtrType ret2(T::narrow(ret));
210 if(CORBA::is_nil(ret))
212 if(CORBA::is_nil(ret2))
214 std::ostringstream oss; oss << "DataServerManager::giveADataScopeCalled : scope \"" << scopeName << "\" exists but with invalid type !";
215 throw Exception(oss.str());
221 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
222 ns.Destroy_Name(fullScopeName.c_str());
224 return CreateDataScope<T>(orb,scopeName,scopes,ns);
232 typedef SALOME::DataScopeServer_ptr PtrType;
233 typedef SALOME::DataScopeServer_var VarType;
234 typedef SALOME::DataScopeServer TheType;
235 static const bool IsTransaction=false;
236 static PtrType nil() { return SALOME::DataScopeServer::_nil(); }
237 static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServer::_narrow(obj); }
238 static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServer::_duplicate(obj); }
241 class TransactionFunctor
244 typedef SALOME::DataScopeServerTransaction_ptr PtrType;
245 typedef SALOME::DataScopeServerTransaction_var VarType;
246 typedef SALOME::DataScopeServerTransaction TheType;
247 static const bool IsTransaction=true;
248 static PtrType nil() { return SALOME::DataScopeServerTransaction::_nil(); }
249 static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServerTransaction::_narrow(obj); }
250 static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServerTransaction::_duplicate(obj); }
253 SALOME::DataScopeServer_ptr DataServerManager::createDataScope(const char *scopeName)
255 const std::lock_guard<std::mutex> lock(_mutex);
256 return CreateDataScope<NormalFunctor>(_orb,scopeName,listOfScopesCpp(),*_ns);
259 SALOME::DataScopeServer_ptr DataServerManager::giveADataScopeCalled(const char *scopeName, CORBA::Boolean& isCreated)
261 const std::lock_guard<std::mutex> lock(_mutex);
262 return GiveADataScopeCalled<NormalFunctor>(_orb,scopeName,listOfScopesCpp(),*_ns,isCreated);
265 SALOME::DataScopeServerTransaction_ptr DataServerManager::createDataScopeTransaction(const char *scopeName)
267 const std::lock_guard<std::mutex> lock(_mutex);
268 return CreateDataScope<TransactionFunctor>(_orb,scopeName,listOfScopesCpp(),*_ns);
271 SALOME::DataScopeServerTransaction_ptr
272 DataServerManager::giveADataScopeTransactionCalled_unsafe(
273 const char *scopeName, CORBA::Boolean& isCreated)
275 return GiveADataScopeCalled<TransactionFunctor>(_orb,scopeName,listOfScopesCpp(),*_ns,isCreated);
279 SALOME::DataScopeServerTransaction_ptr DataServerManager::giveADataScopeTransactionCalled(const char *scopeName, CORBA::Boolean& isCreated)
281 const std::lock_guard<std::mutex> lock(_mutex);
282 return giveADataScopeTransactionCalled_unsafe(scopeName, isCreated);
285 SALOME::DataScopeServerBase_ptr DataServerManager::retriveDataScope(const char *scopeName)
287 const std::lock_guard<std::mutex> lock(_mutex);
288 return retriveDataScope_unsafe(scopeName);
291 SALOME::DataScopeServerBase_ptr DataServerManager::retriveDataScope_unsafe(const char *scopeName)
293 SALOME::DataScopeServerBase_var ret(getScopePtrGivenName(scopeName));
294 return SALOME::DataScopeServerBase::_duplicate(ret);
297 void DataServerManager::removeDataScope(const char *scopeName)
299 const std::lock_guard<std::mutex> lock(_mutex);
300 SALOME::DataScopeServerBase_var scs(getScopePtrGivenName(scopeName));
301 SALOME::DataScopeKiller_ptr killer;
302 if(scs->shutdownIfNotHostedByDSM(killer))
304 CORBA::release(killer);
307 void DataServerManager::cleanScopesInNS()
309 const std::lock_guard<std::mutex> lock(_mutex);
310 std::vector<std::string> scopes(listOfScopesCpp());
311 for(std::vector<std::string>::const_iterator it=scopes.begin();it!=scopes.end();it++)
313 if(!isAliveAndKicking_unsafe((*it).c_str()))
315 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(*it));
316 _ns->Destroy_Name(fullScopeName.c_str());
321 void DataServerManager::shutdownScopes()
323 const std::lock_guard<std::mutex> lock(_mutex);
324 std::vector<std::string> scopeNames(listOfScopesCpp());
325 for(std::vector<std::string>::const_iterator it=scopeNames.begin();it!=scopeNames.end();it++)
327 SALOME::DataScopeServerBase_var scope(getScopePtrGivenName(*it));
328 SALOME::DataScopeKiller_ptr killer;
329 if(scope->shutdownIfNotHostedByDSM(killer))
331 CORBA::release(killer);
335 std::string DataServerManager::CreateAbsNameInNSFromScopeName(const std::string& scopeName)
337 std::ostringstream oss; oss << NAME_IN_NS << "/" << scopeName;
341 CORBA::Boolean DataServerManager::IsAliveAndKicking(SALOME::DataScopeServerBase_ptr scopePtr)
343 CORBA::Boolean ret(true);
353 std::vector<std::string> DataServerManager::listOfScopesCpp()
355 _ns->Change_Directory(NAME_IN_NS);
356 std::vector<std::string> ret(_ns->list_directory());
360 SALOME::DataScopeServerBase_var DataServerManager::GetScopePtrGivenName(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService_Abstract *ns)
362 if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
364 std::ostringstream oss; oss << "DataServerManager::getScopePtrGivenName : scope name \"" << scopeName << "\" does not exist !";
365 throw Exception(oss.str());
367 std::string fullScopeName(CreateAbsNameInNSFromScopeName(scopeName));
368 CORBA::Object_var obj(ns->Resolve(fullScopeName.c_str()));
369 SALOME::DataScopeServerBase_var ret(SALOME::DataScopeServerBase::_narrow(obj));
373 SALOME::DataScopeServerBase_var DataServerManager::getScopePtrGivenName(const std::string& scopeName)
375 return GetScopePtrGivenName(scopeName,listOfScopesCpp(),_ns);
378 SALOME::RequestSwitcherDSM_ptr DataServerManager::getRequestSwitcher()
380 const std::lock_guard<std::mutex> lock(_mutex);
383 _rs=new RequestSwitcherDSM(_orb,this);
385 CORBA::Object_var obj(_rs->activate());
386 return SALOME::RequestSwitcherDSM::_narrow(obj);
389 void DataServerManager::holdRequests()
394 void DataServerManager::activeRequests()