aboutsummaryrefslogtreecommitdiffstats
path: root/src/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread.c')
-rw-r--r--src/thread.c154
1 files changed, 108 insertions, 46 deletions
diff --git a/src/thread.c b/src/thread.c
index e8e43c5e402..9c39b84eb50 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -30,12 +30,119 @@ struct thread_state *current_thread = &primary_thread;
30 30
31static struct thread_state *all_threads = &primary_thread; 31static struct thread_state *all_threads = &primary_thread;
32 32
33sys_mutex_t global_lock; 33static sys_mutex_t global_lock;
34 34
35Lisp_Object Qthreadp, Qmutexp; 35Lisp_Object Qthreadp, Qmutexp;
36 36
37 37
38 38
39static void
40release_global_lock (void)
41{
42 sys_mutex_unlock (&global_lock);
43}
44
45/* You must call this after acquiring the global lock.
46 acquire_global_lock does it for you. */
47static void
48post_acquire_global_lock (struct thread_state *self)
49{
50 Lisp_Object buffer;
51
52 if (self != current_thread)
53 {
54 unbind_for_thread_switch ();
55 current_thread = self;
56 rebind_for_thread_switch ();
57 }
58
59 /* We need special handling to re-set the buffer. */
60 XSETBUFFER (buffer, self->m_current_buffer);
61 self->m_current_buffer = 0;
62 set_buffer_internal (XBUFFER (buffer));
63
64 if (!EQ (current_thread->error_symbol, Qnil))
65 {
66 Lisp_Object sym = current_thread->error_symbol;
67 Lisp_Object data = current_thread->error_data;
68
69 current_thread->error_symbol = Qnil;
70 current_thread->error_data = Qnil;
71 Fsignal (sym, data);
72 }
73}
74
75static void
76acquire_global_lock (struct thread_state *self)
77{
78 sys_mutex_lock (&global_lock);
79 post_acquire_global_lock (self);
80}
81
82
83
84static void
85lisp_mutex_init (lisp_mutex_t *mutex)
86{
87 mutex->owner = NULL;
88 mutex->count = 0;
89 sys_cond_init (&mutex->condition);
90}
91
92static void
93lisp_mutex_lock (lisp_mutex_t *mutex)
94{
95 struct thread_state *self;
96
97 if (mutex->owner == NULL)
98 {
99 mutex->owner = current_thread;
100 mutex->count = 1;
101 return;
102 }
103 if (mutex->owner == current_thread)
104 {
105 ++mutex->count;
106 return;
107 }
108
109 self = current_thread;
110 self->wait_condvar = &mutex->condition;
111 while (mutex->owner != NULL && EQ (self->error_symbol, Qnil))
112 sys_cond_wait (&mutex->condition, &global_lock);
113 self->wait_condvar = NULL;
114
115 post_acquire_global_lock (self);
116
117 mutex->owner = self;
118 mutex->count = 1;
119}
120
121static void
122lisp_mutex_unlock (lisp_mutex_t *mutex)
123{
124 struct thread_state *self = current_thread;
125
126 if (mutex->owner != current_thread)
127 error ("blah");
128
129 if (--mutex->count > 0)
130 return;
131
132 mutex->owner = NULL;
133 sys_cond_broadcast (&mutex->condition);
134
135 post_acquire_global_lock (self);
136}
137
138static void
139lisp_mutex_destroy (lisp_mutex_t *mutex)
140{
141 sys_cond_destroy (&mutex->condition);
142}
143
144
145
39DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 1, 0, 146DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 1, 0,
40 doc: /* Create a mutex. 147 doc: /* Create a mutex.
41A mutex provides a synchronization point for threads. 148A mutex provides a synchronization point for threads.
@@ -146,51 +253,6 @@ finalize_one_mutex (struct Lisp_Mutex *mutex)
146 253
147 254
148 255
149static void
150release_global_lock (void)
151{
152 sys_mutex_unlock (&global_lock);
153}
154
155/* You must call this after acquiring the global lock.
156 acquire_global_lock does it for you. */
157void
158post_acquire_global_lock (struct thread_state *self)
159{
160 Lisp_Object buffer;
161
162 if (self != current_thread)
163 {
164 unbind_for_thread_switch ();
165 current_thread = self;
166 rebind_for_thread_switch ();
167 }
168
169 /* We need special handling to re-set the buffer. */
170 XSETBUFFER (buffer, self->m_current_buffer);
171 self->m_current_buffer = 0;
172 set_buffer_internal (XBUFFER (buffer));
173
174 if (!EQ (current_thread->error_symbol, Qnil))
175 {
176 Lisp_Object sym = current_thread->error_symbol;
177 Lisp_Object data = current_thread->error_data;
178
179 current_thread->error_symbol = Qnil;
180 current_thread->error_data = Qnil;
181 Fsignal (sym, data);
182 }
183}
184
185static void
186acquire_global_lock (struct thread_state *self)
187{
188 sys_mutex_lock (&global_lock);
189 post_acquire_global_lock (self);
190}
191
192
193
194struct select_args 256struct select_args
195{ 257{
196 select_func *func; 258 select_func *func;