@@ -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