From da44cca16ef01c7adaac1f55b8a144ceffe7bf12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 19 Apr 2023 20:37:34 -0300 Subject: [PATCH] eepp: mojoAL is now used by default. ecode: Tentative fix for a segfaul when accesing an LSP Server that isn't running anymore. --- .ecode/project_build.json | 2 +- .github/workflows/eepp-linux-build-check.yml | 2 +- .github/workflows/eepp-macos-build-check.yml | 2 +- .../workflows/eepp-windows-build-check.yml | 2 +- README.md | 17 +++++++------- premake4.lua | 23 +++++++++++++------ premake5.lua | 19 +++++++++++---- projects/haiku/ecode/build.app.sh | 2 +- projects/linux/ecode/build.app.sh | 2 +- projects/linux/ee.creator.user | 16 ++++++------- projects/macos/ecode/cross.build.app.sh | 2 +- projects/macos/make_no_fw.sh | 2 +- projects/mingw32/make.sh | 2 +- .../ecode/plugins/lsp/lspclientserver.cpp | 17 +++++++++++--- .../ecode/plugins/lsp/lspclientserver.hpp | 4 ++++ .../plugins/lsp/lspclientservermanager.cpp | 11 +++++++++ .../plugins/lsp/lspclientservermanager.hpp | 2 ++ .../ecode/plugins/lsp/lspdocumentclient.cpp | 8 +++++-- .../ecode/plugins/lsp/lspdocumentclient.hpp | 2 ++ src/tools/ecode/projectbuild.hpp | 2 +- 20 files changed, 95 insertions(+), 44 deletions(-) diff --git a/.ecode/project_build.json b/.ecode/project_build.json index 0fcb4f5eb..1fd345583 100644 --- a/.ecode/project_build.json +++ b/.ecode/project_build.json @@ -2,7 +2,7 @@ "ecode": { "build": [ { - "args": "--with-mojoal --with-debug-symbols gmake", + "args": "--with-debug-symbols gmake", "command": "premake4", "working_dir": "${project_root}" }, diff --git a/.github/workflows/eepp-linux-build-check.yml b/.github/workflows/eepp-linux-build-check.yml index e7dda8910..2de432d09 100644 --- a/.github/workflows/eepp-linux-build-check.yml +++ b/.github/workflows/eepp-linux-build-check.yml @@ -31,6 +31,6 @@ jobs: tar xvzf premake-5.0.0-beta1-linux.tar.gz - name: Build run: | - ./premake5 --with-mojoal gmake2 + ./premake5 gmake2 cd make/linux make all -j$(nproc) diff --git a/.github/workflows/eepp-macos-build-check.yml b/.github/workflows/eepp-macos-build-check.yml index 5973591ae..423b5e22d 100644 --- a/.github/workflows/eepp-macos-build-check.yml +++ b/.github/workflows/eepp-macos-build-check.yml @@ -21,5 +21,5 @@ jobs: tar -xzf premake-5.0.0-beta1-macosx.tar.gz - name: Build run: | - ./premake5 --with-mojoAL gmake2 + ./premake5 gmake2 make -C make/macosx/ all diff --git a/.github/workflows/eepp-windows-build-check.yml b/.github/workflows/eepp-windows-build-check.yml index 1ad4efb47..7e12351ca 100644 --- a/.github/workflows/eepp-windows-build-check.yml +++ b/.github/workflows/eepp-windows-build-check.yml @@ -23,7 +23,7 @@ jobs: - name: Create project shell: powershell run: | - ./premake5.exe --windows-vc-build --with-mojoal vs2022 + ./premake5.exe --windows-vc-build vs2022 - name: Build shell: cmd run: | diff --git a/README.md b/README.md index 1e4fdfd3a..e87e6b272 100644 --- a/README.md +++ b/README.md @@ -365,17 +365,16 @@ Note: Please use a modern browser with good WebGL and WASM support (Chrome/ium 7 ## How to build it -The library has very few external dependencies. Most of the time you will only -need **SDL2** and **OpenAL** libraries with the headers installed. Also -**premake4** or **premake5** is needed to generate the Makefiles or project +The library has only one external dependency. You will only need **SDL2** library with the headers +installed. Also **premake4** or **premake5** is needed to generate the Makefiles or project files to build the library. I will assume that you know what you are doing and skip the basics. -Notice: OpenAL is not strictly necessary. If you want to avoid it, you -have the alternative to use [mojoAL](https://icculus.org/mojoAL/). The latter -is already integrated to the library but not enabled by default. To enable it -and disable the OpenAL dependency you need to add the parameter `--with-mojoal` -to any `premake` call ( ex: `premake5 --with-mojoal gmake2` ). +Notice: eepp uses [mojoAL](https://icculus.org/mojoAL/) by default as an OpenAL drop-in replacement. +OpenAL is optionally available as an audio backend. If you want to use it, you +have the alternative to enable it. To enable it and disable the mojoAL drop-in replacemente, you +need to add the parameter `--without-mojoal` to any `premake` call +( ex: `premake5 --without-mojoal gmake2` ). ### GNU/Linux @@ -424,7 +423,7 @@ If you are very new to programming there's an alternative to build the project without external dependencies, in order to do that you need to generate the project files with the command: -`premake5.exe --windows-vc-build --with-mojoal vs2022` +`premake5.exe --windows-vc-build vs2022` Then just build the solution in Visual Studio or run `MSBuild` manually in a console: diff --git a/premake4.lua b/premake4.lua index 55e01f4c4..e7705de59 100644 --- a/premake4.lua +++ b/premake4.lua @@ -158,12 +158,13 @@ newoption { trigger = "with-static-eepp", description = "Force to build the demo newoption { trigger = "with-static-backend", description = "It will try to compile the library with a static backend (only for gcc and mingw).\n\t\t\t\tThe backend should be placed in libs/your_platform/libYourBackend.a" } newoption { trigger = "with-gles2", description = "Compile with GLES2 support" } newoption { trigger = "with-gles1", description = "Compile with GLES1 support" } -newoption { trigger = "with-mojoal", description = "Compile with mojoAL as OpenAL implementation instead of using openal-soft (requires SDL2 backend)" } +newoption { trigger = "without-mojoal", description = "Compile without mojoAL as OpenAL implementation (that requires SDL2 backend). Instead it will use openal-soft." } newoption { trigger = "use-frameworks", description = "In macOS it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link agains SDL2.framework." } newoption { trigger = "with-emscripten-pthreads", description = "Enables emscripten build to use posix threads" } newoption { trigger = "with-mold-linker", description = "Tries to use the mold linker instead of the default linker of the toolchain" } newoption { trigger = "with-debug-symbols", description = "Release builds are built with debug symbols." } newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanitizer." } +newoption { trigger = "address-sanitizer", description = "Compile with AddressSanitizer." } newoption { trigger = "with-backend", description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.", @@ -646,7 +647,7 @@ function generate_os_links() if os.is_real("linux") then multiple_insert( os_links, { "rt", "pthread", "GL" } ) - if not _OPTIONS["with-mojoal"] then + if _OPTIONS["without-mojoal"] then table.insert( os_links, "openal" ) end @@ -669,12 +670,12 @@ function generate_os_links() multiple_insert( os_links, { "OpenGLES.framework", "AudioToolbox.framework", "CoreAudio.framework", "Foundation.framework", "CoreFoundation.framework", "UIKit.framework", "QuartzCore.framework", "CoreGraphics.framework", "CoreMotion.framework", "AVFoundation.framework", "GameController.framework" } ) end - if not _OPTIONS["with-mojoal"] then + if _OPTIONS["without-mojoal"] then if os.is_real("linux") or os.is_real("freebsd") or os.is_real("haiku") or os.is_real("emscripten") then multiple_insert( os_links, { "openal" } ) elseif os.is_real("windows") or os.is_real("mingw32") or os.is_real("mingw64") then if os_ishost("msys") then - multiple_insert( os_links, { "openal" } ) + multiple_insert( os_links, { "openal" } ) else multiple_insert( os_links, { "OpenAL32" } ) end @@ -700,6 +701,14 @@ function parse_args() links { "tsan" } end end + + if _OPTIONS["address-sanitizer"] then + buildoptions { "-fsanitize=address" } + linkoptions { "-fsanitize=address" } + if not os.is_real("macosx") then + links { "asan" } + end + end end function add_static_links() @@ -726,7 +735,7 @@ function add_static_links() "vorbis-static" } - if _OPTIONS["with-mojoal"] then + if not _OPTIONS["without-mojoal"] then links { "mojoal-static"} end @@ -904,7 +913,7 @@ end function build_eepp( build_name ) includedirs { "include", "src", "src/thirdparty", "include/eepp/thirdparty", "src/thirdparty/freetype2/include", "src/thirdparty/zlib", "src/thirdparty/libogg/include", "src/thirdparty/libvorbis/include", "src/thirdparty/mbedtls/include" } - if _OPTIONS["with-mojoal"] then + if not _OPTIONS["without-mojoal"] then defines( "AL_LIBTYPE_STATIC" ) includedirs { "src/thirdparty/mojoAL" } end @@ -1107,7 +1116,7 @@ solution "eepp" files { "src/thirdparty/imageresampler/*.cpp" } build_base_cpp_configuration( "imageresampler" ) - if _OPTIONS["with-mojoal"] then + if not _OPTIONS["without-mojoal"] then project "mojoal-static" kind "StaticLib" language "C" diff --git a/premake5.lua b/premake5.lua index 76a679e8d..874bc1489 100644 --- a/premake5.lua +++ b/premake5.lua @@ -4,14 +4,15 @@ newoption { trigger = "with-static-eepp", description = "Force to build the demo newoption { trigger = "with-static-backend", description = "It will try to compile the library with a static backend (only for gcc and mingw).\n\t\t\t\tThe backend should be placed in libs/your_platform/libYourBackend.a" } newoption { trigger = "with-gles2", description = "Compile with GLES2 support" } newoption { trigger = "with-gles1", description = "Compile with GLES1 support" } -newoption { trigger = "with-mojoal", description = "Compile with mojoAL as OpenAL implementation instead of using openal-soft (requires SDL2 backend)" } +newoption { trigger = "without-mojoal", description = "Compile without mojoAL as OpenAL implementation (that requires SDL2 backend). Instead it will use openal-soft." } newoption { trigger = "use-frameworks", description = "In macOS it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link against SDL2.framework." } newoption { trigger = "windows-vc-build", description = "This is used to build the framework in Visual Studio downloading its external dependencies and making them available to the VS project without having to install them manually." } newoption { trigger = "windows-mingw-build", description = "This is used to build the framework with mingw downloading its external dependencies." } newoption { trigger = "with-emscripten-pthreads", description = "Enables emscripten build to use posix threads" } newoption { trigger = "with-mold-linker", description = "Tries to use the mold linker instead of the default linker of the toolchain" } newoption { trigger = "with-debug-symbols", description = "Release builds are built with debug symbols." } -newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanitizer." } +newoption { trigger = "thread-sanitizer", description = "Compile with ThreadSanitizer." } +newoption { trigger = "address-sanitizer", description = "Compile with AddressSanitizer." } newoption { trigger = "with-backend", description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.", @@ -411,7 +412,7 @@ function generate_os_links() multiple_insert( os_links, { "GLESv1_CM", "GLESv2", "log" } ) end - if not _OPTIONS["with-mojoal"] then + if _OPTIONS["without-mojoal"] then if os.istarget("linux") or os.istarget("bsd") or os.istarget("haiku") or os.istarget("emscripten") then multiple_insert( os_links, { "openal" } ) elseif os.istarget("windows") or os.istarget("mingw32") then @@ -442,6 +443,14 @@ function parse_args() links { "tsan" } end end + + if _OPTIONS["address-sanitizer"] then + buildoptions { "-fsanitize=address" } + linkoptions { "-fsanitize=address" } + if not os.istarget("macosx") then + links { "asan" } + end + end end function add_static_links() @@ -469,7 +478,7 @@ function add_static_links() "vorbis-static" } - if _OPTIONS["with-mojoal"] then + if not _OPTIONS["without-mojoal"] then links { "mojoal-static"} end @@ -689,7 +698,7 @@ function build_eepp( build_name ) files { "src/eepp/system/platform/posix/*.cpp" } files { "src/eepp/network/platform/unix/*.cpp" } - filter "options:with-mojoal" + filter "options:not without-mojoal" defines( "AL_LIBTYPE_STATIC" ) incdirs { "src/thirdparty/mojoAL" } diff --git a/projects/haiku/ecode/build.app.sh b/projects/haiku/ecode/build.app.sh index f8feccb1c..2e21946b0 100755 --- a/projects/haiku/ecode/build.app.sh +++ b/projects/haiku/ecode/build.app.sh @@ -3,7 +3,7 @@ CANONPATH=$(readlink -f "$0") DIRPATH="$(dirname "$CANONPATH")" cd "$DIRPATH" || exit cd ../../../ || exit -premake5 --with-mojoal gmake2 +premake5 gmake2 cd make/haiku || exit make -j"$(nproc)" config=release_x86_64 ecode cd "$DIRPATH" || exit diff --git a/projects/linux/ecode/build.app.sh b/projects/linux/ecode/build.app.sh index 82a048e7e..8a60530f8 100755 --- a/projects/linux/ecode/build.app.sh +++ b/projects/linux/ecode/build.app.sh @@ -18,7 +18,7 @@ for i in "$@"; do ;; esac done -premake4 "$DEBUG_SYMBOLS" --with-mojoal gmake +premake4 "$DEBUG_SYMBOLS" gmake cd make/linux || exit make -j"$(nproc)" config=release ecode cd "$DIRPATH" || exit diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 27a61ad95..32b60ea29 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -108,7 +108,7 @@ Desktop Desktop {388e5431-b31b-42b3-b9ad-9002d279d75d} - 13 + 10 0 19 @@ -187,7 +187,7 @@ true - --with-mojoal --with-mold-linker --with-static-eepp gmake + gmake premake4 %{buildDir}../../../ ProjectExplorer.ProcessStep @@ -229,7 +229,7 @@ true - --with-debug-symbols --with-mold-linker --with-mojoal gmake + --with-debug-symbols gmake premake4 %{buildDir}../../../ ProjectExplorer.ProcessStep @@ -1103,11 +1103,11 @@ 2 - %{buildDir}../../../bin/eepp-UIEditor-debug + %{buildDir}/../../bin/eepp-UIEditor-debug eepp-UIEditor-debug ProjectExplorer.CustomExecutableRunConfiguration - -u + -u --xml=/home/downloads/build_settings.xml true false false @@ -1201,7 +1201,7 @@ 2 - %{buildDir}../../../bin/ecode-debug + %{buildDir}/../../bin/ecode-debug ecode-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1210,7 +1210,7 @@ false false false - %{buildDir}../../../bin/ + %{buildDir}/../../bin dwarf diff --git a/projects/macos/ecode/cross.build.app.sh b/projects/macos/ecode/cross.build.app.sh index 0504f4244..32356baba 100755 --- a/projects/macos/ecode/cross.build.app.sh +++ b/projects/macos/ecode/cross.build.app.sh @@ -1,5 +1,5 @@ #!/bin/sh -premake5 --file=../../../premake5.lua --with-mojoal --use-frameworks gmake2 || exit +premake5 --file=../../../premake5.lua --use-frameworks gmake2 || exit make -C ../../../make/macosx/ -j$(nproc) -e verbose=true -e config=release_arm64 ecode || exit rm -rf ./ecode.app mkdir -p ecode.app/Contents/MacOS/ diff --git a/projects/macos/make_no_fw.sh b/projects/macos/make_no_fw.sh index ee43acff9..b8f35e067 100755 --- a/projects/macos/make_no_fw.sh +++ b/projects/macos/make_no_fw.sh @@ -1,6 +1,6 @@ #!/bin/sh cd $(dirname "$0") -premake4 --file=../../premake4.lua --with-mojoal gmake +premake4 --file=../../premake4.lua gmake cd ../../make/macosx/ sed -e "s/-Wl,-x//g" -i .make diff --git a/projects/mingw32/make.sh b/projects/mingw32/make.sh index a809826cd..383eef655 100755 --- a/projects/mingw32/make.sh +++ b/projects/mingw32/make.sh @@ -17,7 +17,7 @@ if [[ "$CONFIG" == *"x86_64"* ]]; then ARCH=64 fi -premake5 --file=../../premake5.lua --os=windows --cc=mingw --with-mojoal --windows-mingw-build gmake2 +premake5 --file=../../premake5.lua --os=windows --cc=mingw --windows-mingw-build gmake2 cd ../../make/windows/ || exit mingw"$ARCH"-make "$@" diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index 93973a079..90e7db443 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -1321,6 +1321,18 @@ LSPClientServer::LSPRequestHandle LSPClientServer::send( const json& msg, const return LSPRequestHandle(); } +LSPClientServer::LSPRequestHandle LSPClientServer::sendSync( const json& msg, + const JsonReplyHandler& h, + const JsonReplyHandler& eh ) { + if ( isRunning() ) { + return write( msg, h, eh ); + } else { + Log::debug( "LSPClientServer server %s Send for non-running server: %s", mLSP.name.c_str(), + mLSP.name.c_str() ); + } + return LSPRequestHandle(); +} + LSPClientServer::LSPRequestHandle LSPClientServer::didOpen( const URI& document, const std::string& text, int version ) { auto params = textDocumentParams( textDocumentItem( document, mLSP.language, text, version ) ); @@ -2028,10 +2040,9 @@ void LSPClientServer::shutdown() { if ( mReady ) { Log::info( "LSPClientServer:shutdown: %s", mLSP.name.c_str() ); mHandlers.clear(); - sendAsync( newRequest( "shutdown" ) ); + sendSync( newRequest( "shutdown" ) ); Sys::sleep( Milliseconds( 10 ) ); - sendAsync( newRequest( "exit" ) ); - Sys::sleep( Milliseconds( 50 ) ); + sendSync( newRequest( "exit" ) ); mReady = false; } } diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.hpp b/src/tools/ecode/plugins/lsp/lspclientserver.hpp index b25d89731..55598deec 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.hpp @@ -282,6 +282,10 @@ class LSPClientServer { bool socketConnect(); void socketInitialize(); + + LSPClientServer::LSPRequestHandle sendSync( const json& msg, + const JsonReplyHandler& h = nullptr, + const JsonReplyHandler& eh = nullptr ); }; } // namespace ecode diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp index a57af9358..fb7f6c80a 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp @@ -199,6 +199,17 @@ void LSPClientServerManager::renameSymbol( const URI& uri, const TextPosition& p } ); } +bool LSPClientServerManager::isServerRunning( const LSPClientServer* server ) { + for ( const auto& svr : mClients ) { + if ( server == svr.second.get() ) { + if ( mErasingClients.find( svr.first ) != mErasingClients.end() ) + return false; + return true; + } + } + return false; +} + void LSPClientServerManager::run( const std::shared_ptr& doc ) { mThreadPool->run( [&, doc]() { tryRunServer( doc ); } ); } diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp index dcdee192b..ea699c483 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp @@ -94,6 +94,8 @@ class LSPClientServerManager { void renameSymbol( const URI& uri, const TextPosition& pos, const std::string& newName ); + bool isServerRunning( const LSPClientServer* server ); + protected: friend class LSPClientServer; PluginManager* mPluginManager{ nullptr }; diff --git a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp index 023fd8dd3..493ded3d9 100644 --- a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp +++ b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp @@ -13,7 +13,7 @@ using namespace EE::System; namespace ecode { LSPDocumentClient::LSPDocumentClient( LSPClientServer* server, TextDocument* doc ) : - mServer( server ), mDoc( doc ) { + mServer( server ), mServerManager( server->getManager() ), mDoc( doc ) { refreshTag(); notifyOpen(); requestSymbolsDelayed(); @@ -63,7 +63,11 @@ void LSPDocumentClient::onDocumentSaved( TextDocument* ) { void LSPDocumentClient::onDocumentClosed( TextDocument* ) { URI uri = mDoc->getURI(); LSPClientServer* server = mServer; - mServer->getThreadPool()->run( [server, uri]() { server->didClose( uri ); } ); + LSPClientServerManager* manager = mServerManager; + mServer->getThreadPool()->run( [server, manager, uri]() { + if ( manager->isServerRunning( server ) ) + server->didClose( uri ); + } ); mServer->removeDoc( mDoc ); } diff --git a/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp b/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp index 10aa5455d..8de4db3bc 100644 --- a/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp +++ b/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp @@ -18,6 +18,7 @@ class UISceneNode; namespace ecode { class LSPClientServer; +class LSPClientServerManager; class LSPDocumentClient : public TextDocument::Client { public: @@ -50,6 +51,7 @@ class LSPDocumentClient : public TextDocument::Client { protected: LSPClientServer* mServer{ nullptr }; + LSPClientServerManager* mServerManager{ nullptr }; TextDocument* mDoc{ nullptr }; String::HashType mTag{ 0 }; String::HashType mTagSemanticTokens{ 0 }; diff --git a/src/tools/ecode/projectbuild.hpp b/src/tools/ecode/projectbuild.hpp index 544f410e6..90bd2808f 100644 --- a/src/tools/ecode/projectbuild.hpp +++ b/src/tools/ecode/projectbuild.hpp @@ -26,7 +26,7 @@ class StatusBuildOutputController; "ecode": { "build": [ { - "args": "--with-mojoal --with-debug-symbols gmake", + "args": "--with-debug-symbols gmake", "command": "premake4", "working_dir": "${project_root}" },