Commit a85a568b authored by Cyril Deguet's avatar Cyril Deguet

- Written the threads/mutex/sem/cond functions for Win32

  Doesn't work very well at the moment but I (re)discovered
  Windows only one week ago ;-)
parent 90e682d3
......@@ -2,7 +2,7 @@
* thread.cpp: thread management
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
* $Id: thread.cpp,v 1.3 2002/03/24 18:54:10 asmax Exp $
* $Id: thread.cpp,v 1.4 2002/03/25 00:42:21 asmax Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
*
......@@ -36,12 +36,13 @@
#include <errno.h>
#elif defined WIN32
#include <windows.h>
#include <process.h>
#endif
#include <stdio.h>
#include <string.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#include <unistd.h>
#endif
#include "common.h"
......@@ -268,16 +269,21 @@ void C_Thread::Create()
pthread_attr_setdetachstate(&sAttr, PTHREAD_CREATE_JOINABLE);
int iRc = pthread_create(&tId, NULL, C_Thread::StartRoutine, this);
pthread_attr_destroy(&sAttr);
#elif defined _WIN32
unsigned threadID;
hThread = (HANDLE)_beginthreadex(NULL, 0,
(PTHREAD_START) C_Thread::StartRoutine, this, 0, &threadID);
int iRc = ( hThread ? 0 : 1 );
#endif
if(iRc)
{
throw E_Exception(GEN_ERR, "Unable to start thread: " + GetErrorMsg());
}
#elif defined WIN32
ASSERT(false);
#endif
// Reference the thread in the list of running threads
s_cThreadList.PushEnd(this);
......@@ -300,12 +306,9 @@ void C_Thread::Cancel()
// Ask for thread cancellation
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
int iRc = pthread_cancel(tId);
#elif defined WIN32
ASSERT(false);
int iRc = GEN_ERR;
int iRc = 0;
#endif
if(iRc)
throw E_Exception(iRc, "Thread cancellation failed: " + GetErrorMsg());
......@@ -333,7 +336,7 @@ void C_Thread::Stop()
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
if(pthread_self() == tId)
#else
if (1)
if (GetCurrentThread() == hThread)
#endif
{
ASSERT(false);
......@@ -348,7 +351,6 @@ void C_Thread::Stop()
// Ask the user work routine to stop its normal processing
StopWork();
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
// Try to join the thread in order to clean the resources it used and
// to synchronise the calling thread with the destruction of this thread
// Seems that there is a bug here in the libpthread: when the thread
......@@ -356,7 +358,12 @@ void C_Thread::Stop()
// the return value of the DoWork method
// Ok, let's try again to see if the pb still occurs
E_Exception* p_eError = NULL;
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
int iRc = pthread_join(tId, (void**)&p_eError);
#elif defined _WIN32
int iRc = 0;
WaitForSingleObject (hThread, INFINITE);
#endif
if(iRc)
{
// Look at thre return code of the joined thread
......@@ -366,10 +373,6 @@ void C_Thread::Stop()
throw e;
}
#elif defined WIN32
ASSERT(false);
#endif
// Cleaning
CleanWork();
......@@ -395,11 +398,11 @@ void C_Thread::Interrupt()
{
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
int iRc = pthread_cancel(tId);
#elif defined _WIN32
int iRc = 0;
#endif
if(iRc)
throw E_Exception(GEN_ERR, "Unable to interrupt thread: " + GetErrorMsg());
#elif defined WIN32
ASSERT(false);
#endif
m_iStatus = THREAD_STATUS_INTERRUPTED;
}
......@@ -440,10 +443,8 @@ bool C_Thread::operator == (const C_Thread& cThread)
{
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
return (this->tId == cThread.tId);
#elif defined WIN32
ASSERT(false);
return false;
return (this->hThread == cThread.hThread);
#endif
};
......@@ -470,9 +471,17 @@ C_Thread* C_Thread::Self()
break;
}
}
#else
ASSERT(false);
#elif defined _WIN32
HANDLE hThread = GetCurrentThread();
for(unsigned int i = 0; i < s_cThreadList.Size(); i++)
{
C_Thread& cCurrent = s_cThreadList[i];
if(cCurrent.hThread == hThread)
{
pResult = &cCurrent;
break;
}
}
#endif
return pResult;
......@@ -535,8 +544,8 @@ C_Mutex::C_Mutex()
ASSERT(!iRc); // The function shouldn't fail
USE(iRc);
#elif defined WIN32
ASSERT(false);
#elif defined _WIN32
InitializeCriticalSection( &m_sMutex );
#endif
}
......@@ -551,8 +560,8 @@ C_Mutex::~C_Mutex()
ASSERT(!iRc); // The mutex should not be locked when being destroyed
USE(iRc);
#elif defined WIN32
ASSERT(false);
#elif defined _WIN32
DeleteCriticalSection( &m_sMutex );
#endif
}
......@@ -567,8 +576,8 @@ void C_Mutex::Lock()
ASSERT(!iRc); // Errors only happen with bad uses of the mutex
USE(iRc);
#elif defined WIN32
ASSERT(false);
#elif defined _WIN32
EnterCriticalSection( &m_sMutex );
#endif
}
......@@ -583,8 +592,8 @@ void C_Mutex::UnLock()
ASSERT(!iRc); // Errors only happen with bad uses of the mutex
USE(iRc);
#elif defined WIN32
ASSERT(false);
#elif defined _WIN32
LeaveCriticalSection( &m_sMutex );
#endif
}
......@@ -607,7 +616,7 @@ int C_Mutex::TryLock()
return NO_ERR;
}
#elif defined WIN32
#elif defined _WIN32
ASSERT(false);
return GEN_ERR;
#endif
......@@ -632,8 +641,8 @@ C_Semaphore::C_Semaphore(unsigned int iInitialValue)
ASSERT(!iRc) // Should never fail
USE(iRc);
#elif defined WIN32
ASSERT(false);
#elif defined _WIN32
sSemaphore = CreateSemaphore(NULL, iInitialValue, 32767, NULL);
#endif
}
......@@ -648,8 +657,8 @@ C_Semaphore::~C_Semaphore()
ASSERT(!iRc); // No thread should be waiting on it at that time
USE(iRc);
#elif defined WIN32
ASSERT(false);
#elif defined _WIN32
CloseHandle(sSemaphore);
#endif
}
......@@ -662,9 +671,8 @@ int C_Semaphore::Post()
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
return sem_post(&sSemaphore);
#elif defined WIN32
ASSERT(false);
return GEN_ERR;
#elif defined _WIN32
return ReleaseSemaphore(sSemaphore, 1, NULL);
#endif
}
......@@ -677,9 +685,8 @@ int C_Semaphore::Wait()
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
return sem_wait(&sSemaphore);
#elif defined WIN32
ASSERT(false);
return GEN_ERR;
#elif defined _WIN32
return WaitForSingleObject(sSemaphore, INFINITE);
#endif
}
......@@ -702,8 +709,17 @@ C_Condition::C_Condition()
iRc = pthread_cond_init(&m_sCondition, NULL);
ASSERT(!iRc);
#else
ASSERT(false);
#elif defined _WIN32
InitializeCriticalSection( &m_sMutex );
/* initialise counter */
m_iWaitingThreads = 0;
/* Create an auto-reset event. */
m_sSignal = CreateEvent(NULL, /* no security */
FALSE, /* auto-reset event */
FALSE, /* non-signaled initially */
NULL); /* unnamed */
//ASSERT (!m_sSignal);
#endif
}
......@@ -720,8 +736,8 @@ C_Condition::~C_Condition()
iRc = pthread_cond_destroy(&m_sCondition);
ASSERT(!iRc); // No thread should wait on the condition
#else
ASSERT(false);
#elif defined _WIN32
DeleteCriticalSection( &m_sMutex );
#endif
}
......@@ -736,8 +752,8 @@ void C_Condition::Protect()
ASSERT(!iRc);
USE(iRc);
#else
ASSERT(false);
#elif defined _WIN32
EnterCriticalSection( &m_sMutex );
#endif
}
......@@ -752,8 +768,8 @@ void C_Condition::Release()
ASSERT(!iRc);
USE(iRc);
#else
ASSERT(false);
#elif defined _WIN32
LeaveCriticalSection( &m_sMutex );
#endif
}
......@@ -769,8 +785,14 @@ void C_Condition::Signal()
iRc = pthread_mutex_unlock(&m_sMutex);
ASSERT(!iRc);
#else
ASSERT(false);
#elif defined _WIN32
int iWaitingThreads = m_iWaitingThreads;
while (m_iWaitingThreads
&& m_iWaitingThreads == iWaitingThreads)
{
PulseEvent (m_sSignal);
Sleep (0); // deschedule the current thread
}
#endif
}
......@@ -786,8 +808,12 @@ void C_Condition::Broadcast()
iRc = pthread_mutex_unlock(&m_sMutex);
ASSERT(!iRc);
#else
ASSERT(false);
#elif defined _WIN32
while (m_iWaitingThreads)
{
PulseEvent( m_sSignal );
Sleep( 0 ); // deschedule the current thread
}
#endif
}
......@@ -802,8 +828,19 @@ void C_Condition::Wait()
ASSERT(!iRc);
USE(iRc);
#else
ASSERT(false);
#elif defined _WIN32
m_iWaitingThreads ++;
// Release the mutex
LeaveCriticalSection( &m_sMutex );
WaitForSingleObject( m_sSignal, INFINITE);
// maybe we should protect this with a mutex ?
m_iWaitingThreads --;
// Reacquire the mutex before returning.
EnterCriticalSection( &m_sMutex );
#endif
}
......@@ -2,7 +2,7 @@
* thread.h: Thread classes definition
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
* $Id: thread.h,v 1.1 2001/10/06 21:23:36 bozo Exp $
* $Id: thread.h,v 1.2 2002/03/25 00:42:21 asmax Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
*
......@@ -28,6 +28,10 @@
#ifndef _THREAD_H_
#define _THREAD_H_
#ifdef _WIN32
typedef unsigned (__stdcall *PTHREAD_START) (void *);
#endif
//------------------------------------------------------------------------------
// Forward declaration
......@@ -150,7 +154,7 @@ class C_Mutex
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
pthread_mutex_t m_sMutex;
#elif defined WIN32
CRITICAL_SECTION m_sMutex;
#endif
};
......@@ -178,6 +182,8 @@ class C_Semaphore
private:
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
sem_t sSemaphore;
#elif defined _WIN32
HANDLE sSemaphore;
#endif
};
......@@ -221,11 +227,14 @@ class C_Condition
#ifdef PTHREAD_COND_T_IN_PTHREAD_H
pthread_mutex_t m_sMutex;
pthread_cond_t m_sCondition;
#elif defined _WIN32
CRITICAL_SECTION m_sMutex;
int m_iWaitingThreads;
HANDLE m_sSignal;
#endif
};
#else
#error "Multiple inclusions of thread.h"
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment