forked from livecode/livecode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththread.cpp
More file actions
118 lines (89 loc) · 2.45 KB
/
thread.cpp
File metadata and controls
118 lines (89 loc) · 2.45 KB
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
#include "core.h"
#include "thread.h"
////////////////////////////////////////////////////////////////////////////////
#if defined(_WINDOWS)
#include <windows.h>
bool MCThreadEventCreate(MCThreadEventRef& r_event)
{
HANDLE t_event;
t_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (t_event == nil)
return false;
r_event = (MCThreadEventRef)t_event;
return true;
}
void MCThreadEventDestroy(MCThreadEventRef self)
{
if (self == nil)
return;
CloseHandle((HANDLE)self);
}
void MCThreadEventTrigger(MCThreadEventRef self)
{
SetEvent((HANDLE)self);
}
void MCThreadEventReset(MCThreadEventRef self)
{
ResetEvent((HANDLE)self);
}
void MCThreadEventWait(MCThreadEventRef self)
{
WaitForSingleObject((HANDLE)self, INFINITE);
}
#elif defined(_MACOSX) || defined(_LINUX)
#include <pthread.h>
struct MCThreadEvent
{
pthread_mutex_t mutex;
pthread_cond_t cond;
bool triggered;
};
bool MCThreadEventCreate(MCThreadEventRef& r_event)
{
MCThreadEvent *self;
if (!MCMemoryNew(self))
return false;
pthread_mutex_init(&self -> mutex, 0);
pthread_cond_init(&self -> cond, 0);
self -> triggered = false;
r_event = self;
return true;
}
void MCThreadEventDestroy(MCThreadEventRef self)
{
if (self == nil)
return;
pthread_cond_destroy(&self -> cond);
pthread_mutex_destroy(&self -> mutex);
MCMemoryDelete(self);
}
void MCThreadEventTrigger(MCThreadEventRef self)
{
// First lock the mutex - this ensures triggering is atomic from one thread
pthread_mutex_lock(&self -> mutex);
self -> triggered = true;
// This call will unblock one of the threads waiting in 'pthread_cond_wait'.
pthread_cond_signal(&self -> cond);
// Now unlock the mutex, causing the chosen thread to continue.
pthread_mutex_unlock(&self -> mutex);
}
void MCThreadEventReset(MCThreadEventRef self)
{
pthread_mutex_lock(&self -> mutex);
self -> triggered = false;
pthread_mutex_unlock(&self -> mutex);
}
void MCThreadEventWait(MCThreadEventRef self)
{
// Lock the mutex so wait can atomically unlock and wait
pthread_mutex_lock(&self -> mutex);
// We loop until the triggered var is true, this is because being woken up
// is no guarantee that we were actually signalled to do so.
while(!self -> triggered)
pthread_cond_wait(&self -> cond, &self -> mutex);
// At this point, we have a lock on the mutex so we release it as its
// has served its purpose.
pthread_mutex_unlock(&self -> mutex);
}
#endif
////////////////////////////////////////////////////////////////////////////////