OSDN Git Service

trunk整理
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / src / schedule_module_control.cpp
diff --git a/l7vsd/src/schedule_module_control.cpp b/l7vsd/src/schedule_module_control.cpp
new file mode 100644 (file)
index 0000000..0c1a686
--- /dev/null
@@ -0,0 +1,176 @@
+/*!
+ * @file  schedule_module_control.cpp
+ * @brief control load/unload shared object schedule module.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2009  NTT COMWARE Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ **********************************************************************/
+#include    <dlfcn.h>
+#include    "schedule_module_control.h"
+#include    "logger.h"
+#include    "parameter.h"
+
+#define L7VS_MODULE_INITFN "create_module"
+#define L7VS_MODULE_FINIFN "destroy_module"
+
+namespace l7vs
+{
+
+#if defined(LOGGER_PROCESS_VSD)
+const LOG_CATEGORY_TAG loggerCategory = LOG_CAT_L7VSD_MODULE;
+const LOG_CATEGORY_TAG loggerCategorySysMem = LOG_CAT_L7VSD_SYSTEM_MEMORY;
+#else
+const LOG_CATEGORY_TAG loggerCategory = LOG_CAT_L7VSADM_MODULE;
+const LOG_CATEGORY_TAG loggerCategorySysMem = LOG_CAT_L7VSADM_COMMON;
+#endif
+
+/*!
+ * returns singleton instance.
+ *
+ * @param   void
+ * @return  instance
+ */
+schedule_module_control&
+schedule_module_control::getInstance()
+{
+        Logger logger(loggerCategory, 6, "schedule_module_control::getInstance", __FILE__, __LINE__);
+        static    schedule_module_control    instance;
+        return    instance;
+}
+
+/*!
+ * initialize class.
+ *
+ * @param   file path
+ * @return  void
+ */
+void
+schedule_module_control::initialize(const std::string &infile_path)
+{
+        Logger logger(loggerCategory, 7, "schedule_module_control::initialize", __FILE__, __LINE__);
+        if (&infile_path != NULL) {
+                module_control_base::modulefile_path    = infile_path;
+        }
+}
+
+/*!
+ * finalize class.
+ *
+ * @param   void
+ * @return  void
+ */
+void
+schedule_module_control::finalize()
+{
+        Logger logger(loggerCategory, 8, "schedule_module_control::finalize", __FILE__, __LINE__);
+}
+
+/*!
+ * load shared object.
+ *
+ * @param   module name
+ * @param   logging function
+ * @return  pointer for schedule_module_base class instance
+ */
+schedule_module_base*
+schedule_module_control::load_module(const    std::string &modulename)
+{
+        Logger logger(loggerCategory, 9, "schedule_module_control::load_module", __FILE__, __LINE__);
+        schedule_module_base *return_value = NULL;
+        boost::mutex::scoped_lock lock(loadmodule_map_mutex);
+        name_module_info_map::iterator it = loadmodule_map.find(modulename);
+        if (it == loadmodule_map.end()) {
+                std::string load_module_name = modulefile_path + "/sched_" + modulename + ".so";
+                void *h = dlopen(load_module_name.c_str(), RTLD_LAZY);
+                if (h == NULL) {
+                        std::string msg = "Could not open " + load_module_name + " module: " + dlerror();
+                        Logger::putLogError(loggerCategory, 7, msg, __FILE__, __LINE__);
+                        return NULL;
+                }
+
+                schedule_module_base*(*create_func)(void);
+                create_func = (schedule_module_base * ( *)(void))dlsym(h, L7VS_MODULE_INITFN);
+                if (create_func == NULL) {
+                        std::stringstream buf;
+                        buf << "Could not find symbol " << L7VS_MODULE_INITFN << ": " << dlerror();
+                        Logger::putLogError(loggerCategory, 8, buf.str(), __FILE__, __LINE__);
+                        dlclose(h);
+                        return NULL;
+                }
+                void (*destroy_func)(schedule_module_base *);
+                destroy_func = (void ( *)(schedule_module_base *))dlsym(h, L7VS_MODULE_FINIFN);
+                if (destroy_func == NULL) {
+                        std::stringstream buf;
+                        buf << "Could not find symbol " << L7VS_MODULE_FINIFN << ": " << dlerror();
+                        Logger::putLogError(loggerCategory, 9, buf.str(), __FILE__, __LINE__);
+                        dlclose(h);
+                        return NULL;
+                }
+                schedule_module_control::schedule_module_info module_info;
+                module_info.handle = h;
+                module_info.create_func = create_func;
+                module_info.destroy_func = destroy_func;
+                loadmodule_map.insert(std::pair< std::string, schedule_module_control::schedule_module_info >(modulename, module_info));
+                it = loadmodule_map.find(modulename);
+        }
+        if (it != loadmodule_map.end()) {
+                return_value = it->second.create_func();
+                if (return_value != NULL) {
+                        it->second.ref_count++;
+                } else {
+                        std::string msg = "Module initialization failed.";
+                        Logger::putLogError(loggerCategory, 10, msg, __FILE__, __LINE__);
+                }
+        }
+        return return_value;
+}
+
+/*!
+ * unload shared object.
+ *
+ * @param   module name
+ * @param   pointer for schedule_module_base class instance
+ * @return  void
+ */
+void
+schedule_module_control::unload_module(schedule_module_base *module_ptr)
+{
+        Logger logger(loggerCategory, 10, "schedule_module_control::unload_module", __FILE__, __LINE__);
+        if (module_ptr == NULL) {
+                std::string msg = "Arg(module_ptr) is NULL pointer.";
+                Logger::putLogError(loggerCategory, 11, msg, __FILE__, __LINE__);
+                return;
+        }
+
+        boost::mutex::scoped_lock lock(loadmodule_map_mutex);
+        name_module_info_map::iterator it = loadmodule_map.find(module_ptr->get_name());
+        if (it == loadmodule_map.end()) {
+                std::string msg = "module name is not found.";
+                Logger::putLogError(loggerCategory, 12, msg, __FILE__, __LINE__);
+                return;
+        }
+        it->second.destroy_func(module_ptr);
+        it->second.ref_count--;
+        if (it->second.ref_count == 0) {
+                dlclose(it->second.handle);
+                loadmodule_map.erase(it);
+        }
+}
+
+}