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