Skip to content

Commit 0a538e3

Browse files
committed
Acquire lock before releasing GIL
1 parent f11c949 commit 0a538e3

1 file changed

Lines changed: 25 additions & 3 deletions

File tree

apriltag_pywrap.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ typedef struct {
6868

6969
apriltag_family_t* tf;
7070
apriltag_detector_t* td;
71+
PyThread_type_lock det_lock;
7172
void (*destroy_func)(apriltag_family_t *tf);
7273
} apriltag_py_t;
7374

@@ -85,6 +86,12 @@ apriltag_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
8586
self->tf = NULL;
8687
self->td = NULL;
8788

89+
self->det_lock = PyThread_allocate_lock();
90+
if (self->det_lock == NULL) {
91+
PyErr_SetString(PyExc_RuntimeError, "Unable to allocate detection lock");
92+
goto done;
93+
}
94+
8895
const char* family = NULL;
8996
int Nthreads = 1;
9097
int maxhamming = 1;
@@ -173,6 +180,11 @@ apriltag_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
173180
self->destroy_func(self->tf);
174181
self->tf = NULL;
175182
}
183+
if(self->det_lock != NULL)
184+
{
185+
PyThread_free_lock(self->det_lock);
186+
self->det_lock = NULL;
187+
}
176188
Py_DECREF(self);
177189
}
178190
return NULL;
@@ -195,6 +207,11 @@ static void apriltag_dealloc(apriltag_py_t* self)
195207
self->destroy_func(self->tf);
196208
self->tf = NULL;
197209
}
210+
if(self->det_lock != NULL)
211+
{
212+
PyThread_free_lock(self->det_lock);
213+
self->det_lock = NULL;
214+
}
198215

199216
Py_TYPE(self)->tp_free((PyObject*)self);
200217
}
@@ -244,9 +261,14 @@ static PyObject* apriltag_detect(apriltag_py_t* self,
244261
.buf = PyArray_DATA(image)};
245262

246263
zarray_t *detections; // Declare detections variable outside of the GIL block
247-
Py_BEGIN_ALLOW_THREADS // Acquire the GIL before running detection
248-
detections = apriltag_detector_detect(self->td, &im);
249-
Py_END_ALLOW_THREADS // Release the GIL after detection completes
264+
Py_BEGIN_ALLOW_THREADS // Acquire the GIL before acquiring the detection lock
265+
if (PyThread_acquire_lock(self->det_lock, 1) == 0) { // Acquire the detection lock before running the detector
266+
PyErr_SetString(PyExc_RuntimeError, "Unable to acquire detection lock");
267+
goto done;
268+
}
269+
detections = apriltag_detector_detect(self->td, &im); // Run detection
270+
PyThread_release_lock(self->det_lock); // Release the detection lock
271+
Py_END_ALLOW_THREADS // Release the GIL after releasing the detection lock
250272

251273
int N = zarray_size(detections);
252274

0 commit comments

Comments
 (0)