blob: d77cc0f3883a6bc0de770a5b9e643d08f2b95b46 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#ifndef _sys_apr_Module_h
#define _sys_apr_Module_h
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include "qpid/QpidError.h"
#include "APRBase.h"
#include "APRPool.h"
#include <boost/noncopyable.hpp>
#include <iostream>
#include <apr_dso.h>
namespace qpid {
namespace sys {
typedef apr_dso_handle_t* dso_handle_t;
template <class T> class Module : private boost::noncopyable
{
typedef T* create_t();
typedef void destroy_t(T*);
dso_handle_t handle;
destroy_t* destroy;
T* ptr;
void load(const std::string& name);
void unload();
void* getSymbol(const std::string& name);
public:
Module(const std::string& name);
T* operator->();
T* get();
~Module() throw();
};
template <class T> Module<T>::Module(const std::string& module) : destroy(0), ptr(0)
{
load(module);
//TODO: need a better strategy for symbol names to allow multiple
//modules to be loaded without clashes...
//Note: need the double cast to avoid errors in casting from void* to function pointer with -pedantic
create_t* create = reinterpret_cast<create_t*>(reinterpret_cast<intptr_t>(getSymbol("create")));
destroy = reinterpret_cast<destroy_t*>(reinterpret_cast<intptr_t>(getSymbol("destroy")));
ptr = create();
}
template <class T> T* Module<T>::operator->()
{
return ptr;
}
template <class T> T* Module<T>::get()
{
return ptr;
}
template <class T> Module<T>::~Module() throw()
{
try {
if (handle && ptr) {
destroy(ptr);
}
if (handle) unload();
} catch (std::exception& e) {
std::cout << "Error while destroying module: " << e.what() << std::endl;
}
destroy = 0;
handle = 0;
ptr = 0;
}
template <class T> void Module<T>::load(const std::string& name)
{
CHECK_APR_SUCCESS(apr_dso_load(&handle, name.c_str(), APRPool::get()));
}
template <class T> void Module<T>::unload()
{
CHECK_APR_SUCCESS(apr_dso_unload(handle));
}
template <class T> void* Module<T>::getSymbol(const std::string& name)
{
apr_dso_handle_sym_t symbol;
CHECK_APR_SUCCESS(apr_dso_sym(&symbol, handle, name.c_str()));
return (void*) symbol;
}
}}
#endif //ifndef _sys_apr_Module_h
|