PageRenderTime 20ms CodeModel.GetById 1ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llplugin/llpluginprocessparent.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 194 lines | 114 code | 41 blank | 39 comment | 2 complexity | 9f5389a760a0ca37b045b84c73f9a371 MD5 | raw file
  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=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 * @endcond
 27 */
 28
 29#ifndef LL_LLPLUGINPROCESSPARENT_H
 30#define LL_LLPLUGINPROCESSPARENT_H
 31
 32#include "llapr.h"
 33#include "llprocesslauncher.h"
 34#include "llpluginmessage.h"
 35#include "llpluginmessagepipe.h"
 36#include "llpluginsharedmemory.h"
 37
 38#include "lliosocket.h"
 39#include "llthread.h"
 40
 41class LLPluginProcessParentOwner
 42{
 43public:
 44	virtual ~LLPluginProcessParentOwner();
 45	virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
 46	virtual bool receivePluginMessageEarly(const LLPluginMessage &message) {return false;};
 47	// This will only be called when the plugin has died unexpectedly 
 48	virtual void pluginLaunchFailed() {};
 49	virtual void pluginDied() {};
 50};
 51
 52class LLPluginProcessParent : public LLPluginMessagePipeOwner
 53{
 54	LOG_CLASS(LLPluginProcessParent);
 55public:
 56	LLPluginProcessParent(LLPluginProcessParentOwner *owner);
 57	~LLPluginProcessParent();
 58		
 59	void init(const std::string &launcher_filename, 
 60			  const std::string &plugin_dir,
 61			  const std::string &plugin_filename, 
 62			  bool debug);
 63
 64	void idle(void);
 65	
 66	// returns true if the plugin is on its way to steady state
 67	bool isLoading(void);
 68
 69	// returns true if the plugin is in the steady state (processing messages)
 70	bool isRunning(void);
 71
 72	// returns true if the process has exited or we've had a fatal error
 73	bool isDone(void);	
 74	
 75	// returns true if the process is currently waiting on a blocking request
 76	bool isBlocked(void) { return mBlocked; };
 77	
 78	void killSockets(void);
 79	
 80	// Go to the proper error state
 81	void errorState(void);
 82
 83	void setSleepTime(F64 sleep_time, bool force_send = false);
 84	F64 getSleepTime(void) const { return mSleepTime; };
 85
 86	void sendMessage(const LLPluginMessage &message);
 87	
 88	void receiveMessage(const LLPluginMessage &message);
 89	
 90	// Inherited from LLPluginMessagePipeOwner
 91	/*virtual*/ void receiveMessageRaw(const std::string &message);
 92	/*virtual*/ void receiveMessageEarly(const LLPluginMessage &message);
 93	/*virtual*/ void setMessagePipe(LLPluginMessagePipe *message_pipe) ;
 94	
 95	// 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.
 96	// 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.
 97	std::string addSharedMemory(size_t size);
 98	// Negotiates for the removal of a shared memory segment.  It is the caller's responsibility to ensure that nothing touches the memory
 99	// after this has been called, since the segment will be unmapped shortly thereafter.
100	void removeSharedMemory(const std::string &name);
101	size_t getSharedMemorySize(const std::string &name);
102	void *getSharedMemoryAddress(const std::string &name);
103	
104	// Returns the version string the plugin indicated for the message class, or an empty string if that class wasn't in the list.
105	std::string getMessageClassVersion(const std::string &message_class);
106
107	std::string getPluginVersion(void);
108	
109	bool getDisableTimeout() { return mDisableTimeout; };
110	void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
111	
112	void setLaunchTimeout(F32 timeout) { mPluginLaunchTimeout = timeout; };
113	void setLockupTimeout(F32 timeout) { mPluginLockupTimeout = timeout; };
114
115	F64 getCPUUsage() { return mCPUUsage; };
116	
117	static void poll(F64 timeout);
118	static bool canPollThreadRun() { return (sPollSet || sPollsetNeedsRebuild || sUseReadThread); };
119	static void setUseReadThread(bool use_read_thread);
120	static bool getUseReadThread() { return sUseReadThread; };
121private:
122
123	enum EState
124	{
125		STATE_UNINITIALIZED,
126		STATE_INITIALIZED,		// init() has been called
127		STATE_LISTENING,		// listening for incoming connection
128		STATE_LAUNCHED,			// process has been launched
129		STATE_CONNECTED,		// process has connected
130		STATE_HELLO,			// first message from the plugin process has been received
131		STATE_LOADING,			// process has been asked to load the plugin
132		STATE_RUNNING,			// 
133		STATE_LAUNCH_FAILURE,	// Failure before plugin loaded
134		STATE_ERROR,			// generic bailout state
135		STATE_CLEANUP,			// clean everything up
136		STATE_EXITING,			// Tried to kill process, waiting for it to exit
137		STATE_DONE				//
138
139	};
140	EState mState;
141	void setState(EState state);
142	
143	bool pluginLockedUp();
144	bool pluginLockedUpOrQuit();
145
146	bool accept();
147		
148	LLSocket::ptr_t mListenSocket;
149	LLSocket::ptr_t mSocket;
150	U32 mBoundPort;
151	
152	LLProcessLauncher mProcess;
153	
154	std::string mPluginFile;
155	std::string mPluginDir;
156
157	LLPluginProcessParentOwner *mOwner;
158	
159	typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType;
160	sharedMemoryRegionsType mSharedMemoryRegions;
161	
162	LLSD mMessageClassVersions;
163	std::string mPluginVersionString;
164	
165	LLTimer mHeartbeat;
166	F64		mSleepTime;
167	F64		mCPUUsage;
168	
169	bool mDisableTimeout;
170	bool mDebug;
171	bool mBlocked;
172	bool mPolledInput;
173
174	LLProcessLauncher mDebugger;
175	
176	F32 mPluginLaunchTimeout;		// Somewhat longer timeout for initial launch.
177	F32 mPluginLockupTimeout;		// If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
178
179	static bool sUseReadThread;
180	apr_pollfd_t mPollFD;
181	static apr_pollset_t *sPollSet;
182	static bool sPollsetNeedsRebuild;
183	static LLMutex *sInstancesMutex;
184	static std::list<LLPluginProcessParent*> sInstances;
185	static void dirtyPollSet();
186	static void updatePollset();
187	void servicePoll();
188	static LLThread *sReadThread;
189	
190	LLMutex mIncomingQueueMutex;
191	std::queue<LLPluginMessage> mIncomingQueue;
192};
193
194#endif // LL_LLPLUGINPROCESSPARENT_H