diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2010-03-10 03:18:42 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2010-03-10 03:18:42 +0200 |
commit | 0269d22d32fb380e7128ca0c60f6f1638c6dab70 (patch) | |
tree | 53ba64153d9ef930f73458138478a6d0def381ce /loader | |
parent | 240550bbb94653907faa6e0bb1c5ac3d279cc252 (diff) | |
parent | 97ef28ad9aa2f34aea0779062976ad4294c0af51 (diff) | |
download | mpv-0269d22d32fb380e7128ca0c60f6f1638c6dab70.tar.bz2 mpv-0269d22d32fb380e7128ca0c60f6f1638c6dab70.tar.xz |
Merge svn changes up to r30876
Diffstat (limited to 'loader')
-rw-r--r-- | loader/dshow/DS_Filter.c | 7 | ||||
-rw-r--r-- | loader/dshow/allocator.c | 8 | ||||
-rw-r--r-- | loader/dshow/graph.c | 163 | ||||
-rw-r--r-- | loader/dshow/graph.h | 57 | ||||
-rw-r--r-- | loader/dshow/guids.c | 4 | ||||
-rw-r--r-- | loader/dshow/guids.h | 2 | ||||
-rw-r--r-- | loader/dshow/interfaces.h | 28 | ||||
-rw-r--r-- | loader/qtx/qtxsdk/components.h | 6 | ||||
-rw-r--r-- | loader/win32.c | 196 |
9 files changed, 431 insertions, 40 deletions
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c index e3102cf264..693d59c25f 100644 --- a/loader/dshow/DS_Filter.c +++ b/loader/dshow/DS_Filter.c @@ -5,6 +5,7 @@ #include "config.h" #include "DS_Filter.h" +#include "graph.h" #include "loader/drv.h" #include "loader/com.h" #include <stdio.h> @@ -125,6 +126,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, // char eb[250]; const char* em = NULL; MemAllocator* tempAll; + FilterGraph* graph; ALLOCATOR_PROPERTIES props,props1; DS_Filter* This = malloc(sizeof(DS_Filter)); if (!This) @@ -166,6 +168,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, ULONG fetched; HRESULT result; unsigned int i; + static const uint16_t filter_name[] = { 'F', 'i', 'l', 't', 'e', 'r', 0 }; This->m_iHandle = LoadLibraryA(dllname); if (!This->m_iHandle) @@ -199,6 +202,10 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, em = "object does not provide IBaseFilter interface"; break; } + + graph = FilterGraphCreate(); + result = This->m_pFilter->vt->JoinFilterGraph(This->m_pFilter, (IFilterGraph*)graph, filter_name); + // enumerate pins result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); if (result || !enum_pins) diff --git a/loader/dshow/allocator.c b/loader/dshow/allocator.c index b75f1bebfb..a90bd9d3d2 100644 --- a/loader/dshow/allocator.c +++ b/loader/dshow/allocator.c @@ -116,7 +116,7 @@ static inline avm_list_t* avm_list_find(avm_list_t* head, void* member) static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv) { - IMemAllocator* p; + IUnknown* p; int result; if (!ppv) return -1; @@ -124,9 +124,9 @@ static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** pp if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID))) return -1; - p = (IMemAllocator*) MemAllocatorCreate(); - result = p->vt->QueryInterface((IUnknown*)p, iid, ppv); - p->vt->Release((IUnknown*)p); + p = (IUnknown*) MemAllocatorCreate(); + result = p->vt->QueryInterface(p, iid, ppv); + p->vt->Release(p); return result; } diff --git a/loader/dshow/graph.c b/loader/dshow/graph.c new file mode 100644 index 0000000000..01bf6c7253 --- /dev/null +++ b/loader/dshow/graph.c @@ -0,0 +1,163 @@ +/* + * Implemention of FilterGraph. Based on allocator.c. + * Copyright 2010 Steinar H. Gunderson + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Modified for use with MPlayer, detailed changelog at + * http://svn.mplayerhq.hu/mplayer/trunk/ + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "config.h" +#include "loader/com.h" +#include "loader/dshow/graph.h" +#include "loader/wine/winerror.h" + +// How many FilterGraph objects exist. +// Used for knowing when to register and unregister the class in COM. +static int GraphKeeper = 0; + +static long FilterGraph_CreateGraph(GUID* clsid, const GUID* iid, void** ppv) +{ + IUnknown* p; + int result; + if (!ppv) + return -1; + *ppv = 0; + if (memcmp(clsid, &CLSID_FilterGraph, sizeof(*clsid))) + return -1; + + p = (IUnknown*) FilterGraphCreate(); + result = p->vt->QueryInterface(p, iid, ppv); + p->vt->Release(p); + + return result; +} + +static void FilterGraph_Destroy(FilterGraph* This) +{ + Debug printf("FilterGraph_Destroy(%p) called (%d, %d)\n", This, This->refcount, GraphKeeper); +#ifdef WIN32_LOADER + if (--GraphKeeper == 0) + UnregisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph); +#endif + free(This->vt); + free(This); +} + +HRESULT STDCALL FilterGraph_AddFilter(FilterGraph* This, + IBaseFilter* pFilter, + unsigned short* pName) +{ + Debug printf("FilterGraph_AddFilter(%p) called\n", This); + return E_NOTIMPL; +} + +HRESULT STDCALL FilterGraph_RemoveFilter(FilterGraph* This, IBaseFilter* pFilter) +{ + Debug printf("FilterGraph_RemoveFilter(%p) called\n", This); + return E_NOTIMPL; +} + +HRESULT STDCALL FilterGraph_EnumFilters(FilterGraph* This, IEnumFilters** ppEnum) +{ + Debug printf("FilterGraph_EnumFilters(%p) called\n", This); + return E_NOTIMPL; +} + +HRESULT STDCALL FilterGraph_FindFilterByName(FilterGraph* This, + unsigned short* pName, + IBaseFilter** ppFilter) +{ + Debug printf("FilterGraph_FindFilterByName(%p) called\n", This); + return E_NOTIMPL; +} + +HRESULT STDCALL FilterGraph_ConnectDirect(FilterGraph* This, + IPin* ppinOut, + IPin* ppinIn, + const AM_MEDIA_TYPE* pmt) +{ + Debug printf("FilterGraph_ConnectDirect(%p) called\n", This); + return E_NOTIMPL; +} + +HRESULT STDCALL FilterGraph_Reconnect(FilterGraph* This, IPin* ppin) +{ + Debug printf("FilterGraph_Reconnect(%p) called\n", This); + return E_NOTIMPL; +} + +HRESULT STDCALL FilterGraph_Disconnect(FilterGraph* This, IPin* ppin) +{ + Debug printf("FilterGraph_Disconnect(%p) called\n", This); + return E_NOTIMPL; +} + +HRESULT STDCALL FilterGraph_SetDefaultSyncSource(FilterGraph* This) +{ + Debug printf("FilterGraph_SetDefaultSyncSource(%p) called\n", This); + return E_NOTIMPL; +} + +IMPLEMENT_IUNKNOWN(FilterGraph) + +FilterGraph* FilterGraphCreate() +{ + FilterGraph* This = calloc(1, sizeof(*This)); + + if (!This) + return NULL; + + Debug printf("FilterGraphCreate() called -> %p\n", This); + + This->refcount = 1; + + This->vt = calloc(1, sizeof(*This->vt)); + + if (!This->vt) { + free(This); + return NULL; + } + + This->vt->QueryInterface = FilterGraph_QueryInterface; + This->vt->AddRef = FilterGraph_AddRef; + This->vt->Release = FilterGraph_Release; + + This->vt->AddFilter = FilterGraph_AddFilter; + This->vt->RemoveFilter = FilterGraph_RemoveFilter; + This->vt->EnumFilters = FilterGraph_EnumFilters; + This->vt->FindFilterByName = FilterGraph_FindFilterByName; + This->vt->ConnectDirect = FilterGraph_ConnectDirect; + This->vt->Reconnect = FilterGraph_Reconnect; + This->vt->Disconnect = FilterGraph_Disconnect; + This->vt->SetDefaultSyncSource = FilterGraph_SetDefaultSyncSource; + + This->interfaces[0] = IID_IUnknown; + This->interfaces[1] = IID_IFilterGraph; + +#ifdef WIN32_LOADER + if (GraphKeeper++ == 0) + RegisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph); +#endif + + return This; +} + diff --git a/loader/dshow/graph.h b/loader/dshow/graph.h new file mode 100644 index 0000000000..7667f5a39e --- /dev/null +++ b/loader/dshow/graph.h @@ -0,0 +1,57 @@ +#ifndef MPLAYER_GRAPH_H +#define MPLAYER_GRAPH_H + +/* + * Copyright 2010 Steinar H. Gunderson + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "interfaces.h" +#include "cmediasample.h" + +typedef struct FilterGraph FilterGraph; + +struct FilterGraph { + IFilterGraph_vt* vt; + DECLARE_IUNKNOWN(); + GUID interfaces[2]; + + HRESULT STDCALL (*AddFilter)(FilterGraph* This, + /* [in] */ IBaseFilter* pFilter, + /* [string][in] */ unsigned short* pName); + HRESULT STDCALL (*RemoveFilter)(FilterGraph* This, + /* [in] */ IBaseFilter* pFilter); + HRESULT STDCALL (*EnumFilters)(FilterGraph* This, + /* [out] */ IEnumFilters** ppEnum); + HRESULT STDCALL (*FindFilterByName)(FilterGraph* This, + /* [string][in] */ unsigned short* pName, + /* [out] */ IBaseFilter** ppFilter); + HRESULT STDCALL (*ConnectDirect)(FilterGraph* This, + /* [in] */ IPin* ppinOut, + /* [in] */ IPin* ppinIn, + /* [in] */ const AM_MEDIA_TYPE* pmt); + HRESULT STDCALL (*Reconnect)(FilterGraph* This, + /* [in] */ IPin* ppin); + HRESULT STDCALL (*Disconnect)(FilterGraph* This, + /* [in] */ IPin* ppin); + HRESULT STDCALL (*SetDefaultSyncSource)(FilterGraph* This); +}; + +FilterGraph* FilterGraphCreate(void); + +#endif /* MPLAYER_GRAPH_H */ diff --git a/loader/dshow/guids.c b/loader/dshow/guids.c index 73cf7f5456..5d793bb14d 100644 --- a/loader/dshow/guids.c +++ b/loader/dshow/guids.c @@ -11,6 +11,8 @@ const GUID IID_IBaseFilter={0x56a86895, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID IID_IEnumPins={0x56a86892, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; +const GUID IID_IFilterGraph={0x56a8689f, 0x0ad4, 0x11ce, + {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID IID_IEnumMediaTypes={0x89c31040, 0x846b, 0x11ce, {0x97, 0xd3, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; const GUID IID_IMemInputPin={0x56a8689d, 0x0ad4, 0x11ce, @@ -64,6 +66,8 @@ const GUID MEDIASUBTYPE_I420={0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_IF09={0x39304649, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID CLSID_FilterGraph={0xe436ebb3, 0x524f, 0x11ce, + {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0, {0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45}}; const GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2, diff --git a/loader/dshow/guids.h b/loader/dshow/guids.h index 80686558b4..76a4970d27 100644 --- a/loader/dshow/guids.h +++ b/loader/dshow/guids.h @@ -46,6 +46,7 @@ typedef GUID IID; extern const GUID IID_IBaseFilter; extern const GUID IID_IEnumPins; extern const GUID IID_IEnumMediaTypes; +extern const GUID IID_IFilterGraph; extern const GUID IID_IMemInputPin; extern const GUID IID_IMemAllocator; extern const GUID IID_IMediaSample; @@ -54,6 +55,7 @@ extern const GUID IID_Iv50Hidden; extern const GUID CLSID_DivxDecompressorCF; extern const GUID IID_IDivxFilterInterface; extern const GUID CLSID_IV50_Decoder; +extern const GUID CLSID_FilterGraph; extern const GUID CLSID_MemoryAllocator; extern const GUID MEDIATYPE_Video; // avoid a clash with MinGW-W64 libuuid diff --git a/loader/dshow/interfaces.h b/loader/dshow/interfaces.h index 5c927a55be..af9544ada5 100644 --- a/loader/dshow/interfaces.h +++ b/loader/dshow/interfaces.h @@ -329,4 +329,32 @@ struct IDivxFilterInterface_vt HRESULT STDCALL ( *get_AspectRatio )(IDivxFilterInterface* This, int* x, IDivxFilterInterface* Thisit, int* y); }; +typedef struct IEnumFilters IEnumFilters; + +typedef struct IFilterGraph_vt +{ + INHERIT_IUNKNOWN(); + + HRESULT STDCALL ( *AddFilter )(IFilterGraph* This, + /* [in] */ IBaseFilter* pFilter, + /* [string][in] */ unsigned short* pName); + HRESULT STDCALL ( *RemoveFilter )(IFilterGraph* This, + /* [in] */ IBaseFilter* pFilter); + HRESULT STDCALL ( *EnumFilters )(IFilterGraph* This, + /* [out] */ IEnumFilters** ppEnum); + HRESULT STDCALL ( *FindFilterByName )(IFilterGraph* This, + /* [string][in] */ unsigned short* pName, + /* [out] */ IBaseFilter** ppFilter); + HRESULT STDCALL ( *ConnectDirect )(IFilterGraph* This, + /* [in] */ IPin* ppinOut, + /* [in] */ IPin* ppinIn, + /* [in] */ const AM_MEDIA_TYPE* pmt); + HRESULT STDCALL ( *Reconnect )(IFilterGraph* This, + /* [in] */ IPin* ppin); + HRESULT STDCALL ( *Disconnect )(IFilterGraph* This, + /* [in] */ IPin* ppin); + HRESULT STDCALL ( *SetDefaultSyncSource )(IFilterGraph* This); +} IFilterGraph_vt; +struct IFilterGraph { IFilterGraph_vt *vt; }; + #endif /*MPLAYER_INTERFACES_H */ diff --git a/loader/qtx/qtxsdk/components.h b/loader/qtx/qtxsdk/components.h index 08b883099c..2e42a0412f 100644 --- a/loader/qtx/qtxsdk/components.h +++ b/loader/qtx/qtxsdk/components.h @@ -12,7 +12,7 @@ typedef unsigned char Boolean; typedef unsigned char Str31[32]; typedef int32_t Fixed; -typedef int32_t OSErr; +typedef int16_t OSErr; typedef int OSType; typedef int32_t ComponentResult; @@ -641,10 +641,10 @@ static inline void dump_ImageDescription(void* xxx){ printf("=============== ImageDescription at %p ==================\n",xxx); printf("idSize=0x%X fourcc=0x%08X\n",id->idSize,id->cType); printf("ver=%d rev=%d vendor=0x%08X\n",id->version,id->revisionLevel,id->vendor); - printf("tempQ=%d spatQ=%d dim: %d x %d dpi: %d x %d depth: %d\n", + printf("tempQ=%d spatQ=%d dim: %d x %d dpi: %.2f x %.2f depth: %d\n", id->temporalQuality,id->spatialQuality, id->width, id->height, - id->hRes, id->vRes, + id->hRes / 65536.0, id->vRes / 65536.0, id->depth); printf("dataSize=%d frameCount=%d clutID=%d\n",id->dataSize, id->frameCount, id->clutID); printf("name='%.*s'\n",((char*)(&id->name))[0],((char*)(&id->name))+1); diff --git a/loader/win32.c b/loader/win32.c index 08985a28e1..d540e6dfe2 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -240,6 +240,7 @@ typedef struct th_list_t{ //static int heap_counter=0; static tls_t* g_tls=NULL; static th_list* list=NULL; +static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; #if 0 static void test_heap(void) @@ -638,6 +639,7 @@ static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, printf( "WARNING: CreateThread flags not supported\n"); if(dwThreadId) *dwThreadId=(long)pth; + pthread_mutex_lock(&list_lock); if(list==NULL) { list=my_mreq(sizeof(th_list), 1); @@ -651,11 +653,19 @@ static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, list=list->next; } list->thread=pth; + pthread_mutex_unlock(&list_lock); dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n", pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth); return pth; } +static DWORD WINAPI expResumeThread(HANDLE hThread) +{ + int ret = 1; + dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret); + return ret; +} + struct mutex_list_t; struct mutex_list_t @@ -667,14 +677,18 @@ struct mutex_list_t char reset; char name[128]; int semaphore; + int lock_count; + pthread_t owner; struct mutex_list_t* next; struct mutex_list_t* prev; }; typedef struct mutex_list_t mutex_list; static mutex_list* mlist=NULL; +static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER; void destroy_event(void* event) { + pthread_mutex_lock(&mlist_lock); mutex_list* pp=mlist; // printf("garbage collector: destroy_event(%x)\n", event); while(pp) @@ -696,10 +710,12 @@ void destroy_event(void* event) } printf("0\n"); */ + pthread_mutex_unlock(&mlist_lock); return; } pp=pp->prev; } + pthread_mutex_unlock(&mlist_lock); } static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, @@ -707,6 +723,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, { pthread_mutex_t *pm; pthread_cond_t *pc; + void *ret; /* mutex_list* pp; pp=mlist; @@ -717,6 +734,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, } printf("0\n"); */ + pthread_mutex_lock(&mlist_lock); if(mlist!=NULL) { mutex_list* pp=mlist; @@ -727,6 +745,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, { dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n", pSecAttr, bManualReset, bInitialState, name, name, pp->pm); + pthread_mutex_unlock(&mlist_lock); return pp->pm; } }while((pp=pp->prev) != NULL); @@ -768,7 +787,9 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, else dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n", pSecAttr, bManualReset, bInitialState, mlist); - return mlist; + ret = mlist; + pthread_mutex_unlock(&mlist_lock); + return ret; } static void* WINAPI expSetEvent(void* event) @@ -800,8 +821,8 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) mutex_list *ml = (mutex_list *)object; // FIXME FIXME FIXME - this value is sometime unititialize !!! int ret = WAIT_FAILED; - mutex_list* pp=mlist; - th_list* tp=list; + mutex_list* pp; + th_list* tp; if(object == (void*)0xcfcf9898) { /** @@ -818,8 +839,11 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration); // See if this is a thread. + pthread_mutex_lock(&list_lock); + tp=list; while (tp && (tp->thread != object)) tp = tp->prev; + pthread_mutex_unlock(&list_lock); if (tp) { if (pthread_join(*(pthread_t*)object, NULL) == 0) { return (void*)WAIT_OBJECT_0; @@ -832,8 +856,11 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) // this object really exists in our list if (!ml) return (void*) ret; + pthread_mutex_lock(&mlist_lock); + pp=mlist; while (pp && (pp->pm != ml->pm)) pp = pp->prev; + pthread_mutex_unlock(&mlist_lock); if (!pp) { dbgprintf("WaitForSingleObject: NotFound\n"); return (void*)ret; @@ -872,7 +899,7 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) if (duration == 0) { if(ml->semaphore==0) ret = WAIT_FAILED; else { - ml->semaphore++; + ml->semaphore--; ret = WAIT_OBJECT_0; } } @@ -880,6 +907,25 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration) if (ml->semaphore==0) pthread_cond_wait(ml->pc,ml->pm); ml->semaphore--; + ret = WAIT_OBJECT_0; + } + break; + case 2: /* Mutex */ + if (duration == 0) { + if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED; + else { + ml->lock_count++; + ml->owner = pthread_self(); + ret = WAIT_OBJECT_0; + } + } + if (duration == -1) { + if (ml->lock_count > 0 && ml->owner != pthread_self()) { + pthread_cond_wait(ml->pc,ml->pm); + } + ml->lock_count++; + ml->owner = pthread_self(); + ret = WAIT_OBJECT_0; } break; } @@ -917,31 +963,6 @@ static void WINAPI expExitThread(int retcode) dbgprintf("ExitThread(%d)\n", retcode); pthread_exit(&retcode); } - -static HANDLE WINAPI expCreateMutexA(void *pSecAttr, - char bInitialOwner, const char *name) -{ - HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name); - - if (name) - dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", - pSecAttr, bInitialOwner, name, mlist); - else - dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n", - pSecAttr, bInitialOwner, mlist); -#ifndef CONFIG_QTX_CODECS - /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject - waits for ever, else it works ;) */ - return mlist; -#endif -} - -static int WINAPI expReleaseMutex(HANDLE hMutex) -{ - dbgprintf("ReleaseMutex(%x) => 1\n", hMutex); - /* FIXME:XXX !! not yet implemented */ - return 1; -} #endif static int pf_set = 0; @@ -1801,6 +1822,7 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, { pthread_mutex_t *pm; pthread_cond_t *pc; + HANDLE ret; /* mutex_list* pp; printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>")); @@ -1812,6 +1834,7 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, } printf("0\n"); */ + pthread_mutex_lock(&mlist_lock); if(mlist!=NULL) { mutex_list* pp=mlist; @@ -1822,7 +1845,9 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, { dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n", v1, init_count, max_count, name, name, mlist); - return (HANDLE)mlist; + ret = (HANDLE)mlist; + pthread_mutex_unlock(&mlist_lock); + return ret; } }while((pp=pp->prev) != NULL); } @@ -1861,7 +1886,9 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, else dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n", v1, init_count, max_count, mlist); - return (HANDLE)mlist; + ret = (HANDLE)mlist; + pthread_mutex_unlock(&mlist_lock); + return ret; } static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count) @@ -1882,6 +1909,105 @@ static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_cou return 1; } +static HANDLE WINAPI expCreateMutexA(void *pSecAttr, + char bInitialOwner, const char *name) +{ + pthread_mutex_t *pm; + pthread_cond_t *pc; + HANDLE ret; + pthread_mutex_lock(&mlist_lock); + if(mlist!=NULL) + { + mutex_list* pp=mlist; + if(name!=NULL) + do + { + if((strcmp(pp->name, name)==0) && (pp->type==2)) + { + dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist); + ret = (HANDLE)mlist; + pthread_mutex_unlock(&mlist_lock); + return ret; + } + }while((pp=pp->prev) != NULL); + } + pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX); + pthread_mutex_init(pm, NULL); + pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND); + pthread_cond_init(pc, NULL); + if(mlist==NULL) + { + mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); + mlist->next=mlist->prev=NULL; + } + else + { + mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); + mlist->next->prev=mlist; + mlist->next->next=NULL; + mlist=mlist->next; + } + mlist->type=2; /* Type Mutex */ + mlist->pm=pm; + mlist->pc=pc; + mlist->state=0; + mlist->reset=0; + mlist->semaphore=0; + if (bInitialOwner) { + mlist->owner = pthread_self(); + mlist->lock_count = 1; + } else { + mlist->owner = (pthread_t)0; + mlist->lock_count = 0; + } + if(name!=NULL) + strncpy(mlist->name, name, 64); + else + mlist->name[0]=0; + if(pm==NULL) + dbgprintf("ERROR::: CreateMutexA failure\n"); + if(name) + dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", + pSecAttr, bInitialOwner, name, mlist); + else + dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n", + pSecAttr, bInitialOwner, mlist); + ret = (HANDLE)mlist; + pthread_mutex_unlock(&mlist_lock); + return ret; +} + +static int WINAPI expReleaseMutex(HANDLE hMutex) +{ + mutex_list *ml = (mutex_list *)hMutex; + + pthread_mutex_lock(ml->pm); + if (--ml->lock_count == 0) pthread_cond_signal(ml->pc); + pthread_mutex_unlock(ml->pm); + return 1; +} + +static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal, + HANDLE hObjectToWaitOn, + DWORD dwMilliseconds, + WIN_BOOL bAlertable) { + mutex_list* mlist = (mutex_list*)hObjectToSignal; + + switch (mlist->type) { + case 0: // Event + expSetEvent(mlist); + break; + case 1: // Semaphore + expReleaseSemaphore(mlist, 1, NULL); + break; + case 2: // Mutex + expReleaseMutex(mlist); + break; + default: + dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal); + } + return expWaitForSingleObject(hObjectToWaitOn, dwMilliseconds); +} static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) { @@ -5002,6 +5128,7 @@ struct exports exp_kernel32[]= FF(IsBadStringPtrA, -1) FF(DisableThreadLibraryCalls, -1) FF(CreateThread, -1) + FF(ResumeThread, -1) FF(CreateEventA, -1) FF(SetEvent, -1) FF(ResetEvent, -1) @@ -5009,8 +5136,6 @@ struct exports exp_kernel32[]= #ifdef CONFIG_QTX_CODECS FF(WaitForMultipleObjects, -1) FF(ExitThread, -1) - FF(CreateMutexA,-1) - FF(ReleaseMutex,-1) #endif FF(GetSystemInfo, -1) FF(GetVersion, 332) @@ -5055,6 +5180,9 @@ struct exports exp_kernel32[]= FF(GlobalFree, -1) FF(LoadResource, -1) FF(ReleaseSemaphore, -1) + FF(CreateMutexA, -1) + FF(ReleaseMutex, -1) + FF(SignalObjectAndWait, -1) FF(FindResourceA, -1) FF(LockResource, -1) FF(FreeResource, -1) @@ -5662,5 +5790,7 @@ void my_garbagecollection(void) dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt); #endif g_tls = NULL; + pthread_mutex_lock(&list_lock); list = NULL; + pthread_mutex_unlock(&list_lock); } |