Merge in channels from love-experiments

Rewritten love.thread and changed communication
method from weird system before, to channels.

--HG--
branch : minor
This commit is contained in:
Bart van Strien
2012-07-04 17:15:16 +02:00
parent e8ee7671c3
commit 399a6a6614
41 changed files with 1192 additions and 1580 deletions
+90
View File
@@ -0,0 +1,90 @@
/**
* Copyright (c) 2006-2012 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Thread.h"
namespace love
{
namespace thread
{
namespace sdl
{
Thread::Thread(Threadable *t)
: t(t), running(false), thread(0)
{
}
Thread::~Thread()
{
if (!running) // Clean up handle
wait();
/*
if (running)
wait();
FIXME: Needed for proper thread cleanup
*/
}
bool Thread::start()
{
Lock l(mutex);
if (running)
return false;
if (thread) // Clean old handle up
SDL_WaitThread(thread, 0);
thread = SDL_CreateThread(thread_runner, this);
running = (thread != 0);
return running;
}
void Thread::wait()
{
mutex.lock();
if (!thread)
return;
mutex.unlock();
SDL_WaitThread(thread, 0);
Lock l(mutex);
running = false;
thread = 0;
}
void Thread::kill()
{
Lock l(mutex);
if (!running)
return;
SDL_KillThread(thread);
SDL_WaitThread(thread, 0);
running = false;
thread = 0;
}
int Thread::thread_runner(void *data)
{
Thread *self = (Thread*) data; // some compilers don't like 'this'
self->t->threadFunction();
Lock l(self->mutex);
self->running = false;
return 0;
}
} // sdl
} // thread
} // love
+57
View File
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2006-2012 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_THREAD_SDL_THREAD_H
#define LOVE_THREAD_SDL_THREAD_H
// LOVE
#include <thread/Thread.h>
#include "threads.h"
// SDL
#include <SDL_thread.h>
namespace love
{
namespace thread
{
namespace sdl
{
class Thread : public thread::Thread
{
private:
Threadable *t;
bool running;
SDL_Thread *thread;
static int thread_runner(void *data);
Mutex mutex;
public:
Thread(Threadable *t);
~Thread();
bool start();
void kill();
void wait();
}; // Thread
} // sdl
} // thread
} // love
#endif // LOVE_THREAD_SDL_THREAD_H
+25 -86
View File
@@ -19,12 +19,14 @@
**/
#include "threads.h"
#include "Thread.h"
namespace love
{
namespace thread
{
namespace sdl
{
Mutex::Mutex()
{
mutex = SDL_CreateMutex();
@@ -45,90 +47,6 @@ void Mutex::unlock()
SDL_mutexV(mutex);
}
int ThreadBase::thread_runner(void *param)
{
ThreadBase *thread = (ThreadBase *)param;
thread->main();
return 0;
}
ThreadBase::ThreadBase()
: running(false)
{
}
ThreadBase::~ThreadBase()
{
if (running)
{
wait();
}
}
bool ThreadBase::start()
{
thread = SDL_CreateThread(thread_runner, this);
if (thread == NULL)
return false;
else
return (running = true);
}
void ThreadBase::wait()
{
SDL_WaitThread(thread, NULL);
running = false;
}
void ThreadBase::kill()
{
SDL_KillThread(thread);
running = false;
}
unsigned int ThreadBase::threadId()
{
return (unsigned int)SDL_ThreadID();
}
Semaphore::Semaphore(unsigned int initial_value)
{
semaphore = SDL_CreateSemaphore(initial_value);
}
Semaphore::~Semaphore()
{
SDL_DestroySemaphore(semaphore);
}
unsigned int Semaphore::value()
{
return SDL_SemValue(semaphore);
}
void Semaphore::post()
{
SDL_SemPost(semaphore);
}
bool Semaphore::wait(int timeout)
{
if (timeout < 0)
return SDL_SemWait(semaphore) ? false : true;
else if (timeout == 0)
return SDL_SemTryWait(semaphore) ? false : true;
else
{
int ret = SDL_SemWaitTimeout(semaphore, timeout);
return (ret == 0);
}
}
bool Semaphore::tryWait()
{
return SDL_SemTryWait(semaphore) ? false : true;
}
Conditional::Conditional()
{
cond = SDL_CreateCond();
@@ -149,13 +67,34 @@ void Conditional::broadcast()
SDL_CondBroadcast(cond);
}
bool Conditional::wait(Mutex *mutex, int timeout)
bool Conditional::wait(thread::Mutex *_mutex, int timeout)
{
// Yes, I realise this can be dangerous,
// however, you're asking for it if you're
// mixing thread implementations.
Mutex *mutex = (Mutex*) _mutex;
if (timeout < 0)
return !SDL_CondWait(cond, mutex->mutex);
else
return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0);
}
} // sdl
thread::Mutex *newMutex()
{
return new sdl::Mutex();
}
thread::Conditional *newConditional()
{
return new sdl::Conditional();
}
thread::Thread *newThread(Threadable *t)
{
return new sdl::Thread(t);
}
} // thread
} // love
+31 -67
View File
@@ -21,87 +21,51 @@
#ifndef LOVE_THREAD_SDL_THREADS_H
#define LOVE_THREAD_SDL_THREADS_H
#include "SDL.h"
#include "common/config.h"
#include <common/config.h>
#include <thread/threads.h>
#include <SDL_thread.h>
namespace love
{
namespace thread
{
class Mutex
namespace sdl
{
public:
Mutex();
~Mutex();
class Conditional;
void lock();
void unlock();
private:
SDL_mutex *mutex;
Mutex(const Mutex &/* mutex*/) {}
class Mutex : public thread::Mutex
{
public:
Mutex();
~Mutex();
friend class Conditional;
};
void lock();
void unlock();
private:
SDL_mutex* mutex;
Mutex(const Mutex&/* mutex*/) {}
friend class Conditional;
};
class ThreadBase
{
public:
ThreadBase();
virtual ~ThreadBase();
class Conditional : public thread::Conditional
{
public:
Conditional();
~Conditional();
bool start();
void wait();
void kill(); // FIXME: not supported by SDL (SDL's kill is probably cancel)?
void signal();
void broadcast();
bool wait(thread::Mutex* mutex, int timeout=-1);
static unsigned int threadId();
protected:
virtual void main() = 0;
private:
SDL_Thread *thread;
ThreadBase(ThreadBase &/* thread*/) {}
bool running;
static int thread_runner(void *param);
};
class Semaphore
{
public:
Semaphore(unsigned int initial_value);
~Semaphore();
unsigned int value();
void post();
bool wait(int timeout = -1);
bool tryWait();
private:
Semaphore(const Semaphore &/* sem*/) {}
SDL_sem *semaphore;
};
// Should conditional inherit from mutex?
class Conditional
{
public:
Conditional();
~Conditional();
void signal();
void broadcast();
bool wait(Mutex *mutex, int timeout=-1);
private:
SDL_cond *cond;
};
private:
SDL_cond* cond;
};
} // sdl
} // thread
} // love
#endif // LOVE_THREAD_SDL_THREADS_H
#endif /* LOVE_THREAD_SDL_THREADS_H */