From 84bcc5642a5f58807493b776b565c28679870c4e Mon Sep 17 00:00:00 2001 From: sesse Date: Thu, 4 Mar 2010 15:23:52 +0000 Subject: Fix return values of WaitForSingleObject when checking an event. These were simply inverted compared to what they should be. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30830 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/win32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'loader') diff --git a/loader/win32.c b/loader/win32.c index f560ffdfb4..b69cf103f1 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -817,8 +817,8 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) switch(ml->type) { case 0: /* Event */ if (duration == 0) { /* Check Only */ - if (ml->state == 1) ret = WAIT_FAILED; - else ret = WAIT_OBJECT_0; + if (ml->state == 1) ret = WAIT_OBJECT_0; + else ret = WAIT_FAILED; } if (duration == -1) { /* INFINITE */ if (ml->state == 0) -- cgit v1.2.3 From c6fb73d6b1e9cbcb469b4a98352c6f3c504ba7fc Mon Sep 17 00:00:00 2001 From: sesse Date: Thu, 4 Mar 2010 15:28:02 +0000 Subject: Fix manual reset behavior of Win32 events. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Events have a “reset” member that specify if they flag is automatically set back on read/wait. However, this was populated by bManualReset, so the flag was inverted and once an event was set, it would forever be counted as so. Fixed by inverting the flag. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30831 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/win32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'loader') diff --git a/loader/win32.c b/loader/win32.c index b69cf103f1..20eda49c01 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -736,7 +736,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, mlist->pm=pm; mlist->pc=pc; mlist->state=bInitialState; - mlist->reset=bManualReset; + mlist->reset=!bManualReset; if(name) strncpy(mlist->name, name, 127); else -- cgit v1.2.3 From f32e92b849b99e6001bc426c08edabf07762ca45 Mon Sep 17 00:00:00 2001 From: sesse Date: Thu, 4 Mar 2010 15:31:54 +0000 Subject: Fix crashes in CreatePalette by fixing the LOGPALETTE struct. CreatePalette had problems for me, and looking at the code it was quite obvious why; someone had reversed the order of the two elements of the LOGPALETTE struct, causing it to allocate and copy a bogus amount of memory. Why on earth anybody would want to do that is beyond me; whoever did it even left a comment, but it wasn't very helpful, as it crashed nevertheless. :-) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30832 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/win32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'loader') diff --git a/loader/win32.c b/loader/win32.c index 20eda49c01..f31de74730 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -4701,10 +4701,9 @@ typedef struct tagPALETTEENTRY { BYTE peFlags; } PALETTEENTRY; -/* reversed the first 2 entries */ typedef struct tagLOGPALETTE { - WORD palNumEntries; WORD palVersion; + WORD palNumEntries; PALETTEENTRY palPalEntry[1]; } LOGPALETTE; -- cgit v1.2.3 From 5fb74d581fbd03748aa94782645dec2e14e19b4d Mon Sep 17 00:00:00 2001 From: sesse Date: Thu, 4 Mar 2010 15:57:08 +0000 Subject: Make emulated Win32 critical sections thread safe. Earlier, cs->locked was accessed outside the mutex to get around the problem that default pthread mutexes are not recursive (ie., you cannot do a double-lock from the same thread), causing a thread-safety problem, as both detected by Helgrind and showing up in some multithreaded codecs. The ideal solution here would be to simply use recursive pthread mutexes, but there were concerns about reduced debuggability and possibly portability. Thus, instead, rewrite the critical sections to be a simple lock count (with owner) protected by a regular mutex. Whenever a thread wants to enter the critical section and lock_count is not 0, it sleeps on a special event that tells it when the critical section is available. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30837 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/win32.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'loader') diff --git a/loader/win32.c b/loader/win32.c index f31de74730..2906d14102 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -350,7 +350,8 @@ struct CRITSECT { pthread_t id; pthread_mutex_t mutex; - int locked; + pthread_cond_t unlocked; + int lock_count; long deadbeef; }; @@ -1331,7 +1332,8 @@ static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) return; } pthread_mutex_init(&cs->mutex, NULL); - cs->locked = 0; + pthread_cond_init(&cs->unlocked, NULL); + cs->lock_count = 0; critsecs_list[i].cs_win = c; critsecs_list[i].cs_unix = cs; dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n", @@ -1342,7 +1344,8 @@ static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION), 0, AREATYPE_CRITSECT); pthread_mutex_init(&cs->mutex, NULL); - cs->locked=0; + pthread_cond_init(&cs->unlocked, NULL); + cs->lock_count = 0; cs->deadbeef = 0xdeadbeef; *(void**)c = cs; } @@ -1374,12 +1377,17 @@ static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c) #endif dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c); } - if(cs->locked) - if(cs->id==pthread_self()) - return; pthread_mutex_lock(&(cs->mutex)); - cs->locked=1; - cs->id=pthread_self(); + if (cs->lock_count > 0 && cs->id == pthread_self()) { + cs->lock_count++; + } else { + while (cs->lock_count != 0) { + pthread_cond_wait(&(cs->unlocked), &(cs->mutex)); + } + cs->lock_count = 1; + cs->id = pthread_self(); + } + pthread_mutex_unlock(&(cs->mutex)); return; } static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c) @@ -1396,13 +1404,16 @@ static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c) dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c); return; } - if (cs->locked) - { - cs->locked=0; - pthread_mutex_unlock(&(cs->mutex)); + pthread_mutex_lock(&(cs->mutex)); + if (cs->lock_count == 0) { + dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c); + } else { + cs->lock_count--; } - else - dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c); + if (cs->lock_count == 0) { + pthread_cond_signal(&(cs->unlocked)); + } + pthread_mutex_unlock(&(cs->mutex)); return; } @@ -1424,14 +1435,16 @@ static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c) return; } - if (cs->locked) + pthread_mutex_lock(&(cs->mutex)); + if (cs->lock_count > 0) { - dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c); - pthread_mutex_unlock(&(cs->mutex)); + dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c); } + pthread_mutex_unlock(&(cs->mutex)); #ifndef GARBAGE pthread_mutex_destroy(&(cs->mutex)); + pthread_cond_destroy(&(cs->unlocked)); // released by GarbageCollector in my_relase otherwise #endif my_release(cs); -- cgit v1.2.3 From 61f351dc908b4868290aa69629e22befcb633ee4 Mon Sep 17 00:00:00 2001 From: sesse Date: Fri, 5 Mar 2010 11:11:47 +0000 Subject: Support thread handles in WaitForSingleObject. Some codecs need this for clean shutdown (as opposed to a crash); we don't really support timed wait since POSIX doesn't, but it doesn't seem necessary. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30843 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/win32.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'loader') diff --git a/loader/win32.c b/loader/win32.c index 2906d14102..2282258d8d 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -569,16 +569,28 @@ static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv) #define MODULE_HANDLE_winmm ((HMODULE)0x128) #define MODULE_HANDLE_psapi ((HMODULE)0x129) +/* fake EXE struct to make msvcrt8+ not to crash: + it checks all exe sections for a section named .mixcrt + we fake a section with that name, so the crt will avoid + using Encode/Decode Pointer, as we was a posix binary */ +static const struct { + IMAGE_DOS_HEADER doshdr; + IMAGE_NT_HEADERS nthdr; + IMAGE_SECTION_HEADER opthdr; +} __attribute__((__packed__)) mp_exe = { + .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER), + .nthdr.FileHeader.NumberOfSections = 1, + .nthdr.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */ + .opthdr.Name = ".mixcrt" +}; + static HMODULE WINAPI expGetModuleHandleA(const char* name) { WINE_MODREF* wm; HMODULE result; if(!name) -#ifdef CONFIG_QTX_CODECS - result=1; -#else - result=0; -#endif + result=(HMODULE)&mp_exe.doshdr; + else { wm=MODULE_FindModule(name); @@ -787,6 +799,7 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) // FIXME FIXME FIXME - this value is sometime unititialize !!! int ret = WAIT_FAILED; mutex_list* pp=mlist; + th_list* tp=list; if(object == (void*)0xcfcf9898) { /** @@ -802,6 +815,17 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) } dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration); + // See if this is a thread. + while (tp && (tp->thread != object)) + tp = tp->prev; + if (tp) { + if (pthread_join(*(pthread_t*)object, NULL) == 0) { + return (void*)WAIT_OBJECT_0; + } else { + return (void*)WAIT_FAILED; + } + } + // loop below was slightly fixed - its used just for checking if // this object really exists in our list if (!ml) -- cgit v1.2.3 From c27b99441b75a8a6c49583c70e4e27d4f61a35a5 Mon Sep 17 00:00:00 2001 From: sesse Date: Fri, 5 Mar 2010 11:14:07 +0000 Subject: Partial revert of r30843. Some extra changes snuck into my commit; they'll probably be reviewed and committed to Subversion eventually, but were not part of the fix for WaitForSingleObject on thread handles. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30844 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/win32.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'loader') diff --git a/loader/win32.c b/loader/win32.c index 2282258d8d..e224d24aec 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -569,28 +569,16 @@ static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv) #define MODULE_HANDLE_winmm ((HMODULE)0x128) #define MODULE_HANDLE_psapi ((HMODULE)0x129) -/* fake EXE struct to make msvcrt8+ not to crash: - it checks all exe sections for a section named .mixcrt - we fake a section with that name, so the crt will avoid - using Encode/Decode Pointer, as we was a posix binary */ -static const struct { - IMAGE_DOS_HEADER doshdr; - IMAGE_NT_HEADERS nthdr; - IMAGE_SECTION_HEADER opthdr; -} __attribute__((__packed__)) mp_exe = { - .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER), - .nthdr.FileHeader.NumberOfSections = 1, - .nthdr.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */ - .opthdr.Name = ".mixcrt" -}; - static HMODULE WINAPI expGetModuleHandleA(const char* name) { WINE_MODREF* wm; HMODULE result; if(!name) - result=(HMODULE)&mp_exe.doshdr; - +#ifdef CONFIG_QTX_CODECS + result=1; +#else + result=0; +#endif else { wm=MODULE_FindModule(name); -- cgit v1.2.3 From fbb74e16a38d6a5af31a7fb369195988f7414766 Mon Sep 17 00:00:00 2001 From: sesse Date: Fri, 5 Mar 2010 23:09:36 +0000 Subject: Make GetModuleHandle(NULL) return a valid pointer. Some codecs, and more recently Microsoft's CRT library, expect GetModuleHandle(NULL) to return a pointer to the program's PE header mapped in memory. Thus, just returning 0x0 or 0x1 won't do it anymore, so create a minimal PE header and return that. Patch originally by Gianluigi Tiesi ( mplayer (at) netfarm (dot) it ). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30848 b3059339-0415-0410-9bf9-f77b7e298cf2 --- loader/win32.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'loader') diff --git a/loader/win32.c b/loader/win32.c index e224d24aec..08985a28e1 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -569,16 +569,30 @@ static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv) #define MODULE_HANDLE_winmm ((HMODULE)0x128) #define MODULE_HANDLE_psapi ((HMODULE)0x129) +// Fake PE header, since some software (and the Microsoft CRT v8 and newer) +// assume GetModuleHandle(NULL) returns a pointer to a PE header. +// We simulate a very simple header with only one section. +// +// NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume +// it's running in a POSIX binary, and stop using EncodePointer/DecodePointer. +static const struct { + IMAGE_DOS_HEADER doshdr; + IMAGE_NT_HEADERS nthdr; + IMAGE_SECTION_HEADER opthdr; +} __attribute__((__packed__)) mp_exe = { + .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER), + .nthdr.FileHeader.NumberOfSections = 1, + .nthdr.FileHeader.SizeOfOptionalHeader = + sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */ + .opthdr.Name = ".text" +}; + static HMODULE WINAPI expGetModuleHandleA(const char* name) { WINE_MODREF* wm; HMODULE result; if(!name) -#ifdef CONFIG_QTX_CODECS - result=1; -#else - result=0; -#endif + result=(HMODULE)&mp_exe.doshdr; else { wm=MODULE_FindModule(name); -- cgit v1.2.3