summaryrefslogtreecommitdiffstats
path: root/loader/win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader/win32.c')
-rw-r--r--loader/win32.c196
1 files changed, 163 insertions, 33 deletions
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);
}