aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llplugin/llplugininstance.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xlinden/indra/llplugin/llplugininstance.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/linden/indra/llplugin/llplugininstance.cpp b/linden/indra/llplugin/llplugininstance.cpp
new file mode 100755
index 0000000..b822b9e
--- /dev/null
+++ b/linden/indra/llplugin/llplugininstance.cpp
@@ -0,0 +1,175 @@
1/**
2 * @file llplugininstance.cpp
3 * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing.
4 *
5 * @cond
6 * $LicenseInfo:firstyear=2008&license=viewergpl$
7 *
8 * Copyright (c) 2008-2010, Linden Research, Inc.
9 *
10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab
12 * to you under the terms of the GNU General Public License, version 2.0
13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2
17 *
18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at
22 * http://secondlife.com/developers/opensource/flossexception
23 *
24 * By copying, modifying or distributing this software, you acknowledge
25 * that you have read and understood your obligations described above,
26 * and agree to abide by those obligations.
27 *
28 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
29 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
30 * COMPLETENESS OR PERFORMANCE.
31 * $/LicenseInfo$
32 *
33 * @endcond
34 */
35
36#include "linden_common.h"
37
38#include "llplugininstance.h"
39
40#include "llapr.h"
41
42/** Virtual destructor. */
43LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
44{
45}
46
47/**
48 * TODO:DOC describe how it's used
49 */
50const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoint";
51
52/**
53 * Constructor.
54 *
55 * @param[in] owner Plugin instance. TODO:DOC is this a good description of what "owner" is?
56 */
57LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) :
58 mDSOHandle(NULL),
59 mPluginUserData(NULL),
60 mPluginSendMessageFunction(NULL)
61{
62 mOwner = owner;
63}
64
65/**
66 * Destructor.
67 */
68LLPluginInstance::~LLPluginInstance()
69{
70 if(mDSOHandle != NULL)
71 {
72 apr_dso_unload(mDSOHandle);
73 mDSOHandle = NULL;
74 }
75}
76
77/**
78 * Dynamically loads the plugin and runs the plugin's init function.
79 *
80 * @param[in] plugin_file Name of plugin dll/dylib/so. TODO:DOC is this correct? see .h
81 * @return 0 if successful, APR error code or error code from the plugin's init function on failure.
82 */
83int LLPluginInstance::load(std::string &plugin_file)
84{
85 pluginInitFunction init_function = NULL;
86
87 int result = apr_dso_load(&mDSOHandle,
88 plugin_file.c_str(),
89 gAPRPoolp);
90 if(result != APR_SUCCESS)
91 {
92 char buf[1024];
93 apr_dso_error(mDSOHandle, buf, sizeof(buf));
94
95 LL_WARNS("Plugin") << "apr_dso_load of " << plugin_file << " failed with error " << result << " , additional info string: " << buf << LL_ENDL;
96
97 }
98
99 if(result == APR_SUCCESS)
100 {
101 result = apr_dso_sym((apr_dso_handle_sym_t*)&init_function,
102 mDSOHandle,
103 PLUGIN_INIT_FUNCTION_NAME);
104
105 if(result != APR_SUCCESS)
106 {
107 LL_WARNS("Plugin") << "apr_dso_sym failed with error " << result << LL_ENDL;
108 }
109 }
110
111 if(result == APR_SUCCESS)
112 {
113 result = init_function(staticReceiveMessage, (void*)this, &mPluginSendMessageFunction, &mPluginUserData);
114
115 if(result != APR_SUCCESS)
116 {
117 LL_WARNS("Plugin") << "call to init function failed with error " << result << LL_ENDL;
118 }
119 }
120
121 return (int)result;
122}
123
124/**
125 * Sends a message to the plugin.
126 *
127 * @param[in] message Message
128 */
129void LLPluginInstance::sendMessage(const std::string &message)
130{
131 if(mPluginSendMessageFunction)
132 {
133 LL_DEBUGS("Plugin") << "sending message to plugin: \"" << message << "\"" << LL_ENDL;
134 mPluginSendMessageFunction(message.c_str(), &mPluginUserData);
135 }
136 else
137 {
138 LL_WARNS("Plugin") << "dropping message: \"" << message << "\"" << LL_ENDL;
139 }
140}
141
142/**
143 * Idle. TODO:DOC what's the purpose of this?
144 *
145 */
146void LLPluginInstance::idle(void)
147{
148}
149
150// static
151void LLPluginInstance::staticReceiveMessage(const char *message_string, void **user_data)
152{
153 // TODO: validate that the user_data argument is still a valid LLPluginInstance pointer
154 // we could also use a key that's looked up in a map (instead of a direct pointer) for safety, but that's probably overkill
155 LLPluginInstance *self = (LLPluginInstance*)*user_data;
156 self->receiveMessage(message_string);
157}
158
159/**
160 * Plugin receives message from plugin loader shell.
161 *
162 * @param[in] message_string Message
163 */
164void LLPluginInstance::receiveMessage(const char *message_string)
165{
166 if(mOwner)
167 {
168 LL_DEBUGS("Plugin") << "processing incoming message: \"" << message_string << "\"" << LL_ENDL;
169 mOwner->receivePluginMessage(message_string);
170 }
171 else
172 {
173 LL_WARNS("Plugin") << "dropping incoming message: \"" << message_string << "\"" << LL_ENDL;
174 }
175}