Files
@ r10214:51bc41889761
Branch filter:
Location: cpp/openttd-patchpack/source/src/fiber_thread.cpp - annotation
r10214:51bc41889761
3.2 KiB
text/x-c
(svn r14436) -Fix [FS#1793]: (fast) trains would sometimes move one time too often/little when moving from diagonal<->non-diagonal tracks (iguannab)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r9479:31c691398ec3 r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r9476:dfe3d556ae24 r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b r8934:d5858392238b | /* $Id$ */
/** @file fiber_thread.cpp ThreadObject implementation of Fiber. */
#include "stdafx.h"
#include "fiber.hpp"
#include "thread.h"
#include <stdlib.h>
class Fiber_Thread : public Fiber {
private:
ThreadObject *m_thread;
FiberFunc m_proc;
void *m_param;
bool m_attached;
ThreadSemaphore *m_sem;
bool m_kill;
static Fiber_Thread *s_current;
static Fiber_Thread *s_main;
public:
/**
* Create a ThreadObject fiber and start it, calling proc(param).
*/
Fiber_Thread(FiberFunc proc, void *param) :
m_thread(NULL),
m_proc(proc),
m_param(param),
m_attached(false),
m_kill(false)
{
this->m_sem = ThreadSemaphore::New();
/* Create a thread and start stFiberProc */
this->m_thread = ThreadObject::New(&stFiberProc, this);
}
/**
* Create a ThreadObject fiber and attach current thread to it.
*/
Fiber_Thread(void *param) :
m_thread(NULL),
m_proc(NULL),
m_param(param),
m_attached(true),
m_kill(false)
{
this->m_sem = ThreadSemaphore::New();
/* Attach the current thread to this Fiber */
this->m_thread = ThreadObject::AttachCurrent();
/* We are the current thread */
if (s_current == NULL) s_current = this;
if (s_main == NULL) s_main = this;
}
~Fiber_Thread()
{
/* Remove the thread if needed */
if (this->m_thread != NULL) {
assert(this->m_attached || !this->m_thread->IsRunning());
delete this->m_thread;
}
/* Remove the semaphore */
delete this->m_sem;
}
/* virtual */ void SwitchToFiber()
{
/* You can't switch to yourself */
assert(s_current != this);
Fiber_Thread *cur = s_current;
/* Continue the execution of 'this' Fiber */
this->m_sem->Set();
/* Hold the execution of the current Fiber */
cur->m_sem->Wait();
if (this->m_kill) {
/* If the thread we switched too was killed, join it so it can finish quiting */
this->m_thread->Join();
}
/* If we continue, we are the current thread */
s_current = cur;
}
/* virtual */ void Exit()
{
/* Kill off our thread */
this->m_kill = true;
this->m_thread->Exit();
}
/* virtual */ bool IsRunning()
{
if (this->m_thread == NULL) return false;
return this->m_thread->IsRunning();
}
/* virtual */ void *GetFiberData()
{
return this->m_param;
}
static Fiber_Thread *GetCurrentFiber()
{
return s_current;
}
private:
/**
* First function which is called within the fiber.
*/
static void stFiberProc(void *fiber)
{
Fiber_Thread *cur = (Fiber_Thread *)fiber;
/* Now suspend the thread until we get SwitchToFiber() for the first time */
cur->m_sem->Wait();
/* If we continue, we are the current thread */
s_current = cur;
try {
cur->m_proc(cur->m_param);
} catch (...) {
/* Unlock the main thread */
s_main->m_sem->Set();
throw;
}
}
};
/* Initialize the static member of Fiber_Thread */
/* static */ Fiber_Thread *Fiber_Thread::s_current = NULL;
/* static */ Fiber_Thread *Fiber_Thread::s_main = NULL;
#ifndef WIN32
/* static */ Fiber *Fiber::New(FiberFunc proc, void *param)
{
return new Fiber_Thread(proc, param);
}
/* static */ Fiber *Fiber::AttachCurrent(void *param)
{
return new Fiber_Thread(param);
}
/* static */ void *Fiber::GetCurrentFiberData()
{
return Fiber_Thread::GetCurrentFiber()->GetFiberData();
}
#endif /* WIN32 */
|