Skip to content

Commit ce3ccd6

Browse files
Merge pull request #386 from Jgunde/master
Acquire Lock Before Releasing Python GIL
2 parents f11c949 + 34b5b74 commit ce3ccd6

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

apriltag_pywrap.c

Lines changed: 23 additions & 4 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
}
@@ -243,10 +260,12 @@ static PyObject* apriltag_detect(apriltag_py_t* self,
243260
.stride = strides[0],
244261
.buf = PyArray_DATA(image)};
245262

246-
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
263+
zarray_t *detections = NULL; // Declare detections variable outside the GIL macro block
264+
Py_BEGIN_ALLOW_THREADS // Release the GIL to allow other Python threads to run
265+
PyThread_acquire_lock(self->det_lock, 1); // Acquire the detection lock before running the detector (blocks until the lock is available)
266+
detections = apriltag_detector_detect(self->td, &im); // Run detection
267+
PyThread_release_lock(self->det_lock); // Release the detection lock
268+
Py_END_ALLOW_THREADS // Acquire the GIL after releasing the detection lock
250269

251270
int N = zarray_size(detections);
252271

0 commit comments

Comments
 (0)