winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
June 2006
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
3 participants
854 discussions
Start a n
N
ew thread
Ken Thomases : winecoreaudio: Improve state tracking.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 6a6aec72d3a63411cd5b1d831bd99c5735f461b8 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=6a6aec72d3a63411cd5b1d8…
Author: Ken Thomases <ken(a)codeweavers.com> Date: Wed May 24 05:34:04 2006 -0500 winecoreaudio: Improve state tracking. Improved tracking of device state (stopped, playing, or paused). Also, tied starting and stopping the AudioUnit more directly to the state. No need to change the state when preparing or unpreparing wavehdrs. Pausing overrides both playing and stopped states; if stopped, pausing prevents output from starting when the program writes. When, restarting from the paused state, the device starts playing if there are queued wavehdrs. Otherwise, it goes to stopped state. --- dlls/winmm/winecoreaudio/audio.c | 94 +++++++++++++++++++++++++------------- 1 files changed, 62 insertions(+), 32 deletions(-) diff --git a/dlls/winmm/winecoreaudio/audio.c b/dlls/winmm/winecoreaudio/audio.c index 945fc80..771bdb6 100644 --- a/dlls/winmm/winecoreaudio/audio.c +++ b/dlls/winmm/winecoreaudio/audio.c @@ -782,8 +782,6 @@ static DWORD wodClose(WORD wDevID) */ static DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize) { - OSStatus status; - TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize); if (wDevID >= MAX_WAVEOUTDRV) { @@ -796,17 +794,7 @@ static DWORD wodPrepare(WORD wDevID, LPW lpWaveHdr->dwFlags |= WHDR_PREPARED; lpWaveHdr->dwFlags &= ~WHDR_DONE; - - WOutDev[wDevID].state = WINE_WS_STOPPED; - - status = AudioOutputUnitStart(WOutDev[wDevID].audioUnit); - if (status) { - ERR("AudioOutputUnitStart return %c%c%c%c\n", (char) (status >> 24), - (char) (status >> 16), - (char) (status >> 8), - (char) status); - return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */ - } + return MMSYSERR_NOERROR; } @@ -815,8 +803,6 @@ static DWORD wodPrepare(WORD wDevID, LPW */ static DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize) { - OSStatus status; - TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize); if (wDevID >= MAX_WAVEOUTDRV) { @@ -830,11 +816,6 @@ static DWORD wodUnprepare(WORD wDevID, L lpWaveHdr->dwFlags &= ~WHDR_PREPARED; lpWaveHdr->dwFlags |= WHDR_DONE; - status = AudioOutputUnitStop(WOutDev[wDevID].audioUnit); - if (status) { - ERR("AudioOutputUnitStop return %c%c%c%c\n", (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status); - return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */ - } return MMSYSERR_NOERROR; } @@ -848,12 +829,32 @@ static DWORD wodUnprepare(WORD wDevID, L */ static void wodHelper_BeginWaveHdr(WINE_WAVEOUT* wwo, LPWAVEHDR lpWaveHdr) { + OSStatus status; + wwo->lpPlayPtr = lpWaveHdr; if (!lpWaveHdr) { + if (wwo->state == WINE_WS_PLAYING) + { + wwo->state = WINE_WS_STOPPED; + status = AudioOutputUnitStop(wwo->audioUnit); + if (status) + fprintf(stderr, "err:winecoreaudio:wodHelper_BeginWaveHdr AudioOutputUnitStop return %c%c%c%c\n", + (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status); + } return; } + + if (wwo->state == WINE_WS_STOPPED) + { + status = AudioOutputUnitStart(wwo->audioUnit); + if (status) { + fprintf(stderr, "err:winecoreaudio:AudioOutputUnitStart return %c%c%c%c\n", + (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status); + } + else wwo->state = WINE_WS_PLAYING; + } if (lpWaveHdr->dwFlags & WHDR_BEGINLOOP) { @@ -968,8 +969,10 @@ static DWORD wodHelper_NotifyCompletions * * Resets current output stream. */ -static void wodHelper_Reset(WINE_WAVEOUT* wwo, BOOL reset) +static DWORD wodHelper_Reset(WINE_WAVEOUT* wwo, BOOL reset) { + OSStatus status; + FIXME("\n"); /* updates current notify list */ @@ -1017,7 +1020,17 @@ static void wodHelper_Reset(WINE_WAVEO wwo->state = WINE_WS_PAUSED; } + status = AudioOutputUnitStop(wwo->audioUnit); + pthread_mutex_unlock(&wwo->lock); + + if (status) { + ERR( "AudioOutputUnitStop return %c%c%c%c\n", + (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status); + return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */ + } + + return MMSYSERR_NOERROR; } @@ -1065,8 +1078,6 @@ static DWORD wodWrite(WORD wDevID, LPWAV if (!wwo->lpPlayPtr) wodHelper_BeginWaveHdr(wwo,lpWaveHdr); - if (wwo->state == WINE_WS_STOPPED) - wwo->state = WINE_WS_PLAYING; pthread_mutex_unlock(&wwo->lock); return MMSYSERR_NOERROR; @@ -1077,6 +1088,8 @@ static DWORD wodWrite(WORD wDevID, LPWAV */ static DWORD wodPause(WORD wDevID) { + OSStatus status; + TRACE("(%u);!\n", wDevID); if (wDevID >= MAX_WAVEOUTDRV) @@ -1085,12 +1098,19 @@ static DWORD wodPause(WORD wDevID) return MMSYSERR_BADDEVICEID; } - if (WOutDev[wDevID].state == WINE_WS_PLAYING) + pthread_mutex_lock(&WOutDev[wDevID].lock); + if (WOutDev[wDevID].state == WINE_WS_PLAYING || WOutDev[wDevID].state == WINE_WS_STOPPED) { - pthread_mutex_lock(&WOutDev[wDevID].lock); WOutDev[wDevID].state = WINE_WS_PAUSED; - pthread_mutex_unlock(&WOutDev[wDevID].lock); + status = AudioOutputUnitStop(WOutDev[wDevID].audioUnit); + if (status) { + ERR( "AudioOutputUnitStop return %c%c%c%c\n", + (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status); + pthread_mutex_unlock(&WOutDev[wDevID].lock); + return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */ + } } + pthread_mutex_unlock(&WOutDev[wDevID].lock); return MMSYSERR_NOERROR; } @@ -1108,12 +1128,24 @@ static DWORD wodRestart(WORD wDevID) return MMSYSERR_BADDEVICEID; } + pthread_mutex_lock(&WOutDev[wDevID].lock); if (WOutDev[wDevID].state == WINE_WS_PAUSED) { - pthread_mutex_lock(&WOutDev[wDevID].lock); - WOutDev[wDevID].state = WINE_WS_PLAYING; - pthread_mutex_unlock(&WOutDev[wDevID].lock); + if (WOutDev[wDevID].lpPlayPtr) + { + OSStatus status = AudioOutputUnitStart(WOutDev[wDevID].audioUnit); + if (status) { + ERR("AudioOutputUnitStart return %c%c%c%c\n", + (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status); + pthread_mutex_unlock(&WOutDev[wDevID].lock); + return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */ + } + WOutDev[wDevID].state = WINE_WS_PLAYING; + } + else + WOutDev[wDevID].state = WINE_WS_STOPPED; } + pthread_mutex_unlock(&WOutDev[wDevID].lock); return MMSYSERR_NOERROR; } @@ -1131,9 +1163,7 @@ static DWORD wodReset(WORD wDevID) return MMSYSERR_BADDEVICEID; } - wodHelper_Reset(&WOutDev[wDevID], TRUE); - - return MMSYSERR_NOERROR; + return wodHelper_Reset(&WOutDev[wDevID], TRUE); } /**************************************************************************
1
0
0
0
Ken Thomases : winecoreaudio: Miscellaneous cleanup.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: fb9f878849fd468cf418c5731fa5a75c42051267 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=fb9f878849fd468cf418c57…
Author: Ken Thomases <ken(a)codeweavers.com> Date: Wed May 24 05:28:18 2006 -0500 winecoreaudio: Miscellaneous cleanup. Miscellaneous cleanup: release resources when done with them; protect against null pointers; reduce redundant code; avoid potential integer underflow; clarify a do-nothing loop. --- dlls/winmm/winecoreaudio/audio.c | 42 +++++++++++++++++++++++--------------- 1 files changed, 25 insertions(+), 17 deletions(-) diff --git a/dlls/winmm/winecoreaudio/audio.c b/dlls/winmm/winecoreaudio/audio.c index ea15635..945fc80 100644 --- a/dlls/winmm/winecoreaudio/audio.c +++ b/dlls/winmm/winecoreaudio/audio.c @@ -286,7 +286,11 @@ static DWORD WINAPI messageThread(LPVOID CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); CFRunLoopRun(); - + + CFRunLoopSourceInvalidate(source); + CFRelease(source); + CFRelease(local); + return 0; } @@ -318,6 +322,7 @@ static DWORD wodSendDriverCallbackMessag ret = CFMessagePortSendRequest(messagePort, kWaveOutCallbackMessage, data, 0.0, 0.0, NULL, NULL); CFRelease(data); CFAllocatorDeallocate(NULL, buffer); + CFRelease(messagePort); return (ret == kCFMessagePortSuccess)?1:0; } @@ -687,6 +692,7 @@ # endif ret = AudioUnit_InitializeWithStreamDescription(wwo->audioUnit, &streamFormat); if (!ret) { + AudioUnit_CloseAudioUnit(wwo->audioUnit); pthread_mutex_unlock(&wwo->lock); return WAVERR_BADFORMAT; /* FIXME return an error based on the OSStatus */ } @@ -881,19 +887,24 @@ static LPWAVEHDR wodHelper_PlayPtrNext(W pthread_mutex_lock(&wwo->lock); lpWaveHdr = wwo->lpPlayPtr; - + if (!lpWaveHdr) + { + pthread_mutex_unlock(&wwo->lock); + return NULL; + } + wwo->dwPartialOffset = 0; if ((lpWaveHdr->dwFlags & WHDR_ENDLOOP) && wwo->lpLoopPtr) { /* We're at the end of a loop, loop if required */ - if (--wwo->dwLoops > 0) + if (wwo->dwLoops > 1) { + wwo->dwLoops--; wwo->lpPlayPtr = wwo->lpLoopPtr; } else { /* Handle overlapping loops correctly */ if (wwo->lpLoopPtr != lpWaveHdr && (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)) { - fprintf(stderr, "trace:winecoreaudio:wodHelper_PlayPtrNext Correctly handled case ? (ending loop buffer also starts a new loop)\n"); /* shall we consider the END flag for the closing loop or for * the opening one or for both ??? * code assumes for closing loop only @@ -962,26 +973,21 @@ static void wodHelper_Reset(WINE_WAVEO FIXME("\n"); /* updates current notify list */ - wodHelper_NotifyCompletions(wwo, FALSE); + /* if resetting, remove all wave headers and notify client that all headers were completed */ + wodHelper_NotifyCompletions(wwo, reset); + + pthread_mutex_lock(&wwo->lock); if (reset) { - /* remove all wave headers and notify client that all headers were completed */ - wodHelper_NotifyCompletions(wwo, TRUE); - - pthread_mutex_lock(&wwo->lock); - wwo->lpPlayPtr = wwo->lpQueuePtr = wwo->lpLoopPtr = NULL; wwo->state = WINE_WS_STOPPED; wwo->dwPlayedTotal = wwo->dwWrittenTotal = 0; wwo->dwPartialOffset = 0; /* Clear partial wavehdr */ - - pthread_mutex_unlock(&wwo->lock); } else { - pthread_mutex_lock(&wwo->lock); if (wwo->lpLoopPtr) { /* complicated case, not handled yet (could imply modifying the loop counter) */ @@ -996,7 +1002,7 @@ static void wodHelper_Reset(WINE_WAVEO /* reset all the data as if we had written only up to lpPlayedTotal bytes */ /* compute the max size playable from lpQueuePtr */ - for (ptr = wwo->lpQueuePtr; ptr != wwo->lpPlayPtr; ptr = ptr->lpNext) + for (ptr = wwo->lpQueuePtr; ptr && ptr != wwo->lpPlayPtr; ptr = ptr->lpNext) { sz += ptr->dwBufferLength; } @@ -1009,8 +1015,9 @@ static void wodHelper_Reset(WINE_WAVEO } wwo->state = WINE_WS_PAUSED; - pthread_mutex_unlock(&wwo->lock); } + + pthread_mutex_unlock(&wwo->lock); } @@ -1052,7 +1059,8 @@ static DWORD wodWrite(WORD wDevID, LPWAV pthread_mutex_lock(&wwo->lock); /* insert buffer at the end of queue */ - for (wh = &(wwo->lpQueuePtr); *wh; wh = &((*wh)->lpNext)); + for (wh = &(wwo->lpQueuePtr); *wh; wh = &((*wh)->lpNext)) + /* Do nothing */; *wh = lpWaveHdr; if (!wwo->lpPlayPtr) @@ -1263,7 +1271,7 @@ DWORD WINAPI CoreAudio_wodMessage(UINT w case DRVM_ENABLE: case DRVM_DISABLE: - // FIXME: Pretend this is supported // + /* FIXME: Pretend this is supported */ return 0; case WODM_OPEN: return wodOpen(wDevID, (LPWAVEOPENDESC) dwParam1, dwParam2); case WODM_CLOSE: return wodClose(wDevID);
1
0
0
0
Ken Thomases : winecoreaudio: Fix race to open.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 00e99963398ae0f46f25fc6cc541e37958ab1224 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=00e99963398ae0f46f25fc6…
Author: Ken Thomases <ken(a)codeweavers.com> Date: Wed May 24 05:27:24 2006 -0500 winecoreaudio: Fix race to open. Fixes a race condition (noted in a comment for wodOpen) when multiple threads try to open the same wave-out device simultaneously. Addressed by creating the device mutexes when the driver is initialized, instead of as each device is opened. Then use the mutex to protect the open operation against races. At the same time, made the mutexes recursive to avoid self-deadlocks the driver was encountering when reentered from the callback. --- dlls/winmm/winecoreaudio/audio.c | 43 +++++++++++++++++++++++++++----------- 1 files changed, 30 insertions(+), 13 deletions(-) diff --git a/dlls/winmm/winecoreaudio/audio.c b/dlls/winmm/winecoreaudio/audio.c index 7c43d95..ea15635 100644 --- a/dlls/winmm/winecoreaudio/audio.c +++ b/dlls/winmm/winecoreaudio/audio.c @@ -445,6 +445,7 @@ LONG CoreAudio_WaveInit(void) OSStatus status; UInt32 propertySize; CHAR szPname[MAXPNAMELEN]; + pthread_mutexattr_t mutexattr; int i; HANDLE hThread; @@ -476,6 +477,9 @@ LONG CoreAudio_WaveInit(void) CoreAudio_DefaultDevice.interface_name=HeapAlloc(GetProcessHeap(),0,strlen(CoreAudio_DefaultDevice.dev_name)+1); sprintf(CoreAudio_DefaultDevice.interface_name, "%s", CoreAudio_DefaultDevice.dev_name); + pthread_mutexattr_init(&mutexattr); + pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); + for (i = 0; i < MAX_WAVEOUTDRV; ++i) { WOutDev[i].state = WINE_WS_CLOSED; @@ -509,7 +513,11 @@ LONG CoreAudio_WaveInit(void) WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S08; WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M16; WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S16; + + pthread_mutex_init(&WOutDev[i].lock, &mutexattr); /* initialize the mutex */ } + + pthread_mutexattr_destroy(&mutexattr); /* create mach messages handler */ hThread = CreateThread(NULL, 0, messageThread, NULL, 0, NULL); @@ -526,12 +534,18 @@ void CoreAudio_WaveRelease(void) { /* Stop CFRunLoop in messageThread */ CFMessagePortRef messagePort; + int i; TRACE("()\n"); messagePort = CFMessagePortCreateRemote(kCFAllocatorDefault, CFSTR("WaveMessagePort")); CFMessagePortSendRequest(messagePort, kStopLoopMessage, NULL, 0.0, 0.0, NULL, NULL); CFRelease(messagePort); + + for (i = 0; i < MAX_WAVEOUTDRV; ++i) + { + pthread_mutex_destroy(&WOutDev[i].lock); + } } /*======================================================================* @@ -591,9 +605,6 @@ static DWORD wodGetDevCaps(WORD wDevID, /************************************************************************** * wodOpen [internal] -* -* NOTE: doesn't it seem like there is a race condition if you try to open -* the same device twice? */ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags) { @@ -637,9 +648,18 @@ static DWORD wodOpen(WORD wDevID, LPWAVE } wwo = &WOutDev[wDevID]; + pthread_mutex_lock(&wwo->lock); + + if (wwo->state != WINE_WS_CLOSED) + { + pthread_mutex_unlock(&wwo->lock); + return MMSYSERR_ALLOCATED; + } + if (!AudioUnit_CreateDefaultAudioUnit((void *) wwo, &wwo->audioUnit)) { ERR("CoreAudio_CreateDefaultAudioUnit(%p) failed\n", wwo); + pthread_mutex_unlock(&wwo->lock); return MMSYSERR_ERROR; } @@ -648,11 +668,6 @@ static DWORD wodOpen(WORD wDevID, LPWAVE /* not supported, ignore it */ dwFlags &= ~WAVE_DIRECTSOUND; - if (wwo->state != WINE_WS_CLOSED) return MMSYSERR_ALLOCATED; - - pthread_mutex_init(&wwo->lock, NULL); /* initialize the mutex */ - pthread_mutex_lock(&wwo->lock); - streamFormat.mFormatID = kAudioFormatLinearPCM; /* FIXME check for 32bits float -> kLinearPCMFormatFlagIsFloat */ @@ -677,8 +692,6 @@ # endif } wwo->streamDescription = streamFormat; wwo->state = WINE_WS_STOPPED; - - pthread_mutex_unlock(&wwo->lock); wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); @@ -695,6 +708,8 @@ # endif wwo->dwPlayedTotal = 0; wwo->dwWrittenTotal = 0; + + pthread_mutex_unlock(&wwo->lock); retval = wodNotifyClient(wwo, WOM_OPEN, 0L, 0L); @@ -718,9 +733,11 @@ static DWORD wodClose(WORD wDevID) } wwo = &WOutDev[wDevID]; + pthread_mutex_lock(&wwo->lock); if (wwo->lpQueuePtr) { WARN("buffers still playing !\n"); + pthread_mutex_unlock(&wwo->lock); ret = WAVERR_STILLPLAYING; } else { @@ -736,17 +753,17 @@ static DWORD wodClose(WORD wDevID) (char) (err >> 16), (char) (err >> 8), (char) err); - pthread_mutex_destroy(&wwo->lock); + pthread_mutex_unlock(&wwo->lock); return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */ } if ( !AudioUnit_CloseAudioUnit(wwo->audioUnit) ) { ERR("Can't close AudioUnit\n"); - pthread_mutex_destroy(&wwo->lock); + pthread_mutex_unlock(&wwo->lock); return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */ } - pthread_mutex_destroy(&wwo->lock); + pthread_mutex_unlock(&wwo->lock); ret = wodNotifyClient(wwo, WOM_CLOSE, 0L, 0L); }
1
0
0
0
Mike McCormack : rpcrt4: Implement NDRCContext(Un) marshall and NDRCContextBinding.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 7f98594f75823057aedb6ece689921d301882ac9 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=7f98594f75823057aedb6ec…
Author: Mike McCormack <mike(a)codeweavers.com> Date: Thu Jun 1 13:09:49 2006 +0900 rpcrt4: Implement NDRCContext(Un)marshall and NDRCContextBinding. --- dlls/rpcrt4/ndr_marshall.c | 116 ++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 112 insertions(+), 4 deletions(-) diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c index 582851b..83fc9be 100644 --- a/dlls/rpcrt4/ndr_marshall.c +++ b/dlls/rpcrt4/ndr_marshall.c @@ -49,6 +49,7 @@ #include "wine/unicode.h" #include "wine/rpcfc.h" #include "wine/debug.h" +#include "wine/list.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -4406,15 +4407,113 @@ NDR_SCONTEXT WINAPI NdrServerContextNewU return NULL; } -RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext) +#define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e + +typedef struct ndr_context_handle +{ + DWORD attributes; + GUID uuid; +} ndr_context_handle; + +struct context_handle_entry +{ + struct list entry; + DWORD magic; + RPC_BINDING_HANDLE handle; + ndr_context_handle wire_data; +}; + +static struct list context_handle_list = LIST_INIT(context_handle_list); + +static CRITICAL_SECTION ndr_context_cs; +static CRITICAL_SECTION_DEBUG ndr_context_debug = { - FIXME("(%p): stub\n", CContext); + 0, 0, &ndr_context_cs, + { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") } +}; +static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 }; + +static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) +{ + struct context_handle_entry *che = (struct context_handle_entry*) CContext; + + if (che->magic != NDR_CONTEXT_HANDLE_MAGIC) + return NULL; + return che; +} + +static struct context_handle_entry *context_entry_from_guid(LPGUID uuid) +{ + struct context_handle_entry *che; + LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry) + if (IsEqualGUID(&che->wire_data.uuid, uuid)) + return che; return NULL; } +RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext) +{ + struct context_handle_entry *che; + RPC_BINDING_HANDLE handle = NULL; + + TRACE("%p\n", CContext); + + EnterCriticalSection(&ndr_context_cs); + che = get_context_entry(CContext); + if (che) + handle = che->handle; + LeaveCriticalSection(&ndr_context_cs); + + if (!handle) + RpcRaiseException(ERROR_INVALID_HANDLE); + return handle; +} + void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff) { - FIXME("(%p %p): stub\n", CContext, pBuff); + struct context_handle_entry *che; + + TRACE("%p %p\n", CContext, pBuff); + + EnterCriticalSection(&ndr_context_cs); + che = get_context_entry(CContext); + memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle)); + LeaveCriticalSection(&ndr_context_cs); +} + +static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext, + RPC_BINDING_HANDLE hBinding, + ndr_context_handle *chi) +{ + static const GUID zeroguid = {0,0,0,{0,0,0,0,0,0,0,0}}; + struct context_handle_entry *che = NULL; + + /* a null UUID means we should free the context handle */ + if (IsEqualGUID(&chi->uuid, &zeroguid)) + { + che = get_context_entry(*CContext); + if (!che) + return ERROR_INVALID_HANDLE; + list_remove(&che->entry); + HeapFree(GetProcessHeap(), 0, che); + che = NULL; + } + /* if there's no existing entry matching the GUID, allocate one */ + else if (!(che = context_entry_from_guid(&chi->uuid))) + { + che = HeapAlloc(GetProcessHeap(), 0, sizeof *che); + if (!che) + return ERROR_NOT_ENOUGH_MEMORY; + che->magic = NDR_CONTEXT_HANDLE_MAGIC; + che->handle = hBinding; + list_add_tail(&context_handle_list, &che->entry); + memcpy(&che->wire_data, chi, sizeof *chi); + } + + *CContext = che; + + return ERROR_SUCCESS; } void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext, @@ -4422,7 +4521,16 @@ void WINAPI NDRCContextUnmarshall(NDR_CC void *pBuff, unsigned long DataRepresentation) { - FIXME("(%p %p %p %08lx): stub\n", CContext, hBinding, pBuff, DataRepresentation); + UINT r; + + TRACE("*%p=(%p) %p %p %08lx\n", + CContext, *CContext, hBinding, pBuff, DataRepresentation); + + EnterCriticalSection(&ndr_context_cs); + r = ndr_update_context_handle(CContext, hBinding, pBuff); + LeaveCriticalSection(&ndr_context_cs); + if (r) + RpcRaiseException(r); } void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
1
0
0
0
Stefan Dösinger : wined3d: Adjust the video mem when dropping the pow2 size in GDISurface.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 5de8cd3bd6aed7dba24e91ca91598c84cdba106b URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=5de8cd3bd6aed7dba24e91c…
Author: Stefan Dösinger <stefan(a)codeweavers.com> Date: Thu Jun 1 01:13:36 2006 +0200 wined3d: Adjust the video mem when dropping the pow2 size in GDISurface. --- dlls/wined3d/surface_gdi.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c index b84bc25..086af46 100644 --- a/dlls/wined3d/surface_gdi.c +++ b/dlls/wined3d/surface_gdi.c @@ -1458,6 +1458,7 @@ IWineGDISurfaceImpl_PrivateSetup(IWineD3 IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; HRESULT hr; HDC hdc; + long oldsize = This->resource.size; /* Sysmem textures have memory already allocated - * release it, this avoids an unnecessary memcpy @@ -1472,6 +1473,9 @@ IWineGDISurfaceImpl_PrivateSetup(IWineD3 This->pow2Height = This->currentDesc.Height; This->Flags &= ~SFLAG_NONPOW2; + /* Adjust the opengl mem counter */ + globalChangeGlRam(This->resource.size - oldsize); + /* Call GetDC to create a DIB section. We will use that * DIB section for rendering *
1
0
0
0
Jacek Caban : urlmon: Remove no longer needed binding value in task_t.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 349b93ae57a8a4c37f96a96ec0c6fba281edc6b4 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=349b93ae57a8a4c37f96a96…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed May 31 19:48:23 2006 +0200 urlmon: Remove no longer needed binding value in task_t. --- dlls/urlmon/binding.c | 41 +++++++++++++++-------------------------- 1 files changed, 15 insertions(+), 26 deletions(-) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index c70364e..20a95f1 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -51,7 +51,6 @@ typedef struct { typedef struct _task_t { enum task_enum task; - Binding *binding; struct _task_t *next; union { on_progress_data on_progress; @@ -109,18 +108,18 @@ #define STREAM(x) ((IStream*) &(x)->lpSt #define WM_MK_CONTINUE (WM_USER+101) -static void push_task(task_t *task) +static void push_task(Binding *binding, task_t *task) { task->next = NULL; - EnterCriticalSection(&task->binding->section); + EnterCriticalSection(&binding->section); - if(task->binding->task_queue_tail) - task->binding->task_queue_tail->next = task; + if(binding->task_queue_tail) + binding->task_queue_tail->next = task; else - task->binding->task_queue_tail = task->binding->task_queue_head = task; + binding->task_queue_tail = binding->task_queue_head = task; - LeaveCriticalSection(&task->binding->section); + LeaveCriticalSection(&binding->section); } static task_t *pop_task(Binding *binding) @@ -141,13 +140,13 @@ static task_t *pop_task(Binding *binding return ret; } -static void do_task(task_t *task) +static void do_task(Binding *binding, task_t *task) { switch(task->task) { case TASK_ON_PROGRESS: { on_progress_data *data = &task->data.on_progress; - IBindStatusCallback_OnProgress(task->binding->callback, data->progress, + IBindStatusCallback_OnProgress(binding->callback, data->progress, data->progress_max, data->status_code, data->status_text); HeapFree(GetProcessHeap(), 0, data->status_text); @@ -156,9 +155,9 @@ static void do_task(task_t *task) break; } case TASK_SWITCH: - task->binding->continue_call++; - IInternetProtocol_Continue(task->binding->protocol, task->data.protocol_data); - task->binding->continue_call--; + binding->continue_call++; + IInternetProtocol_Continue(binding->protocol, task->data.protocol_data); + binding->continue_call--; } } @@ -166,10 +165,8 @@ static void do_tasks(Binding *This) { task_t *task; - while((task = pop_task(This))) { - do_task(task); - IBinding_Release(BINDING(task->binding)); - } + while((task = pop_task(This))) + do_task(This, task); } static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -240,10 +237,6 @@ static void on_progress(Binding *This, U task = HeapAlloc(GetProcessHeap(), 0, sizeof(task_t)); task->task = TASK_ON_PROGRESS; - - IBinding_AddRef(BINDING(This)); - task->binding = This; - task->data.on_progress.progress = progress; task->data.on_progress.progress_max = progress_max; task->data.on_progress.status_code = status_code; @@ -257,7 +250,7 @@ static void on_progress(Binding *This, U task->data.on_progress.status_text = NULL; } - push_task(task); + push_task(This, task); if(GetCurrentThreadId() != This->apartment_thread) { IBinding_AddRef(BINDING(This)); @@ -772,13 +765,9 @@ static HRESULT WINAPI InternetProtocolSi task = HeapAlloc(GetProcessHeap(), 0, sizeof(task_t)); task->task = TASK_SWITCH; - - IBinding_AddRef(BINDING(This)); - task->binding = This; - task->data.protocol_data = pProtocolData; - push_task(task); + push_task(This, task); IBinding_AddRef(BINDING(This)); PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This);
1
0
0
0
Jacek Caban : urlmon: Use task queue for cross thread calls in on_progress.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: e6fc0c5dc22e34258383bc033ff86932d35f2abf URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=e6fc0c5dc22e34258383bc0…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed May 31 19:47:42 2006 +0200 urlmon: Use task queue for cross thread calls in on_progress. --- dlls/urlmon/binding.c | 52 +++++++------------------------------------------ 1 files changed, 7 insertions(+), 45 deletions(-) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 93ff949..c70364e 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -107,7 +107,6 @@ #define SERVPROV(x) ((IServiceProvider* #define STREAM(x) ((IStream*) &(x)->lpStreamVtbl) -#define WM_MK_ONPROGRESS (WM_USER+100) #define WM_MK_CONTINUE (WM_USER+101) static void push_task(task_t *task) @@ -175,22 +174,7 @@ static void do_tasks(Binding *This) static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - switch(msg) { - case WM_MK_ONPROGRESS: { - on_progress_data *data = (on_progress_data*)lParam; - - TRACE("WM_MK_PROGRESS %p\n", data); - - IBindStatusCallback_OnProgress(data->binding->callback, data->progress, - data->progress_max, data->status_code, data->status_text); - - IBinding_Release(BINDING(data->binding)); - HeapFree(GetProcessHeap(), 0, data->status_text); - HeapFree(GetProcessHeap(), 0, data); - - return 0; - } - case WM_MK_CONTINUE: { + if(msg == WM_MK_CONTINUE) { Binding *binding = (Binding*)lParam; do_tasks(binding); @@ -198,7 +182,6 @@ static LRESULT WINAPI notif_wnd_proc(HWN IBinding_Release(BINDING(binding)); return 0; } - } return DefWindowProcW(hwnd, msg, wParam, lParam); } @@ -248,33 +231,7 @@ static void on_progress(Binding *This, U { task_t *task; - if(GetCurrentThreadId() != This->apartment_thread) { - on_progress_data *data; - - data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); - - IBinding_AddRef(BINDING(This)); - - data->binding = This; - data->progress = progress; - data->progress_max = progress_max; - data->status_code = status_code; - - if(status_text) { - DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR); - - data->status_text = HeapAlloc(GetProcessHeap(), 0, size); - memcpy(data->status_text, status_text, size); - }else { - data->status_text = NULL; - } - - PostMessageW(This->notif_hwnd, WM_MK_ONPROGRESS, 0, (LPARAM)data); - - return; - } - - if(!This->continue_call) { + if(GetCurrentThreadId() == This->apartment_thread && !This->continue_call) { IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text); return; @@ -301,6 +258,11 @@ static void on_progress(Binding *This, U } push_task(task); + + if(GetCurrentThreadId() != This->apartment_thread) { + IBinding_AddRef(BINDING(This)); + PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); + } } static void dump_BINDINFO(BINDINFO *bi)
1
0
0
0
Jacek Caban : urlmon: Use task queue in Switch implementation.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 08685417ab762d030a954823cfd15b85b87612d4 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=08685417ab762d030a95482…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed May 31 19:46:04 2006 +0200 urlmon: Use task queue in Switch implementation. --- dlls/urlmon/binding.c | 41 ++++++++++++++++++++++------------------- 1 files changed, 22 insertions(+), 19 deletions(-) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 9a13002..93ff949 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -37,7 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); typedef struct Binding Binding; enum task_enum { - TASK_ON_PROGRESS + TASK_ON_PROGRESS, + TASK_SWITCH }; typedef struct { @@ -48,17 +49,13 @@ typedef struct { LPWSTR status_text; } on_progress_data; -typedef struct { - Binding *binding; - PROTOCOLDATA *data; -} switch_data; - typedef struct _task_t { enum task_enum task; Binding *binding; struct _task_t *next; union { on_progress_data on_progress; + PROTOCOLDATA *protocol_data; } data; } task_t; @@ -156,7 +153,13 @@ static void do_task(task_t *task) HeapFree(GetProcessHeap(), 0, data->status_text); HeapFree(GetProcessHeap(), 0, data); + + break; } + case TASK_SWITCH: + task->binding->continue_call++; + IInternetProtocol_Continue(task->binding->protocol, task->data.protocol_data); + task->binding->continue_call--; } } @@ -188,16 +191,11 @@ static LRESULT WINAPI notif_wnd_proc(HWN return 0; } case WM_MK_CONTINUE: { - switch_data *data = (switch_data*)lParam; - - data->binding->continue_call++; - IInternetProtocol_Continue(data->binding->protocol, data->data); - data->binding->continue_call--; + Binding *binding = (Binding*)lParam; - do_tasks(data->binding); + do_tasks(binding); - IBinding_Release(BINDING(data->binding)); - HeapFree(GetProcessHeap(), 0, data); + IBinding_Release(BINDING(binding)); return 0; } } @@ -806,17 +804,22 @@ static HRESULT WINAPI InternetProtocolSi PROTOCOLDATA *pProtocolData) { Binding *This = PROTSINK_THIS(iface); - switch_data *data; + task_t *task; TRACE("(%p)->(%p)\n", This, pProtocolData); - data = HeapAlloc(GetProcessHeap(), 0, sizeof(switch_data)); + task = HeapAlloc(GetProcessHeap(), 0, sizeof(task_t)); + task->task = TASK_SWITCH; IBinding_AddRef(BINDING(This)); - data->binding = This; - data->data = pProtocolData; + task->binding = This; - PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)data); + task->data.protocol_data = pProtocolData; + + push_task(task); + + IBinding_AddRef(BINDING(This)); + PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); return S_OK; }
1
0
0
0
Jacek Caban : urlmon: Added task queue architecture and use it for OnProgress calls from Continue call .
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 99cb95394aaeb0a1100874a6d217d6f7810523f5 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=99cb95394aaeb0a1100874a…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed May 31 19:45:16 2006 +0200 urlmon: Added task queue architecture and use it for OnProgress calls from Continue call. --- dlls/urlmon/binding.c | 179 ++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 145 insertions(+), 34 deletions(-) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 22a4ea2..9a13002 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -34,9 +34,47 @@ #include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(urlmon); -typedef struct ProtocolStream ProtocolStream; +typedef struct Binding Binding; + +enum task_enum { + TASK_ON_PROGRESS +}; + +typedef struct { + Binding *binding; + ULONG progress; + ULONG progress_max; + ULONG status_code; + LPWSTR status_text; +} on_progress_data; + +typedef struct { + Binding *binding; + PROTOCOLDATA *data; +} switch_data; + +typedef struct _task_t { + enum task_enum task; + Binding *binding; + struct _task_t *next; + union { + on_progress_data on_progress; + } data; +} task_t; typedef struct { + const IStreamVtbl *lpStreamVtbl; + + LONG ref; + + IInternetProtocol *protocol; + + BYTE buf[1024*8]; + DWORD buf_size; + BOOL init_buf; +} ProtocolStream; + +struct Binding { const IBindingVtbl *lpBindingVtbl; const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl; const IInternetBindInfoVtbl *lpInternetBindInfoVtbl; @@ -54,23 +92,15 @@ typedef struct { LPWSTR mime; LPWSTR url; BOOL verified_mime; + DWORD continue_call; DWORD apartment_thread; HWND notif_hwnd; STGMEDIUM stgmed; -} Binding; - -struct ProtocolStream { - const IStreamVtbl *lpStreamVtbl; - - LONG ref; - - IInternetProtocol *protocol; - BYTE buf[1024*8]; - DWORD buf_size; - BOOL init_buf; + task_t *task_queue_head, *task_queue_tail; + CRITICAL_SECTION section; }; #define BINDING(x) ((IBinding*) &(x)->lpBindingVtbl) @@ -83,18 +113,62 @@ #define STREAM(x) ((IStream*) &(x)->lpSt #define WM_MK_ONPROGRESS (WM_USER+100) #define WM_MK_CONTINUE (WM_USER+101) -typedef struct { - Binding *binding; - ULONG progress; - ULONG progress_max; - ULONG status_code; - LPWSTR status_text; -} on_progress_data; +static void push_task(task_t *task) +{ + task->next = NULL; -typedef struct { - Binding *binding; - PROTOCOLDATA *data; -} switch_data; + EnterCriticalSection(&task->binding->section); + + if(task->binding->task_queue_tail) + task->binding->task_queue_tail->next = task; + else + task->binding->task_queue_tail = task->binding->task_queue_head = task; + + LeaveCriticalSection(&task->binding->section); +} + +static task_t *pop_task(Binding *binding) +{ + task_t *ret; + + EnterCriticalSection(&binding->section); + + ret = binding->task_queue_head; + if(ret) { + binding->task_queue_head = ret->next; + if(!binding->task_queue_head) + binding->task_queue_tail = NULL; + } + + LeaveCriticalSection(&binding->section); + + return ret; +} + +static void do_task(task_t *task) +{ + switch(task->task) { + case TASK_ON_PROGRESS: { + on_progress_data *data = &task->data.on_progress; + + IBindStatusCallback_OnProgress(task->binding->callback, data->progress, + data->progress_max, data->status_code, data->status_text); + + HeapFree(GetProcessHeap(), 0, data->status_text); + HeapFree(GetProcessHeap(), 0, data); + } + } +} + +static void do_tasks(Binding *This) +{ + task_t *task; + + while((task = pop_task(This))) { + do_task(task); + IBinding_Release(BINDING(task->binding)); + } +} static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -116,7 +190,11 @@ static LRESULT WINAPI notif_wnd_proc(HWN case WM_MK_CONTINUE: { switch_data *data = (switch_data*)lParam; + data->binding->continue_call++; IInternetProtocol_Continue(data->binding->protocol, data->data); + data->binding->continue_call--; + + do_tasks(data->binding); IBinding_Release(BINDING(data->binding)); HeapFree(GetProcessHeap(), 0, data); @@ -170,33 +248,61 @@ static HWND get_notif_hwnd(void) static void on_progress(Binding *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text) { - on_progress_data *data; + task_t *task; + + if(GetCurrentThreadId() != This->apartment_thread) { + on_progress_data *data; + + data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); + + IBinding_AddRef(BINDING(This)); + + data->binding = This; + data->progress = progress; + data->progress_max = progress_max; + data->status_code = status_code; + + if(status_text) { + DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR); - if(GetCurrentThreadId() == This->apartment_thread) { + data->status_text = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(data->status_text, status_text, size); + }else { + data->status_text = NULL; + } + + PostMessageW(This->notif_hwnd, WM_MK_ONPROGRESS, 0, (LPARAM)data); + + return; + } + + if(!This->continue_call) { IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text); return; } - data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); + task = HeapAlloc(GetProcessHeap(), 0, sizeof(task_t)); + + task->task = TASK_ON_PROGRESS; IBinding_AddRef(BINDING(This)); + task->binding = This; - data->binding = This; - data->progress = progress; - data->progress_max = progress_max; - data->status_code = status_code; + task->data.on_progress.progress = progress; + task->data.on_progress.progress_max = progress_max; + task->data.on_progress.status_code = status_code; if(status_text) { DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR); - data->status_text = HeapAlloc(GetProcessHeap(), 0, size); - memcpy(data->status_text, status_text, size); + task->data.on_progress.status_text = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(task->data.on_progress.status_text, status_text, size); }else { - data->status_text = NULL; + task->data.on_progress.status_text = NULL; } - PostMessageW(This->notif_hwnd, WM_MK_ONPROGRESS, 0, (LPARAM)data); + push_task(task); } static void dump_BINDINFO(BINDINFO *bi) @@ -606,6 +712,7 @@ static ULONG WINAPI Binding_Release(IBin IStream_Release(STREAM(This->stream)); ReleaseBindInfo(&This->bindinfo); + DeleteCriticalSection(&This->section); HeapFree(GetProcessHeap(), 0, This->mime); HeapFree(GetProcessHeap(), 0, This->url); @@ -1041,11 +1148,15 @@ static HRESULT Binding_Create(LPCWSTR ur ret->apartment_thread = GetCurrentThreadId(); ret->notif_hwnd = get_notif_hwnd(); ret->verified_mime = FALSE; + ret->continue_call = 0; + ret->task_queue_head = ret->task_queue_tail = NULL; memset(&ret->bindinfo, 0, sizeof(BINDINFO)); ret->bindinfo.cbSize = sizeof(BINDINFO); ret->bindf = 0; + InitializeCriticalSection(&ret->section); + hres = get_callback(pbc, &ret->callback); if(FAILED(hres)) { WARN("Could not get IBindStatusCallback\n");
1
0
0
0
Jacek Caban : urlmon: Make suse that every OnProgress call is in an apartment thread.
by Alexandre Julliard
01 Jun '06
01 Jun '06
Module: wine Branch: refs/heads/master Commit: 89d9287af6f756a7c1e94f520655327b5cfd9304 URL:
http://source.winehq.org/git/?p=wine.git;a=commit;h=89d9287af6f756a7c1e94f5…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed May 31 19:43:01 2006 +0200 urlmon: Make suse that every OnProgress call is in an apartment thread. --- dlls/urlmon/binding.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index e64cef7..22a4ea2 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -773,18 +773,15 @@ static HRESULT WINAPI InternetProtocolSi FindMimeFromData(NULL, This->url, This->stream->buf, min(This->stream->buf_size, 255), This->mime, 0, &mime, 0); - IBindStatusCallback_OnProgress(This->callback, ulProgress, ulProgressMax, - BINDSTATUS_MIMETYPEAVAILABLE, mime); + on_progress(This, ulProgress, ulProgressMax, BINDSTATUS_MIMETYPEAVAILABLE, mime); } if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) { - IBindStatusCallback_OnProgress(This->callback, ulProgress, ulProgressMax, - BINDSTATUS_BEGINDOWNLOADDATA, This->url); + on_progress(This, ulProgress, ulProgressMax, BINDSTATUS_BEGINDOWNLOADDATA, This->url); } if(grfBSCF & BSCF_LASTDATANOTIFICATION) - IBindStatusCallback_OnProgress(This->callback, ulProgress, ulProgressMax, - BINDSTATUS_ENDDOWNLOADDATA, This->url); + on_progress(This, ulProgress, ulProgressMax, BINDSTATUS_ENDDOWNLOADDATA, This->url); if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) IInternetProtocol_LockRequest(This->protocol, 0);
1
0
0
0
← Newer
1
...
82
83
84
85
86
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Results per page:
10
25
50
100
200