mirror of
https://github.com/mpv-player/mpv
synced 2025-03-01 20:00:37 +00:00
Implement Win32 mutexes.
Implement Win32 mutexes; they used to just be mapped on top of events, which is not the same thing at all. The implementation is pretty much the obvious one, similar to the current critical section implementation and the semaphore implementation; a single lock count protected by a pthread mutex, and an event lockers can sleep on to know when the mutex is available. Also make CreateMutexA and ReleaseMutex available even if QuickTime codecs support is not configured. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30853 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
8e19e87761
commit
b951d42e4e
126
loader/win32.c
126
loader/win32.c
@ -670,6 +670,8 @@ struct mutex_list_t
|
|||||||
char reset;
|
char reset;
|
||||||
char name[128];
|
char name[128];
|
||||||
int semaphore;
|
int semaphore;
|
||||||
|
int lock_count;
|
||||||
|
pthread_t owner;
|
||||||
struct mutex_list_t* next;
|
struct mutex_list_t* next;
|
||||||
struct mutex_list_t* prev;
|
struct mutex_list_t* prev;
|
||||||
};
|
};
|
||||||
@ -901,6 +903,24 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
|
|||||||
ret = WAIT_OBJECT_0;
|
ret = WAIT_OBJECT_0;
|
||||||
}
|
}
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(ml->pm);
|
pthread_mutex_unlock(ml->pm);
|
||||||
|
|
||||||
@ -936,31 +956,6 @@ static void WINAPI expExitThread(int retcode)
|
|||||||
dbgprintf("ExitThread(%d)\n", retcode);
|
dbgprintf("ExitThread(%d)\n", retcode);
|
||||||
pthread_exit(&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
|
#endif
|
||||||
|
|
||||||
static int pf_set = 0;
|
static int pf_set = 0;
|
||||||
@ -1907,6 +1902,83 @@ static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_cou
|
|||||||
return 1;
|
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 long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
|
static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
|
||||||
{
|
{
|
||||||
@ -5034,8 +5106,6 @@ struct exports exp_kernel32[]=
|
|||||||
#ifdef CONFIG_QTX_CODECS
|
#ifdef CONFIG_QTX_CODECS
|
||||||
FF(WaitForMultipleObjects, -1)
|
FF(WaitForMultipleObjects, -1)
|
||||||
FF(ExitThread, -1)
|
FF(ExitThread, -1)
|
||||||
FF(CreateMutexA,-1)
|
|
||||||
FF(ReleaseMutex,-1)
|
|
||||||
#endif
|
#endif
|
||||||
FF(GetSystemInfo, -1)
|
FF(GetSystemInfo, -1)
|
||||||
FF(GetVersion, 332)
|
FF(GetVersion, 332)
|
||||||
@ -5080,6 +5150,8 @@ struct exports exp_kernel32[]=
|
|||||||
FF(GlobalFree, -1)
|
FF(GlobalFree, -1)
|
||||||
FF(LoadResource, -1)
|
FF(LoadResource, -1)
|
||||||
FF(ReleaseSemaphore, -1)
|
FF(ReleaseSemaphore, -1)
|
||||||
|
FF(CreateMutexA, -1)
|
||||||
|
FF(ReleaseMutex, -1)
|
||||||
FF(FindResourceA, -1)
|
FF(FindResourceA, -1)
|
||||||
FF(LockResource, -1)
|
FF(LockResource, -1)
|
||||||
FF(FreeResource, -1)
|
FF(FreeResource, -1)
|
||||||
|
Loading…
Reference in New Issue
Block a user