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