mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Multiple thread backends.
This commit is contained in:
@@ -21,3 +21,6 @@
|
|||||||
./modules/native/tcc/libtcc/stab.h
|
./modules/native/tcc/libtcc/stab.h
|
||||||
./libraries/luasocket/libluasocket/wsocket.*
|
./libraries/luasocket/libluasocket/wsocket.*
|
||||||
./modules/sound/lullaby/FLACDecoder.*
|
./modules/sound/lullaby/FLACDecoder.*
|
||||||
|
./modules/thread/sdl/*
|
||||||
|
./modules/thread/win32/*
|
||||||
|
./modules/thread/posix/*
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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 "delay.h"
|
||||||
|
|
||||||
|
namespace love {
|
||||||
|
|
||||||
|
void delay(unsigned int ms) {
|
||||||
|
#if LOVE_THREADS == LOVE_THREADS_POSIX
|
||||||
|
struct timespec ts1, ts2;
|
||||||
|
|
||||||
|
ts1.tv_sec = ms / 1000;
|
||||||
|
ts1.tv_nsec = (ms % 1000) * 1000000;
|
||||||
|
// FIXME: handle signals
|
||||||
|
nanosleep(&ts1, &ts2);
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_WIN32
|
||||||
|
Sleep(ms);
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_SDL
|
||||||
|
SDL_Delay(ms);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace love
|
||||||
@@ -18,24 +18,16 @@
|
|||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef LOVE_THREAD_THREAD_H
|
#ifndef DELAY_H_
|
||||||
#define LOVE_THREAD_THREAD_H
|
#define DELAY_H_
|
||||||
|
|
||||||
#include <common/Module.h>
|
#include <thread/threads.h>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace love
|
|
||||||
{
|
|
||||||
namespace thread
|
|
||||||
{
|
|
||||||
class ThreadModule : public Module
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~ThreadModule(){};
|
|
||||||
virtual void unregister(const std::string & name) = 0;
|
|
||||||
}; // ThreadModule
|
|
||||||
|
|
||||||
} // thread
|
namespace love {
|
||||||
} // love
|
|
||||||
|
|
||||||
#endif // LOVE_THREAD_THREAD_H
|
void delay(unsigned int ms);
|
||||||
|
|
||||||
|
}; // namespace love
|
||||||
|
|
||||||
|
#endif /* DELAY_H_ */
|
||||||
@@ -25,17 +25,15 @@
|
|||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "Reference.h"
|
#include "Reference.h"
|
||||||
#include "StringMap.h"
|
#include "StringMap.h"
|
||||||
|
#include <thread/threads.h>
|
||||||
|
|
||||||
// STD
|
// STD
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// SDL
|
|
||||||
#include <SDL_mutex.h>
|
|
||||||
#include <SDL_thread.h>
|
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
static SDL_mutex *gcmutex = 0;
|
static thread::Mutex *gcmutex = 0;
|
||||||
void *_gcmutex = 0;
|
void *_gcmutex = 0;
|
||||||
unsigned int _gcthread = 0;
|
unsigned int _gcthread = 0;
|
||||||
/**
|
/**
|
||||||
@@ -46,17 +44,16 @@ namespace love
|
|||||||
{
|
{
|
||||||
if (!gcmutex)
|
if (!gcmutex)
|
||||||
{
|
{
|
||||||
gcmutex = SDL_CreateMutex();
|
gcmutex = new thread::Mutex();
|
||||||
_gcmutex = (void*) gcmutex;
|
_gcmutex = (void*) gcmutex;
|
||||||
}
|
}
|
||||||
Proxy * p = (Proxy *)lua_touserdata(L, 1);
|
Proxy * p = (Proxy *)lua_touserdata(L, 1);
|
||||||
Object * t = (Object *)p->data;
|
Object * t = (Object *)p->data;
|
||||||
if(p->own)
|
if(p->own)
|
||||||
{
|
{
|
||||||
SDL_mutexP(gcmutex);
|
thread::Lock lock(gcmutex);
|
||||||
_gcthread = (unsigned int) SDL_ThreadID();
|
_gcthread = thread::ThreadBase::threadId();
|
||||||
t->release();
|
t->release();
|
||||||
SDL_mutexV(gcmutex);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -52,7 +52,7 @@
|
|||||||
#include <physics/box2d/wrap_Physics.h>
|
#include <physics/box2d/wrap_Physics.h>
|
||||||
#include <sound/wrap_Sound.h>
|
#include <sound/wrap_Sound.h>
|
||||||
#include <timer/sdl/wrap_Timer.h>
|
#include <timer/sdl/wrap_Timer.h>
|
||||||
#include <thread/sdl/wrap_Thread.h>
|
#include <thread/wrap_Thread.h>
|
||||||
|
|
||||||
// Libraries.
|
// Libraries.
|
||||||
#include "libraries/luasocket/luasocket.h"
|
#include "libraries/luasocket/luasocket.h"
|
||||||
@@ -77,7 +77,7 @@ static const luaL_Reg modules[] = {
|
|||||||
{ "love.physics", love::physics::box2d::luaopen_love_physics },
|
{ "love.physics", love::physics::box2d::luaopen_love_physics },
|
||||||
{ "love.sound", love::sound::luaopen_love_sound },
|
{ "love.sound", love::sound::luaopen_love_sound },
|
||||||
{ "love.timer", love::timer::sdl::luaopen_love_timer },
|
{ "love.timer", love::timer::sdl::luaopen_love_timer },
|
||||||
{ "love.thread", love::thread::sdl::luaopen_love_thread },
|
{ "love.thread", love::thread::luaopen_love_thread },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include "Audio.h"
|
#include "Audio.h"
|
||||||
|
#include <common/delay.h>
|
||||||
|
|
||||||
#include <sound/Decoder.h>
|
#include <sound/Decoder.h>
|
||||||
|
|
||||||
@@ -28,8 +29,34 @@ namespace audio
|
|||||||
{
|
{
|
||||||
namespace openal
|
namespace openal
|
||||||
{
|
{
|
||||||
|
Audio::PoolThread::PoolThread(Pool* pool)
|
||||||
|
: pool(pool), finish(false) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audio::PoolThread::main()
|
||||||
|
{
|
||||||
|
while(true) {
|
||||||
|
{
|
||||||
|
thread::Lock lock(mutex);
|
||||||
|
if (finish) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->update();
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audio::PoolThread::setFinish()
|
||||||
|
{
|
||||||
|
thread::Lock lock(mutex);
|
||||||
|
finish = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Audio::Audio()
|
Audio::Audio()
|
||||||
: finish(false)
|
|
||||||
{
|
{
|
||||||
// Passing zero for default device.
|
// Passing zero for default device.
|
||||||
device = alcOpenDevice(0);
|
device = alcOpenDevice(0);
|
||||||
@@ -67,15 +94,16 @@ namespace openal
|
|||||||
// pool must be allocated after AL context.
|
// pool must be allocated after AL context.
|
||||||
pool = new Pool();
|
pool = new Pool();
|
||||||
|
|
||||||
thread = SDL_CreateThread(Audio::run, (void*)this);
|
poolThread = new PoolThread(pool);
|
||||||
|
poolThread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Audio::~Audio()
|
Audio::~Audio()
|
||||||
{
|
{
|
||||||
finish = true;
|
poolThread->setFinish();
|
||||||
|
poolThread->wait();
|
||||||
SDL_WaitThread(thread, 0);
|
|
||||||
|
|
||||||
|
delete poolThread;
|
||||||
delete pool;
|
delete pool;
|
||||||
|
|
||||||
alcMakeContextCurrent(0);
|
alcMakeContextCurrent(0);
|
||||||
@@ -84,18 +112,6 @@ namespace openal
|
|||||||
alcCloseDevice(device);
|
alcCloseDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Audio::run(void * d)
|
|
||||||
{
|
|
||||||
Audio * instance = (Audio*)d;
|
|
||||||
|
|
||||||
while(!instance->finish)
|
|
||||||
{
|
|
||||||
instance->pool->update();
|
|
||||||
SDL_Delay(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * Audio::getName() const
|
const char * Audio::getName() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
#include "Pool.h"
|
#include "Pool.h"
|
||||||
|
#include <thread/threads.h>
|
||||||
|
|
||||||
// OpenAL
|
// OpenAL
|
||||||
#ifdef LOVE_MACOSX
|
#ifdef LOVE_MACOSX
|
||||||
@@ -66,17 +67,30 @@ namespace openal
|
|||||||
// The OpenAL context.
|
// The OpenAL context.
|
||||||
ALCcontext * context;
|
ALCcontext * context;
|
||||||
|
|
||||||
SDL_Thread * thread;
|
|
||||||
|
|
||||||
// The Pool.
|
// The Pool.
|
||||||
Pool * pool;
|
Pool * pool;
|
||||||
|
|
||||||
// Set this to true when the thread should finish.
|
|
||||||
// Main thread will write to this value, and Audio::run
|
|
||||||
// will read from it.
|
|
||||||
bool finish;
|
|
||||||
|
|
||||||
static int run(void * unused);
|
class PoolThread: public thread::ThreadBase {
|
||||||
|
protected:
|
||||||
|
Pool* pool;
|
||||||
|
|
||||||
|
// Set this to true when the thread should finish.
|
||||||
|
// Main thread will write to this value, and PoolThread
|
||||||
|
// will read from it.
|
||||||
|
volatile bool finish;
|
||||||
|
|
||||||
|
// finish lock
|
||||||
|
thread::Mutex mutex;
|
||||||
|
|
||||||
|
virtual void main();
|
||||||
|
|
||||||
|
public:
|
||||||
|
PoolThread(Pool* pool);
|
||||||
|
void setFinish();
|
||||||
|
};
|
||||||
|
|
||||||
|
PoolThread* poolThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace openal
|
|||||||
alGenSources(NUM_SOURCES, sources);
|
alGenSources(NUM_SOURCES, sources);
|
||||||
|
|
||||||
// Create the mutex.
|
// Create the mutex.
|
||||||
mutex = SDL_CreateMutex();
|
mutex = new thread::Mutex();
|
||||||
|
|
||||||
if(alGetError() != AL_NO_ERROR)
|
if(alGetError() != AL_NO_ERROR)
|
||||||
throw love::Exception("Could not generate sources.");
|
throw love::Exception("Could not generate sources.");
|
||||||
@@ -58,7 +58,7 @@ namespace openal
|
|||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
SDL_DestroyMutex(mutex);
|
delete mutex;
|
||||||
|
|
||||||
// Free all sources.
|
// Free all sources.
|
||||||
alDeleteSources(NUM_SOURCES, sources);
|
alDeleteSources(NUM_SOURCES, sources);
|
||||||
@@ -67,28 +67,30 @@ namespace openal
|
|||||||
bool Pool::isAvailable() const
|
bool Pool::isAvailable() const
|
||||||
{
|
{
|
||||||
bool has = false;
|
bool has = false;
|
||||||
LOCK(mutex);
|
{
|
||||||
has = !available.empty();
|
thread::Lock lock(mutex);
|
||||||
UNLOCK(mutex);
|
has = !available.empty();
|
||||||
|
}
|
||||||
return has;
|
return has;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pool::isPlaying(Source * s)
|
bool Pool::isPlaying(Source * s)
|
||||||
{
|
{
|
||||||
bool p = false;
|
bool p = false;
|
||||||
LOCK(mutex);
|
|
||||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
|
||||||
{
|
{
|
||||||
if(i->first == s)
|
thread::Lock lock(mutex);
|
||||||
p = true;
|
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||||
|
{
|
||||||
|
if(i->first == s)
|
||||||
|
p = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UNLOCK(mutex);
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::update()
|
void Pool::update()
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
|
|
||||||
std::map<Source *, ALuint>::iterator i = playing.begin();
|
std::map<Source *, ALuint>::iterator i = playing.begin();
|
||||||
|
|
||||||
@@ -107,8 +109,6 @@ namespace openal
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Pool::getNumSources() const
|
int Pool::getNumSources() const
|
||||||
@@ -126,7 +126,7 @@ namespace openal
|
|||||||
bool ok;
|
bool ok;
|
||||||
out = 0;
|
out = 0;
|
||||||
|
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
|
|
||||||
bool alreadyPlaying = findSource(source, out);
|
bool alreadyPlaying = findSource(source, out);
|
||||||
|
|
||||||
@@ -160,14 +160,12 @@ namespace openal
|
|||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK(mutex);
|
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::stop()
|
void Pool::stop()
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||||
{
|
{
|
||||||
i->first->stopAtomic();
|
i->first->stopAtomic();
|
||||||
@@ -175,66 +173,57 @@ namespace openal
|
|||||||
}
|
}
|
||||||
|
|
||||||
playing.clear();
|
playing.clear();
|
||||||
|
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::stop(Source * source)
|
void Pool::stop(Source * source)
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
removeSource(source);
|
removeSource(source);
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::pause()
|
void Pool::pause()
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||||
i->first->pauseAtomic();
|
i->first->pauseAtomic();
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::pause(Source * source)
|
void Pool::pause(Source * source)
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
ALuint out;
|
ALuint out;
|
||||||
if(findSource(source, out))
|
if(findSource(source, out))
|
||||||
source->pauseAtomic();
|
source->pauseAtomic();
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::resume()
|
void Pool::resume()
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||||
i->first->resumeAtomic();
|
i->first->resumeAtomic();
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::resume(Source * source)
|
void Pool::resume(Source * source)
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
ALuint out;
|
ALuint out;
|
||||||
if(findSource(source, out))
|
if(findSource(source, out))
|
||||||
source->resumeAtomic();
|
source->resumeAtomic();
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::rewind()
|
void Pool::rewind()
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
|
||||||
i->first->rewindAtomic();
|
i->first->rewindAtomic();
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::rewind(Source * source)
|
void Pool::rewind(Source * source)
|
||||||
{
|
{
|
||||||
LOCK(mutex);
|
thread::Lock lock(mutex);
|
||||||
ALuint out;
|
ALuint out;
|
||||||
if(findSource(source, out))
|
if(findSource(source, out))
|
||||||
source->rewindAtomic();
|
source->rewindAtomic();
|
||||||
UNLOCK(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pool::release(Source * source)
|
void Pool::release(Source * source)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
// LOVE
|
// LOVE
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
#include <common/Exception.h>
|
#include <common/Exception.h>
|
||||||
|
#include <thread/threads.h>
|
||||||
|
|
||||||
// OpenAL
|
// OpenAL
|
||||||
#ifdef LOVE_MACOSX
|
#ifdef LOVE_MACOSX
|
||||||
@@ -70,7 +71,7 @@ namespace openal
|
|||||||
|
|
||||||
// Only one thread can access this object at the same time. This mutex will
|
// Only one thread can access this object at the same time. This mutex will
|
||||||
// make sure of that.
|
// make sure of that.
|
||||||
SDL_mutex * mutex;
|
thread::Mutex* mutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,14 @@ namespace love
|
|||||||
{
|
{
|
||||||
namespace thread
|
namespace thread
|
||||||
{
|
{
|
||||||
namespace sdl
|
|
||||||
{
|
Thread::ThreadThread::ThreadThread(ThreadData* comm)
|
||||||
int threadfunc(ThreadData *comm)
|
: comm(comm)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::ThreadThread::main() {
|
||||||
lua_State * L = lua_open();
|
lua_State * L = lua_open();
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
#ifdef LOVE_BUILD_STANDALONE
|
#ifdef LOVE_BUILD_STANDALONE
|
||||||
@@ -53,17 +57,18 @@ namespace sdl
|
|||||||
lua_setfield(L, -2, "_curthread");
|
lua_setfield(L, -2, "_curthread");
|
||||||
if(luaL_dostring(L, comm->getCode()) == 1)
|
if(luaL_dostring(L, comm->getCode()) == 1)
|
||||||
{
|
{
|
||||||
SDL_mutexP((SDL_mutex*) comm->mutex);
|
{
|
||||||
ThreadVariant *v = new ThreadVariant(lua_tostring(L, -1), lua_strlen(L, -1));
|
Lock lock((Mutex*) comm->mutex);
|
||||||
comm->setValue("error", v);
|
ThreadVariant *v = new ThreadVariant(lua_tostring(L, -1), lua_strlen(L, -1));
|
||||||
v->release();
|
comm->setValue("error", v);
|
||||||
SDL_mutexV((SDL_mutex*) comm->mutex);
|
v->release();
|
||||||
SDL_CondBroadcast((SDL_cond*) comm->cond);
|
}
|
||||||
|
((Conditional*) comm->cond)->broadcast();
|
||||||
}
|
}
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ThreadVariant::ThreadVariant(bool boolean)
|
ThreadVariant::ThreadVariant(bool boolean)
|
||||||
{
|
{
|
||||||
type = BOOLEAN;
|
type = BOOLEAN;
|
||||||
@@ -183,8 +188,8 @@ namespace sdl
|
|||||||
this->data = new char[len+1];
|
this->data = new char[len+1];
|
||||||
memset(this->data, 0, len+1);
|
memset(this->data, 0, len+1);
|
||||||
memcpy(this->data, data->getData(), len);
|
memcpy(this->data, data->getData(), len);
|
||||||
mutex = SDL_CreateMutex();
|
mutex = new Mutex();
|
||||||
cond = SDL_CreateCond();
|
cond = new Conditional();
|
||||||
comm = new ThreadData(name.c_str(), name.length(), this->data, mutex, cond);
|
comm = new ThreadData(name.c_str(), name.length(), this->data, mutex, cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +197,8 @@ namespace sdl
|
|||||||
: handle(0), module(module), name(name), data(0), isThread(false)
|
: handle(0), module(module), name(name), data(0), isThread(false)
|
||||||
{
|
{
|
||||||
module->retain();
|
module->retain();
|
||||||
mutex = SDL_CreateMutex();
|
mutex = new Mutex();
|
||||||
cond = SDL_CreateCond();
|
cond = new Conditional();
|
||||||
comm = new ThreadData(name.c_str(), name.length(), NULL, mutex, cond);
|
comm = new ThreadData(name.c_str(), name.length(), NULL, mutex, cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,25 +208,27 @@ namespace sdl
|
|||||||
delete[] data;
|
delete[] data;
|
||||||
delete comm;
|
delete comm;
|
||||||
module->unregister(name);
|
module->unregister(name);
|
||||||
SDL_DestroyMutex(mutex);
|
delete mutex;
|
||||||
SDL_DestroyCond(cond);
|
delete cond;
|
||||||
module->release();
|
module->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::start()
|
void Thread::start()
|
||||||
{
|
{
|
||||||
if (!handle && isThread)
|
if (!handle && isThread) {
|
||||||
handle = SDL_CreateThread((int (*)(void*)) threadfunc, (void*) comm);
|
handle = new ThreadThread(comm);
|
||||||
|
handle->start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::kill()
|
void Thread::kill()
|
||||||
{
|
{
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
SDL_mutexP((SDL_mutex *) _gcmutex);
|
Lock lock((Mutex *) _gcmutex);
|
||||||
SDL_KillThread(handle);
|
handle->kill();
|
||||||
|
delete handle;
|
||||||
handle = 0;
|
handle = 0;
|
||||||
SDL_mutexV((SDL_mutex *) _gcmutex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,19 +236,20 @@ namespace sdl
|
|||||||
{
|
{
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
SDL_WaitThread(handle, NULL);
|
handle->wait();
|
||||||
|
delete handle;
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::lock()
|
void Thread::lock()
|
||||||
{
|
{
|
||||||
SDL_mutexP(mutex);
|
mutex->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::unlock()
|
void Thread::unlock()
|
||||||
{
|
{
|
||||||
SDL_mutexV(mutex);
|
mutex->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Thread::getName()
|
std::string Thread::getName()
|
||||||
@@ -264,7 +272,7 @@ namespace sdl
|
|||||||
{
|
{
|
||||||
if (comm->getValue("error"))
|
if (comm->getValue("error"))
|
||||||
return 0;
|
return 0;
|
||||||
SDL_CondWait(cond, mutex);
|
cond->wait(mutex);
|
||||||
v = comm->getValue(name);
|
v = comm->getValue(name);
|
||||||
}
|
}
|
||||||
v->retain();
|
v->retain();
|
||||||
@@ -281,7 +289,7 @@ namespace sdl
|
|||||||
lock(); //this function explicitly locks
|
lock(); //this function explicitly locks
|
||||||
comm->setValue(name, v); //because we need
|
comm->setValue(name, v); //because we need
|
||||||
unlock(); //it to unlock here for the cond
|
unlock(); //it to unlock here for the cond
|
||||||
SDL_CondBroadcast(cond);
|
cond->broadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadModule::ThreadModule()
|
ThreadModule::ThreadModule()
|
||||||
@@ -294,6 +302,7 @@ namespace sdl
|
|||||||
for (threadlist_t::iterator i = threads.begin(); i != threads.end(); i++)
|
for (threadlist_t::iterator i = threads.begin(); i != threads.end(); i++)
|
||||||
{
|
{
|
||||||
i->second->kill();
|
i->second->kill();
|
||||||
|
delete i->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,6 +342,7 @@ namespace sdl
|
|||||||
if (threads.count(name) == 0)
|
if (threads.count(name) == 0)
|
||||||
return;
|
return;
|
||||||
threadlist_t::iterator i = threads.find(name);
|
threadlist_t::iterator i = threads.find(name);
|
||||||
|
// FIXME: shouldn't the thread be deleted?
|
||||||
threads.erase(i);
|
threads.erase(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,6 +350,6 @@ namespace sdl
|
|||||||
{
|
{
|
||||||
return "love.thread.sdl";
|
return "love.thread.sdl";
|
||||||
}
|
}
|
||||||
} // sdl
|
|
||||||
} // thread
|
} // thread
|
||||||
} // love
|
} // love
|
||||||
@@ -21,25 +21,24 @@
|
|||||||
#ifndef LOVE_THREAD_SDL_THREAD_H
|
#ifndef LOVE_THREAD_SDL_THREAD_H
|
||||||
#define LOVE_THREAD_SDL_THREAD_H
|
#define LOVE_THREAD_SDL_THREAD_H
|
||||||
|
|
||||||
// SDL
|
|
||||||
#include <SDL_thread.h>
|
|
||||||
#include <SDL_mutex.h>
|
|
||||||
|
|
||||||
// STL
|
// STL
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include <thread/ThreadModule.h>
|
|
||||||
#include <filesystem/File.h>
|
#include <filesystem/File.h>
|
||||||
#include <common/runtime.h>
|
#include <common/runtime.h>
|
||||||
|
#include <common/Module.h>
|
||||||
|
#include <thread/threads.h>
|
||||||
|
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace thread
|
namespace thread
|
||||||
{
|
{
|
||||||
namespace sdl
|
|
||||||
{
|
class ThreadModule;
|
||||||
|
|
||||||
enum ThreadVariantType
|
enum ThreadVariantType
|
||||||
{
|
{
|
||||||
UNKNOWN = 0,
|
UNKNOWN = 0,
|
||||||
@@ -98,15 +97,28 @@ namespace sdl
|
|||||||
class Thread : public love::Object
|
class Thread : public love::Object
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SDL_Thread *handle;
|
class ThreadThread: public ThreadBase {
|
||||||
love::thread::ThreadModule *module;
|
private:
|
||||||
|
ThreadData* comm;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void main();
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThreadThread(ThreadData* comm);
|
||||||
|
};
|
||||||
|
|
||||||
|
ThreadThread *handle;
|
||||||
|
|
||||||
|
ThreadModule *module;
|
||||||
ThreadData *comm;
|
ThreadData *comm;
|
||||||
std::string name;
|
std::string name;
|
||||||
char *data;
|
char *data;
|
||||||
SDL_mutex *mutex;
|
Mutex *mutex;
|
||||||
SDL_cond *cond;
|
Conditional *cond;
|
||||||
bool isThread;
|
bool isThread;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Thread(love::thread::ThreadModule *module, const std::string & name, love::Data *data);
|
Thread(love::thread::ThreadModule *module, const std::string & name, love::Data *data);
|
||||||
Thread(love::thread::ThreadModule *module, const std::string & name);
|
Thread(love::thread::ThreadModule *module, const std::string & name);
|
||||||
@@ -125,7 +137,7 @@ namespace sdl
|
|||||||
|
|
||||||
typedef std::map<std::string, Thread*> threadlist_t;
|
typedef std::map<std::string, Thread*> threadlist_t;
|
||||||
|
|
||||||
class ThreadModule : public love::thread::ThreadModule
|
class ThreadModule : public love::Module
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
threadlist_t threads;
|
threadlist_t threads;
|
||||||
@@ -140,7 +152,6 @@ namespace sdl
|
|||||||
void unregister(const std::string & name);
|
void unregister(const std::string & name);
|
||||||
const char *getName() const;
|
const char *getName() const;
|
||||||
}; // ThreadModule
|
}; // ThreadModule
|
||||||
} // sdl
|
|
||||||
} // thread
|
} // thread
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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 "threads.h"
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
Mutex::Mutex() {
|
||||||
|
pthread_create_mutex(&mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mutex::~Mutex() {
|
||||||
|
pthread_mutex_destroy(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex::lock() {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex::unlock() {
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void* ThreadBase::thread_runner(void* param) {
|
||||||
|
ThreadBase* thread = (ThreadBase*)param;
|
||||||
|
thread->main();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ThreadBase::ThreadBase() : running(false) {
|
||||||
|
pthread_t thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ThreadBase::~ThreadBase() {
|
||||||
|
if (running) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool ThreadBase::start() {
|
||||||
|
if (pthread_create(&thread, NULL, thread_runner, this)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
running = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ThreadBase::wait() {
|
||||||
|
pthread_join(thread, NULL);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ThreadBase::kill() {
|
||||||
|
// FIXME: I'm not sure about that one.
|
||||||
|
pthread_kill(thread, 9);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ThreadBase::threadId() {
|
||||||
|
return (unsigned int)((size_t)pthread_self());
|
||||||
|
}
|
||||||
|
|
||||||
|
Semaphore::Semaphore(unsigned int initial_value) {
|
||||||
|
sem_init(&sem, 0, initial_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Semaphore::~Semaphore() {
|
||||||
|
sem_destroy(&sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Semaphore::value() {
|
||||||
|
int val = 0;
|
||||||
|
if (sem_getvalue(&sem, &val)) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Semaphore::post() {
|
||||||
|
sem_post(&sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Semaphore::wait(int timeout) {
|
||||||
|
if (timeout < 0) {
|
||||||
|
if (sem_wait(&sem)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (timeout == 0) {
|
||||||
|
if (sem_trywait(&sem)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = timeout/1000;
|
||||||
|
ts.tv_nsec = (timeout % 1000) * 1000000;
|
||||||
|
if (sem_timedwait(&sem, &ts)) {
|
||||||
|
return false; // either timeout or error...
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Semaphore::tryWait() {
|
||||||
|
if (sem_trywait(&sem)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Conditional::Conditional() {
|
||||||
|
pthread_cond_init(&cond, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditional::~Conditional() {
|
||||||
|
pthread_cond_destroy(&cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conditional::signal() {
|
||||||
|
pthread_cond_signal(&cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conditional::broadcast() {
|
||||||
|
pthread_cond_broadcast(&cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Conditional::wait(Mutex* mutex, int timeout) {
|
||||||
|
if (timeout < 0) {
|
||||||
|
if (pthread_cond_wait(cond, mutex->mutex)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct timespec ts;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ts.tv_sec = timeout / 1000;
|
||||||
|
ts.tv_nsec = (timeout % 1000) * 1000000;
|
||||||
|
|
||||||
|
ret = pthread_cond_timedwait(&cond, mutex->mutex, &ts);
|
||||||
|
if (ret == ETIMEDOUT) {
|
||||||
|
return false;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// something bad happend!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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_PLATFORM_POSIX_THREADS_H_
|
||||||
|
#define LOVE_PLATFORM_POSIX_THREADS_H_
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
class Mutex {
|
||||||
|
private:
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
Mutex(const Mutex& mutex) {}
|
||||||
|
|
||||||
|
friend class Conditional;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mutex();
|
||||||
|
~Mutex();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadBase {
|
||||||
|
private:
|
||||||
|
pthread_t thread;
|
||||||
|
ThreadBase(ThreadBase& thread) {}
|
||||||
|
|
||||||
|
static void* thread_runner(void* param);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void main() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThreadBase();
|
||||||
|
virtual ~ThreadBase();
|
||||||
|
|
||||||
|
bool start();
|
||||||
|
void wait();
|
||||||
|
void kill();
|
||||||
|
|
||||||
|
static unsigned int threadId();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Semaphore {
|
||||||
|
private:
|
||||||
|
Semaphore(const Semaphore& sem) {}
|
||||||
|
sem_t semaphore;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Semaphore(unsigned int initial_value);
|
||||||
|
~Semaphore();
|
||||||
|
|
||||||
|
unsigned int value();
|
||||||
|
void post();
|
||||||
|
bool wait(int timeout = -1);
|
||||||
|
bool tryWait();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Should conditional inherit from mutex?
|
||||||
|
class Conditional {
|
||||||
|
private:
|
||||||
|
pthread_cond_t cond;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Conditional();
|
||||||
|
~Conditional();
|
||||||
|
|
||||||
|
void signal();
|
||||||
|
void broadcast();
|
||||||
|
bool wait(Mutex* mutex, int timeout=-1);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !LOVE_PLATFORM_POSIX_THREADS_H_
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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 "threads.h"
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
Mutex::Mutex() {
|
||||||
|
mutex = SDL_CreateMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mutex::~Mutex() {
|
||||||
|
SDL_DestroyMutex(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex::lock() {
|
||||||
|
SDL_mutexP(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex::unlock() {
|
||||||
|
SDL_mutexV(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ThreadBase::thread_runner(void* param) {
|
||||||
|
ThreadBase* thread = (ThreadBase*)param;
|
||||||
|
thread->main();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBase::ThreadBase() : running(false) {
|
||||||
|
SDL_Thread* thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBase::~ThreadBase() {
|
||||||
|
if (running) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadBase::start() {
|
||||||
|
thread = SDL_CreateThread(thread_runner, this);
|
||||||
|
if (thread == NULL) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
running = true;
|
||||||
|
return 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);
|
||||||
|
if (ret == SDL_MUTEX_TIMEDOUT) {
|
||||||
|
return false;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// some nasty error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Semaphore::tryWait() {
|
||||||
|
return SDL_SemTryWait(semaphore) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Conditional::Conditional() {
|
||||||
|
cond = SDL_CreateCond();
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditional::~Conditional() {
|
||||||
|
SDL_DestroyCond(cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conditional::signal() {
|
||||||
|
SDL_CondSignal(cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conditional::broadcast() {
|
||||||
|
SDL_CondBroadcast(cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Conditional::wait(Mutex* mutex, int timeout) {
|
||||||
|
if (timeout < 0) {
|
||||||
|
if (SDL_CondWait(cond, mutex->mutex)) {
|
||||||
|
// error
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int ret = SDL_CondWaitTimeout(cond, mutex->mutex, timeout);
|
||||||
|
if (ret == SDL_MUTEX_TIMEDOUT) {
|
||||||
|
return false;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// some bad error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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_PLATFORM_SDL_THREADS_H_
|
||||||
|
#define LOVE_PLATFORM_SDL_THREADS_H_
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
class Mutex {
|
||||||
|
private:
|
||||||
|
SDL_mutex* mutex;
|
||||||
|
Mutex(const Mutex& mutex) {}
|
||||||
|
|
||||||
|
friend class Conditional;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mutex();
|
||||||
|
~Mutex();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadBase {
|
||||||
|
private:
|
||||||
|
SDL_Thread* thread;
|
||||||
|
ThreadBase(ThreadBase& thread) {}
|
||||||
|
bool running;
|
||||||
|
|
||||||
|
static int thread_runner(void* param);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void main() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThreadBase();
|
||||||
|
virtual ~ThreadBase();
|
||||||
|
|
||||||
|
bool start();
|
||||||
|
void wait();
|
||||||
|
void kill(); // FIXME: not supported by SDL (SDL's kill is probably cancel)?
|
||||||
|
|
||||||
|
static unsigned int threadId();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Semaphore {
|
||||||
|
private:
|
||||||
|
Semaphore(const Semaphore& sem) {}
|
||||||
|
SDL_sem* semaphore;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Semaphore(unsigned int initial_value);
|
||||||
|
~Semaphore();
|
||||||
|
|
||||||
|
unsigned int value();
|
||||||
|
void post();
|
||||||
|
bool wait(int timeout = -1);
|
||||||
|
bool tryWait();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Should conditional inherit from mutex?
|
||||||
|
class Conditional {
|
||||||
|
private:
|
||||||
|
SDL_cond* cond;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Conditional();
|
||||||
|
~Conditional();
|
||||||
|
|
||||||
|
void signal();
|
||||||
|
void broadcast();
|
||||||
|
bool wait(Mutex* mutex, int timeout=-1);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !LOVE_PLATFORM_SDL_THREADS_H_
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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 "threads.h"
|
||||||
|
|
||||||
|
#if LOVE_THREADS == LOVE_THREADS_POSIX
|
||||||
|
# include "posix/threads.cpp"
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_WIN32
|
||||||
|
# include "win32/threads.cpp"
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_SDL
|
||||||
|
# include "sdl/threads.cpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
const char* threadAPI() {
|
||||||
|
#if LOVE_THREADS == LOVE_THREADS_POSIX
|
||||||
|
return "posix";
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_WIN32
|
||||||
|
return "win32";
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_SDL
|
||||||
|
return "sdl";
|
||||||
|
#else
|
||||||
|
return "unknown"; // ?!?!?!
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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_THREADS_H_
|
||||||
|
#define LOVE_THREADS_H_
|
||||||
|
|
||||||
|
#define LOVE_THREADS_SDL 0
|
||||||
|
#define LOVE_THREADS_WIN32 1
|
||||||
|
#define LOVE_THREADS_POSIX 2
|
||||||
|
|
||||||
|
// Choose correct threads API.
|
||||||
|
// Headless love uses either windows threads or posix threads.
|
||||||
|
// Headed (standard) love uses SDL threads.
|
||||||
|
#ifdef LOVE_HEADLESS
|
||||||
|
# ifdef WIN32
|
||||||
|
# define LOVE_THREADS LOVE_THREADS_WIN32
|
||||||
|
# else
|
||||||
|
# define LOVE_THREADS LOVE_THREADS_POSIX
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define LOVE_THREADS LOVE_THREADS_SDL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// include the correct header
|
||||||
|
#if LOVE_THREADS == LOVE_THREADS_POSIX
|
||||||
|
# include "posix/threads.h"
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_WIN32
|
||||||
|
# include "win32/threads.h"
|
||||||
|
#elif LOVE_THREADS == LOVE_THREADS_SDL
|
||||||
|
# include "sdl/threads.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
const char* threadAPI();
|
||||||
|
|
||||||
|
class Lock {
|
||||||
|
private:
|
||||||
|
Mutex* mutex;
|
||||||
|
|
||||||
|
Lock(Lock& lock) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Lock(Mutex* m): mutex(m) {
|
||||||
|
mutex->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
Lock(Mutex& m): mutex(&m) {
|
||||||
|
mutex->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~Lock() {
|
||||||
|
mutex->unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
|
|
||||||
|
#endif /* LOVE_THREADS_H_ */
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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 "threads.h"
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
Mutex::Mutex() {
|
||||||
|
InitializeCriticalSection(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mutex::~Mutex() {
|
||||||
|
DeleteCriticalSection(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Mutex::lock() {
|
||||||
|
EnterCriticalSection(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Mutex::unlock() {
|
||||||
|
LeaveCriticalSection(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ThreadBase::thread_runner(void* param) {
|
||||||
|
ThreadBase* thread = (ThreadBase*)param;
|
||||||
|
thread->main();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBase::ThreadBase() : running(false) {
|
||||||
|
HANDLE thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ThreadBase::~ThreadBase() {
|
||||||
|
if (running) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool ThreadBase::start() {
|
||||||
|
thread = CreateThread(NULL, 0, run_thread, rd, NULL);
|
||||||
|
if (thread == NULL) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
running = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadBase::wait() {
|
||||||
|
WaitForSingleObject(thread, INFINITE);
|
||||||
|
CloseHandle(thread);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadBase::kill() {
|
||||||
|
TerminateThread(thread, FALSE);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ThreadBase::threadId() {
|
||||||
|
return (unsigned int)GetCurrentThreadId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Semaphore::Semaphore(unsigned int initial_value)
|
||||||
|
: count(initial_value) {
|
||||||
|
semaphore = CreateSemaphore(NULL, initial_value, 65535, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Semaphore::~Semaphore() {
|
||||||
|
CloseHandle(semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Semaphore::value() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Semaphore::post() {
|
||||||
|
InterlockedIncrement(&count);
|
||||||
|
if (ReleaseSemaphore(semaphore, 1, NULL) == FALSE) {
|
||||||
|
InterlockedDecrement(&count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Semaphore::wait(int timeout) {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = WaitForSingleObject(semaphore, timeout < 0 ? INFINITE : timeout);
|
||||||
|
if (result == WAIT_OBJECT_0) {
|
||||||
|
InterlockedDecrement(&count);
|
||||||
|
return true;
|
||||||
|
} else if (result == WAIT_TIMEOUT) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Semaphore::tryWait() {
|
||||||
|
return wait(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Conditional variable implementation based on semaphores.
|
||||||
|
// Vista+ builds should probably use CONDITIONAL_VARIABLE.
|
||||||
|
//
|
||||||
|
// based on http://www.cs.wustl.edu/~schmidt/win32-cv-2.html and ACE
|
||||||
|
|
||||||
|
|
||||||
|
Conditional::Conditional()
|
||||||
|
: waiting(0), signals(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditional::~Conditional() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conditional::signal() {
|
||||||
|
mutex.lock();
|
||||||
|
if (waiting > signals) {
|
||||||
|
signals++;
|
||||||
|
sem.post();
|
||||||
|
mutex.unlock();
|
||||||
|
done.wait();
|
||||||
|
} else {
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conditional::broadcast() {
|
||||||
|
mutex.lock();
|
||||||
|
if (waiting > signals) {
|
||||||
|
int num = waiting - signals;
|
||||||
|
signals = waiting;
|
||||||
|
for(int i = 0; i < num; i++) sem.post();
|
||||||
|
mutex.unlock();
|
||||||
|
for(int i = 0; i < num; i++) done.wait();
|
||||||
|
} else {
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Conditional::wait(Mutex* cmutex, int timeout) {
|
||||||
|
mutex.lock();
|
||||||
|
waiting++;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
cmutex->unlock();
|
||||||
|
bool ret = sem.wait(timeout);
|
||||||
|
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
if (signals > 0) {
|
||||||
|
if (!ret) sem.wait();
|
||||||
|
done.post();
|
||||||
|
signals--;
|
||||||
|
}
|
||||||
|
waiting--;
|
||||||
|
mutex.unlock();
|
||||||
|
cmutex->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 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_PLATFROM_WIN32_THREADS_H_
|
||||||
|
#define LOVE_PLATFROM_WIN32_THREADS_H_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace thread
|
||||||
|
{
|
||||||
|
|
||||||
|
class Mutex {
|
||||||
|
private:
|
||||||
|
CRITICAL_SECTION mutex;
|
||||||
|
Mutex(const Mutex& mutex) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mutex();
|
||||||
|
~Mutex();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThreadBase {
|
||||||
|
private:
|
||||||
|
HANDLE thread;
|
||||||
|
ThreadBase(ThreadBase& thread) {}
|
||||||
|
bool running;
|
||||||
|
|
||||||
|
static int thread_runner(void* param);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void main() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThreadBase();
|
||||||
|
virtual ~ThreadBase();
|
||||||
|
|
||||||
|
bool start();
|
||||||
|
void wait();
|
||||||
|
void kill();
|
||||||
|
|
||||||
|
static unsigned int threadId();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Semaphore {
|
||||||
|
private:
|
||||||
|
Semaphore(const Semaphore& sem) {}
|
||||||
|
HANDLE semaphore;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Semaphore(unsigned int initial_value);
|
||||||
|
~Semaphore();
|
||||||
|
|
||||||
|
unsigned int value();
|
||||||
|
void post();
|
||||||
|
bool wait(int timeout = -1);
|
||||||
|
bool tryWait();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Should conditional inherit from mutex?
|
||||||
|
class Conditional {
|
||||||
|
private:
|
||||||
|
Mutex mutex;
|
||||||
|
int waiting;
|
||||||
|
int signals;
|
||||||
|
Semaphore sem;
|
||||||
|
Semaphore done;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Conditional();
|
||||||
|
~Conditional();
|
||||||
|
|
||||||
|
void signal();
|
||||||
|
void broadcast();
|
||||||
|
bool wait(Mutex* cmutex, int timeout=-1);
|
||||||
|
};
|
||||||
|
} // namespace thread
|
||||||
|
} // namespace love
|
||||||
|
|
||||||
|
#endif /* LOVE_PLATFROM_WIN32_THREADS_H_ */
|
||||||
@@ -35,8 +35,6 @@ namespace
|
|||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace thread
|
namespace thread
|
||||||
{
|
|
||||||
namespace sdl
|
|
||||||
{
|
{
|
||||||
Thread *luax_checkthread(lua_State *L, int idx)
|
Thread *luax_checkthread(lua_State *L, int idx)
|
||||||
{
|
{
|
||||||
@@ -390,4 +388,3 @@ namespace sdl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -29,8 +29,6 @@ namespace love
|
|||||||
{
|
{
|
||||||
extern StringMap<Type, TYPE_MAX_ENUM> types;
|
extern StringMap<Type, TYPE_MAX_ENUM> types;
|
||||||
namespace thread
|
namespace thread
|
||||||
{
|
|
||||||
namespace sdl
|
|
||||||
{
|
{
|
||||||
Thread *luax_checkthread(lua_State *L, int idx);
|
Thread *luax_checkthread(lua_State *L, int idx);
|
||||||
int w_Thread_start(lua_State *L);
|
int w_Thread_start(lua_State *L);
|
||||||
@@ -49,7 +47,7 @@ namespace sdl
|
|||||||
int w_getThread(lua_State *L);
|
int w_getThread(lua_State *L);
|
||||||
|
|
||||||
extern "C" LOVE_EXPORT int luaopen_love_thread(lua_State * L);
|
extern "C" LOVE_EXPORT int luaopen_love_thread(lua_State * L);
|
||||||
} // sdl
|
|
||||||
} // thread
|
} // thread
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/delay.h>
|
||||||
|
|
||||||
#ifdef LOVE_WINDOWS
|
#ifdef LOVE_WINDOWS
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
@@ -81,7 +82,7 @@ namespace sdl
|
|||||||
void Timer::sleep(int ms)
|
void Timer::sleep(int ms)
|
||||||
{
|
{
|
||||||
if(ms > 0)
|
if(ms > 0)
|
||||||
SDL_Delay(ms);
|
delay(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Timer::getDelta() const
|
float Timer::getDelta() const
|
||||||
|
|||||||
Reference in New Issue
Block a user