]> granicus.if.org Git - icinga2/blob - lib/base/component.cpp
928cca446a3f915ff0b56a48a139b9ebe70e1c5c
[icinga2] / lib / base / component.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "i2-base.h"
21
22 using namespace icinga;
23
24 REGISTER_TYPE(Component, NULL);
25
26 /**
27  * Constructor for the component class.
28  */
29 Component::Component(const Dictionary::Ptr& properties)
30         : DynamicObject(properties)
31 {
32         assert(Application::IsMainThread());
33
34         if (!IsLocal())
35                 throw_exception(runtime_error("Component objects must be local."));
36
37 #ifdef _WIN32
38         HMODULE
39 #else /* _WIN32 */
40         lt_dlhandle
41 #endif /* _WIN32 */
42         hModule;
43
44         Logger::Write(LogInformation, "base", "Loading component '" + GetName() + "'");
45
46         hModule = Utility::LoadIcingaLibrary(GetName(), true);
47
48         CreateComponentFunction pCreateComponent;
49
50 #ifdef _WIN32
51         pCreateComponent = reinterpret_cast<CreateComponentFunction>(GetProcAddress(hModule,
52             "CreateComponent"));
53 #else /* _WIN32 */
54 #       ifdef __GNUC__
55         /* suppress compiler warning for void * cast */
56         __extension__
57 #       endif
58         pCreateComponent = reinterpret_cast<CreateComponentFunction>(lt_dlsym(hModule,
59             "CreateComponent"));
60 #endif /* _WIN32 */
61
62         IComponent::Ptr impl;
63
64         try {
65                 if (pCreateComponent == NULL)
66                         throw_exception(runtime_error("Loadable module does not contain "
67                             "CreateComponent function"));
68
69                 /* pCreateComponent returns a raw pointer which we must wrap in a shared_ptr */
70                 impl = IComponent::Ptr(pCreateComponent());
71
72                 if (!impl)
73                         throw_exception(runtime_error("CreateComponent function returned NULL."));
74         } catch (...) {
75 #ifdef _WIN32
76                 FreeLibrary(hModule);
77 #else /* _WIN32 */
78                 lt_dlclose(hModule);
79 #endif /* _WIN32 */
80                 throw;
81         }
82
83         m_Impl = impl;
84 }
85
86 /**
87  * Destructor for the Component class.
88  */
89 Component::~Component(void)
90 {
91         if (m_Impl)
92                 m_Impl->Stop();
93 }
94
95 /**
96  * Starts the component. Called when the DynamicObject is fully
97  * constructed/registered.
98  */
99 void Component::Start(void)
100 {
101         m_Impl->m_Config = GetSelf();
102         m_Impl->Start();
103 }
104
105 /**
106  * Adds a directory to the component search path.
107  *
108  * @param componentDirectory The directory.
109  */
110 void Component::AddSearchDir(const String& componentDirectory)
111 {
112         Logger::Write(LogInformation, "base", "Adding library search dir: " +
113             componentDirectory);
114
115 #ifdef _WIN32
116         SetDllDirectory(componentDirectory.CStr());
117 #else /* _WIN32 */
118         lt_dladdsearchdir(componentDirectory.CStr());
119 #endif /* _WIN32 */
120 }
121
122 /**
123  * Retrieves the configuration for this component.
124  *
125  * @returns The configuration.
126  */
127 DynamicObject::Ptr IComponent::GetConfig(void) const
128 {
129         return m_Config.lock();
130 }
131
132 /**
133  * Starts the component.
134  */
135 void IComponent::Start(void)
136 {
137         /* Nothing to do in the default implementation. */
138 }
139
140 /**
141  * Stops the component.
142  */
143 void IComponent::Stop(void)
144 {
145         /* Nothing to do in the default implementation. */
146 }