Merge "implemented decmatch (artf724241)"
[deliverable/titan.core.git] / core / LoggerPlugin_dynamic.cc
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Delic, Adam
11 * Raduly, Csaba
12 *
13 ******************************************************************************/
14 #include "LoggerPlugin.hh"
15 #include "ILoggerPlugin.hh"
16
17 #include <assert.h>
18 #include <dlfcn.h>
19
20 bool str_ends_with(const char *str, const char *suffix)
21 {
22 if (!str || !suffix) return false;
23 size_t lenstr = strlen(str);
24 size_t lensuffix = strlen(suffix);
25 if (lensuffix > lenstr) return false;
26 return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
27 }
28
29 enum SoType { RT1_SINGLE, RT1_PARALLEL, RT2_SINGLE, RT2_PARALLEL };
30
31 // determine the library type from the name ending
32 SoType get_so_type(const char* filename)
33 {
34 if (str_ends_with(filename, "-rt2.so")) {
35 return str_ends_with(filename, "-parallel-rt2.so") ? RT2_PARALLEL : RT2_SINGLE;
36 } else { // rt1
37 return str_ends_with(filename, "-parallel.so") ? RT1_PARALLEL : RT1_SINGLE;
38 }
39 }
40
41 void LoggerPlugin::load()
42 {
43 if (this->filename_) {
44 // determine the required library
45 bool single_mode = TTCN_Runtime::is_single();
46 #ifndef TITAN_RUNTIME_2
47 const SoType required_so_type = single_mode ? RT1_SINGLE : RT1_PARALLEL;
48 const char* required_suffix_str = single_mode ? ".so" : "-parallel.so";
49 const char* required_runtime_str = single_mode ? "Load Test Single Mode Runtime" : "Load Test Parallel Mode Runtime";
50 #else
51 const SoType required_so_type = single_mode ? RT2_SINGLE : RT2_PARALLEL;
52 const char* required_suffix_str = single_mode ? "-rt2.so" : "-parallel-rt2.so";
53 const char* required_runtime_str = single_mode ? "Function Test Single Mode Runtime" : "Function Test Parallel Mode Runtime";
54 #endif
55 // if the provided filename ends with .so it is assumed to be a full file name,
56 // otherwise it's assumed to be the base of the file name that has to be suffixed automatically
57 expstring_t real_filename = mcopystr(this->filename_);
58 if (str_ends_with(this->filename_,".so")) {
59 // check if the filename is correct
60 if (get_so_type(this->filename_)!=required_so_type) {
61 TTCN_Logger::fatal_error("Incorrect plugin file name was provided (%s). "
62 "This executable is linked with the %s, the matching plugin file name must end with `%s'. "
63 "Note: if the file name ending is omitted it will be automatically appended.",
64 this->filename_, required_runtime_str, required_suffix_str);
65 }
66 } else { // add the appropriate suffix if the filename extension was not provided
67 real_filename = mputstr(real_filename, required_suffix_str);
68 }
69
70 // Dynamic plug-in. Try to resolve all symbols, die early with RTLD_NOW.
71 this->handle_ = dlopen(real_filename, RTLD_NOW);
72 if (!this->handle_) {
73 TTCN_Logger::fatal_error("Unable to load plug-in %s with file name %s (%s)", this->filename_, real_filename, dlerror());
74 }
75 Free(real_filename);
76
77 cb_create_plugin create_plugin =
78 (cb_create_plugin)(unsigned long)dlsym(this->handle_, "create_plugin");
79 if (!create_plugin) return;
80 this->ref_ = (*create_plugin)();
81 } else {
82 // Static plug-in. We simply instantiate the class without any `dl*()'.
83 assert(this->create_);
84 this->ref_ = this->create_();
85 }
86
87 this->ref_->init();
88 this->is_log2str_capable_ = this->ref_->is_log2str_capable();
89 }
90
91 // Completely destroy the logger plug-in and make it useless. However,
92 // reloading is possible. This should be called before the logger is
93 // deleted.
94 void LoggerPlugin::unload()
95 {
96 if (!this->ref_) return;
97 this->ref_->fini();
98 if (this->filename_) {
99 cb_destroy_plugin destroy_plugin =
100 (cb_destroy_plugin)(unsigned long)dlsym(this->handle_,
101 "destroy_plugin");
102 if (destroy_plugin) {
103 (*destroy_plugin)(this->ref_);
104 }
105 dlclose(this->handle_);
106 this->handle_ = NULL;
107 } else {
108 // For static plug-ins, it's simple.
109 delete this->ref_;
110 this->create_ = NULL;
111 }
112 this->ref_ = NULL;
113 }
114
This page took 0.034415 seconds and 5 git commands to generate.