aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llplugin/llpluginprocessparent.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xlinden/indra/llplugin/llpluginprocessparent.h201
1 files changed, 201 insertions, 0 deletions
diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h
new file mode 100755
index 0000000..a8929b1
--- /dev/null
+++ b/linden/indra/llplugin/llpluginprocessparent.h
@@ -0,0 +1,201 @@
1/**
2 * @file llpluginprocessparent.h
3 * @brief LLPluginProcessParent handles the parent side of the external-process plugin API.
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#ifndef LL_LLPLUGINPROCESSPARENT_H
37#define LL_LLPLUGINPROCESSPARENT_H
38
39#include <queue> //imprudence
40
41#include "llapr.h"
42#include "llprocesslauncher.h"
43#include "llpluginmessage.h"
44#include "llpluginmessagepipe.h"
45#include "llpluginsharedmemory.h"
46
47#include "lliosocket.h"
48#include "llthread.h"
49
50class LLPluginProcessParentOwner
51{
52public:
53 virtual ~LLPluginProcessParentOwner();
54 virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
55 virtual bool receivePluginMessageEarly(const LLPluginMessage &message) {return false;};
56 // This will only be called when the plugin has died unexpectedly
57 virtual void pluginLaunchFailed() {};
58 virtual void pluginDied() {};
59};
60
61class LLPluginProcessParent : public LLPluginMessagePipeOwner
62{
63 LOG_CLASS(LLPluginProcessParent);
64public:
65 LLPluginProcessParent(LLPluginProcessParentOwner *owner);
66 ~LLPluginProcessParent();
67
68 void init(const std::string &launcher_filename,
69 const std::string &plugin_filename,
70 bool debug);
71
72 void idle(void);
73
74 // returns true if the plugin is on its way to steady state
75 bool isLoading(void);
76
77 // returns true if the plugin is in the steady state (processing messages)
78 bool isRunning(void);
79
80 // returns true if the process has exited or we've had a fatal error
81 bool isDone(void);
82
83 // returns true if the process is currently waiting on a blocking request
84 bool isBlocked(void) { return mBlocked; };
85
86 void killSockets(void);
87
88 // Go to the proper error state
89 void errorState(void);
90
91 void setSleepTime(F64 sleep_time, bool force_send = false);
92 F64 getSleepTime(void) const { return mSleepTime; };
93
94 void sendMessage(const LLPluginMessage &message);
95
96 void receiveMessage(const LLPluginMessage &message);
97
98 // Inherited from LLPluginMessagePipeOwner
99 /*virtual*/ void receiveMessageRaw(const std::string &message);
100 /*virtual*/ void receiveMessageEarly(const LLPluginMessage &message);
101 /*virtual*/ void setMessagePipe(LLPluginMessagePipe *message_pipe) ;
102
103 // This adds a memory segment shared with the client, generating a name for the segment. The name generated is guaranteed to be unique on the host.
104 // The caller must call removeSharedMemory first (and wait until getSharedMemorySize returns 0 for the indicated name) before re-adding a segment with the same name.
105 std::string addSharedMemory(size_t size);
106 // Negotiates for the removal of a shared memory segment. It is the caller's responsibility to ensure that nothing touches the memory
107 // after this has been called, since the segment will be unmapped shortly thereafter.
108 void removeSharedMemory(const std::string &name);
109 size_t getSharedMemorySize(const std::string &name);
110 void *getSharedMemoryAddress(const std::string &name);
111
112 // Returns the version string the plugin indicated for the message class, or an empty string if that class wasn't in the list.
113 std::string getMessageClassVersion(const std::string &message_class);
114
115 std::string getPluginVersion(void);
116
117 bool getDisableTimeout() { return mDisableTimeout; };
118 void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
119
120 void setLaunchTimeout(F32 timeout) { mPluginLaunchTimeout = timeout; };
121 void setLockupTimeout(F32 timeout) { mPluginLockupTimeout = timeout; };
122
123 F64 getCPUUsage() { return mCPUUsage; };
124
125 static void poll(F64 timeout);
126 static bool canPollThreadRun() { return (sPollSet || sPollsetNeedsRebuild || sUseReadThread); };
127 static void setUseReadThread(bool use_read_thread);
128 static bool getUseReadThread() { return sUseReadThread; };
129private:
130
131 enum EState
132 {
133 STATE_UNINITIALIZED,
134 STATE_INITIALIZED, // init() has been called
135 STATE_LISTENING, // listening for incoming connection
136 STATE_LAUNCHED, // process has been launched
137 STATE_CONNECTED, // process has connected
138 STATE_HELLO, // first message from the plugin process has been received
139 STATE_LOADING, // process has been asked to load the plugin
140 STATE_RUNNING, //
141 STATE_LAUNCH_FAILURE, // Failure before plugin loaded
142 STATE_ERROR, // generic bailout state
143 STATE_CLEANUP, // clean everything up
144 STATE_EXITING, // Tried to kill process, waiting for it to exit
145 STATE_DONE //
146
147 };
148 EState mState;
149 void setState(EState state);
150
151 bool pluginLockedUp();
152 bool pluginLockedUpOrQuit();
153
154 bool accept();
155
156 LLSocket::ptr_t mListenSocket;
157 LLSocket::ptr_t mSocket;
158 U32 mBoundPort;
159
160 LLProcessLauncher mProcess;
161
162 std::string mPluginFile;
163
164 LLPluginProcessParentOwner *mOwner;
165
166 typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType;
167 sharedMemoryRegionsType mSharedMemoryRegions;
168
169 LLSD mMessageClassVersions;
170 std::string mPluginVersionString;
171
172 LLTimer mHeartbeat;
173 F64 mSleepTime;
174 F64 mCPUUsage;
175
176 bool mDisableTimeout;
177 bool mDebug;
178 bool mBlocked;
179 bool mPolledInput;
180
181 LLProcessLauncher mDebugger;
182
183 F32 mPluginLaunchTimeout; // Somewhat longer timeout for initial launch.
184 F32 mPluginLockupTimeout; // If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
185
186 static bool sUseReadThread;
187 apr_pollfd_t mPollFD;
188 static apr_pollset_t *sPollSet;
189 static bool sPollsetNeedsRebuild;
190 static LLMutex *sInstancesMutex;
191 static std::list<LLPluginProcessParent*> sInstances;
192 static void dirtyPollSet();
193 static void updatePollset();
194 void servicePoll();
195 static LLThread *sReadThread;
196
197 LLMutex mIncomingQueueMutex;
198 std::queue<LLPluginMessage> mIncomingQueue;
199};
200
201#endif // LL_LLPLUGINPROCESSPARENT_H