diff options
Diffstat (limited to '')
-rwxr-xr-x | linden/indra/llplugin/llpluginprocessparent.h | 201 |
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 | |||
50 | class LLPluginProcessParentOwner | ||
51 | { | ||
52 | public: | ||
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 | |||
61 | class LLPluginProcessParent : public LLPluginMessagePipeOwner | ||
62 | { | ||
63 | LOG_CLASS(LLPluginProcessParent); | ||
64 | public: | ||
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; }; | ||
129 | private: | ||
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 | ||