diff options
Diffstat (limited to '')
-rwxr-xr-x | linden/indra/llplugin/llpluginprocessparent.cpp | 123 |
1 files changed, 56 insertions, 67 deletions
diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp index 8fd18ef..5a66279 100755 --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp | |||
@@ -49,6 +49,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() | |||
49 | 49 | ||
50 | bool LLPluginProcessParent::sUseReadThread = false; | 50 | bool LLPluginProcessParent::sUseReadThread = false; |
51 | apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; | 51 | apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; |
52 | AIAPRPool LLPluginProcessParent::sPollSetPool; | ||
52 | bool LLPluginProcessParent::sPollsetNeedsRebuild = false; | 53 | bool LLPluginProcessParent::sPollsetNeedsRebuild = false; |
53 | LLMutex *LLPluginProcessParent::sInstancesMutex; | 54 | LLMutex *LLPluginProcessParent::sInstancesMutex; |
54 | std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; | 55 | std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; |
@@ -59,7 +60,7 @@ class LLPluginProcessParentPollThread: public LLThread | |||
59 | { | 60 | { |
60 | public: | 61 | public: |
61 | LLPluginProcessParentPollThread() : | 62 | LLPluginProcessParentPollThread() : |
62 | LLThread("LLPluginProcessParentPollThread", gAPRPoolp) | 63 | LLThread("LLPluginProcessParentPollThread") |
63 | { | 64 | { |
64 | } | 65 | } |
65 | protected: | 66 | protected: |
@@ -84,12 +85,11 @@ protected: | |||
84 | 85 | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): | 88 | LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) |
88 | mIncomingQueueMutex(gAPRPoolp) | ||
89 | { | 89 | { |
90 | if(!sInstancesMutex) | 90 | if(!sInstancesMutex) |
91 | { | 91 | { |
92 | sInstancesMutex = new LLMutex(gAPRPoolp); | 92 | sInstancesMutex = new LLMutex; |
93 | } | 93 | } |
94 | 94 | ||
95 | mOwner = owner; | 95 | mOwner = owner; |
@@ -102,6 +102,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): | |||
102 | mBlocked = false; | 102 | mBlocked = false; |
103 | mPolledInput = false; | 103 | mPolledInput = false; |
104 | mPollFD.client_data = NULL; | 104 | mPollFD.client_data = NULL; |
105 | mPollFDPool.create(); | ||
105 | 106 | ||
106 | mPluginLaunchTimeout = 60.0f; | 107 | mPluginLaunchTimeout = 60.0f; |
107 | mPluginLockupTimeout = 15.0f; | 108 | mPluginLockupTimeout = 15.0f; |
@@ -119,7 +120,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): | |||
119 | 120 | ||
120 | LLPluginProcessParent::~LLPluginProcessParent() | 121 | LLPluginProcessParent::~LLPluginProcessParent() |
121 | { | 122 | { |
122 | LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; | 123 | LL_DEBUGS("PluginParent") << "destructor" << LL_ENDL; |
123 | 124 | ||
124 | // Remove from the global list before beginning destruction. | 125 | // Remove from the global list before beginning destruction. |
125 | { | 126 | { |
@@ -177,44 +178,28 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std | |||
177 | bool LLPluginProcessParent::accept() | 178 | bool LLPluginProcessParent::accept() |
178 | { | 179 | { |
179 | bool result = false; | 180 | bool result = false; |
180 | |||
181 | apr_status_t status = APR_EGENERAL; | 181 | apr_status_t status = APR_EGENERAL; |
182 | apr_socket_t *new_socket = NULL; | ||
183 | |||
184 | status = apr_socket_accept( | ||
185 | &new_socket, | ||
186 | mListenSocket->getSocket(), | ||
187 | gAPRPoolp); | ||
188 | 182 | ||
183 | mSocket = LLSocket::create(status, mListenSocket); | ||
189 | 184 | ||
190 | if(status == APR_SUCCESS) | 185 | if(status == APR_SUCCESS) |
191 | { | 186 | { |
192 | // llinfos << "SUCCESS" << llendl; | 187 | // llinfos << "SUCCESS" << llendl; |
193 | // Success. Create a message pipe on the new socket | 188 | // Success. Create a message pipe on the new socket |
194 | |||
195 | // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! | ||
196 | apr_pool_t* new_pool = NULL; | ||
197 | status = apr_pool_create(&new_pool, gAPRPoolp); | ||
198 | |||
199 | mSocket = LLSocket::create(new_socket, new_pool); | ||
200 | new LLPluginMessagePipe(this, mSocket); | 189 | new LLPluginMessagePipe(this, mSocket); |
201 | 190 | ||
202 | result = true; | 191 | result = true; |
203 | } | 192 | } |
204 | else if(APR_STATUS_IS_EAGAIN(status)) | ||
205 | { | ||
206 | // llinfos << "EAGAIN" << llendl; | ||
207 | |||
208 | // No incoming connections. This is not an error. | ||
209 | status = APR_SUCCESS; | ||
210 | } | ||
211 | else | 193 | else |
212 | { | 194 | { |
213 | // llinfos << "Error:" << llendl; | 195 | mSocket.reset(); |
214 | ll_apr_warn_status(status); | 196 | // EAGAIN means "No incoming connections". This is not an error. |
215 | 197 | if (!APR_STATUS_IS_EAGAIN(status)) | |
216 | // Some other error. | 198 | { |
217 | errorState(); | 199 | // Some other error. |
200 | ll_apr_warn_status(status); | ||
201 | errorState(); | ||
202 | } | ||
218 | } | 203 | } |
219 | 204 | ||
220 | return result; | 205 | return result; |
@@ -264,10 +249,10 @@ void LLPluginProcessParent::idle(void) | |||
264 | else if(mSocketError != APR_SUCCESS) | 249 | else if(mSocketError != APR_SUCCESS) |
265 | { | 250 | { |
266 | // The socket is in an error state -- the plugin is gone. | 251 | // The socket is in an error state -- the plugin is gone. |
267 | LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; | 252 | LL_WARNS("PluginParent") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; |
268 | errorState(); | 253 | errorState(); |
269 | } | 254 | } |
270 | } | 255 | } |
271 | 256 | ||
272 | // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). | 257 | // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). |
273 | // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. | 258 | // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. |
@@ -283,7 +268,7 @@ void LLPluginProcessParent::idle(void) | |||
283 | 268 | ||
284 | apr_status_t status = APR_SUCCESS; | 269 | apr_status_t status = APR_SUCCESS; |
285 | apr_sockaddr_t* addr = NULL; | 270 | apr_sockaddr_t* addr = NULL; |
286 | mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); | 271 | mListenSocket = LLSocket::create(LLSocket::STREAM_TCP); |
287 | mBoundPort = 0; | 272 | mBoundPort = 0; |
288 | 273 | ||
289 | // This code is based on parts of LLSocket::create() in lliosocket.cpp. | 274 | // This code is based on parts of LLSocket::create() in lliosocket.cpp. |
@@ -294,7 +279,7 @@ void LLPluginProcessParent::idle(void) | |||
294 | APR_INET, | 279 | APR_INET, |
295 | 0, // port 0 = ephemeral ("find me a port") | 280 | 0, // port 0 = ephemeral ("find me a port") |
296 | 0, | 281 | 0, |
297 | gAPRPoolp); | 282 | AIAPRRootPool::get()()); |
298 | 283 | ||
299 | if(ll_apr_warn_status(status)) | 284 | if(ll_apr_warn_status(status)) |
300 | { | 285 | { |
@@ -327,15 +312,15 @@ void LLPluginProcessParent::idle(void) | |||
327 | 312 | ||
328 | if(mBoundPort == 0) | 313 | if(mBoundPort == 0) |
329 | { | 314 | { |
330 | LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL; | 315 | LL_WARNS("PluginParent") << "Bound port number unknown, bailing out." << LL_ENDL; |
331 | 316 | ||
332 | killSockets(); | 317 | killSockets(); |
333 | errorState(); | 318 | errorState(); |
334 | break; | 319 | break; |
335 | } | 320 | } |
336 | } | 321 | } |
337 | 322 | ||
338 | LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL; | 323 | LL_DEBUGS("PluginParent") << "Bound tcp socket to port: " << addr->port << LL_ENDL; |
339 | 324 | ||
340 | // Make the listen socket non-blocking | 325 | // Make the listen socket non-blocking |
341 | status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1); | 326 | status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1); |
@@ -458,8 +443,8 @@ void LLPluginProcessParent::idle(void) | |||
458 | break; | 443 | break; |
459 | 444 | ||
460 | case STATE_HELLO: | 445 | case STATE_HELLO: |
461 | LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL; | 446 | LL_DEBUGS("PluginParent") << "received hello message" << LL_ENDL; |
462 | 447 | ||
463 | // Send the message to load the plugin | 448 | // Send the message to load the plugin |
464 | { | 449 | { |
465 | LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); | 450 | LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); |
@@ -492,7 +477,7 @@ void LLPluginProcessParent::idle(void) | |||
492 | } | 477 | } |
493 | else if(pluginLockedUp()) | 478 | else if(pluginLockedUp()) |
494 | { | 479 | { |
495 | LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL; | 480 | LL_WARNS("PluginParent") << "timeout in exiting state, bailing out" << LL_ENDL; |
496 | errorState(); | 481 | errorState(); |
497 | } | 482 | } |
498 | break; | 483 | break; |
@@ -589,11 +574,11 @@ void LLPluginProcessParent::sendMessage(const LLPluginMessage &message) | |||
589 | // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked. | 574 | // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked. |
590 | mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); | 575 | mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); |
591 | } | 576 | } |
592 | 577 | ||
593 | std::string buffer = message.generate(); | 578 | std::string buffer = message.generate(); |
594 | LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL; | 579 | LL_DEBUGS("PluginParent") << "Sending: " << buffer << LL_ENDL; |
595 | writeMessageRaw(buffer); | 580 | writeMessageRaw(buffer); |
596 | 581 | ||
597 | // Try to send message immediately. | 582 | // Try to send message immediately. |
598 | if(mMessagePipe) | 583 | if(mMessagePipe) |
599 | { | 584 | { |
@@ -617,7 +602,8 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) | |||
617 | if(message_pipe != NULL) | 602 | if(message_pipe != NULL) |
618 | { | 603 | { |
619 | // Set up the apr_pollfd_t | 604 | // Set up the apr_pollfd_t |
620 | mPollFD.p = gAPRPoolp; | 605 | |
606 | mPollFD.p = mPollFDPool(); | ||
621 | mPollFD.desc_type = APR_POLL_SOCKET; | 607 | mPollFD.desc_type = APR_POLL_SOCKET; |
622 | mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; | 608 | mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; |
623 | mPollFD.rtnevents = 0; | 609 | mPollFD.rtnevents = 0; |
@@ -664,6 +650,7 @@ void LLPluginProcessParent::updatePollset() | |||
664 | // delete the existing pollset. | 650 | // delete the existing pollset. |
665 | apr_pollset_destroy(sPollSet); | 651 | apr_pollset_destroy(sPollSet); |
666 | sPollSet = NULL; | 652 | sPollSet = NULL; |
653 | sPollSetPool.destroy(); | ||
667 | } | 654 | } |
668 | 655 | ||
669 | std::list<LLPluginProcessParent*>::iterator iter; | 656 | std::list<LLPluginProcessParent*>::iterator iter; |
@@ -686,12 +673,14 @@ void LLPluginProcessParent::updatePollset() | |||
686 | { | 673 | { |
687 | #ifdef APR_POLLSET_NOCOPY | 674 | #ifdef APR_POLLSET_NOCOPY |
688 | // The pollset doesn't exist yet. Create it now. | 675 | // The pollset doesn't exist yet. Create it now. |
689 | apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); | 676 | sPollSetPool.create(); |
677 | apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY); | ||
690 | if(status != APR_SUCCESS) | 678 | if(status != APR_SUCCESS) |
691 | { | 679 | { |
692 | #endif // APR_POLLSET_NOCOPY | 680 | #endif // APR_POLLSET_NOCOPY |
693 | LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; | 681 | LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; |
694 | sPollSet = NULL; | 682 | sPollSet = NULL; |
683 | sPollSetPool.destroy(); | ||
695 | #ifdef APR_POLLSET_NOCOPY | 684 | #ifdef APR_POLLSET_NOCOPY |
696 | } | 685 | } |
697 | else | 686 | else |
@@ -851,8 +840,8 @@ void LLPluginProcessParent::servicePoll() | |||
851 | 840 | ||
852 | void LLPluginProcessParent::receiveMessageRaw(const std::string &message) | 841 | void LLPluginProcessParent::receiveMessageRaw(const std::string &message) |
853 | { | 842 | { |
854 | LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL; | 843 | LL_DEBUGS("PluginParent") << "Received: " << message << LL_ENDL; |
855 | 844 | ||
856 | LLPluginMessage parsed; | 845 | LLPluginMessage parsed; |
857 | if(parsed.parse(message) != -1) | 846 | if(parsed.parse(message) != -1) |
858 | { | 847 | { |
@@ -918,19 +907,19 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) | |||
918 | } | 907 | } |
919 | else | 908 | else |
920 | { | 909 | { |
921 | LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; | 910 | LL_WARNS("PluginParent") << "received hello message in wrong state -- bailing out" << LL_ENDL; |
922 | errorState(); | 911 | errorState(); |
923 | } | 912 | } |
924 | 913 | ||
925 | } | 914 | } |
926 | else if(message_name == "load_plugin_response") | 915 | else if(message_name == "load_plugin_response") |
927 | { | 916 | { |
928 | if(mState == STATE_LOADING) | 917 | if(mState == STATE_LOADING) |
929 | { | 918 | { |
930 | // Plugin has been loaded. | 919 | // Plugin has been loaded. |
931 | 920 | ||
932 | mPluginVersionString = message.getValue("plugin_version"); | 921 | mPluginVersionString = message.getValue("plugin_version"); |
933 | LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL; | 922 | LL_INFOS("PluginParent") << "plugin version string: " << mPluginVersionString << LL_ENDL; |
934 | 923 | ||
935 | // Check which message classes/versions the plugin supports. | 924 | // Check which message classes/versions the plugin supports. |
936 | // TODO: check against current versions | 925 | // TODO: check against current versions |
@@ -939,9 +928,9 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) | |||
939 | LLSD::map_iterator iter; | 928 | LLSD::map_iterator iter; |
940 | for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++) | 929 | for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++) |
941 | { | 930 | { |
942 | LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL; | 931 | LL_INFOS("PluginParent") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL; |
943 | } | 932 | } |
944 | 933 | ||
945 | // Send initial sleep time | 934 | // Send initial sleep time |
946 | setSleepTime(mSleepTime, true); | 935 | setSleepTime(mSleepTime, true); |
947 | 936 | ||
@@ -949,7 +938,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) | |||
949 | } | 938 | } |
950 | else | 939 | else |
951 | { | 940 | { |
952 | LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; | 941 | LL_WARNS("PluginParent") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; |
953 | errorState(); | 942 | errorState(); |
954 | } | 943 | } |
955 | } | 944 | } |
@@ -960,8 +949,8 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) | |||
960 | 949 | ||
961 | mCPUUsage = message.getValueReal("cpu_usage"); | 950 | mCPUUsage = message.getValueReal("cpu_usage"); |
962 | 951 | ||
963 | LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL; | 952 | LL_DEBUGS("PluginSpam") << "cpu usage reported as " << mCPUUsage << LL_ENDL; |
964 | 953 | ||
965 | } | 954 | } |
966 | else if(message_name == "shm_add_response") | 955 | else if(message_name == "shm_add_response") |
967 | { | 956 | { |
@@ -983,7 +972,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) | |||
983 | } | 972 | } |
984 | else | 973 | else |
985 | { | 974 | { |
986 | LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL; | 975 | LL_WARNS("PluginParent") << "Unknown internal message from child: " << message_name << LL_ENDL; |
987 | } | 976 | } |
988 | } | 977 | } |
989 | else | 978 | else |
@@ -1015,7 +1004,7 @@ std::string LLPluginProcessParent::addSharedMemory(size_t size) | |||
1015 | } | 1004 | } |
1016 | else | 1005 | else |
1017 | { | 1006 | { |
1018 | LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; | 1007 | LL_WARNS("PluginParent") << "Couldn't create a shared memory segment!" << LL_ENDL; |
1019 | 1008 | ||
1020 | // Don't leak | 1009 | // Don't leak |
1021 | delete region; | 1010 | delete region; |
@@ -1037,7 +1026,7 @@ void LLPluginProcessParent::removeSharedMemory(const std::string &name) | |||
1037 | } | 1026 | } |
1038 | else | 1027 | else |
1039 | { | 1028 | { |
1040 | LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL; | 1029 | LL_WARNS("PluginParent") << "Request to remove an unknown shared memory segment." << LL_ENDL; |
1041 | } | 1030 | } |
1042 | } | 1031 | } |
1043 | size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name) | 1032 | size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name) |
@@ -1084,25 +1073,25 @@ std::string LLPluginProcessParent::getPluginVersion(void) | |||
1084 | 1073 | ||
1085 | void LLPluginProcessParent::setState(EState state) | 1074 | void LLPluginProcessParent::setState(EState state) |
1086 | { | 1075 | { |
1087 | LL_DEBUGS("Plugin") << "setting state to " << stateToString(state) << LL_ENDL; | 1076 | LL_DEBUGS("PluginParent") << "setting state to " << stateToString(state) << LL_ENDL; |
1088 | mState = state; | 1077 | mState = state; |
1089 | }; | 1078 | }; |
1090 | 1079 | ||
1091 | bool LLPluginProcessParent::pluginLockedUpOrQuit() | 1080 | bool LLPluginProcessParent::pluginLockedUpOrQuit() |
1092 | { | 1081 | { |
1093 | bool result = false; | 1082 | bool result = false; |
1094 | 1083 | ||
1095 | if(!mProcess.isRunning()) | 1084 | if(!mProcess.isRunning()) |
1096 | { | 1085 | { |
1097 | LL_WARNS("Plugin") << "child exited" << LL_ENDL; | 1086 | LL_WARNS("PluginParent") << "child exited" << LL_ENDL; |
1098 | result = true; | 1087 | result = true; |
1099 | } | 1088 | } |
1100 | else if(pluginLockedUp()) | 1089 | else if(pluginLockedUp()) |
1101 | { | 1090 | { |
1102 | LL_WARNS("Plugin") << "timeout" << LL_ENDL; | 1091 | LL_WARNS("PluginParent") << "timeout" << LL_ENDL; |
1103 | result = true; | 1092 | result = true; |
1104 | } | 1093 | } |
1105 | 1094 | ||
1106 | return result; | 1095 | return result; |
1107 | } | 1096 | } |
1108 | 1097 | ||