summaryrefslogtreecommitdiff
path: root/indra/llplugin/slplugin
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
committerAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
commit1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch)
treeab243607f74f78200787bba5b9b88f07ef1b966f /indra/llplugin/slplugin
parent6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff)
parente1623bb276f83a43ce7a197e388720c05bdefe61 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts: # autobuild.xml # indra/cmake/CMakeLists.txt # indra/cmake/GoogleMock.cmake # indra/llaudio/llaudioengine_fmodstudio.cpp # indra/llaudio/llaudioengine_fmodstudio.h # indra/llaudio/lllistener_fmodstudio.cpp # indra/llaudio/lllistener_fmodstudio.h # indra/llaudio/llstreamingaudio_fmodstudio.cpp # indra/llaudio/llstreamingaudio_fmodstudio.h # indra/llcharacter/llmultigesture.cpp # indra/llcharacter/llmultigesture.h # indra/llimage/llimage.cpp # indra/llimage/llimagepng.cpp # indra/llimage/llimageworker.cpp # indra/llimage/tests/llimageworker_test.cpp # indra/llmessage/tests/llmockhttpclient.h # indra/llprimitive/llgltfmaterial.h # indra/llrender/llfontfreetype.cpp # indra/llui/llcombobox.cpp # indra/llui/llfolderview.cpp # indra/llui/llfolderviewmodel.h # indra/llui/lllineeditor.cpp # indra/llui/lllineeditor.h # indra/llui/lltextbase.cpp # indra/llui/lltextbase.h # indra/llui/lltexteditor.cpp # indra/llui/lltextvalidate.cpp # indra/llui/lltextvalidate.h # indra/llui/lluictrl.h # indra/llui/llview.cpp # indra/llwindow/llwindowmacosx.cpp # indra/newview/app_settings/settings.xml # indra/newview/llappearancemgr.cpp # indra/newview/llappearancemgr.h # indra/newview/llavatarpropertiesprocessor.cpp # indra/newview/llavatarpropertiesprocessor.h # indra/newview/llbreadcrumbview.cpp # indra/newview/llbreadcrumbview.h # indra/newview/llbreastmotion.cpp # indra/newview/llbreastmotion.h # indra/newview/llconversationmodel.h # indra/newview/lldensityctrl.cpp # indra/newview/lldensityctrl.h # indra/newview/llface.inl # indra/newview/llfloatereditsky.cpp # indra/newview/llfloatereditwater.cpp # indra/newview/llfloateremojipicker.h # indra/newview/llfloaterimsessiontab.cpp # indra/newview/llfloaterprofiletexture.cpp # indra/newview/llfloaterprofiletexture.h # indra/newview/llgesturemgr.cpp # indra/newview/llgesturemgr.h # indra/newview/llimpanel.cpp # indra/newview/llimpanel.h # indra/newview/llinventorybridge.cpp # indra/newview/llinventorybridge.h # indra/newview/llinventoryclipboard.cpp # indra/newview/llinventoryclipboard.h # indra/newview/llinventoryfunctions.cpp # indra/newview/llinventoryfunctions.h # indra/newview/llinventorygallery.cpp # indra/newview/lllistbrowser.cpp # indra/newview/lllistbrowser.h # indra/newview/llpanelobjectinventory.cpp # indra/newview/llpanelprofile.cpp # indra/newview/llpanelprofile.h # indra/newview/llpreviewgesture.cpp # indra/newview/llsavedsettingsglue.cpp # indra/newview/llsavedsettingsglue.h # indra/newview/lltooldraganddrop.cpp # indra/newview/llurllineeditorctrl.cpp # indra/newview/llvectorperfoptions.cpp # indra/newview/llvectorperfoptions.h # indra/newview/llviewerparceloverlay.cpp # indra/newview/llviewertexlayer.cpp # indra/newview/llviewertexturelist.cpp # indra/newview/macmain.h # indra/test/test.cpp
Diffstat (limited to 'indra/llplugin/slplugin')
-rw-r--r--indra/llplugin/slplugin/slplugin-objc.h10
-rw-r--r--indra/llplugin/slplugin/slplugin.cpp536
2 files changed, 273 insertions, 273 deletions
diff --git a/indra/llplugin/slplugin/slplugin-objc.h b/indra/llplugin/slplugin/slplugin-objc.h
index af0ebe1af2..b2e5c16ff0 100644
--- a/indra/llplugin/slplugin/slplugin-objc.h
+++ b/indra/llplugin/slplugin/slplugin-objc.h
@@ -7,21 +7,21 @@
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
@@ -37,7 +37,7 @@ class NSWindow;
class LLCocoaPlugin
{
-public:
+public:
LLCocoaPlugin();
void setupCocoa();
void createAutoReleasePool();
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index bf5e223181..2fe94a3387 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -1,268 +1,268 @@
-/**
- * @file slplugin.cpp
- * @brief Loader shell for plugins, intended to be launched by the plugin host application, which directly loads a plugin dynamic library.
- *
- * @cond
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- *
- * @endcond
- */
-
-
-#include "linden_common.h"
-
-#include "llpluginprocesschild.h"
-#include "llpluginmessage.h"
-#include "llerrorcontrol.h"
-#include "llapr.h"
-#include "llstring.h"
-
-#include <iostream>
-#include <fstream>
-using namespace std;
-
-
-#if LL_DARWIN
- #include "slplugin-objc.h"
-#endif
-
-#if LL_DARWIN || LL_LINUX
- #include <signal.h>
-#endif
-
-/*
- On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly or LSUIElement flag in the Info.plist.
-
- Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags:
-
- -sectcreate __TEXT __info_plist /path/to/slplugin_info.plist
-
- which means adding this to the gcc flags:
-
- -Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist
-
- Now that SLPlugin is a bundled app on the Mac, this is no longer necessary (it can just use a regular Info.plist file), but I'm leaving this comment in for posterity.
-*/
-
-#if LL_DARWIN || LL_LINUX
-// Signal handlers to make crashes not show an OS dialog...
-static void crash_handler(int sig)
-{
- // Just exit cleanly.
- // TODO: add our own crash reporting
- _exit(1);
-}
-#endif
-
-#if LL_WINDOWS
-#include <windows.h>
-////////////////////////////////////////////////////////////////////////////////
-// Our exception handler - will probably just exit and the host application
-// will miss the heartbeat and log the error in the usual fashion.
-LONG WINAPI myWin32ExceptionHandler( struct _EXCEPTION_POINTERS* exception_infop )
-{
- //std::cerr << "This plugin (" << __FILE__ << ") - ";
- //std::cerr << "intercepted an unhandled exception and will exit immediately." << std::endl;
-
- // TODO: replace exception handler before we exit?
- return EXCEPTION_EXECUTE_HANDLER;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Hook our exception handler and replace the system one
-void initExceptionHandler()
-{
- LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
-
- // save old exception handler in case we need to restore it at the end
- prev_filter = SetUnhandledExceptionFilter( myWin32ExceptionHandler );
-}
-
-bool checkExceptionHandler()
-{
- bool ok = true;
- LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
- prev_filter = SetUnhandledExceptionFilter(myWin32ExceptionHandler);
-
- if (prev_filter != myWin32ExceptionHandler)
- {
- LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with " << prev_filter << "!" << LL_ENDL;
- ok = false;
- }
-
- if (prev_filter == nullptr)
- {
- ok = false;
- if (nullptr == myWin32ExceptionHandler)
- {
- LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL;
- }
- else
- {
- LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with NULL!" << LL_ENDL;
- }
- }
-
- return ok;
-}
-#endif
-
-// If this application on Windows platform is a console application, a console is always
-// created which is bad. Making it a Windows "application" via CMake settings but not
-// adding any code to explicitly create windows does the right thing.
-#if LL_WINDOWS
-int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
-#else
-int main(int argc, char **argv)
-#endif
-{
-
- ll_init_apr();
-
- // Set up llerror logging
- {
- LLError::initForApplication(".",".");
- LLError::setDefaultLevel(LLError::LEVEL_INFO);
-// LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
-// LLError::logToFile("slplugin.log");
- }
-
-#if LL_WINDOWS
- if( strlen( lpCmdLine ) == 0 )
- {
- LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL;
- };
-
- U32 port = 0;
- if(!LLStringUtil::convertToU32(lpCmdLine, port))
- {
- LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
- };
-
- // Insert our exception handler into the system so this plugin doesn't
- // display a crash message if something bad happens. The host app will
- // see the missing heartbeat and log appropriately.
- initExceptionHandler();
-#elif LL_DARWIN || LL_LINUX
- if(argc < 2)
- {
- LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL;
- }
-
- U32 port = 0;
- if(!LLStringUtil::convertToU32(argv[1], port))
- {
- LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
- }
-
- // Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown.
- signal(SIGILL, &crash_handler); // illegal instruction
- signal(SIGFPE, &crash_handler); // floating-point exception
- signal(SIGBUS, &crash_handler); // bus error
- signal(SIGSEGV, &crash_handler); // segmentation violation
- signal(SIGSYS, &crash_handler); // non-existent system call invoked
-#endif
-# if LL_DARWIN
- signal(SIGEMT, &crash_handler); // emulate instruction executed
-
- LLCocoaPlugin cocoa_interface;
- cocoa_interface.setupCocoa();
- cocoa_interface.createAutoReleasePool();
-#endif //LL_DARWIN
-
- LLPluginProcessChild *plugin = new LLPluginProcessChild();
-
- plugin->init(port);
-
-#if LL_DARWIN
- cocoa_interface.deleteAutoReleasePool();
-#endif
-
- LLTimer timer;
- timer.start();
-
-#if LL_WINDOWS
- checkExceptionHandler();
-#endif
-
-#if LL_DARWIN
-
- // If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground.
- // Use this to track the current frontmost window and bring this process to the front if it changes.
- // cocoa_interface.mEventTarget = GetEventDispatcherTarget();
-#endif
- while(!plugin->isDone())
- {
-#if LL_DARWIN
- cocoa_interface.createAutoReleasePool();
-#endif
- timer.reset();
- plugin->idle();
-#if LL_DARWIN
- {
- cocoa_interface.processEvents();
- }
-#endif
- F64 elapsed = timer.getElapsedTimeF64();
- F64 remaining = plugin->getSleepTime() - elapsed;
-
- if(remaining <= 0.0)
- {
- // We've already used our full allotment.
-// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, not sleeping" << LL_ENDL;
-
- // Still need to service the network...
- plugin->pump();
- }
- else
- {
-
-// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL;
-// timer.reset();
-
- // This also services the network as needed.
- plugin->sleep(remaining);
-
-// LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" << LL_ENDL;
- }
-
-
-#if LL_WINDOWS
- // More agressive checking of interfering exception handlers.
- // Doesn't appear to be required so far - even for plugins
- // that do crash with a single call to the intercept
- // exception handler such as QuickTime.
- //checkExceptionHandler();
-#endif
-
-#if LL_DARWIN
- cocoa_interface.deleteAutoReleasePool();
-#endif
- }
- delete plugin;
-
- ll_cleanup_apr();
-
-
- return 0;
-}
+/**
+ * @file slplugin.cpp
+ * @brief Loader shell for plugins, intended to be launched by the plugin host application, which directly loads a plugin dynamic library.
+ *
+ * @cond
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ *
+ * @endcond
+ */
+
+
+#include "linden_common.h"
+
+#include "llpluginprocesschild.h"
+#include "llpluginmessage.h"
+#include "llerrorcontrol.h"
+#include "llapr.h"
+#include "llstring.h"
+
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+
+#if LL_DARWIN
+ #include "slplugin-objc.h"
+#endif
+
+#if LL_DARWIN || LL_LINUX
+ #include <signal.h>
+#endif
+
+/*
+ On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly or LSUIElement flag in the Info.plist.
+
+ Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags:
+
+ -sectcreate __TEXT __info_plist /path/to/slplugin_info.plist
+
+ which means adding this to the gcc flags:
+
+ -Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist
+
+ Now that SLPlugin is a bundled app on the Mac, this is no longer necessary (it can just use a regular Info.plist file), but I'm leaving this comment in for posterity.
+*/
+
+#if LL_DARWIN || LL_LINUX
+// Signal handlers to make crashes not show an OS dialog...
+static void crash_handler(int sig)
+{
+ // Just exit cleanly.
+ // TODO: add our own crash reporting
+ _exit(1);
+}
+#endif
+
+#if LL_WINDOWS
+#include <windows.h>
+////////////////////////////////////////////////////////////////////////////////
+// Our exception handler - will probably just exit and the host application
+// will miss the heartbeat and log the error in the usual fashion.
+LONG WINAPI myWin32ExceptionHandler( struct _EXCEPTION_POINTERS* exception_infop )
+{
+ //std::cerr << "This plugin (" << __FILE__ << ") - ";
+ //std::cerr << "intercepted an unhandled exception and will exit immediately." << std::endl;
+
+ // TODO: replace exception handler before we exit?
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Hook our exception handler and replace the system one
+void initExceptionHandler()
+{
+ LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
+
+ // save old exception handler in case we need to restore it at the end
+ prev_filter = SetUnhandledExceptionFilter( myWin32ExceptionHandler );
+}
+
+bool checkExceptionHandler()
+{
+ bool ok = true;
+ LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
+ prev_filter = SetUnhandledExceptionFilter(myWin32ExceptionHandler);
+
+ if (prev_filter != myWin32ExceptionHandler)
+ {
+ LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with " << prev_filter << "!" << LL_ENDL;
+ ok = false;
+ }
+
+ if (prev_filter == nullptr)
+ {
+ ok = false;
+ if (nullptr == myWin32ExceptionHandler)
+ {
+ LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with NULL!" << LL_ENDL;
+ }
+ }
+
+ return ok;
+}
+#endif
+
+// If this application on Windows platform is a console application, a console is always
+// created which is bad. Making it a Windows "application" via CMake settings but not
+// adding any code to explicitly create windows does the right thing.
+#if LL_WINDOWS
+int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
+#else
+int main(int argc, char **argv)
+#endif
+{
+
+ ll_init_apr();
+
+ // Set up llerror logging
+ {
+ LLError::initForApplication(".",".");
+ LLError::setDefaultLevel(LLError::LEVEL_INFO);
+// LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
+// LLError::logToFile("slplugin.log");
+ }
+
+#if LL_WINDOWS
+ if( strlen( lpCmdLine ) == 0 )
+ {
+ LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL;
+ };
+
+ U32 port = 0;
+ if(!LLStringUtil::convertToU32(lpCmdLine, port))
+ {
+ LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
+ };
+
+ // Insert our exception handler into the system so this plugin doesn't
+ // display a crash message if something bad happens. The host app will
+ // see the missing heartbeat and log appropriately.
+ initExceptionHandler();
+#elif LL_DARWIN || LL_LINUX
+ if(argc < 2)
+ {
+ LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL;
+ }
+
+ U32 port = 0;
+ if(!LLStringUtil::convertToU32(argv[1], port))
+ {
+ LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
+ }
+
+ // Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown.
+ signal(SIGILL, &crash_handler); // illegal instruction
+ signal(SIGFPE, &crash_handler); // floating-point exception
+ signal(SIGBUS, &crash_handler); // bus error
+ signal(SIGSEGV, &crash_handler); // segmentation violation
+ signal(SIGSYS, &crash_handler); // non-existent system call invoked
+#endif
+# if LL_DARWIN
+ signal(SIGEMT, &crash_handler); // emulate instruction executed
+
+ LLCocoaPlugin cocoa_interface;
+ cocoa_interface.setupCocoa();
+ cocoa_interface.createAutoReleasePool();
+#endif //LL_DARWIN
+
+ LLPluginProcessChild *plugin = new LLPluginProcessChild();
+
+ plugin->init(port);
+
+#if LL_DARWIN
+ cocoa_interface.deleteAutoReleasePool();
+#endif
+
+ LLTimer timer;
+ timer.start();
+
+#if LL_WINDOWS
+ checkExceptionHandler();
+#endif
+
+#if LL_DARWIN
+
+ // If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground.
+ // Use this to track the current frontmost window and bring this process to the front if it changes.
+ // cocoa_interface.mEventTarget = GetEventDispatcherTarget();
+#endif
+ while(!plugin->isDone())
+ {
+#if LL_DARWIN
+ cocoa_interface.createAutoReleasePool();
+#endif
+ timer.reset();
+ plugin->idle();
+#if LL_DARWIN
+ {
+ cocoa_interface.processEvents();
+ }
+#endif
+ F64 elapsed = timer.getElapsedTimeF64();
+ F64 remaining = plugin->getSleepTime() - elapsed;
+
+ if(remaining <= 0.0)
+ {
+ // We've already used our full allotment.
+// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, not sleeping" << LL_ENDL;
+
+ // Still need to service the network...
+ plugin->pump();
+ }
+ else
+ {
+
+// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL;
+// timer.reset();
+
+ // This also services the network as needed.
+ plugin->sleep(remaining);
+
+// LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" << LL_ENDL;
+ }
+
+
+#if LL_WINDOWS
+ // More agressive checking of interfering exception handlers.
+ // Doesn't appear to be required so far - even for plugins
+ // that do crash with a single call to the intercept
+ // exception handler such as QuickTime.
+ //checkExceptionHandler();
+#endif
+
+#if LL_DARWIN
+ cocoa_interface.deleteAutoReleasePool();
+#endif
+ }
+ delete plugin;
+
+ ll_cleanup_apr();
+
+
+ return 0;
+}