Skip to content

Commit c567afc

Browse files
committed
py/modthread: Make Lock objects work when GIL is enabled.
1 parent a1c93a6 commit c567afc

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

py/modthread.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,24 @@
4444

4545
/****************************************************************/
4646
// Lock object
47+
// Note: with the GIL enabled we can easily synthesise a lock object
4748

4849
STATIC const mp_obj_type_t mp_type_thread_lock;
4950

5051
typedef struct _mp_obj_thread_lock_t {
5152
mp_obj_base_t base;
53+
#if !MICROPY_PY_THREAD_GIL
5254
mp_thread_mutex_t mutex;
53-
bool locked;
55+
#endif
56+
volatile bool locked;
5457
} mp_obj_thread_lock_t;
5558

5659
STATIC mp_obj_thread_lock_t *mp_obj_new_thread_lock(void) {
5760
mp_obj_thread_lock_t *self = m_new_obj(mp_obj_thread_lock_t);
5861
self->base.type = &mp_type_thread_lock;
62+
#if !MICROPY_PY_THREAD_GIL
5963
mp_thread_mutex_init(&self->mutex);
64+
#endif
6065
self->locked = false;
6166
return self;
6267
}
@@ -68,6 +73,19 @@ STATIC mp_obj_t thread_lock_acquire(size_t n_args, const mp_obj_t *args) {
6873
wait = mp_obj_get_int(args[1]);
6974
// TODO support timeout arg
7075
}
76+
#if MICROPY_PY_THREAD_GIL
77+
if (self->locked) {
78+
if (!wait) {
79+
return mp_const_false;
80+
}
81+
do {
82+
MP_THREAD_GIL_EXIT();
83+
MP_THREAD_GIL_ENTER();
84+
} while (self->locked);
85+
}
86+
self->locked = true;
87+
return mp_const_true;
88+
#else
7189
int ret = mp_thread_mutex_lock(&self->mutex, wait);
7290
if (ret == 0) {
7391
return mp_const_false;
@@ -77,14 +95,17 @@ STATIC mp_obj_t thread_lock_acquire(size_t n_args, const mp_obj_t *args) {
7795
} else {
7896
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-ret)));
7997
}
98+
#endif
8099
}
81100
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(thread_lock_acquire_obj, 1, 3, thread_lock_acquire);
82101

83102
STATIC mp_obj_t thread_lock_release(mp_obj_t self_in) {
84103
mp_obj_thread_lock_t *self = MP_OBJ_TO_PTR(self_in);
85104
// TODO check if already unlocked
86105
self->locked = false;
106+
#if !MICROPY_PY_THREAD_GIL
87107
mp_thread_mutex_unlock(&self->mutex);
108+
#endif
88109
return mp_const_none;
89110
}
90111
STATIC MP_DEFINE_CONST_FUN_OBJ_1(thread_lock_release_obj, thread_lock_release);

0 commit comments

Comments
 (0)