--- ucb/source/ucp/webdav/NeonHeadRequest.cxx 2010-09-27 11:08:46.000000000 +0100 +++ ucb/source/ucp/webdav/NeonHeadRequest.cxx 2010-09-27 13:21:17.000000000 +0100 @@ -156,6 +156,8 @@ // Constructor // ------------------------------------------------------------------- +extern osl::Mutex aGlobalNeonMutex; + NeonHeadRequest::NeonHeadRequest( HttpSession* inSession, const rtl::OUString & inPath, const std::vector< ::rtl::OUString > & @@ -179,7 +181,10 @@ ne_add_response_header_catcher( req, NHR_ResponseHeaderCatcher, &aCtx ); #endif - nError = ne_request_dispatch( req ); + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + nError = ne_request_dispatch( req ); + } #if NEON_VERSION >= 0x0250 process_headers(req, ioResource, inHeaderNames); --- ucb/source/ucp/webdav/NeonSession.cxx 2010-09-27 11:08:46.000000000 +0100 +++ ucb/source/ucp/webdav/NeonSession.cxx 2010-09-27 13:26:01.000000000 +0100 @@ -121,7 +121,12 @@ // ------------------------------------------------------------------- // static members! bool NeonSession::m_bGlobalsInited = false; -osl::Mutex NeonSession::m_aGlobalMutex; +//See https://bugzilla.redhat.com/show_bug.cgi?id=544619#c4 +//neon is threadsafe, but uses gnutls which is only thread-safe +//if initialized to be thread-safe. cups, unfortunately, generally +//initializes it first, and as non-thread-safe, leaving the entire +//stack unsafe +osl::Mutex aGlobalNeonMutex; // ------------------------------------------------------------------- // Helper fuction // ------------------------------------------------------------------- @@ -668,7 +673,10 @@ { if ( m_pHttpSession ) { - ne_session_destroy( m_pHttpSession ); + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + ne_session_destroy( m_pHttpSession ); + } m_pHttpSession = 0; // Note: Uncomment the following if locking support is required /* @@ -694,11 +702,7 @@ if ( m_pHttpSession == 0 ) { // Ensure that Neon sockets are initialize - - // --> tkr #151111# crashed if copy and pasted pictures from the internet - // ne_sock_init() was executed by two threads at the same time. - osl::Guard< osl::Mutex > theGlobalGuard( m_aGlobalMutex ); - // <-- + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); if ( !m_bGlobalsInited ) { if ( ne_sock_init() != 0 ) @@ -733,7 +737,10 @@ m_nProxyPort = rProxyCfg.nPort; // new session needed, destroy old first - ne_session_destroy( m_pHttpSession ); + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + ne_session_destroy( m_pHttpSession ); + } m_pHttpSession = 0; bCreateNewSession = true; } @@ -746,15 +753,16 @@ // currently (0.22.0) neon does not allow to pass the user info // to the session - m_pHttpSession = ne_session_create( - rtl::OUStringToOString( m_aScheme, - RTL_TEXTENCODING_UTF8 ).getStr(), - /* theUri.GetUserInfo(), - @@@ for FTP via HTTP proxy, but not supported by Neon */ - rtl::OUStringToOString( m_aHostName, - RTL_TEXTENCODING_UTF8 ).getStr(), - m_nPort ); - + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + m_pHttpSession = ne_session_create( + rtl::OUStringToOString( m_aScheme, RTL_TEXTENCODING_UTF8 ).getStr(), + /* theUri.GetUserInfo(), + @@@ for FTP via HTTP proxy, but not supported by Neon */ + rtl::OUStringToOString( m_aHostName, RTL_TEXTENCODING_UTF8 ).getStr(), + m_nPort ); + } + if ( m_pHttpSession == 0 ) throw DAVException( DAVException::DAV_SESSION_CREATE, NeonUri::makeConnectionEndPointString( @@ -1319,11 +1327,11 @@ void NeonSession::ABORT() throw ( DAVException ) { - // 11.11.09 (tkr): The following code lines causing crashes if closing a ongoing connection. It turned out that this existing solution doesn't work in multi-threading environments. - // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3. - - //if (NULL !=m_pHttpSession) - // ne_close_connection(m_pHttpSession); + if ( m_pHttpSession ) + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + ne_close_connection( m_pHttpSession ); + } } // ------------------------------------------------------------------- @@ -1706,7 +1714,10 @@ #endif ne_add_response_body_reader( req, ne_accept_2xx, reader, userdata ); - ret = ne_request_dispatch( req ); + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + ret = ne_request_dispatch( req ); + } #if NEON_VERSION >= 0x0250 if ( getheaders ) @@ -1744,7 +1755,10 @@ ne_set_request_body_buffer( req, buffer, size ); - ret = ne_request_dispatch( req ); + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + ret = ne_request_dispatch( req ); + } if ( ret == NE_OK && ne_get_status( req )->klass != 2 ) ret = NE_ERROR; @@ -1789,7 +1803,10 @@ ne_set_request_body_buffer( req, buffer, strlen( buffer ) ); - ret = ne_request_dispatch( req ); + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + ret = ne_request_dispatch( req ); + } //if ( ctx.error ) // ret = NE_ERROR; --- ucb/source/ucp/webdav/NeonSession.hxx 2010-09-27 11:08:46.000000000 +0100 +++ ucb/source/ucp/webdav/NeonSession.hxx 2010-09-27 13:06:43.000000000 +0100 @@ -53,7 +53,6 @@ { private: osl::Mutex m_aMutex; - static osl::Mutex m_aGlobalMutex; rtl::OUString m_aScheme; rtl::OUString m_aHostName; rtl::OUString m_aProxyName; --- ucb/source/ucp/webdav/NeonPropFindRequest.cxx 2010-11-26 09:07:55.000000000 +0000 +++ ucb/source/ucp/webdav/NeonPropFindRequest.cxx 2010-12-09 20:16:41.000000000 +0000 @@ -181,6 +181,7 @@ = static_cast< vector< DAVResource > * >( userdata ); theResources->push_back( theResource ); } + // ------------------------------------------------------------------- extern "C" int NPFR_propnames_iter( void* userdata, const NeonPropName* pname, @@ -225,6 +226,8 @@ theResources->push_back( theResource ); } +extern osl::Mutex aGlobalNeonMutex; + // ------------------------------------------------------------------- // Constructor // ------------------------------------------------------------------- @@ -252,12 +255,15 @@ thePropNames[ theIndex ].nspace = NULL; thePropNames[ theIndex ].name = NULL; - nError = ne_simple_propfind( inSession, + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + nError = ne_simple_propfind( inSession, inPath, inDepth, thePropNames, NPFR_propfind_results, &ioResources ); + } for ( theIndex = 0; theIndex < thePropCount; theIndex ++ ) free( (void *)thePropNames[ theIndex ].name ); @@ -266,6 +272,7 @@ } else { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); // ALLPROP nError = ne_simple_propfind( inSession, inPath, @@ -292,11 +299,14 @@ std::vector< DAVResourceInfo > & ioResInfo, int & nError ) { - nError = ne_propnames( inSession, + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + nError = ne_propnames( inSession, inPath, inDepth, NPFR_propnames_results, &ioResInfo ); + } // #87585# - Sometimes neon lies (because some servers lie). if ( ( nError == NE_OK ) && ioResInfo.empty() )