AcessNative - Bugfixes 'r' us, GUI can start and render (partially)
[tpg/acess2.git] / AcessNative / acesskernel_src / threads.c
index c390a03..9de6140 100644 (file)
@@ -15,6 +15,7 @@
 #include <acess.h>
 #include <mutex.h>
 #include <semaphore.h>
+#include <rwlock.h>
 #include <events.h>
 #include <threads_int.h>
 
@@ -119,6 +120,9 @@ tThread *Threads_CloneTCB(tThread *TemplateThread)
        
        ret->ThreadName = strdup(TemplateThread->ThreadName);
        ret->EventSem = SDL_CreateSemaphore(0);
+       if( !ret->EventSem ) {
+               Log_Warning("Threads", "Semaphore creation failed - %s", SDL_GetError());
+       }
        
        ret->WaitingThreads = NULL;
        ret->WaitingThreadsEnd = NULL;
@@ -333,6 +337,33 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
        return AmmountToAdd;
 }
 
+// --------------------------------------------------------------------
+// Event handling
+// --------------------------------------------------------------------
+int RWLock_AcquireRead(tRWLock *Lock)
+{
+       if( !Lock->ReaderWaiting ) {
+               Lock->ReaderWaiting = malloc(sizeof(pthread_rwlock_t));
+               pthread_rwlock_init( (void*)Lock->ReaderWaiting, 0 );
+       }
+       pthread_rwlock_rdlock( (void*)Lock->ReaderWaiting );
+       return 0;
+}
+int RWLock_AcquireWrite(tRWLock *Lock)
+{
+       if( !Lock->ReaderWaiting ) {
+               Lock->ReaderWaiting = malloc(sizeof(pthread_rwlock_t));
+               pthread_rwlock_init( (void*)Lock->ReaderWaiting, 0 );
+       }
+       pthread_rwlock_wrlock( (void*)Lock->ReaderWaiting );
+       return 0;
+}
+void RWLock_Release(tRWLock *Lock)
+{
+       pthread_rwlock_unlock( (void*)Lock->ReaderWaiting );
+}
+
+
 // --------------------------------------------------------------------
 // Event handling
 // --------------------------------------------------------------------
@@ -345,12 +376,22 @@ Uint32 Threads_WaitEvents(Uint32 Mask)
        gpCurrentThread->WaitMask = Mask;
        if( !(gpCurrentThread->Events & Mask) )
        {
-               SDL_SemWait( gpCurrentThread->EventSem );
+               do {
+                       if( SDL_SemWait( gpCurrentThread->EventSem ) == -1 ) {
+                               Log_Warning("Threads", "Wait on eventsem of %p, %p failed",
+                                       gpCurrentThread, gpCurrentThread->EventSem);
+                               break;
+                       }
+               } while(SDL_SemValue(gpCurrentThread->EventSem));
+               // NOTE: While loop catches multiple event occurances
+               Log_Debug("Threads", "Woken from nap (%i here)", SDL_SemValue(gpCurrentThread->EventSem));
        }
        rv = gpCurrentThread->Events & Mask;
        gpCurrentThread->Events &= ~Mask;
        gpCurrentThread->WaitMask = -1;
-       
+
+       Log_Debug("Threads", "- rv = %x", rv);
+
        return rv;
 }
 
@@ -359,7 +400,7 @@ void Threads_PostEvent(tThread *Thread, Uint32 Events)
        Thread->Events |= Events;
        Log_Debug("Threads", "Trigger event %x (->Events = %p)", Events, Thread->Events);
        
-       if( Thread->WaitMask & Events ) {
+       if( Events == 0 || Thread->WaitMask & Events ) {
                SDL_SemPost( Thread->EventSem );
 //             Log_Debug("Threads", "Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
        }

UCC git Repository :: git.ucc.asn.au