2019-11-15 13:52 CET

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000843Spring engineGeneralpublic2008-02-12 19:12
Reporterzizu 
Assigned ToAuswaschbar 
PrioritynormalSeveritymajorReproducibilityalways
StatusresolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000843: [patch]Deadlock in new avi generator
DescriptionTurns out my new threading code could deadlock if the codec sent blocking messages to winProc.
Attached patch should fix the problem.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • patch file icon deadlock_fix.patch (2,547 bytes) 2008-02-11 18:06 -
    Index: rts/System/Platform/Win/AVIGenerator.cpp
    ===================================================================
    --- rts/System/Platform/Win/AVIGenerator.cpp	(revision 5484)
    +++ rts/System/Platform/Win/AVIGenerator.cpp	(working copy)
    @@ -207,13 +207,12 @@
     	memset(&cv,0,sizeof(COMPVARS));
     	cv.cbSize=sizeof(COMPVARS);
     	cv.dwFlags=ICMF_COMPVARS_VALID;
    -	cv.fccHandler=mmioFOURCC('f','f','d','s');//default video codec
    +	cv.fccHandler=mmioFOURCC('x','v','i','d');//default video codec
     	cv.lQ=ICQUALITY_DEFAULT;
     
     
    -	HWND hWnd = FindWindow(NULL, ("Spring " + std::string(VERSION_STRING)).c_str());
     	//Set the compression, prompting dialog if necessary
    -	if (!ICCompressorChoose_ptr(hWnd, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, &bitmapInfo, NULL, &cv, NULL)){
    +	if (!ICCompressorChoose_ptr(NULL, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, &bitmapInfo, NULL, &cv, NULL)){
     		return S_FALSE;
     	}
     
    @@ -341,19 +340,22 @@
     		return false;
     	}
     
    -	HRESULT hr = InitAVICompressionEngine();
    -	if(hr != AVIERR_OK){
    -		quitAVIgen = true;
    -		return false;
    -	}
    -
     	for(int i=0; i<10; i++){
     		unsigned char* tmpBuf = SAFE_NEW unsigned char[bitmapInfo.biSizeImage];
     		freeDataPointers.push_back(tmpBuf);
     	}
     
    +	HWND mainWindow = FindWindow(NULL, ("Spring " + std::string(VERSION_STRING)).c_str());
    +	if(fullscreen){
    +		ShowWindow(mainWindow, SW_MINIMIZE);
    +	}
    +	boost::mutex::scoped_lock lock(AVIMutex);
     	AVIThread = SAFE_NEW boost::thread(boost::bind(&CAVIGenerator::AVIGeneratorThreadProc, this));
    -	return true;
    +	AVICondition.wait(lock);  //Wait until InitAVICompressionEngine() completes.
    +	if(fullscreen){
    +		ShowWindow(mainWindow, SW_RESTORE);
    +	}
    +	return !quitAVIgen;
     }
     
     
    @@ -403,6 +405,11 @@
     
     void CAVIGenerator::AVIGeneratorThreadProc(){
     
    +	//Run init from the encoding thread because custom controls displayed by codecs
    +	//sends window messages to the thread it started from, thus deadlocking if
    +	//sending to the main thread whilst it is blocking on readOpenglPixelDataThreaded().
    +	quitAVIgen = InitAVICompressionEngine() != AVIERR_OK;
    +	AVICondition.notify_all();
     	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
     	unsigned char* localWriteBuf = 0;
     
    @@ -427,6 +434,15 @@
     		if(AddFrame(localWriteBuf)){
     			quitAVIgen = true;
     		}
    +		MSG msg;
    +		//Handle all messages the codec sends.
    +		while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
    +			if(GetMessage(&msg, NULL, 0, 0) < 0){
    +				quitAVIgen = true;
    +				break;
    +			}
    +			DispatchMessage(&msg);
    +		}
     	}
     	delete [] localWriteBuf;
     }
    
    patch file icon deadlock_fix.patch (2,547 bytes) 2008-02-11 18:06 +
  • patch file icon deadlock_fix_v2.patch (2,582 bytes) 2008-02-11 20:08 -
    Index: rts/System/Platform/Win/AVIGenerator.cpp
    ===================================================================
    --- rts/System/Platform/Win/AVIGenerator.cpp	(revision 5485)
    +++ rts/System/Platform/Win/AVIGenerator.cpp	(working copy)
    @@ -207,13 +207,12 @@
     	memset(&cv,0,sizeof(COMPVARS));
     	cv.cbSize=sizeof(COMPVARS);
     	cv.dwFlags=ICMF_COMPVARS_VALID;
    -	cv.fccHandler=mmioFOURCC('f','f','d','s');//default video codec
    +	cv.fccHandler=mmioFOURCC('x','v','i','d');//default video codec
     	cv.lQ=ICQUALITY_DEFAULT;
     
     
    -	HWND hWnd = FindWindow(NULL, ("Spring " + std::string(VERSION_STRING)).c_str());
     	//Set the compression, prompting dialog if necessary
    -	if (!ICCompressorChoose_ptr(hWnd, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, &bitmapInfo, NULL, &cv, NULL)){
    +	if (!ICCompressorChoose_ptr(NULL, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, &bitmapInfo, NULL, &cv, NULL)){
     		return S_FALSE;
     	}
     
    @@ -341,19 +340,22 @@
     		return false;
     	}
     
    -	HRESULT hr = InitAVICompressionEngine();
    -	if(hr != AVIERR_OK){
    -		quitAVIgen = true;
    -		return false;
    -	}
    -
     	for(int i=0; i<10; i++){
     		unsigned char* tmpBuf = SAFE_NEW unsigned char[bitmapInfo.biSizeImage];
     		freeDataPointers.push_back(tmpBuf);
     	}
     
    +	HWND mainWindow = FindWindow(NULL, ("Spring " + std::string(VERSION_STRING)).c_str());
    +	if(fullscreen){
    +		ShowWindow(mainWindow, SW_SHOWMINNOACTIVE);
    +	}
    +	boost::mutex::scoped_lock lock(AVIMutex);
     	AVIThread = SAFE_NEW boost::thread(boost::bind(&CAVIGenerator::AVIGeneratorThreadProc, this));
    -	return true;
    +	AVICondition.wait(lock);  //Wait until InitAVICompressionEngine() completes.
    +	if(fullscreen){
    +		ShowWindow(mainWindow, SW_RESTORE);
    +	}
    +	return !quitAVIgen;
     }
     
     
    @@ -403,6 +405,11 @@
     
     void CAVIGenerator::AVIGeneratorThreadProc(){
     
    +	//Run init from the encoding thread because custom controls displayed by codecs
    +	//sends window messages to the thread it started from, thus deadlocking if
    +	//sending to the main thread whilst it is blocking on readOpenglPixelDataThreaded().
    +	quitAVIgen = InitAVICompressionEngine() != AVIERR_OK;
    +	AVICondition.notify_all();
     	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
     	unsigned char* localWriteBuf = 0;
     
    @@ -427,6 +434,16 @@
     		if(AddFrame(localWriteBuf)){
     			quitAVIgen = true;
     		}
    +		MSG msg;
    +		//Handle all messages the codec sends.
    +		while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
    +			if(GetMessage(&msg, NULL, 0, 0) < 0){
    +				quitAVIgen = true;
    +				break;
    +			}
    +			TranslateMessage(&msg);
    +			DispatchMessage(&msg);
    +		}
     	}
     	delete [] localWriteBuf;
     }
    
    patch file icon deadlock_fix_v2.patch (2,582 bytes) 2008-02-11 20:08 +

-Relationships
+Relationships

-Notes

~0001967

Auswaschbar (reporter)

rev 5491
+Notes

-Issue History
Date Modified Username Field Change
2008-02-11 18:06 zizu New Issue
2008-02-11 18:06 zizu File Added: deadlock_fix.patch
2008-02-11 20:08 zizu File Added: deadlock_fix_v2.patch
2008-02-12 19:12 Auswaschbar Status new => resolved
2008-02-12 19:12 Auswaschbar Resolution open => fixed
2008-02-12 19:12 Auswaschbar Assigned To => Auswaschbar
2008-02-12 19:12 Auswaschbar Note Added: 0001967
+Issue History