Salome HOME
28132975c435ebbadbf303573fc3b59e42d95381
[modules/kernel.git] / src / ParallelContainer / SALOME_ParallelContainerProxyMpi.cxx
1 // Copyright (C) 2007-2023  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, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME ParallelContainerProxyMpi : Launching the proxy of a MPI PaCO++ object
24 //  File   : SALOME_ParallelContainerProxyMpi.cxx
25 //  Author : Andr� Ribes, EDF
26 //  Module : SALOME PARALLEL
27 //
28 #include <iostream>
29 #include <string>
30 #include <stdio.h>
31
32 #ifndef WIN32
33 #include <unistd.h>
34 #else
35 #include <process.h>
36 #endif
37
38 //#include "SALOME_ComponentPaCO_Engines_Container_server.h"
39 #include "SALOME_ParallelContainerProxy_i.hxx"
40 #include <paco_omni.h>
41 #include <paco_dummy.h>
42
43 #include <mpi.h>
44
45 #include "SALOME_NamingService.hxx"
46
47 #include "utilities.h"
48 #include "ArgvKeeper.hxx"
49 #include "Basics_Utils.hxx"
50 #include "SALOMETraceCollector.hxx"
51 #include "OpUtil.hxx"
52
53 #include "Container_init_python.hxx"
54
55 #ifdef _DEBUG_
56 #include <signal.h>
57
58
59 typedef void (*sighandler_t)(int);
60 sighandler_t setsig(int sig, sighandler_t handler)
61 {
62   struct sigaction context, ocontext;
63   context.sa_handler = handler;
64   sigemptyset(&context.sa_mask);
65   context.sa_flags = 0;
66   if (sigaction(sig, &context, &ocontext) == -1)
67     return SIG_ERR;
68   return ocontext.sa_handler;
69 }
70
71 void AttachDebugger()
72 {
73   if(getenv ("DEBUGGER"))
74   {
75     std::stringstream exec;
76     exec << "$DEBUGGER SALOME_ParallelContainerProxyMpi " << getpid() << "&";
77     std::cerr << exec.str() << std::endl;
78     system(exec.str().c_str());
79     while(1);
80   }
81 }
82
83 void Handler(int theSigId)
84 {
85   std::cerr << "SIGSEGV: "  << std::endl;
86   AttachDebugger();
87   //to exit or not to exit
88   exit(1);
89 }
90
91 void terminateHandler(void)
92 {
93   std::cerr << "Terminate: not managed exception !"  << std::endl;
94   AttachDebugger();
95 }
96
97 void unexpectedHandler(void)
98 {
99   std::cerr << "Unexpected: unexpected exception !"  << std::endl;
100   AttachDebugger();
101 }
102
103 void handler(int t) {
104   std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
105   std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
106   std::cerr << "SIGSEGV in :" << getpid() << std::endl;
107   std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
108   std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
109   while (1) {}
110 }
111 #endif
112
113 int main(int argc, char* argv[])
114 {
115   INFOS("Launching a parallel Mpi proxy container");
116
117 #ifdef _DEBUG_
118   signal(SIGSEGV, handler);
119 #endif
120
121   // MPI Init
122   int provided;
123   MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED ,&provided);
124   SetArgcArgv(argc, argv);
125   CORBA::ORB_var orb = KERNEL::GetRefToORB();
126   KERNEL_PYTHON::init_python(argc,argv);
127
128 #ifdef _DEBUG_
129   if(getenv ("DEBUGGER"))
130   {
131     std::cerr << "Unexpected: unexpected exception !"  << std::endl;
132     setsig(SIGSEGV,&Handler);
133     //set_terminate(&terminateHandler);
134     set_terminate(__gnu_cxx::__verbose_terminate_handler);
135     set_unexpected(&unexpectedHandler);
136   }
137 #endif
138
139   std::string containerName("");
140   containerName = argv[1];
141   int nb_nodes;
142   sscanf(argv[2],"%d",&nb_nodes);
143
144   try {  
145     CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
146     ASSERT(!CORBA::is_nil(obj));
147     PortableServer::POA_var root_poa = PortableServer::POA::_narrow(obj);
148     PortableServer::POAManager_var pman = root_poa->the_POAManager();
149
150 #ifndef WIN32
151     // add this container to the kill list
152     char aCommand[100];
153     sprintf(aCommand, "addToKillList.py %d SALOME_ParallelContainerProxyMpi", getpid());
154     system(aCommand);
155 #endif
156
157     SALOME_NamingService * ns = new SALOME_NamingService(CORBA::ORB::_duplicate(orb));
158
159     // PaCO++ code
160     paco_fabrique_manager* pfm = paco_getFabriqueManager();
161     pfm->register_com("dummy", new paco_dummy_fabrique());
162     pfm->register_thread("omnithread", new paco_omni_fabrique());
163
164     Container_proxy_impl_final * proxy =   new Container_proxy_impl_final(orb,
165                                                                           pfm->get_thread("omnithread"),
166                                                                           root_poa,
167                                                                           containerName);
168
169     // PaCO++ code
170     proxy->setLibCom("dummy", proxy);
171     proxy->setLibThread("omnithread");
172     PaCO::PacoTopology_t serveur_topo;
173     serveur_topo.total = nb_nodes;
174     proxy->setTopology(serveur_topo);
175
176     // Activation
177     //PortableServer::ObjectId_var _id = root_poa->activate_object(proxy);
178     //obj = root_poa->id_to_reference(_id);
179     obj = proxy->_this();
180
181     // in the NamingService
182     std::string hostname = Kernel_Utils::GetHostname();
183     Engines::Container_var pCont = Engines::Container::_narrow(obj);
184     std::string _containerName = ns->BuildContainerNameForNS(containerName.c_str(),
185                                                         hostname.c_str());
186     std::cerr << "---------" << _containerName << "----------" << std::endl;
187     ns->Register(pCont, _containerName.c_str());
188     pman->activate();
189     orb->run();
190     PyGILState_Ensure();
191     //Delete python container that destroy orb from python (pyCont._orb.destroy())
192     Py_Finalize();
193     MPI_Finalize();
194     delete ns;
195   }
196   catch (PaCO::PACO_Exception& e)
197   {
198     INFOS("Caught PaCO::PACO_Exception");
199     std::cerr << e << std::endl;
200   }
201   catch(CORBA::SystemException&)
202   {
203     INFOS("Caught CORBA::SystemException.");
204   }
205   catch(PortableServer::POA::ServantAlreadyActive&)
206   {
207     INFOS("Caught CORBA::ServantAlreadyActiveException");
208   }
209   catch(CORBA::Exception&)
210   {
211     INFOS("Caught CORBA::Exception.");
212   }
213   catch(std::exception& exc)
214   {
215     INFOS("Caught std::exception - "<<exc.what()); 
216   }
217   catch(...)
218   {
219     INFOS("Caught unknown exception.");
220   }
221   return 0 ;
222 }
223