The Gaudi Framework  v33r0 (d5ea422b)
Application.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include <Gaudi/Application.h>
13 #include <GaudiKernel/Bootstrap.h>
14 #include <GaudiKernel/IAppMgrUI.h>
19 #include <GaudiKernel/IProperty.h>
21 #include <GaudiKernel/Property.h>
22 #include <gsl/span>
23 
24 #define GAUDI_ASSERT_THROW_NAME( cond, msg, name ) \
25  if ( !cond ) throw GaudiException{msg, name, StatusCode::FAILURE};
26 
27 #define GAUDI_ASSERT_THROW( cond, msg ) \
28  if ( !cond ) throw GaudiException{msg, this->name(), StatusCode::FAILURE};
29 
30 namespace {
31  void consumeOptions( SmartIF<IProperty> prop, Gaudi::Application::Options& options ) {
32  GAUDI_ASSERT_THROW_NAME( prop, "invalid IProperty", "Gaudi::Application" );
34  const auto prefix_size = prefix.size();
35 
36  auto opt = options.upper_bound( prefix );
37  while ( opt != end( options ) && std::string_view( opt->first ).substr( 0, prefix_size ) == prefix ) {
38  GAUDI_ASSERT_THROW_NAME( prop->setProperty( opt->first.substr( prefix_size ), opt->second ),
39  "failure setting " + opt->first + " to " + opt->second, "Gaudi::Application" );
40  // drop processed option and increase iterator
41  opt = options.erase( opt );
42  }
43  }
44 } // namespace
45 
46 Gaudi::Application::Factory::ReturnType Gaudi::Application::create( std::string_view type, Options opts ) {
47  if ( type == "Gaudi::Application" ) { return std::make_unique<Application>( std::move( opts ) ); }
48  return Factory::create( type, std::move( opts ) );
49 }
50 
52  // # Prepare the application
53  // - instantiate
55  GAUDI_ASSERT_THROW_NAME( app, "failure instantiating ApplicationMgr", "Gaudi::Application" );
56 
57  // - main configuration
58  consumeOptions( app.as<IProperty>(), options );
59  // - start minimal services
60  GAUDI_ASSERT_THROW_NAME( app->configure(), "failure creating basic services", "Gaudi::Application" );
61 
62  consumeOptions( SmartIF<IMessageSvc>{app}.as<IProperty>(), options );
63 
64  // - prepare job configuration
65  {
66  auto sloc = app.as<ISvcLocator>();
67  auto jos = sloc->service<IJobOptionsSvc>( "JobOptionsSvc" );
68  std::for_each( begin( options ), end( options ), [&jos]( const auto& item ) {
69  std::string_view name = item.first;
70  const auto sep_pos = name.find_last_of( '.' );
71  std::string_view client = name.substr( 0, sep_pos );
72  name.remove_prefix( sep_pos + 1 );
73  jos->addPropertyToCatalogue( std::string{client}, Gaudi::Property<std::string>{std::string{name}, item.second} );
74  } );
75  }
76 }
77 
78 Gaudi::Application::~Application() { app->terminate().ignore(); }
79 
81  auto prop = app.as<IProperty>();
82  auto processor = app.as<IEventProcessor>();
83 
85  evtMax.assign( prop->getProperty( "EvtMax" ) );
86 
87  // - get ready to process events
88  if ( app->initialize() ) {
89  if ( app->start() ) {
90  // - main processing loop
91  if ( !processor->executeRun( evtMax ) ) setAppReturnCode( prop, Gaudi::ReturnCode::GenericFailure );
92 
93  app->stop().ignore();
94  } else
96  app->finalize().ignore();
97  } else
99  return getAppReturnCode( prop );
100 }
101 
102 namespace {
103  struct c_opt_t {
104  char* key;
105  char* value;
106  };
107 } // namespace
108 
109 #ifdef GAUDI_HASCLASSVISIBILITY
110 # pragma GCC visibility push( default )
111 #endif
112 
113 extern "C" {
114 // helper to invoke the factory from Python
115 Gaudi::Application* _py_Gaudi__Application__create( const char* name, const c_opt_t* options, long n ) {
117  gsl::span py_opts{options, n};
118  for ( auto& opt : py_opts ) { opts[opt.key] = opt.value; }
119  return Gaudi::Application::create( name, std::move( opts ) ).release();
120 }
121 int _py_Gaudi__Application__run( Gaudi::Application* self ) { return self->run(); }
123 }
124 
125 #ifdef GAUDI_HASCLASSVISIBILITY
126 # pragma GCC visibility pop
127 #endif
int getAppReturnCode(const SmartIF< IProperty > &appmgr)
Get the application (current) return code.
Definition: AppReturnCode.h:79
Gaudi::Application * _py_Gaudi__Application__create(const char *name, const c_opt_t *options, long n)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:35
Implementation of property with value of concrete type.
Definition: Property.h:370
#define GAUDI_ASSERT_THROW_NAME(cond, msg, name)
Definition: Application.cpp:24
virtual int run()
Implement the application main logic:
Definition: Application.cpp:80
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:117
constexpr int GenericFailure
Definition: AppReturnCode.h:28
virtual const std::string & name() const =0
Retrieve the name of the instance.
STL class.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
virtual StatusCode setProperty(const Gaudi::Details::PropertyBase &p)=0
Set the property by property.
Main interface for the JobOptions service.
string prefix
Definition: gaudirun.py:343
def end
Definition: IOTest.py:123
def create(cls, appType, opts)
Definition: __init__.py:96
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
Definition: AppReturnCode.h:59
T move(T... args)
Gaudi application entry point.
Definition: __init__.py:72
Application(Options opts)
Construct and configure the application from the provided options.
Definition: Application.cpp:51
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:164
int _py_Gaudi__Application__run(Gaudi::Application *self)
virtual ~Application()
Definition: Application.cpp:78
The IEventProcessor is the interface to process events.
AttribStringParser::Iterator begin(const AttribStringParser &parser)
The IProperty is the basic interface for all components which have properties that can be set or get.
Definition: IProperty.h:30
T for_each(T... args)
void _py_Gaudi__Application__delete(Gaudi::Application *self)
GAUDI_API IAppMgrUI * createApplicationMgr(const std::string &dllname, const std::string &factname)
std::map< std::string, std::string > Options
Definition: Application.h:29