diff options
Diffstat (limited to 'indra/llplugin')
| -rw-r--r-- | indra/llplugin/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 54 | ||||
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 25 | ||||
| -rw-r--r-- | indra/llplugin/llpluginprocessparent.cpp | 169 | ||||
| -rw-r--r-- | indra/llplugin/llpluginprocessparent.h | 9 | ||||
| -rw-r--r-- | indra/llplugin/slplugin/CMakeLists.txt | 39 |
6 files changed, 172 insertions, 126 deletions
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 7fa5c957b6..0525e3d9ea 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -35,7 +35,7 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) target_include_directories( llplugin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries( llplugin llcommon llmath llrender llmessage ) +target_link_libraries( llplugin llcommon llmath llmessage llxml ) add_subdirectory(slplugin) include(LibraryInstall) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 17f403e8e8..53a338b3d6 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -33,9 +33,7 @@ #include "llpluginmessageclasses.h" #include "llcontrol.h" -#if LL_DARWIN || LL_LINUX || __FreeBSD__ extern LLControlGroup gSavedSettings; -#endif #if LL_DARWIN extern bool gHiDPISupport; #endif @@ -134,9 +132,13 @@ void LLPluginClassMedia::reset() mLastMouseY = 0; mStatus = LLPluginClassMediaOwner::MEDIA_NONE; mSleepTime = 1.0f / 100.0f; + mCanUndo = false; + mCanRedo = false; mCanCut = false; mCanCopy = false; mCanPaste = false; + mCanDoDelete = false; + mCanSelectAll = false; mMediaName.clear(); mMediaDescription.clear(); mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f); @@ -909,6 +911,18 @@ void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, sendMessage(message); } +void LLPluginClassMedia::undo() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_undo"); + sendMessage(message); +} + +void LLPluginClassMedia::redo() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_redo"); + sendMessage(message); +} + void LLPluginClassMedia::cut() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut"); @@ -927,6 +941,24 @@ void LLPluginClassMedia::paste() sendMessage(message); } +void LLPluginClassMedia::doDelete() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_delete"); + sendMessage(message); +} + +void LLPluginClassMedia::selectAll() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_select_all"); + sendMessage(message); +} + +void LLPluginClassMedia::showPageSource() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_show_source"); + sendMessage(message); +} + void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log) @@ -936,10 +968,8 @@ void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache message.setValue("username", username); // cef shares cache between users but creates user-based contexts message.setValue("cef_log_file", user_data_path_cef_log); -#if LL_DARWIN || LL_LINUX || __FreeBSD__ bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog"); message.setValueBoolean("cef_verbose_log", cef_verbose_log); -#endif sendMessage(message); } @@ -1191,6 +1221,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) } else if(message_name == "edit_state") { + if(message.hasValue("undo")) + { + mCanUndo = message.getValueBoolean("undo"); + } + if(message.hasValue("redo")) + { + mCanRedo = message.getValueBoolean("redo"); + } if(message.hasValue("cut")) { mCanCut = message.getValueBoolean("cut"); @@ -1203,6 +1241,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mCanPaste = message.getValueBoolean("paste"); } + if (message.hasValue("delete")) + { + mCanDoDelete = message.getValueBoolean("delete"); + } + if (message.hasValue("select_all")) + { + mCanSelectAll = message.getValueBoolean("select_all"); + } } else if(message_name == "name_text") { diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 80862284ff..6c512003cc 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -29,7 +29,6 @@ #ifndef LL_LLPLUGINCLASSMEDIA_H #define LL_LLPLUGINCLASSMEDIA_H -#include "llgltypes.h" #include "llpluginprocessparent.h" #include "llrect.h" #include "llpluginclassmediaowner.h" @@ -205,6 +204,12 @@ public: LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; } + void undo(); + bool canUndo() const { return mCanUndo; }; + + void redo(); + bool canRedo() const { return mCanRedo; }; + void cut(); bool canCut() const { return mCanCut; }; @@ -214,6 +219,14 @@ public: void paste(); bool canPaste() const { return mCanPaste; }; + void doDelete(); + bool canDoDelete() const { return mCanDoDelete; }; + + void selectAll(); + bool canSelectAll() const { return mCanSelectAll; }; + + void showPageSource(); + // These can be called before init(), and they will be queued and sent before the media init message. void setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log); void setLanguageCode(const std::string &language_code); @@ -357,9 +370,9 @@ protected: bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true S32 mRequestedTextureDepth; - LLGLenum mRequestedTextureInternalFormat; - LLGLenum mRequestedTextureFormat; - LLGLenum mRequestedTextureType; + U32 mRequestedTextureInternalFormat; + U32 mRequestedTextureFormat; + U32 mRequestedTextureType; bool mRequestedTextureSwapBytes; bool mRequestedTextureCoordsOpenGL; @@ -425,9 +438,13 @@ protected: F64 mSleepTime; + bool mCanUndo; + bool mCanRedo; bool mCanCut; bool mCanCopy; bool mCanPaste; + bool mCanDoDelete; + bool mCanSelectAll; std::string mMediaName; std::string mMediaTitle; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 00abcf740f..63f1de8d6a 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -34,6 +34,9 @@ #include "llpluginmessageclasses.h" #include "llsdserialize.h" #include "stringize.h" +#include "threadpool.h" +#include "workqueue.h" + #include "llapr.h" //virtual @@ -45,7 +48,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() bool LLPluginProcessParent::sUseReadThread = false; apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; bool LLPluginProcessParent::sPollsetNeedsRebuild = false; -LLCoros::Mutex *LLPluginProcessParent::sInstancesMutex; +LLCoros::Mutex *LLPluginProcessParent::sInstancesMutex = nullptr; LLPluginProcessParent::mapInstances_t LLPluginProcessParent::sInstances; LLThread *LLPluginProcessParent::sReadThread = NULL; @@ -79,29 +82,8 @@ protected: }; - -class LLPluginProcessCreationThread : public LLThread -{ -public: - LLPluginProcessCreationThread(LLPluginProcessParent *parent) : - LLThread("LLPluginProcessCreationThread", gAPRPoolp), - pParent(parent) - { - } -protected: - // Inherited from LLThread, should run once - /*virtual*/ void run(void) - { - pParent->createPluginProcess(); - } -private: - LLPluginProcessParent *pParent; - -}; - LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): - mIncomingQueueMutex(), - pProcessCreationThread(NULL) + mIncomingQueueMutex() { if(!sInstancesMutex) { @@ -130,18 +112,6 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): LLPluginProcessParent::~LLPluginProcessParent() { LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; - if (pProcessCreationThread) - { - if (!pProcessCreationThread->isStopped()) - { - // Shouldn't happen at this stage - LL_WARNS("Plugin") << "Shutting down active pProcessCreationThread" << LL_ENDL; - pProcessCreationThread->shutdown(); - ms_sleep(20); - } - delete pProcessCreationThread; - pProcessCreationThread = NULL; - } // Destroy any remaining shared memory regions sharedMemoryRegionsType::iterator iter; @@ -185,6 +155,12 @@ LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParent /*static*/ void LLPluginProcessParent::shutdown() { + if (!sInstancesMutex) + { + // setup was not complete, skip shutdown + return; + } + LLCoros::LockType lock(*sInstancesMutex); mapInstances_t::iterator it; @@ -299,6 +275,9 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std { mProcessParams.executable = launcher_filename; mProcessParams.cwd = plugin_dir; +#if LL_WINDOWS + mProcessParams.envs.add(llformat("SYSTEMROOT=%s", getenv("SYSTEMROOT"))); +#endif mPluginFile = plugin_filename; mPluginDir = plugin_dir; mCPUUsage = 0.0f; @@ -352,35 +331,6 @@ bool LLPluginProcessParent::accept() return result; } -bool LLPluginProcessParent::createPluginProcess() -{ - if (!mProcess) - { - // Only argument to the launcher is the port number we're listening on - mProcessParams.args.add(stringize(mBoundPort)); - mProcess = LLProcess::create(mProcessParams); - return mProcess != NULL; - } - - return false; -} - -void LLPluginProcessParent::clearProcessCreationThread() -{ - if (pProcessCreationThread) - { - if (!pProcessCreationThread->isStopped()) - { - pProcessCreationThread->shutdown(); - } - else - { - delete pProcessCreationThread; - pProcessCreationThread = NULL; - } - } -} - void LLPluginProcessParent::idle(void) { bool idle_again; @@ -453,9 +403,14 @@ void LLPluginProcessParent::idle(void) apr_sockaddr_t* addr = NULL; mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mBoundPort = 0; + if (!mListenSocket) + { + killSockets(); + errorState(); + break; + } // This code is based on parts of LLSocket::create() in lliosocket.cpp. - status = apr_sockaddr_info_get( &addr, "127.0.0.1", @@ -542,30 +497,72 @@ void LLPluginProcessParent::idle(void) case STATE_LISTENING: { + // Only argument to the launcher is the port number we're listening on + mProcessParams.args.add(stringize(mBoundPort)); + // Launch the plugin process. - if (mDebug && !pProcessCreationThread) + if (mDebug && !mProcess) { - createPluginProcess(); - if (!mProcess) + if (!(mProcess = LLProcess::create(mProcessParams))) { errorState(); } } - else if (pProcessCreationThread == NULL) + else if (!mProcess && !mProcessCreationRequested) { - // exe plugin process allocation can be hindered by a number - // of factors, don't hold whole viewer because of it, use thread - pProcessCreationThread = new LLPluginProcessCreationThread(this); - pProcessCreationThread->start(); - } - else if (!mProcess && pProcessCreationThread->isStopped()) - { - delete pProcessCreationThread; - pProcessCreationThread = NULL; - errorState(); + mProcessCreationRequested = true; + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak + // pointer + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + llassert_always(main_queue); + llassert_always(general_queue); + + auto process_params = mProcessParams; + + bool posted = main_queue->postTo( + general_queue, + [process_params]() // Work done on general queue + { + return LLProcess::create(process_params); + }, + [this](LLProcessPtr new_process) // Callback to main thread + mutable { + ptr_t that; + { + // this grabs a copy of the smart pointer to ourselves to ensure that we do not + // get destroyed until after this method returns. + LLCoros::LockType lock(*sInstancesMutex); + mapInstances_t::iterator it = sInstances.find(this); + if (it != sInstances.end()) + that = (*it).second; + } + + if (that) + { + if (new_process) + { + that->mProcess = new_process; + } + else + { + that->mProcessCreationRequested = false; + that->errorState(); + } + } + + }); + if (!posted) + { + LL_WARNS("Plugin") << "Failed to dispath process creation to threadpool" << LL_ENDL; + if (!(mProcess = LLProcess::create(mProcessParams))) + { + mProcessCreationRequested = false; + errorState(); + } + } } - if (mProcess) { if(mDebug) @@ -581,7 +578,7 @@ void LLPluginProcessParent::idle(void) params.args.add("-e"); params.args.add("tell application \"Terminal\""); params.args.add("-e"); - params.args.add(STRINGIZE("set win to do script \"lldb -pid " + params.args.add(STRINGIZE("set win to do script \"lldb -p " << mProcess->getProcessID() << "\"")); params.args.add("-e"); params.args.add("do script \"continue\" in win"); @@ -595,15 +592,6 @@ void LLPluginProcessParent::idle(void) // This will allow us to time out if the process never starts. mHeartbeat.start(); mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout); - - // pProcessCreationThread should have stopped by this point, - // but check just in case it paused on statistics sync - if (pProcessCreationThread && pProcessCreationThread->isStopped()) - { - delete pProcessCreationThread; - pProcessCreationThread = NULL; - } - setState(STATE_LAUNCHED); } } @@ -706,7 +694,6 @@ void LLPluginProcessParent::idle(void) killSockets(); setState(STATE_DONE); dirtyPollSet(); - clearProcessCreationThread(); break; case STATE_DONE: diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index d1c4933d81..334f1411af 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -69,11 +69,6 @@ public: const std::string &plugin_filename, bool debug); - // Creates a process - // returns true if process already exists or if created, - // false if failed to create - bool createPluginProcess(); - void idle(void); // returns true if the plugin is on its way to steady state @@ -168,15 +163,13 @@ private: bool accept(); - void clearProcessCreationThread(); - LLSocket::ptr_t mListenSocket; LLSocket::ptr_t mSocket; U32 mBoundPort; LLProcess::Params mProcessParams; LLProcessPtr mProcess; - LLThread *pProcessCreationThread; + bool mProcessCreationRequested = false; std::string mPluginFile; std::string mPluginDir; diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 3ad6d10336..38f4c92b09 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -30,18 +30,6 @@ add_executable(SLPlugin ${SLPlugin_SOURCE_FILES} ) -if (WINDOWS) -set_target_properties(SLPlugin - PROPERTIES - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\"" - ) -else () -set_target_properties(SLPlugin - PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist - ) -endif () - target_link_libraries(SLPlugin llplugin llmessage @@ -49,7 +37,20 @@ target_link_libraries(SLPlugin ll::pluginlibraries ) -if (DARWIN) +if (WINDOWS) + set_target_properties(SLPlugin + PROPERTIES + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\"" + ) +elseif (DARWIN) + set_target_properties(SLPlugin + PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_RPATH "@executable_path/../../../../Frameworks;@executable_path/../Frameworks;@executable_path/../Frameworks/plugins" + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist + XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym" + ) + # Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later) add_custom_command( TARGET SLPlugin POST_BUILD @@ -58,7 +59,7 @@ if (DARWIN) -p ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/SLPlugin.app/Contents/Frameworks ) -endif (DARWIN) +endif () if (BUILD_SHARED_LIBS) set_target_properties(SLPlugin PROPERTIES LINK_FLAGS_RELEASE @@ -66,12 +67,14 @@ if (BUILD_SHARED_LIBS) endif () if (INSTALL) - if (DARWIN) + if (DARWIN OR WINDOWS) install(TARGETS ${PROJECT_NAME} DESTINATION .) - else (DARWIN) + elseif (${LINUX_DISTRO} MATCHES arch) + install(TARGETS ${PROJECT_NAME} DESTINATION lib/${VIEWER_BINARY_NAME}) + else () install(TARGETS ${PROJECT_NAME} DESTINATION libexec/${VIEWER_BINARY_NAME}) - endif (DARWIN) -endif (INSTALL) + endif () +endif () if (LL_TESTS) ll_deploy_sharedlibs_command(SLPlugin) |
