// Copyright (C) 2000 Stephen A. Torri // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Questions, comments or improvements should be sent to: // s.torri@lancaster.ac.uk or storri@stratos.net // #include #include #include // CORBA headers #include #include #include // DGCC headers #include //************************** // Variables //************************** Comms::Master_ptr mstr_ptr; Comms::Slave_var slv_var; Job_List::Job_List* todo_list; JTCRunnableHandle job_thread; //************************** // Constructor & Destructor //************************** Slave_impl::Slave_impl() { todo_list = new Job_List(); } Slave_impl::~Slave_impl() {} CORBA::Boolean Slave_impl::slave_busy() throw(CORBA::SystemException) { CORBA::Boolean value = true; return value; } //---------------------------------------------------------------------- // Helper functions // //---------------------------------------------------------------------- // pre: Slave setup and registered // post: Monitor thread started // function: Initialize and start the monitor thread void Slave_impl::startMonitor(){ dout << "Slave_impl.cpp::startMonitor - starting thread" << endl; } // pre: Monitor Thread running // post: JobProcess Thread started // function: Initialize and start the job process thread void Slave_impl::startJobProcess(){ // Create thread if (CORBA::is_nil ( mstr_ptr)) { cerr << "Slave_impl::startJobProcess - mstr_ptr IS nil" << endl; exit(1); } else if (! (mstr_ptr -> _is_a("IDL:torri.linux/Comms/Master:1.0"))) { cerr << "Slave_impl::startJobProcess - mstr_ptr is not a Master" << endl; exit(1); } else { dout << "Slave_impl::startJobProcess - mstr_ptr [OK]" << endl; } if (CORBA::is_nil ( slv_var )) { cerr << "Slave_impl::startJobProcess - slv_var is nil" << endl; exit(1); } else if (! (slv_var -> _is_a("IDL:torri.linux/Comms/Slave:1.0"))) { cerr << "Slave_impl::startJobProcess - slv_var is not a Slave" << endl; exit(1); } else { dout << "Slave_impl::startJobProcess - slv_var [OK]" << endl; } job_thread = new Job_Process( todo_list, mstr_ptr, slv_var); dout << "Slave_impl.cpp::startJobProcess - starting thread" << endl; job_thread->run(); } //----------------------------- // pre: // post: // function: //------------------------------- void Slave_impl::initialize(CORBA::ORB_ptr orb_ptr, Comms::Slave_ptr slv) { try { cout << "Slave_impl.cpp::initialize - Entering initialize" << endl; CORBA::Object_var naming_object; slv_var = Comms::Slave::_duplicate(slv); // Sanity Check: see if slv and slv_var are not nil if (CORBA::is_nil(slv)){ cerr << "Slave_impl::initialize - slv is nil" << endl; exit(1); } else if (! (slv -> _is_a("IDL:torri.linux/Comms/Slave:1.0"))) { cerr << "Slave_impl::initialize - slv is not a Slave" << endl; exit(1); } else { dout << "Slave_impl::initialize - slv [OK]" << endl; } if (CORBA::is_nil(slv_var)){ cerr << "Slave_impl::initialize - slv_var is nil" << endl; exit(1); } else if (! (slv_var -> _is_a("IDL:torri.linux/Comms/Slave:1.0"))) { cerr << "Slave_impl::initialize - slv_var is not a Slave" << endl; exit(1); } else { dout << "Slave_impl::initialize - slv_var [OK]" << endl; } if ( slv_var -> _is_equivalent( slv ) ){ dout << "Slave_impl::initialize - slv == slv_var [OK]" << endl; } else { cerr << "Slave_impl::initialize - slv != slv_var" << endl; cerr << "\tBoth do not point to the same object" << endl; exit(1); } try { naming_object = orb_ptr->resolve_initial_references("NameService"); } catch (const CORBA::ORB::InvalidName &e ) { cerr << "Slave_impl::initialize - Invalid name: " << e << endl; throw; } catch (const CORBA::Exception &e) { cerr << "Slave_impl::initialize - Cannot get initial reference for NameService: " << e << endl; throw 0; } assert(! CORBA::is_nil( naming_object ) ); // Get the reference to initial naming context CosNaming::NamingContext_var naming_context; naming_context = CosNaming::NamingContext::_narrow(naming_object); // Attempt to create DGCC context CosNaming::Name name; name.length(1); name[0].id = CORBA::string_dup("DGCC"); name[0].kind = CORBA::string_dup("project"); try { CosNaming::NamingContext_var nv = naming_context->bind_new_context(name); } catch(CosNaming::NamingContext::AlreadyBound &ab) { // Fine, DGCC context already exists. } // Force bind of master reference to make sure it is always up to date. name.length(2); name[0].id = CORBA::string_dup("DGCC"); name[0].kind = CORBA::string_dup("project"); name[1].id = CORBA::string_dup("Slave"); name[1].kind = CORBA::string_dup("worker"); naming_context->rebind(name, slv_var); } catch (const CORBA::Exception &e) { cerr << "Slave_impl::initialize - Uncaught CORBA exception: " << e << endl; throw 0; } catch (...) { abort(); // Unexpected exception, dump core throw 0; } dout << "Slave_impl::initialize - registered with NameService" << endl; } //----------------------------- // pre: // post: // function: //------------------------------- void Slave_impl::registerSlave(CORBA::ORB_ptr orb_ptr, Comms::Master_ptr m_ptr) { dout << "Slave_impl::registerSlave - Entering local registerSlave method" << endl; if (CORBA::is_nil(slv_var)){ cerr << "Slave_impl::registerSlave - slv_var IS nil" << endl; exit(1); } else if (! (slv_var -> _is_a("IDL:torri.linux/Comms/Slave:1.0"))) { cerr << "Slave_impl::registerSlave - slv_var is not a Slave" << endl; exit(1); } else { dout << "Slave_impl::registerSlave - slv_var [OK]" << endl; } try{ if(! CORBA::is_nil(m_ptr)){ dout << "Slave_impl::registerSlave - master reference is not nil" << endl; dout << "\tCalling registerSlave on master reference" << endl; m_ptr->registerSlave(slv_var); } else{ cerr << "Slave_impl::registerSlave - Master reference is not initialized!" << endl; exit(1); } } catch(CORBA::Exception &e){ cerr << "Slave_impl::registerSlave - CORBA Exception: " << e << endl; } dout << "Slave_impl::registerSlave - Registered slave with master reference (Comms::Master_ptr m_ptr)" << endl; CORBA::release(m_ptr); } void Slave_impl::slaveFree () { try { if (! CORBA::is_nil(mstr_ptr) ) { mstr_ptr->slaveFree(slv_var); } else { cerr << "Slave_impl::slaveFree - Master reference is nil" << endl; exit(1); } } catch(CORBA::Exception &e) { cerr << "Slave_impl::slaveFree - CORBA Exception: " << e << endl; exit(1); } } //----------------------------- // pre: // post: // function: //------------------------------- Comms::Master_ptr Slave_impl::findMaster (CORBA::ORB_ptr orb_ptr) { dout << "Slave_impl::findMaster - Entering findMaster" << endl; Comms::Master_var mstr; try { CORBA::Object_var naming_object; try { naming_object = orb_ptr->resolve_initial_references("NameService"); } catch (const CORBA::ORB::InvalidName &e ) { cerr << "Slave_impl::findMaster - Invalid name: " << e << endl; throw 0; } catch (const CORBA::Exception &e) { cerr << "Slave_impl::findMaster - Cannot get initial reference for NameService: " << e << endl; throw 0; } if(CORBA::is_nil( naming_object )){ cerr << "Slave_impl::findMaster - Naming object IS null!" << endl; throw 0; } // Get the reference to initial naming context CosNaming::NamingContext_ptr naming_context; naming_context = CosNaming::NamingContext::_narrow(naming_object); CosNaming::Name name; name.length(2); name[0].id = CORBA::string_dup("DGCC"); name[0].kind = CORBA::string_dup("project"); name[1].id = CORBA::string_dup("Master"); name[1].kind = CORBA::string_dup("controller"); CORBA::Object_var obj_var; try { obj_var = naming_context->resolve(name); } catch (const CosNaming::NamingContext::NotFound &e ){ cerr << "Slave_impl::findMaster - Master not found: " << e << endl; throw; } catch (const CORBA::Exception &e ) { cerr << "Slave_impl::findMaster - Cannot resolve binding: " << e << endl; throw 0; } if (CORBA::is_nil (obj_var) ){ cerr << "Slave_impl::findMaster - Nil binding in Naming Service" << endl; throw 0; } try { mstr = Comms::Master::_narrow( obj_var.in() ); } catch (const CORBA::Exception &e) { cerr << "Slave_impl::findMaster - Cannot narrow Master reference: " << e << endl; throw 0; } if (CORBA::is_nil (mstr)) { cerr << "Slave_impl::findMaster - Master reference has wrong type" << endl; throw 0; } mstr_ptr = Comms::Master::_duplicate(mstr); } catch (const CORBA::Exception &e) { cerr << "Slave_impl::findMaster - Uncaught CORBA exception: " << e << endl; throw 0; } catch (...) { abort(); // Unexpected exception, dump core throw 0; } dout << "Slave_impl::findMaster - Found the Master reference" << endl; // Return Master return mstr._retn(); } //----------------------------- // pre: // post: // function: //------------------------------- void Slave_impl::send_command(const char* cmd, const char* dir) throw (CORBA::SystemException) { dout << "Slave_impl::send_command - Entering send_command" << endl; dout << "Slave_impl::send_command - directory = " << dir << endl; dout << "Slave_impl::send_command - command = " << cmd << endl; todo_list->addJob(string(cmd),string(dir)); } //------------------------------ // pre: // post: // function: //------------------------------ void Slave_impl::stop_slave(bool trigger) throw (CORBA::SystemException) { if ((trigger) && (todo_list->size() != 0)) { dout << "Slave_impl::stop_slave - Job done" << endl; exit(0); } // If false, do nothing. The trigger should only be sent when true. }