From 71e237a3f79cd90b432205460fe6e5c6b536d9db Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 10 Mar 2014 12:16:49 -0400 Subject: MAINT-3703 Suspected thread race crasher in fmodex library Two problems found in DLL involving threads. First, DllMain was reinitializing a critical section for all entry reasons (process attach, detach and thread attach, detach). Should only be done on process attach. Second, static container object was being modified and accessed without serialization. Added some double-check locking to the initialization path to reduce the total number of serialization calls made while making the code thread safe. --- indra/media_plugins/winmmshim/winmm_shim.cpp | 81 +++++++++++++++++----------- 1 file changed, 50 insertions(+), 31 deletions(-) (limited to 'indra') diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp index aac349bf57..49a1c9dba3 100755 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp +++ b/indra/media_plugins/winmmshim/winmm_shim.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2010-2014, 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 @@ -30,8 +30,8 @@ using std::wstring; -static float sVolumeLevel = 1.f; -static bool sMute = false; +static float sVolumeLevel = 1.f; // Could be covered by critical section, +static bool sMute = false; // not needed with atomicity and alignment. static CRITICAL_SECTION sCriticalSection; BOOL APIENTRY DllMain( HMODULE hModule, @@ -39,37 +39,44 @@ BOOL APIENTRY DllMain( HMODULE hModule, LPVOID lpReserved ) { - InitializeCriticalSection(&sCriticalSection); + if (DLL_PROCESS_ATTACH == ul_reason_for_call) + { + InitializeCriticalSection(&sCriticalSection); + } return TRUE; } void ll_winmm_shim_initialize(){ - static bool initialized = false; - // do this only once - EnterCriticalSection(&sCriticalSection); + static volatile bool initialized = false; + + // do this only once using double-check locking if (!initialized) - { // bind to original winmm.dll - TCHAR system_path[MAX_PATH]; - TCHAR dll_path[MAX_PATH]; - ::GetSystemDirectory(system_path, MAX_PATH); - - // grab winmm.dll from system path, where it should live - wsprintf(dll_path, "%s\\winmm.dll", system_path); - HMODULE winmm_handle = ::LoadLibrary(dll_path); - - if (winmm_handle != NULL) - { // we have a dll, let's get out pointers! - initialized = true; - init_function_pointers(winmm_handle); - ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); - } - else - { - // failed to initialize real winmm.dll - ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n"); + { + EnterCriticalSection(&sCriticalSection); + if (!initialized) + { // bind to original winmm.dll + TCHAR system_path[MAX_PATH]; + TCHAR dll_path[MAX_PATH]; + ::GetSystemDirectory(system_path, MAX_PATH); + + // grab winmm.dll from system path, where it should live + wsprintf(dll_path, "%s\\winmm.dll", system_path); + HMODULE winmm_handle = ::LoadLibrary(dll_path); + + if (winmm_handle != NULL) + { // we have a dll, let's get out pointers! + init_function_pointers(winmm_handle); + ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); + initialized = true; // Last thing after completing setup + } + else + { + // failed to initialize real winmm.dll + ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n"); + } } + LeaveCriticalSection(&sCriticalSection); } - LeaveCriticalSection(&sCriticalSection); } @@ -84,7 +91,7 @@ extern "C" int mBitsPerSample; }; typedef std::map wave_out_map_t; - static wave_out_map_t sWaveOuts; + static wave_out_map_t sWaveOuts; // Covered by sCriticalSection MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) { @@ -100,7 +107,9 @@ extern "C" && ((fdwOpen & WAVE_FORMAT_QUERY) == 0)) // not just querying for format support { // remember the requested bits per sample, and associate with the given handle WaveOutFormat* wave_outp = new WaveOutFormat(pwfx->wBitsPerSample); + EnterCriticalSection(&sCriticalSection); sWaveOuts.insert(std::make_pair(*phwo, wave_outp)); + LeaveCriticalSection(&sCriticalSection); } return result; } @@ -108,13 +117,15 @@ extern "C" MMRESULT WINAPI waveOutClose( HWAVEOUT hwo) { ll_winmm_shim_initialize(); + EnterCriticalSection(&sCriticalSection); wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); if (found_it != sWaveOuts.end()) { // forget what we know about this handle delete found_it->second; sWaveOuts.erase(found_it); } - return waveOutClose_orig( hwo); + LeaveCriticalSection(&sCriticalSection); + return waveOutClose_orig(hwo); } MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) @@ -128,11 +139,19 @@ extern "C" } else if (sVolumeLevel != 1.f) { // need to apply volume level + int bits_per_sample(0); + + EnterCriticalSection(&sCriticalSection); wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); if (found_it != sWaveOuts.end()) { - WaveOutFormat* formatp = found_it->second; - switch (formatp->mBitsPerSample){ + bits_per_sample = found_it->second->mBitsPerSample; + } + LeaveCriticalSection(&sCriticalSection); + if (bits_per_sample) + { + switch (bits_per_sample) + { case 8: { char volume = (char)(sVolumeLevel * 127.f); -- cgit v1.2.3 From 4f565ed077058cd3ce90ffd347c4a8346d734dbd Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 14 Mar 2014 19:48:35 -0400 Subject: Update fmodex to 4.44.31. Move DSP descriptor to heap storage. --- indra/cmake/FMODEX.cmake | 2 +- indra/llaudio/llaudioengine_fmodex.cpp | 23 +++++++++++++---------- indra/llaudio/llaudioengine_fmodex.h | 3 ++- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'indra') diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake index 65bc1cabeb..163260137b 100644 --- a/indra/cmake/FMODEX.cmake +++ b/indra/cmake/FMODEX.cmake @@ -39,7 +39,7 @@ if (FMODEX) optimized fmodex) endif (WINDOWS) set(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex) + set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/) endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) endif (STANDALONE) endif (FMODEX) diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index e9b74b8f41..71f5d47367 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, 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 @@ -320,8 +320,8 @@ void LLAudioEngine_FMODEX::shutdown() llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl; if ( mSystem ) // speculative fix for MAINT-2657 { - mSystem->close(); - mSystem->release(); + mSystem->close(); + mSystem->release(); } llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl; @@ -347,15 +347,14 @@ bool LLAudioEngine_FMODEX::initWind() if (!mWindDSP) { - FMOD_DSP_DESCRIPTION dspdesc; - memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero - strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit" - dspdesc.channels=2; - dspdesc.read = &windCallback; //Assign callback. - if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP")) + memset(&mWindDSPDesc, 0, sizeof(mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc.name, "Wind Unit", sizeof(mWindDSPDesc.name)); + mWindDSPDesc.channels = 2; + mWindDSPDesc.read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(&mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) return false; - if(mWindGen) + if (mWindGen) delete mWindGen; float frequency = 44100; @@ -364,6 +363,7 @@ bool LLAudioEngine_FMODEX::initWind() mWindDSP->setUserData((void*)mWindGen); } + // *TODO: Should this guard against multiple plays? if (mWindDSP) { mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0); @@ -741,6 +741,9 @@ void LLAudioChannelFMODEX::set3DMode(bool use3d) } } +// *NOTE: This is almost certainly being called on the mixer thread, +// not the main thread. May have implications for callees or audio +// engine shutdown. FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels) { diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h index 415a9ed0ef..ca9a6c0df0 100644 --- a/indra/llaudio/llaudioengine_fmodex.h +++ b/indra/llaudio/llaudioengine_fmodex.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, 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 @@ -74,6 +74,7 @@ protected: LLWindGen *mWindGen; + FMOD_DSP_DESCRIPTION mWindDSPDesc; FMOD::DSP *mWindDSP; FMOD::System *mSystem; bool mEnableProfiler; -- cgit v1.2.3 From c62d2cca2962f9847f844df137c21aa44edc2d75 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 14 Mar 2014 20:58:35 -0400 Subject: Additions & fixes for lib copy, use only forwarded ptrs in LLAE interfaces. Copy3rdPartyLibs needed to copy the now-corrected fmodexL libraries and it had a bad library reference on Linux for release. In llaudio land, the audio engine interfaces, even the fmodex specializations, seem to want to be external-structure free so use a forward declaration and pointer to FMOD_DSP_DESCRIPTION and deal with it in the ctor/dtor. --- indra/cmake/Copy3rdPartyLibs.cmake | 4 +++- indra/llaudio/llaudioengine_fmodex.cpp | 12 +++++++----- indra/llaudio/llaudioengine_fmodex.h | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 44c2d3ac27..f98e88b697 100755 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -64,6 +64,7 @@ if(WINDOWS) endif(USE_TCMALLOC) if (FMODEX) + set(debug_files ${debug_files} fmodexL.dll) set(release_files ${release_files} fmodex.dll) endif (FMODEX) @@ -294,7 +295,8 @@ elseif(LINUX) endif (USE_TCMALLOC) if (FMODEX) - set(release_file ${release_files} "libfmodex.so") + set(debug_files ${debug_files} "libfmodexL.so") + set(release_files ${release_files} "libfmodex.so") endif (FMODEX) else(WINDOWS) diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 71f5d47367..36e8044a25 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -55,11 +55,13 @@ LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler) mWindDSP = NULL; mSystem = NULL; mEnableProfiler = enable_profiler; + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); } LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX() { + delete mWindDSPDesc; } @@ -347,11 +349,11 @@ bool LLAudioEngine_FMODEX::initWind() if (!mWindDSP) { - memset(&mWindDSPDesc, 0, sizeof(mWindDSPDesc)); //Set everything to zero - strncpy(mWindDSPDesc.name, "Wind Unit", sizeof(mWindDSPDesc.name)); - mWindDSPDesc.channels = 2; - mWindDSPDesc.read = &windCallback; // Assign callback - may be called from arbitrary threads - if (Check_FMOD_Error(mSystem->createDSP(&mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->channels = 2; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) return false; if (mWindGen) diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h index ca9a6c0df0..ca389d489f 100644 --- a/indra/llaudio/llaudioengine_fmodex.h +++ b/indra/llaudio/llaudioengine_fmodex.h @@ -41,6 +41,7 @@ namespace FMOD class Sound; class DSP; } +typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; //Interfaces class LLAudioEngine_FMODEX : public LLAudioEngine @@ -74,7 +75,7 @@ protected: LLWindGen *mWindGen; - FMOD_DSP_DESCRIPTION mWindDSPDesc; + FMOD_DSP_DESCRIPTION *mWindDSPDesc; FMOD::DSP *mWindDSP; FMOD::System *mSystem; bool mEnableProfiler; -- cgit v1.2.3 From 0bc8e67ebb969888364395b8ceea02393d14e9f5 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Sat, 15 Mar 2014 18:18:58 -0400 Subject: Mac Debug build is functional with this manifest change --- indra/newview/viewer_manifest.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index fe0774b409..f7b3a45e8d 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -7,7 +7,7 @@ $LicenseInfo:firstyear=2006&license=viewerlgpl$ Second Life Viewer Source Code -Copyright (C) 2006-2011, Linden Research, Inc. +Copyright (C) 2006-2014, 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 @@ -749,7 +749,6 @@ class Darwin_i386_Manifest(ViewerManifest): "libcollada14dom.dylib", "libexpat.1.5.2.dylib", "libexception_handler.dylib", - "libfmodex.dylib", "libGLOD.dylib", ): dylibs += path_optional(os.path.join(libdir, libfile), libfile) @@ -765,6 +764,20 @@ class Darwin_i386_Manifest(ViewerManifest): 'SLVoice', ): self.path2basename(libdir, libfile) + + # dylibs that vary based on configuration + if self.args['configuration'].lower() == 'debug': + for libfile in ( + "libfmodexL.dylib", + ): + dylibs += path_optional(os.path.join("../packages/lib/debug", + libfile), libfile) + else: + for libfile in ( + "libfmodex.dylib", + ): + dylibs += path_optional(os.path.join("../packages/lib/release", + libfile), libfile) # our apps for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), -- cgit v1.2.3 From cb2bd577099f87881d467249cac679200bb367f0 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 17 Mar 2014 14:59:49 -0700 Subject: ACME-1376 : Take the location checkbox out of the photo panel --- indra/newview/llfloatersocial.cpp | 22 ---------------------- indra/newview/llfloatersocial.h | 1 - .../skins/default/xui/en/panel_social_photo.xml | 8 -------- 3 files changed, 31 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatersocial.cpp b/indra/newview/llfloatersocial.cpp index 9490769d8c..e8c6b179cf 100644 --- a/indra/newview/llfloatersocial.cpp +++ b/indra/newview/llfloatersocial.cpp @@ -170,7 +170,6 @@ mRefreshBtn(NULL), mWorkingLabel(NULL), mThumbnailPlaceholder(NULL), mCaptionTextBox(NULL), -mLocationCheckbox(NULL), mPostButton(NULL) { mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLSocialPhotoPanel::onSend, this)); @@ -196,7 +195,6 @@ BOOL LLSocialPhotoPanel::postBuild() mWorkingLabel = getChild("working_lbl"); mThumbnailPlaceholder = getChild("thumbnail_placeholder"); mCaptionTextBox = getChild("photo_caption"); - mLocationCheckbox = getChild("add_location_cb"); mPostButton = getChild("post_photo_btn"); mCancelButton = getChild("cancel_photo_btn"); @@ -213,7 +211,6 @@ void LLSocialPhotoPanel::draw() mCaptionTextBox->setEnabled(no_ongoing_connection); mResolutionComboBox->setEnabled(no_ongoing_connection); mRefreshBtn->setEnabled(no_ongoing_connection); - mLocationCheckbox->setEnabled(no_ongoing_connection); // Display the preview if one is available if (previewp && previewp->getThumbnailImage()) @@ -343,25 +340,6 @@ void LLSocialPhotoPanel::sendPhoto() // Get the caption std::string caption = mCaptionTextBox->getValue().asString(); - // Add the location if required - bool add_location = mLocationCheckbox->getValue().asBoolean(); - if (add_location) - { - // Get the SLURL for the location - LLSLURL slurl; - LLAgentUI::buildSLURL(slurl); - std::string slurl_string = slurl.getSLURLString(); - - // Add query parameters so Google Analytics can track incoming clicks! - slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS; - - // Add it to the caption (pretty crude, but we don't have a better option with photos) - if (caption.empty()) - caption = slurl_string; - else - caption = caption + " " + slurl_string; - } - // Get the image LLSnapshotLivePreview* previewp = getPreviewView(); diff --git a/indra/newview/llfloatersocial.h b/indra/newview/llfloatersocial.h index bbe07c9704..309f015ce9 100644 --- a/indra/newview/llfloatersocial.h +++ b/indra/newview/llfloatersocial.h @@ -85,7 +85,6 @@ private: LLUICtrl * mWorkingLabel; LLUICtrl * mThumbnailPlaceholder; LLUICtrl * mCaptionTextBox; - LLUICtrl * mLocationCheckbox; LLUICtrl * mPostButton; LLUICtrl* mCancelButton; }; diff --git a/indra/newview/skins/default/xui/en/panel_social_photo.xml b/indra/newview/skins/default/xui/en/panel_social_photo.xml index a55613b52a..c79a246d9d 100644 --- a/indra/newview/skins/default/xui/en/panel_social_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_social_photo.xml @@ -113,14 +113,6 @@ type="string" word_wrap="true"> - Date: Mon, 24 Mar 2014 14:20:14 -0400 Subject: increment viewer version to 3.7.5 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 0833a98f14..aaf18d2948 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.4 +3.7.5 -- cgit v1.2.3