// CORBA Comms::Master implementation methods and local methods // for handling the compilation of the target project. // // 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 // // DGCC headers #include #include // C++ headers #include #include #include #include #include #include #include // CORBA headers #include //******************************* // Variables //******************************* using namespace std; CORBA::ORB_ptr mstr_orb_ptr; Job_List* jobs = new Job_List(); Slave_Service* slv_serv; Overseer* ovsr; //******************************* // Constructor & Destructor //******************************* Master_impl::Master_impl() { slv_serv = new Slave_Service(); ovsr = new Overseer(jobs, slv_serv); } Master_impl::~Master_impl() {} //******************************* // Initialization Functions //******************************* //--------------------------------------------------------------- // pre: Orb initialized // post: Master registered with Naming_Service // function: This setups up the Master for service. By first, // registering with the NameService. Second, by // keeping track of the orb pointer for future use. // // orb - reference to the CORBA ORB //--------------------------------------------------------------- void Master_impl::initialize(CORBA::ORB_ptr orb) { try { mstr_orb_ptr = orb; dout << "Master_impl::initialize - Entered initialize" << endl; Master_impl* m_impl = new Master_impl(); Comms::Master_var m_var = m_impl -> _this(); CORBA::Object_var naming_object; try { dout << "Master_impl::initialize - resolve_initial_references('NameService')" << endl; naming_object = orb->resolve_initial_references("NameService"); } catch (const CORBA::ORB::InvalidName &e ) { cerr << "Master_impl::initialize - Invalid name: " << e << endl; throw 0; } catch (const CORBA::Exception &e) { cerr << "Master_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 { dout << "Master_impl::initialize - naming_context -> bind_new_context" << endl; 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("Master"); name[1].kind = CORBA::string_dup("controller"); dout << "Master_impl::initialize - naming_context -> rebind" << endl; naming_context->rebind(name, m_var); dout << "Master_impl::initialize - Registered with the naming service" << endl; } catch (const CORBA::Exception &e) { cerr << "Master_impl::initialize - Uncaught CORBA exception: " << e << endl; throw 0; } catch (...) { abort(); // Unexpected exception, dump core throw 0; } } //--------------------------------------------------------------- // pre: Filename is known (Makefile) // post: jobQueue is filled with commands // function: run "make -nW Makefile" to get commands and add them // to a queue. //--------------------------------------------------------------- void Master_impl::readMakefile(){ string command = ""; string target = ""; char c = ' '; // run "make -nW Makefile" command = "|make -nW Makefile"; ipfstream* runPipe = new ipfstream( command.c_str(), ios::in, 0644); while((c = runPipe->get()) != EOF) { if(c == '\n') { dout << "Master_impl::readMakefile - Command: " << target << endl; jobs -> addJob(target.c_str()); target = ""; } else { target += c; } } dout << "Master_impl::readMakefile - Job Queue size: " << jobs->size() << endl; } //--------------------------------------------------------------- // pre: initalize(), readMakefile() and startSlaveService() completed. // post: Overseer running. // function: Creates and executes Overseer. // // *Note: This was here because I thought the Overseer would be a thread. // At present the Master as a whole is a non-threaded server. ORBacus // handles each request to it as a thread. This setup is not ideal but works // during the development of this proof of concept. //--------------------------------------------------------------- void Master_impl::startOverseer() { // We have the jobQueue ready // create thread to handle sending out jobs } //******************************* // Runtime functions //******************************* //-------------------------------------------------------------- // pre: Master initialized and running. Slave initialized. // post: Master has added slave to its slave list // function: As slaves start up they register with the master. // This list will help the master know what slaves // are available for work. // // s_ptr - reference to the Slave we are trying to register //--------------------------------------------------------------- void Master_impl::registerSlave(Comms::Slave_ptr s_ptr) throw (CORBA::SystemException) { dout << "Master_impl::registerSlave - Entering Register Slave" << endl; slv_serv -> addSlave(s_ptr); dout << "Master_impl::registerSlave - Added slave to slave service" << endl; ovsr -> awaken(); } //--------------------------------------------------------------- // pre: Master initialized and running. Slave is initialized and running. // post: Master moved slave from busy list to free list. Overseer awakened. // function: Slaves that finished a job call this method to be 1) moved from // the busy list to the free list and 2) awaken the overseer for // jobs if that there is more. // // s_ptr - reference to the Slave that is free for work //--------------------------------------------------------------- void Master_impl::slaveFree(Comms::Slave_ptr s_ptr) throw (CORBA::SystemException) { dout << "Master_impl::slaveFree - Slave is free" << endl; slv_serv -> finishedWork(s_ptr); dout << "Master_impl::slaveFree - Moved slave from busy to free" << endl; ovsr -> awaken(); }